refactor(query): deepen command/dispatch seams and resolve coderabbit findings
* refactor(query): deepen command definition seam and fold fallback mapping cleanup * refactor(query): add shared dispatch formatting module seam * fix(query): restore QueryResult type import in dispatch deps * test/query: align raw-output policy and definition normalization contracts * refactor(query): deepen diagnosis, invariant report, and error taxonomy seams * refactor(query): deepen dispatch plan, fallback bridge, policy snapshot, and hints seams * refactor(query): deepen validation, fallback policy, capability, and result builder seams * refactor(query): deepen resolution strategy, output classifier, observability, and policy-capability seams * refactor(query): finalize deep strategy/classifier/observability/capability seams * test/query: address coderabbit inline and out-of-diff dispatch nits * fix(query): address remaining coderabbit input-validation and bridge stderr threads * fix(query): address remaining coderabbit dispatch and strategy/output nits
This commit is contained in:
54
sdk/src/query/query-fallback-bridge-adapter.ts
Normal file
54
sdk/src/query/query-fallback-bridge-adapter.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { execFile } from 'node:child_process';
|
||||
import { classifyFallbackOutput } from './query-fallback-output-classifier.js';
|
||||
|
||||
export interface FallbackBridgeRunInput {
|
||||
projectDir: string;
|
||||
gsdToolsPath: string;
|
||||
normCmd: string;
|
||||
normArgs: string[];
|
||||
ws?: string;
|
||||
}
|
||||
|
||||
export interface FallbackBridgeOutput {
|
||||
mode: 'json' | 'text';
|
||||
output: unknown;
|
||||
stderr: string;
|
||||
}
|
||||
|
||||
function dottedCommandToCjsArgv(normCmd: string, normArgs: string[]): string[] {
|
||||
if (normCmd.includes('.')) return [...normCmd.split('.'), ...normArgs];
|
||||
return [normCmd, ...normArgs];
|
||||
}
|
||||
|
||||
function execBridge(input: FallbackBridgeRunInput): Promise<{ stdout: string; stderr: string }> {
|
||||
const cjsArgv = dottedCommandToCjsArgv(input.normCmd, input.normArgs);
|
||||
const wsSuffix = input.ws ? ['--ws', input.ws] : [];
|
||||
const fullArgv = [input.gsdToolsPath, ...cjsArgv, ...wsSuffix];
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
execFile(
|
||||
process.execPath,
|
||||
fullArgv,
|
||||
{ cwd: input.projectDir, maxBuffer: 10 * 1024 * 1024, timeout: 30_000, killSignal: 'SIGKILL', env: { ...process.env } },
|
||||
(err, stdout, stderr) => {
|
||||
const stdoutText = stdout?.toString() ?? '';
|
||||
const stderrText = stderr?.toString() ?? '';
|
||||
if (err) {
|
||||
if (stderrText.trim()) {
|
||||
reject(new Error(`${err.message}\n${stderrText.trimEnd()}`));
|
||||
return;
|
||||
}
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve({ stdout: stdoutText, stderr: stderrText });
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export async function runFallbackBridge(input: FallbackBridgeRunInput): Promise<FallbackBridgeOutput> {
|
||||
const { stdout, stderr } = await execBridge(input);
|
||||
const classified = await classifyFallbackOutput(stdout, input.projectDir);
|
||||
return { ...classified, stderr };
|
||||
}
|
||||
Reference in New Issue
Block a user