import type { GSDEventStream } from './event-stream.js'; import { createRegistry } from './query/index.js'; import type { QueryResult } from './query/utils.js'; import { GSDTransport } from './gsd-transport.js'; import { QueryExecutionPolicy } from './query-execution-policy.js'; import { QuerySubprocessAdapter } from './query-subprocess-adapter.js'; import { QueryNativeDirectAdapter } from './query-native-direct-adapter.js'; import { QueryNativeHotpathAdapter } from './query-native-hotpath-adapter.js'; import { formatQueryRawOutput } from './query-raw-output-projection.js'; import { GSDToolsError } from './gsd-tools-error.js'; export interface GSDToolsRuntime { registry: ReturnType; executionPolicy: QueryExecutionPolicy; nativeHotpathAdapter: QueryNativeHotpathAdapter; } export function createGSDToolsRuntime(opts: { projectDir: string; gsdToolsPath: string; timeoutMs: number; workstream?: string; eventStream?: GSDEventStream; sessionId?: string; shouldUseNativeQuery: () => boolean; execJsonFallback: (legacyCommand: string, legacyArgs: string[]) => Promise; execRawFallback: (legacyCommand: string, legacyArgs: string[]) => Promise; }): GSDToolsRuntime { const registry = createRegistry(opts.eventStream, opts.sessionId); const subprocessAdapter = new QuerySubprocessAdapter({ projectDir: opts.projectDir, gsdToolsPath: opts.gsdToolsPath, timeoutMs: opts.timeoutMs, workstream: opts.workstream, createTimeoutError: (message, command, args, stderr, timeoutMs) => GSDToolsError.timeout(message, command, args, stderr, timeoutMs), createFailureError: (message, command, args, exitCode, stderr) => GSDToolsError.failure(message, command, args, exitCode, stderr), }); const nativeDirectAdapter = new QueryNativeDirectAdapter({ timeoutMs: opts.timeoutMs, dispatch: (registryCommand, registryArgs) => registry.dispatch(registryCommand, registryArgs, opts.projectDir), createTimeoutError: (message, command, args) => GSDToolsError.timeout(message, command, args, '', opts.timeoutMs), createFailureError: (message, command, args, cause) => GSDToolsError.failure(message, command, args, 1, '', { cause }), }); const transport = new GSDTransport(registry, { dispatchNative: async (request) => nativeDirectAdapter.dispatchResult( request.legacyCommand, request.legacyArgs, request.registryCommand, request.registryArgs, ) as Promise, execSubprocessJson: async (legacyCommand, legacyArgs) => subprocessAdapter.execJson(legacyCommand, legacyArgs), execSubprocessRaw: async (legacyCommand, legacyArgs) => subprocessAdapter.execRaw(legacyCommand, legacyArgs), formatNativeRaw: (registryCommand, data) => formatQueryRawOutput(registryCommand, data), }); const executionPolicy = new QueryExecutionPolicy(transport); const nativeHotpathAdapter = new QueryNativeHotpathAdapter( opts.shouldUseNativeQuery, nativeDirectAdapter, opts.execJsonFallback, opts.execRawFallback, ); return { registry, executionPolicy, nativeHotpathAdapter }; }