import type { GSDEventStream } from './event-stream.js'; import { createRegistry } from './query/index.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 { createQueryNativeErrorFactory, createQueryToolsErrorFactory } from './query-tools-error-factory.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 queryToolsErrorFactory = createQueryToolsErrorFactory(); const subprocessAdapter = new QuerySubprocessAdapter({ projectDir: opts.projectDir, gsdToolsPath: opts.gsdToolsPath, timeoutMs: opts.timeoutMs, workstream: opts.workstream, ...queryToolsErrorFactory, }); const nativeErrorFactory = createQueryNativeErrorFactory(opts.timeoutMs); const nativeDirectAdapter = new QueryNativeDirectAdapter({ timeoutMs: opts.timeoutMs, dispatch: (registryCommand, registryArgs) => registry.dispatch(registryCommand, registryArgs, opts.projectDir), ...nativeErrorFactory, }); const transport = new GSDTransport(registry, { dispatchNative: (request) => nativeDirectAdapter.dispatchResult( request.legacyCommand, request.legacyArgs, request.registryCommand, request.registryArgs, ), execSubprocessJson: (legacyCommand, legacyArgs) => subprocessAdapter.execJson(legacyCommand, legacyArgs), execSubprocessRaw: (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 }; }