@llm-dev-ops/agentics-cli 1.4.7 → 1.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +109 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/contracts/adr-006-claude-code-synthesis-runner.d.ts +196 -0
- package/dist/contracts/adr-006-claude-code-synthesis-runner.d.ts.map +1 -0
- package/dist/contracts/adr-006-claude-code-synthesis-runner.js +177 -0
- package/dist/contracts/adr-006-claude-code-synthesis-runner.js.map +1 -0
- package/dist/contracts/adr-007-subcommand-synthesis-router.d.ts +273 -0
- package/dist/contracts/adr-007-subcommand-synthesis-router.d.ts.map +1 -0
- package/dist/contracts/adr-007-subcommand-synthesis-router.js +226 -0
- package/dist/contracts/adr-007-subcommand-synthesis-router.js.map +1 -0
- package/dist/contracts/adr-008-synthesis-artifact-persistence.d.ts +323 -0
- package/dist/contracts/adr-008-synthesis-artifact-persistence.d.ts.map +1 -0
- package/dist/contracts/adr-008-synthesis-artifact-persistence.js +184 -0
- package/dist/contracts/adr-008-synthesis-artifact-persistence.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +35 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -0
- package/dist/mcp/mcp-server.js +692 -0
- package/dist/mcp/mcp-server.js.map +1 -0
- package/dist/runtime/claude-code-runner.d.ts +93 -0
- package/dist/runtime/claude-code-runner.d.ts.map +1 -0
- package/dist/runtime/claude-code-runner.js +588 -0
- package/dist/runtime/claude-code-runner.js.map +1 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/synthesis/artifact-writer.d.ts +62 -0
- package/dist/synthesis/artifact-writer.d.ts.map +1 -0
- package/dist/synthesis/artifact-writer.js +603 -0
- package/dist/synthesis/artifact-writer.js.map +1 -0
- package/dist/synthesis/index.d.ts +7 -0
- package/dist/synthesis/index.d.ts.map +1 -0
- package/dist/synthesis/index.js +7 -0
- package/dist/synthesis/index.js.map +1 -0
- package/dist/synthesis/prompts/index.d.ts +50 -0
- package/dist/synthesis/prompts/index.d.ts.map +1 -0
- package/dist/synthesis/prompts/index.js +502 -0
- package/dist/synthesis/prompts/index.js.map +1 -0
- package/dist/synthesis/router.d.ts +70 -0
- package/dist/synthesis/router.d.ts.map +1 -0
- package/dist/synthesis/router.js +346 -0
- package/dist/synthesis/router.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesis Router — ADR-007 Implementation
|
|
3
|
+
*
|
|
4
|
+
* Enterprise-grade subcommand-aware routing layer. Intercepts decision-grade
|
|
5
|
+
* subcommands, constructs a prompt, invokes Claude Code, and returns
|
|
6
|
+
* contract-validated output with full traceability metadata.
|
|
7
|
+
*
|
|
8
|
+
* INVARIANTS:
|
|
9
|
+
* - Only DECISION_GRADE_SUBCOMMANDS can trigger Claude Code invocation
|
|
10
|
+
* - Every invocation produces exactly one Claude Code call
|
|
11
|
+
* - All returned data is contract-validated against the mapped schema
|
|
12
|
+
* - SYNTHESIS_FORBIDDEN commands never reach the Claude Code runner
|
|
13
|
+
* - The prompt, run-id, seed, and synthesis class are always in the result
|
|
14
|
+
* - Errors are wrapped with routing context for diagnostics
|
|
15
|
+
* - User-provided correlationId flows through the entire pipeline
|
|
16
|
+
*
|
|
17
|
+
* FORBIDDEN:
|
|
18
|
+
* - Calling Claude Code for SYNTHESIS_FORBIDDEN commands
|
|
19
|
+
* - Writing artifacts (ADR-008 handles that)
|
|
20
|
+
* - Calling the platform API (command executors handle that)
|
|
21
|
+
* - Mutating CLI state
|
|
22
|
+
* - Interactive confirmation (the CLI's gate pipeline handles that)
|
|
23
|
+
*/
|
|
24
|
+
import type { SynthesisRequest, SynthesisResult, SynthesisGovernanceClass, SynthesisPromptResult } from '../contracts/adr-007-subcommand-synthesis-router.js';
|
|
25
|
+
/**
|
|
26
|
+
* Determine the synthesis governance class for a (command, subcommand) pair.
|
|
27
|
+
*
|
|
28
|
+
* @returns 'COMMITMENT_GRADE' or 'SYNTHESIS_REQUIRED' for decision-grade commands, null otherwise
|
|
29
|
+
*/
|
|
30
|
+
export declare function getSynthesisClass(command: string, subcommand: string): SynthesisGovernanceClass | null;
|
|
31
|
+
/**
|
|
32
|
+
* Check if a (command, subcommand) pair is decision-grade.
|
|
33
|
+
* Convenience function for use in CLI dispatch.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isDecisionGrade(command: string, subcommand?: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Build a synthesis prompt without invoking Claude Code.
|
|
38
|
+
*
|
|
39
|
+
* Useful for:
|
|
40
|
+
* - Dry-run mode: inspect what would be sent to Claude Code
|
|
41
|
+
* - Testing: verify prompt generation in isolation
|
|
42
|
+
* - Debugging: see the exact prompt for a given (command, subcommand)
|
|
43
|
+
*
|
|
44
|
+
* Executes all four routing gates but stops before subprocess invocation.
|
|
45
|
+
*
|
|
46
|
+
* @returns SynthesisPromptResult with prompt and metadata, or null if not decision-grade
|
|
47
|
+
* @throws CLIError on missing template or schema (internal configuration errors)
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildSynthesisPrompt(request: SynthesisRequest): SynthesisPromptResult | null;
|
|
50
|
+
/**
|
|
51
|
+
* Route a command through the synthesis pipeline.
|
|
52
|
+
*
|
|
53
|
+
* This is the primary entry point for ADR-007. The flow is:
|
|
54
|
+
*
|
|
55
|
+
* 1. Validate request structure
|
|
56
|
+
* 2. Execute routing gates (decision-grade check, ADR-001 agreement,
|
|
57
|
+
* template existence, schema mapping)
|
|
58
|
+
* 3. Determine synthesis governance class (SYNTHESIS_REQUIRED or COMMITMENT_GRADE)
|
|
59
|
+
* 4. Generate run-id, seed, and prompt
|
|
60
|
+
* 5. Invoke Claude Code via ADR-006 runner with contract validation
|
|
61
|
+
* 6. Return result with full traceability metadata
|
|
62
|
+
*
|
|
63
|
+
* For non-decision-grade commands, returns null immediately with zero overhead.
|
|
64
|
+
*
|
|
65
|
+
* @returns SynthesisResult if the command is decision-grade, null otherwise
|
|
66
|
+
* @throws CLIError on router configuration errors (ECLI-SYNTH-010/011/020/021)
|
|
67
|
+
* @throws SynthesisError on Claude Code invocation failures (ECLI-SYNTH-001..005)
|
|
68
|
+
*/
|
|
69
|
+
export declare function routeSynthesis(request: SynthesisRequest): SynthesisResult | null;
|
|
70
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/synthesis/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAYH,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EAEtB,MAAM,qDAAqD,CAAC;AAwM7D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,wBAAwB,GAAG,IAAI,CAMjC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAG7E;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,GACxB,qBAAqB,GAAG,IAAI,CAkB9B;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,GAAG,IAAI,CAmGhF"}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synthesis Router — ADR-007 Implementation
|
|
3
|
+
*
|
|
4
|
+
* Enterprise-grade subcommand-aware routing layer. Intercepts decision-grade
|
|
5
|
+
* subcommands, constructs a prompt, invokes Claude Code, and returns
|
|
6
|
+
* contract-validated output with full traceability metadata.
|
|
7
|
+
*
|
|
8
|
+
* INVARIANTS:
|
|
9
|
+
* - Only DECISION_GRADE_SUBCOMMANDS can trigger Claude Code invocation
|
|
10
|
+
* - Every invocation produces exactly one Claude Code call
|
|
11
|
+
* - All returned data is contract-validated against the mapped schema
|
|
12
|
+
* - SYNTHESIS_FORBIDDEN commands never reach the Claude Code runner
|
|
13
|
+
* - The prompt, run-id, seed, and synthesis class are always in the result
|
|
14
|
+
* - Errors are wrapped with routing context for diagnostics
|
|
15
|
+
* - User-provided correlationId flows through the entire pipeline
|
|
16
|
+
*
|
|
17
|
+
* FORBIDDEN:
|
|
18
|
+
* - Calling Claude Code for SYNTHESIS_FORBIDDEN commands
|
|
19
|
+
* - Writing artifacts (ADR-008 handles that)
|
|
20
|
+
* - Calling the platform API (command executors handle that)
|
|
21
|
+
* - Mutating CLI state
|
|
22
|
+
* - Interactive confirmation (the CLI's gate pipeline handles that)
|
|
23
|
+
*/
|
|
24
|
+
import { isSynthesisAllowed, isCommitmentGrade, } from '../contracts/adr-command-semantics.js';
|
|
25
|
+
import { SYNTHESIS_SCHEMA_MAP, } from '../contracts/adr-006-claude-code-synthesis-runner.js';
|
|
26
|
+
import { DECISION_GRADE_SUBCOMMANDS, } from '../contracts/adr-007-subcommand-synthesis-router.js';
|
|
27
|
+
import { PROMPT_TEMPLATES } from './prompts/index.js';
|
|
28
|
+
import { createClaudeCodeRunner } from '../runtime/claude-code-runner.js';
|
|
29
|
+
import { CLIError } from '../errors/index.js';
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Constants
|
|
32
|
+
// ============================================================================
|
|
33
|
+
/** Maximum prompt length before emitting a diagnostic warning (50 KiB) */
|
|
34
|
+
const MAX_PROMPT_LENGTH = 50_000;
|
|
35
|
+
/** Minimum acceptable prompt length — templates must produce >50 chars */
|
|
36
|
+
const MIN_PROMPT_LENGTH = 50;
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Input Validation
|
|
39
|
+
// ============================================================================
|
|
40
|
+
/**
|
|
41
|
+
* Validate a SynthesisRequest has required structure.
|
|
42
|
+
* Catches programming errors at the boundary before touching the runner.
|
|
43
|
+
*
|
|
44
|
+
* @throws CLIError (ECLI-SYNTH-020) on invalid request structure
|
|
45
|
+
*/
|
|
46
|
+
function validateSynthesisRequest(request) {
|
|
47
|
+
if (!request.command || typeof request.command !== 'string') {
|
|
48
|
+
throw new CLIError({
|
|
49
|
+
code: 'ECLI-SYNTH-020',
|
|
50
|
+
category: 'INTERNAL_ERROR',
|
|
51
|
+
message: 'SynthesisRequest.command is empty or invalid',
|
|
52
|
+
details: { command: request.command },
|
|
53
|
+
module: 'synthesis-router',
|
|
54
|
+
recoverable: false,
|
|
55
|
+
exitCode: 70,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (!request.subcommand || typeof request.subcommand !== 'string') {
|
|
59
|
+
throw new CLIError({
|
|
60
|
+
code: 'ECLI-SYNTH-020',
|
|
61
|
+
category: 'INTERNAL_ERROR',
|
|
62
|
+
message: 'SynthesisRequest.subcommand is empty or invalid',
|
|
63
|
+
details: { command: request.command, subcommand: request.subcommand },
|
|
64
|
+
module: 'synthesis-router',
|
|
65
|
+
recoverable: false,
|
|
66
|
+
exitCode: 70,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (!request.userContext || typeof request.userContext.traceId !== 'string') {
|
|
70
|
+
throw new CLIError({
|
|
71
|
+
code: 'ECLI-SYNTH-020',
|
|
72
|
+
category: 'INTERNAL_ERROR',
|
|
73
|
+
message: 'SynthesisRequest.userContext.traceId is required',
|
|
74
|
+
details: { command: request.command, subcommand: request.subcommand },
|
|
75
|
+
module: 'synthesis-router',
|
|
76
|
+
recoverable: false,
|
|
77
|
+
exitCode: 70,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Validate the prompt generated by a template meets minimum requirements.
|
|
83
|
+
*
|
|
84
|
+
* @throws CLIError (ECLI-SYNTH-021) on invalid prompt output
|
|
85
|
+
*/
|
|
86
|
+
function validatePromptOutput(prompt, key) {
|
|
87
|
+
if (typeof prompt !== 'string' || prompt.length < MIN_PROMPT_LENGTH) {
|
|
88
|
+
throw new CLIError({
|
|
89
|
+
code: 'ECLI-SYNTH-021',
|
|
90
|
+
category: 'INTERNAL_ERROR',
|
|
91
|
+
message: `Prompt template for "${key}" produced ${prompt?.length ?? 0} characters (minimum: ${MIN_PROMPT_LENGTH})`,
|
|
92
|
+
details: {
|
|
93
|
+
key,
|
|
94
|
+
prompt_length: prompt?.length ?? 0,
|
|
95
|
+
minimum_length: MIN_PROMPT_LENGTH,
|
|
96
|
+
},
|
|
97
|
+
module: 'synthesis-router',
|
|
98
|
+
recoverable: false,
|
|
99
|
+
exitCode: 70,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (prompt.length > MAX_PROMPT_LENGTH) {
|
|
103
|
+
process.stderr.write(`[synthesis-router] WARNING: Prompt for "${key}" is ${prompt.length} characters ` +
|
|
104
|
+
`(recommended max: ${MAX_PROMPT_LENGTH}). Large prompts may increase latency.\n`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// Routing Gates (shared between routeSynthesis and buildSynthesisPrompt)
|
|
109
|
+
// ============================================================================
|
|
110
|
+
/**
|
|
111
|
+
* Execute the four routing gates common to synthesis and dry-run.
|
|
112
|
+
* Returns the validated template function, schema name, synthesis class,
|
|
113
|
+
* and routing key — or null if the command is not decision-grade.
|
|
114
|
+
*
|
|
115
|
+
* @throws CLIError on missing template or schema (internal configuration errors)
|
|
116
|
+
*/
|
|
117
|
+
function executeRoutingGates(request) {
|
|
118
|
+
const key = `${request.command}.${request.subcommand}`;
|
|
119
|
+
const correlationId = request.userContext.traceId;
|
|
120
|
+
// Gate 1: Check if this is a decision-grade subcommand
|
|
121
|
+
if (!DECISION_GRADE_SUBCOMMANDS.has(key)) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
// Gate 2: Verify ADR-001 registry agrees
|
|
125
|
+
if (!isSynthesisAllowed(request.command, request.subcommand)) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
// Gate 3: Verify we have a prompt template
|
|
129
|
+
const templateFn = PROMPT_TEMPLATES[key];
|
|
130
|
+
if (!templateFn) {
|
|
131
|
+
throw new CLIError({
|
|
132
|
+
code: 'ECLI-SYNTH-010',
|
|
133
|
+
category: 'INTERNAL_ERROR',
|
|
134
|
+
message: `No prompt template registered for ${key}`,
|
|
135
|
+
details: { command: request.command, subcommand: request.subcommand },
|
|
136
|
+
module: 'synthesis-router',
|
|
137
|
+
correlationId,
|
|
138
|
+
recoverable: false,
|
|
139
|
+
exitCode: 70,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// Gate 4: Verify we have a schema mapping
|
|
143
|
+
const schemaName = SYNTHESIS_SCHEMA_MAP[key];
|
|
144
|
+
if (!schemaName) {
|
|
145
|
+
throw new CLIError({
|
|
146
|
+
code: 'ECLI-SYNTH-011',
|
|
147
|
+
category: 'INTERNAL_ERROR',
|
|
148
|
+
message: `No contract schema mapped for ${key}`,
|
|
149
|
+
details: { command: request.command, subcommand: request.subcommand },
|
|
150
|
+
module: 'synthesis-router',
|
|
151
|
+
correlationId,
|
|
152
|
+
recoverable: false,
|
|
153
|
+
exitCode: 70,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// Determine synthesis governance class from ADR-001 registry
|
|
157
|
+
const synthesisClass = isCommitmentGrade(request.command, request.subcommand)
|
|
158
|
+
? 'COMMITMENT_GRADE'
|
|
159
|
+
: 'SYNTHESIS_REQUIRED';
|
|
160
|
+
return { key, templateFn, schemaName, synthesisClass };
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Generate a run-id, seed, and prompt from a validated routing gate result.
|
|
164
|
+
*/
|
|
165
|
+
function generatePrompt(request, gate) {
|
|
166
|
+
const runId = `run-${crypto.randomUUID()}`;
|
|
167
|
+
const seed = Math.floor(Math.random() * 1_000_000);
|
|
168
|
+
const promptArgs = {
|
|
169
|
+
runId,
|
|
170
|
+
seed,
|
|
171
|
+
command: request.command,
|
|
172
|
+
subcommand: request.subcommand,
|
|
173
|
+
positionalArgs: request.positionalArgs,
|
|
174
|
+
options: request.options,
|
|
175
|
+
contractSchemaName: gate.schemaName,
|
|
176
|
+
};
|
|
177
|
+
const prompt = gate.templateFn(promptArgs);
|
|
178
|
+
validatePromptOutput(prompt, gate.key);
|
|
179
|
+
return { runId, seed, prompt };
|
|
180
|
+
}
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// Classification Helpers
|
|
183
|
+
// ============================================================================
|
|
184
|
+
/**
|
|
185
|
+
* Determine the synthesis governance class for a (command, subcommand) pair.
|
|
186
|
+
*
|
|
187
|
+
* @returns 'COMMITMENT_GRADE' or 'SYNTHESIS_REQUIRED' for decision-grade commands, null otherwise
|
|
188
|
+
*/
|
|
189
|
+
export function getSynthesisClass(command, subcommand) {
|
|
190
|
+
const key = `${command}.${subcommand}`;
|
|
191
|
+
if (!DECISION_GRADE_SUBCOMMANDS.has(key)) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
return isCommitmentGrade(command, subcommand) ? 'COMMITMENT_GRADE' : 'SYNTHESIS_REQUIRED';
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check if a (command, subcommand) pair is decision-grade.
|
|
198
|
+
* Convenience function for use in CLI dispatch.
|
|
199
|
+
*/
|
|
200
|
+
export function isDecisionGrade(command, subcommand) {
|
|
201
|
+
if (!subcommand)
|
|
202
|
+
return false;
|
|
203
|
+
return DECISION_GRADE_SUBCOMMANDS.has(`${command}.${subcommand}`);
|
|
204
|
+
}
|
|
205
|
+
// ============================================================================
|
|
206
|
+
// Dry-Run / Prompt Builder
|
|
207
|
+
// ============================================================================
|
|
208
|
+
/**
|
|
209
|
+
* Build a synthesis prompt without invoking Claude Code.
|
|
210
|
+
*
|
|
211
|
+
* Useful for:
|
|
212
|
+
* - Dry-run mode: inspect what would be sent to Claude Code
|
|
213
|
+
* - Testing: verify prompt generation in isolation
|
|
214
|
+
* - Debugging: see the exact prompt for a given (command, subcommand)
|
|
215
|
+
*
|
|
216
|
+
* Executes all four routing gates but stops before subprocess invocation.
|
|
217
|
+
*
|
|
218
|
+
* @returns SynthesisPromptResult with prompt and metadata, or null if not decision-grade
|
|
219
|
+
* @throws CLIError on missing template or schema (internal configuration errors)
|
|
220
|
+
*/
|
|
221
|
+
export function buildSynthesisPrompt(request) {
|
|
222
|
+
validateSynthesisRequest(request);
|
|
223
|
+
const gate = executeRoutingGates(request);
|
|
224
|
+
if (gate === null) {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
const { runId, seed, prompt } = generatePrompt(request, gate);
|
|
228
|
+
return {
|
|
229
|
+
prompt,
|
|
230
|
+
runId,
|
|
231
|
+
seed,
|
|
232
|
+
key: gate.key,
|
|
233
|
+
contractSchema: gate.schemaName,
|
|
234
|
+
synthesisClass: gate.synthesisClass,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// Router Implementation
|
|
239
|
+
// ============================================================================
|
|
240
|
+
/**
|
|
241
|
+
* Route a command through the synthesis pipeline.
|
|
242
|
+
*
|
|
243
|
+
* This is the primary entry point for ADR-007. The flow is:
|
|
244
|
+
*
|
|
245
|
+
* 1. Validate request structure
|
|
246
|
+
* 2. Execute routing gates (decision-grade check, ADR-001 agreement,
|
|
247
|
+
* template existence, schema mapping)
|
|
248
|
+
* 3. Determine synthesis governance class (SYNTHESIS_REQUIRED or COMMITMENT_GRADE)
|
|
249
|
+
* 4. Generate run-id, seed, and prompt
|
|
250
|
+
* 5. Invoke Claude Code via ADR-006 runner with contract validation
|
|
251
|
+
* 6. Return result with full traceability metadata
|
|
252
|
+
*
|
|
253
|
+
* For non-decision-grade commands, returns null immediately with zero overhead.
|
|
254
|
+
*
|
|
255
|
+
* @returns SynthesisResult if the command is decision-grade, null otherwise
|
|
256
|
+
* @throws CLIError on router configuration errors (ECLI-SYNTH-010/011/020/021)
|
|
257
|
+
* @throws SynthesisError on Claude Code invocation failures (ECLI-SYNTH-001..005)
|
|
258
|
+
*/
|
|
259
|
+
export function routeSynthesis(request) {
|
|
260
|
+
// Validate request structure
|
|
261
|
+
validateSynthesisRequest(request);
|
|
262
|
+
const verbose = request.flags['verbose'] ?? false;
|
|
263
|
+
const correlationId = request.userContext.traceId;
|
|
264
|
+
// Execute routing gates
|
|
265
|
+
const gate = executeRoutingGates(request);
|
|
266
|
+
if (gate === null) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
if (verbose) {
|
|
270
|
+
process.stderr.write(`[synthesis-router] routing ${gate.key} class=${gate.synthesisClass} ` +
|
|
271
|
+
`schema=${gate.schemaName} correlationId=${correlationId}\n`);
|
|
272
|
+
}
|
|
273
|
+
// Generate prompt
|
|
274
|
+
const { runId, seed, prompt } = generatePrompt(request, gate);
|
|
275
|
+
if (verbose) {
|
|
276
|
+
process.stderr.write(`[synthesis-router] prompt generated: ${prompt.length} chars ` +
|
|
277
|
+
`runId=${runId} seed=${seed}\n`);
|
|
278
|
+
}
|
|
279
|
+
// Invoke Claude Code with contract validation
|
|
280
|
+
let result;
|
|
281
|
+
try {
|
|
282
|
+
const runner = createClaudeCodeRunner();
|
|
283
|
+
result = runner.invoke(prompt, {
|
|
284
|
+
runId,
|
|
285
|
+
seed,
|
|
286
|
+
verbose,
|
|
287
|
+
schemaKey: gate.key,
|
|
288
|
+
correlationId,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
// Wrap errors with routing context for diagnostics
|
|
293
|
+
if (error instanceof CLIError) {
|
|
294
|
+
const enrichedDetails = {
|
|
295
|
+
...error.details,
|
|
296
|
+
routing_key: gate.key,
|
|
297
|
+
routing_synthesis_class: gate.synthesisClass,
|
|
298
|
+
routing_schema: gate.schemaName,
|
|
299
|
+
};
|
|
300
|
+
throw new CLIError({
|
|
301
|
+
code: error.code,
|
|
302
|
+
category: error.category,
|
|
303
|
+
message: `[${gate.key}] ${error.message}`,
|
|
304
|
+
details: enrichedDetails,
|
|
305
|
+
module: error.module,
|
|
306
|
+
correlationId: error.correlationId ?? correlationId,
|
|
307
|
+
recoverable: error.recoverable,
|
|
308
|
+
exitCode: error.exitCode,
|
|
309
|
+
cause: error.cause instanceof Error ? error.cause : undefined,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
// Unknown error — wrap with context
|
|
313
|
+
throw new CLIError({
|
|
314
|
+
code: 'ECLI-SYNTH-099',
|
|
315
|
+
category: 'INTERNAL_ERROR',
|
|
316
|
+
message: `Unexpected error routing ${gate.key}: ${error instanceof Error ? error.message : String(error)}`,
|
|
317
|
+
details: {
|
|
318
|
+
routing_key: gate.key,
|
|
319
|
+
routing_synthesis_class: gate.synthesisClass,
|
|
320
|
+
error_type: error instanceof Error ? error.constructor.name : typeof error,
|
|
321
|
+
},
|
|
322
|
+
module: 'synthesis-router',
|
|
323
|
+
correlationId,
|
|
324
|
+
recoverable: false,
|
|
325
|
+
exitCode: 150,
|
|
326
|
+
cause: error instanceof Error ? error : undefined,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
if (verbose) {
|
|
330
|
+
process.stderr.write(`[synthesis-router] synthesis complete: model=${result.model} ` +
|
|
331
|
+
`duration=${result.durationMs}ms output=${result.rawOutput.length}B\n`);
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
data: result.data,
|
|
335
|
+
runId,
|
|
336
|
+
command: request.command,
|
|
337
|
+
subcommand: request.subcommand,
|
|
338
|
+
model: result.model,
|
|
339
|
+
durationMs: result.durationMs,
|
|
340
|
+
contractSchema: gate.schemaName,
|
|
341
|
+
rawOutput: result.rawOutput,
|
|
342
|
+
synthesisClass: gate.synthesisClass,
|
|
343
|
+
prompt,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/synthesis/router.ts"],"names":[],"mappings":"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"}
|