@contentful/experience-design-system-generation 2.36.2-dev-build-a6f80ae6.0 → 2.36.2-dev-build-d9a75f6e.0

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.
Files changed (65) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/src/agent-names.d.ts +1 -0
  3. package/dist/src/agent-names.js +7 -0
  4. package/dist/src/controller/create-generation-endpoint.d.ts +3 -0
  5. package/dist/src/controller/create-generation-endpoint.js +15 -0
  6. package/dist/src/controller/helpers/validate-generation-request.d.ts +2 -0
  7. package/dist/src/controller/helpers/validate-generation-request.js +18 -0
  8. package/dist/src/index.d.ts +19 -7
  9. package/dist/src/index.js +18 -6
  10. package/dist/src/orchestrator/execute-generation-orchestrator.d.ts +6 -0
  11. package/dist/src/orchestrator/execute-generation-orchestrator.js +12 -0
  12. package/dist/src/services/agent/helpers/build-agent-args.d.ts +6 -0
  13. package/dist/src/services/agent/helpers/build-agent-args.js +58 -0
  14. package/dist/src/services/agent/helpers/check-agent-auth.d.ts +3 -0
  15. package/dist/src/services/agent/helpers/check-agent-auth.js +19 -0
  16. package/dist/src/services/agent/helpers/check-claude-auth.d.ts +2 -0
  17. package/dist/src/services/agent/helpers/check-claude-auth.js +37 -0
  18. package/dist/src/services/agent/helpers/describe-agent-failure.d.ts +2 -0
  19. package/dist/src/services/agent/helpers/describe-agent-failure.js +5 -0
  20. package/dist/src/services/agent/helpers/extract-sentinel-output.d.ts +1 -0
  21. package/dist/src/services/agent/helpers/extract-sentinel-output.js +16 -0
  22. package/dist/src/services/agent/helpers/resolve-agent-binary.d.ts +2 -0
  23. package/dist/src/services/agent/helpers/resolve-agent-binary.js +8 -0
  24. package/dist/src/services/agent/local-cli-agent-invoker.d.ts +3 -0
  25. package/dist/src/{agent-invoker.js → services/agent/local-cli-agent-invoker.js} +2 -2
  26. package/dist/src/services/agent/run-agent.d.ts +15 -0
  27. package/dist/src/services/agent/run-agent.js +70 -0
  28. package/dist/src/services/parsing/helpers/read-tool-call-objects.d.ts +4 -0
  29. package/dist/src/services/parsing/helpers/read-tool-call-objects.js +54 -0
  30. package/dist/src/services/parsing/parse-map-token-tool-calls.d.ts +2 -0
  31. package/dist/src/services/parsing/parse-map-token-tool-calls.js +39 -0
  32. package/dist/src/services/parsing/parse-prop-tool-calls.d.ts +2 -0
  33. package/dist/src/services/parsing/parse-prop-tool-calls.js +91 -0
  34. package/dist/src/services/parsing/parse-select-tool-calls.d.ts +2 -0
  35. package/dist/src/services/parsing/parse-select-tool-calls.js +27 -0
  36. package/dist/src/services/parsing/parse-token-tool-calls.d.ts +2 -0
  37. package/dist/src/services/parsing/parse-token-tool-calls.js +39 -0
  38. package/dist/src/services/prompts/build-prompt.d.ts +4 -0
  39. package/dist/src/services/prompts/build-prompt.js +8 -0
  40. package/dist/src/services/prompts/helpers/build-preamble.d.ts +2 -0
  41. package/dist/src/services/prompts/helpers/build-preamble.js +48 -0
  42. package/dist/src/services/prompts/helpers/build-skill-preambles.d.ts +4 -0
  43. package/dist/src/services/prompts/helpers/build-skill-preambles.js +126 -0
  44. package/dist/src/services/prompts/helpers/format-source-refs.d.ts +2 -0
  45. package/dist/src/services/prompts/helpers/format-source-refs.js +31 -0
  46. package/dist/src/services/prompts/helpers/format-token-candidates.d.ts +8 -0
  47. package/dist/src/services/prompts/helpers/format-token-candidates.js +80 -0
  48. package/dist/src/services/prompts/helpers/resolve-skill-file.d.ts +4 -0
  49. package/dist/src/services/prompts/helpers/resolve-skill-file.js +49 -0
  50. package/dist/src/types/agent.d.ts +10 -0
  51. package/dist/src/types/agent.js +1 -0
  52. package/dist/src/types/contract.d.ts +24 -0
  53. package/dist/src/types/contract.js +1 -0
  54. package/dist/src/types/invoker.d.ts +17 -0
  55. package/dist/src/types/invoker.js +1 -0
  56. package/dist/src/types/prompt.d.ts +53 -0
  57. package/dist/src/types/prompt.js +1 -0
  58. package/dist/src/types/tool-calls.d.ts +91 -0
  59. package/dist/src/types/tool-calls.js +1 -0
  60. package/package.json +2 -2
  61. package/dist/src/agent-invoker.d.ts +0 -25
  62. package/dist/src/agent-runner.d.ts +0 -144
  63. package/dist/src/agent-runner.js +0 -564
  64. package/dist/src/prompt-builder.d.ts +0 -81
  65. package/dist/src/prompt-builder.js +0 -344
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-generation",
3
- "version": "2.36.2-dev-build-a6f80ae6.0",
3
+ "version": "2.36.2-dev-build-d9a75f6e.0",
4
4
  "description": "Agent-invocation and skill-prompt engine for the Contentful Experience Design System SDK",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,4 +1,5 @@
1
1
  export declare const AGENT_NAMES: readonly ["claude", "codex", "opencode", "cursor", "copilot"];
2
2
  export type AgentName = (typeof AGENT_NAMES)[number];
3
3
  export declare const DEFAULT_AGENT_NAME: AgentName;
4
+ export declare const AGENT_BINARIES: Record<AgentName, string>;
4
5
  export declare function isAgentName(value: string): value is AgentName;
@@ -1,5 +1,12 @@
1
1
  export const AGENT_NAMES = ['claude', 'codex', 'opencode', 'cursor', 'copilot'];
2
2
  export const DEFAULT_AGENT_NAME = 'claude';
3
+ export const AGENT_BINARIES = {
4
+ claude: 'claude',
5
+ codex: 'codex',
6
+ opencode: 'opencode',
7
+ cursor: 'cursor-agent',
8
+ copilot: 'copilot',
9
+ };
3
10
  export function isAgentName(value) {
4
11
  return AGENT_NAMES.includes(value);
5
12
  }
@@ -0,0 +1,3 @@
1
+ import type { GenerationEndpoint, GenerationEndpointOptions, GenerationEndpointRequest, GenerationEndpointResponse } from '../types/contract.js';
2
+ export type { GenerationEndpoint, GenerationEndpointOptions, GenerationEndpointRequest, GenerationEndpointResponse };
3
+ export declare function createGenerationEndpoint(options?: GenerationEndpointOptions): GenerationEndpoint;
@@ -0,0 +1,15 @@
1
+ import { validateGenerationRequest } from './helpers/validate-generation-request.js';
2
+ import { executeGenerationOrchestrator } from '../orchestrator/execute-generation-orchestrator.js';
3
+ import { createLocalCliAgentInvoker } from '../services/agent/local-cli-agent-invoker.js';
4
+ export function createGenerationEndpoint(options = {}) {
5
+ const invoker = createLocalCliAgentInvoker({ onDebugEvent: options.onDebugEvent });
6
+ return {
7
+ async run(request) {
8
+ validateGenerationRequest(request);
9
+ return executeGenerationOrchestrator({ ...request, invoker });
10
+ },
11
+ checkAuth(agent) {
12
+ return invoker.checkAuth(agent);
13
+ },
14
+ };
15
+ }
@@ -0,0 +1,2 @@
1
+ import type { GenerationEndpointRequest } from '../../types/contract.js';
2
+ export declare function validateGenerationRequest(request: GenerationEndpointRequest): void;
@@ -0,0 +1,18 @@
1
+ import { isAgentName } from '../../agent-names.js';
2
+ export function validateGenerationRequest(request) {
3
+ if (request === null || typeof request !== 'object') {
4
+ throw new TypeError('createGenerationEndpoint requires a request object');
5
+ }
6
+ if (!isAgentName(request.agent)) {
7
+ throw new TypeError(`createGenerationEndpoint requires agent to be a valid agent name, got: ${String(request.agent)}`);
8
+ }
9
+ if (typeof request.timeoutMs !== 'number' || request.timeoutMs <= 0) {
10
+ throw new TypeError('createGenerationEndpoint requires timeoutMs to be a positive number');
11
+ }
12
+ if (request.promptOptions === null || typeof request.promptOptions !== 'object') {
13
+ throw new TypeError('createGenerationEndpoint requires promptOptions to be an object');
14
+ }
15
+ if (request.onOutput !== undefined && typeof request.onOutput !== 'function') {
16
+ throw new TypeError('createGenerationEndpoint requires onOutput to be a function when provided');
17
+ }
18
+ }
@@ -1,9 +1,21 @@
1
- export { AGENT_NAMES, DEFAULT_AGENT_NAME, isAgentName } from './agent-names.js';
1
+ export { AGENT_NAMES, AGENT_BINARIES, DEFAULT_AGENT_NAME, isAgentName } from './agent-names.js';
2
2
  export type { AgentName } from './agent-names.js';
3
- export { agentSupportsBedrock, buildArgs, checkAgentAuth, describeAgentFailure, extractSentinelOutput, parseMapTokenPropToolCallLines, parseSelectToolCallLines, parseTokenToolCallLines, parseToolCallLines, resolveAgentModel, resolveBinary, runAgent, } from './agent-runner.js';
4
- export type { AgentAuthStatus, AgentDebugEvent, AgentRunResult, ClassifyComponentCall, ClassifyPropCall, ClassifySlotCall, ExcludePropCall, MapTokenPropCall, ParsedMapTokenPropToolCalls, ParsedSelectToolCalls, ParsedTokenToolCalls, ParsedToolCalls, RejectComponentCall, SelectComponentCall, SelectToolCall, SetGroupCall, SetTokenCall, ToolCall, TokenToolCall, } from './agent-runner.js';
5
- export { createLocalCliAgentInvoker } from './agent-invoker.js';
6
- export type { AgentInvoker, CreateLocalCliAgentInvokerOptions, InvokeAgentOptions } from './agent-invoker.js';
7
- export { buildPrompt, formatCustomPromptBanner, resolveSkillPath } from './prompt-builder.js';
8
- export type { ComponentSourceRef, GeneratedCdf, Mode, PromptOptions, Skill } from './prompt-builder.js';
3
+ export type { AgentAuthStatus, AgentDebugEvent, AgentRunResult } from './types/agent.js';
4
+ export type { ClassifyComponentCall, ClassifyPropCall, ClassifySlotCall, ExcludePropCall, MapTokenPropCall, ParsedMapTokenPropToolCalls, ParsedSelectToolCalls, ParsedTokenToolCalls, ParsedToolCalls, RejectComponentCall, SelectComponentCall, SelectToolCall, SetGroupCall, SetTokenCall, ToolCall, TokenToolCall, } from './types/tool-calls.js';
5
+ export type { ComponentSourceRef, GeneratedCdf, Mode, PromptOptions, Skill } from './types/prompt.js';
6
+ export { createGenerationEndpoint } from './controller/create-generation-endpoint.js';
7
+ export type { GenerationEndpoint, GenerationEndpointOptions, GenerationEndpointRequest, GenerationEndpointResponse, } from './controller/create-generation-endpoint.js';
8
+ export { executeGenerationOrchestrator } from './orchestrator/execute-generation-orchestrator.js';
9
+ export type { GenerationOrchestratorRequest } from './orchestrator/execute-generation-orchestrator.js';
10
+ export { agentSupportsBedrock, buildAgentArgs as buildArgs, resolveAgentModel, } from './services/agent/helpers/build-agent-args.js';
11
+ export { resolveAgentBinary as resolveBinary } from './services/agent/helpers/resolve-agent-binary.js';
12
+ export { checkAgentAuth } from './services/agent/helpers/check-agent-auth.js';
13
+ export { runAgent, describeAgentFailure, extractSentinelOutput } from './services/agent/run-agent.js';
14
+ export { parsePropToolCallLines as parseToolCallLines } from './services/parsing/parse-prop-tool-calls.js';
15
+ export { parseSelectToolCallLines } from './services/parsing/parse-select-tool-calls.js';
16
+ export { parseTokenToolCallLines } from './services/parsing/parse-token-tool-calls.js';
17
+ export { parseMapTokenPropToolCallLines } from './services/parsing/parse-map-token-tool-calls.js';
18
+ export { buildPrompt, formatCustomPromptBanner, resolveSkillPath } from './services/prompts/build-prompt.js';
9
19
  export { formatGenerateProgressLine } from './progress.js';
20
+ export { createLocalCliAgentInvoker } from './services/agent/local-cli-agent-invoker.js';
21
+ export type { AgentInvoker, InvokeAgentOptions, LocalCliAgentInvokerOptions as CreateLocalCliAgentInvokerOptions, } from './types/invoker.js';
package/dist/src/index.js CHANGED
@@ -1,10 +1,22 @@
1
1
  // Agent identity
2
- export { AGENT_NAMES, DEFAULT_AGENT_NAME, isAgentName } from './agent-names.js';
3
- // Agent invocation (low-level)
4
- export { agentSupportsBedrock, buildArgs, checkAgentAuth, describeAgentFailure, extractSentinelOutput, parseMapTokenPropToolCallLines, parseSelectToolCallLines, parseTokenToolCallLines, parseToolCallLines, resolveAgentModel, resolveBinary, runAgent, } from './agent-runner.js';
5
- // Agent invocation (interface)
6
- export { createLocalCliAgentInvoker } from './agent-invoker.js';
2
+ export { AGENT_NAMES, AGENT_BINARIES, DEFAULT_AGENT_NAME, isAgentName } from './agent-names.js';
3
+ // Generation endpoint (primary entry point)
4
+ export { createGenerationEndpoint } from './controller/create-generation-endpoint.js';
5
+ // Orchestrator (lower-level — for callers that supply their own invoker)
6
+ export { executeGenerationOrchestrator } from './orchestrator/execute-generation-orchestrator.js';
7
+ // Agent execution (low-level)
8
+ export { agentSupportsBedrock, buildAgentArgs as buildArgs, resolveAgentModel, } from './services/agent/helpers/build-agent-args.js';
9
+ export { resolveAgentBinary as resolveBinary } from './services/agent/helpers/resolve-agent-binary.js';
10
+ export { checkAgentAuth } from './services/agent/helpers/check-agent-auth.js';
11
+ export { runAgent, describeAgentFailure, extractSentinelOutput } from './services/agent/run-agent.js';
12
+ // Tool call parsing
13
+ export { parsePropToolCallLines as parseToolCallLines } from './services/parsing/parse-prop-tool-calls.js';
14
+ export { parseSelectToolCallLines } from './services/parsing/parse-select-tool-calls.js';
15
+ export { parseTokenToolCallLines } from './services/parsing/parse-token-tool-calls.js';
16
+ export { parseMapTokenPropToolCallLines } from './services/parsing/parse-map-token-tool-calls.js';
7
17
  // Prompt building
8
- export { buildPrompt, formatCustomPromptBanner, resolveSkillPath } from './prompt-builder.js';
18
+ export { buildPrompt, formatCustomPromptBanner, resolveSkillPath } from './services/prompts/build-prompt.js';
9
19
  // Progress reporting
10
20
  export { formatGenerateProgressLine } from './progress.js';
21
+ // Backward-compat exports — CLI callers still use these; migrate to createGenerationEndpoint
22
+ export { createLocalCliAgentInvoker } from './services/agent/local-cli-agent-invoker.js';
@@ -0,0 +1,6 @@
1
+ import type { GenerationEndpointRequest, GenerationEndpointResponse } from '../types/contract.js';
2
+ import type { AgentInvoker } from '../services/agent/local-cli-agent-invoker.js';
3
+ export interface GenerationOrchestratorRequest extends GenerationEndpointRequest {
4
+ readonly invoker: AgentInvoker;
5
+ }
6
+ export declare function executeGenerationOrchestrator(request: GenerationOrchestratorRequest): Promise<GenerationEndpointResponse>;
@@ -0,0 +1,12 @@
1
+ import { buildPrompt } from '../services/prompts/build-prompt.js';
2
+ export async function executeGenerationOrchestrator(request) {
3
+ const prompt = await buildPrompt(request.promptOptions);
4
+ return request.invoker.invoke({
5
+ agent: request.agent,
6
+ model: request.model,
7
+ bedrock: request.bedrock,
8
+ prompt,
9
+ timeoutMs: request.timeoutMs,
10
+ onOutput: request.onOutput,
11
+ });
12
+ }
@@ -0,0 +1,6 @@
1
+ import type { AgentName } from '../../../agent-names.js';
2
+ /** Per-agent env vars that switch model calls to AWS Bedrock. */
3
+ export declare const BEDROCK_ENV_BY_AGENT: Partial<Record<AgentName, Record<string, string>>>;
4
+ export declare function agentSupportsBedrock(agent: AgentName): boolean;
5
+ export declare function resolveAgentModel(agent: AgentName, explicit?: string, bedrock?: boolean): string | undefined;
6
+ export declare function buildAgentArgs(agent: AgentName, prompt: string, model?: string, promptViaStdin?: boolean, bedrock?: boolean): string[];
@@ -0,0 +1,58 @@
1
+ /** Per-agent env vars that switch model calls to AWS Bedrock. */
2
+ export const BEDROCK_ENV_BY_AGENT = {
3
+ claude: { CLAUDE_CODE_USE_BEDROCK: '1' },
4
+ };
5
+ const BEDROCK_CAPABLE_AGENTS = new Set(['claude', 'codex', 'opencode']);
6
+ export function agentSupportsBedrock(agent) {
7
+ return BEDROCK_CAPABLE_AGENTS.has(agent);
8
+ }
9
+ const DEFAULT_CODEX_BEDROCK_REGION = 'us-east-1';
10
+ const DEFAULT_OPENCODE_MODEL = 'claude-haiku-4-5';
11
+ const DEFAULT_CODEX_BEDROCK_MODEL = 'openai.gpt-5.6-luna';
12
+ const DEFAULT_MODELS = {
13
+ claude: 'haiku',
14
+ opencode: DEFAULT_OPENCODE_MODEL,
15
+ cursor: 'gpt-mini',
16
+ copilot: 'Auto',
17
+ };
18
+ function withBedrockProviderPrefix(model) {
19
+ return model.includes('/') ? model : `amazon-bedrock/${model}`;
20
+ }
21
+ export function resolveAgentModel(agent, explicit, bedrock = false) {
22
+ if (explicit && explicit.trim())
23
+ return explicit.trim();
24
+ const override = process.env[`EDS_AGENT_MODEL_${agent.toUpperCase()}`];
25
+ if (override && override.trim())
26
+ return override.trim();
27
+ if (bedrock && agent === 'codex')
28
+ return DEFAULT_CODEX_BEDROCK_MODEL;
29
+ if (bedrock && agent === 'opencode')
30
+ return withBedrockProviderPrefix(DEFAULT_OPENCODE_MODEL);
31
+ return DEFAULT_MODELS[agent];
32
+ }
33
+ function codexBedrockConfigArgs() {
34
+ const region = process.env.AWS_REGION?.trim() || process.env.AWS_DEFAULT_REGION?.trim() || DEFAULT_CODEX_BEDROCK_REGION;
35
+ return ['-c', 'model_provider=amazon-bedrock', '-c', `model_providers.amazon-bedrock.region=${region}`];
36
+ }
37
+ export function buildAgentArgs(agent, prompt, model, promptViaStdin = false, bedrock = false) {
38
+ const resolvedModel = resolveAgentModel(agent, model, bedrock);
39
+ const modelArg = resolvedModel ? ['--model', resolvedModel] : [];
40
+ const promptArg = promptViaStdin ? [] : [prompt];
41
+ switch (agent) {
42
+ case 'claude':
43
+ return ['--print', ...modelArg, ...promptArg];
44
+ case 'codex': {
45
+ const bedrockArgs = bedrock ? codexBedrockConfigArgs() : [];
46
+ return ['exec', ...bedrockArgs, ...modelArg, '--dangerously-bypass-approvals-and-sandbox', ...promptArg];
47
+ }
48
+ case 'opencode':
49
+ return ['run', ...modelArg, ...promptArg];
50
+ case 'cursor':
51
+ return ['--print', ...modelArg, ...promptArg];
52
+ case 'copilot': {
53
+ const copilotModel = resolveAgentModel('copilot', model);
54
+ const copilotModelArg = !copilotModel || copilotModel === 'Auto' ? [] : ['--model', copilotModel];
55
+ return ['-p', ...promptArg, ...copilotModelArg, '--allow-all-tools'];
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,3 @@
1
+ import type { AgentName } from '../../../agent-names.js';
2
+ import type { AgentAuthStatus } from '../../../types/agent.js';
3
+ export declare function checkAgentAuth(agent: AgentName): Promise<AgentAuthStatus>;
@@ -0,0 +1,19 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { resolveAgentBinary } from './resolve-agent-binary.js';
3
+ import { checkClaudeAuth } from './check-claude-auth.js';
4
+ export async function checkAgentAuth(agent) {
5
+ const binary = resolveAgentBinary(agent);
6
+ const binaryExists = await new Promise((resolve) => {
7
+ if (binary.startsWith('/')) {
8
+ import('node:fs/promises').then((fs) => fs.access(binary).then(() => resolve(true), () => resolve(false)));
9
+ return;
10
+ }
11
+ const child = spawn(process.platform === 'win32' ? 'where' : 'which', [binary], { stdio: 'ignore' });
12
+ child.on('close', (code) => resolve(code === 0));
13
+ });
14
+ if (!binaryExists)
15
+ return 'not-found';
16
+ if (agent !== 'claude')
17
+ return 'ok';
18
+ return checkClaudeAuth(binary);
19
+ }
@@ -0,0 +1,2 @@
1
+ import type { AgentAuthStatus } from '../../../types/agent.js';
2
+ export declare function checkClaudeAuth(binary: string): Promise<AgentAuthStatus>;
@@ -0,0 +1,37 @@
1
+ import { spawn } from 'node:child_process';
2
+ export function checkClaudeAuth(binary) {
3
+ return new Promise((resolve) => {
4
+ const child = spawn(binary, ['auth', 'status', '--json'], {
5
+ stdio: ['ignore', 'pipe', 'pipe'],
6
+ });
7
+ let stdout = '';
8
+ let done = false;
9
+ const timer = setTimeout(() => {
10
+ if (!done) {
11
+ done = true;
12
+ child.kill('SIGTERM');
13
+ resolve('unauthenticated');
14
+ }
15
+ }, 5000);
16
+ child.stdout?.on('data', (chunk) => {
17
+ stdout += chunk.toString();
18
+ });
19
+ child.on('close', (code) => {
20
+ if (done)
21
+ return;
22
+ done = true;
23
+ clearTimeout(timer);
24
+ if (code !== 0) {
25
+ resolve('unauthenticated');
26
+ return;
27
+ }
28
+ try {
29
+ const status = JSON.parse(stdout);
30
+ resolve(status.loggedIn ? 'ok' : 'unauthenticated');
31
+ }
32
+ catch {
33
+ resolve('unauthenticated');
34
+ }
35
+ });
36
+ });
37
+ }
@@ -0,0 +1,2 @@
1
+ import type { AgentRunResult } from '../../../types/agent.js';
2
+ export declare function describeAgentFailure(result: AgentRunResult, maxDetail?: number): string;
@@ -0,0 +1,5 @@
1
+ export function describeAgentFailure(result, maxDetail = 800) {
2
+ const base = result.exitCode !== 0 ? `agent exited with code ${result.exitCode}` : 'agent produced no tool calls';
3
+ const detail = (result.stderr.trim() || result.stdout.trim()).slice(-maxDetail).trim();
4
+ return detail ? `${base} — ${detail}` : base;
5
+ }
@@ -0,0 +1 @@
1
+ export declare function extractSentinelOutput(stdout: string): string | null | 'multiple';
@@ -0,0 +1,16 @@
1
+ export function extractSentinelOutput(stdout) {
2
+ const START = '<<<EDS_OUTPUT_START>>>';
3
+ const END = '<<<EDS_OUTPUT_END>>>';
4
+ const startIdx = stdout.indexOf(START);
5
+ const endIdx = stdout.indexOf(END);
6
+ if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx)
7
+ return null;
8
+ const secondStart = stdout.indexOf(START, startIdx + START.length);
9
+ if (secondStart !== -1 && secondStart < endIdx)
10
+ return 'multiple';
11
+ const afterStart = stdout.indexOf(END, startIdx);
12
+ const secondEnd = stdout.indexOf(END, afterStart + END.length);
13
+ if (secondEnd !== -1)
14
+ return 'multiple';
15
+ return stdout.slice(startIdx + START.length, endIdx).trim();
16
+ }
@@ -0,0 +1,2 @@
1
+ import { type AgentName } from '../../../agent-names.js';
2
+ export declare function resolveAgentBinary(agent: AgentName): string;
@@ -0,0 +1,8 @@
1
+ import { AGENT_BINARIES } from '../../../agent-names.js';
2
+ export function resolveAgentBinary(agent) {
3
+ const envKey = `EDS_AGENT_BINARY_${agent.toUpperCase()}`;
4
+ const override = process.env[envKey];
5
+ if (override && override.trim())
6
+ return override.trim();
7
+ return AGENT_BINARIES[agent];
8
+ }
@@ -0,0 +1,3 @@
1
+ import type { AgentInvoker, InvokeAgentOptions, LocalCliAgentInvokerOptions } from '../../types/invoker.js';
2
+ export type { AgentInvoker, InvokeAgentOptions, LocalCliAgentInvokerOptions };
3
+ export declare function createLocalCliAgentInvoker(options?: LocalCliAgentInvokerOptions): AgentInvoker;
@@ -1,5 +1,5 @@
1
- import { checkAgentAuth, runAgent } from './agent-runner.js';
2
- /** Default `AgentInvoker`: spawns the agent CLI binary as a local subprocess. */
1
+ import { runAgent } from './run-agent.js';
2
+ import { checkAgentAuth } from './helpers/check-agent-auth.js';
3
3
  export function createLocalCliAgentInvoker(options = {}) {
4
4
  const { onDebugEvent } = options;
5
5
  return {
@@ -0,0 +1,15 @@
1
+ import type { AgentName } from '../../agent-names.js';
2
+ import type { AgentRunResult, AgentDebugEvent } from '../../types/agent.js';
3
+ import { describeAgentFailure } from './helpers/describe-agent-failure.js';
4
+ import { extractSentinelOutput } from './helpers/extract-sentinel-output.js';
5
+ export { describeAgentFailure, extractSentinelOutput };
6
+ export declare function runAgent(options: {
7
+ agent: AgentName;
8
+ prompt: string;
9
+ timeoutMs: number;
10
+ model?: string;
11
+ bedrock?: boolean;
12
+ onOutput?: (chunk: string) => void;
13
+ promptViaStdin?: boolean;
14
+ onDebugEvent?: AgentDebugEvent;
15
+ }): Promise<AgentRunResult>;
@@ -0,0 +1,70 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { resolveAgentBinary } from './helpers/resolve-agent-binary.js';
3
+ import { buildAgentArgs, BEDROCK_ENV_BY_AGENT } from './helpers/build-agent-args.js';
4
+ import { describeAgentFailure } from './helpers/describe-agent-failure.js';
5
+ import { extractSentinelOutput } from './helpers/extract-sentinel-output.js';
6
+ export { describeAgentFailure, extractSentinelOutput };
7
+ export async function runAgent(options) {
8
+ const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
9
+ const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === '1';
10
+ const binary = resolveAgentBinary(agent);
11
+ const useStdin = !!promptViaStdin;
12
+ const args = buildAgentArgs(agent, prompt, model, useStdin, bedrock);
13
+ const startedAt = Date.now();
14
+ onDebugEvent?.('run.start', {
15
+ agent,
16
+ binary,
17
+ model,
18
+ bedrock: !!bedrock,
19
+ timeoutMs,
20
+ promptLen: prompt.length,
21
+ promptHead: prompt.slice(0, 500),
22
+ });
23
+ return new Promise((resolve) => {
24
+ const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : undefined;
25
+ const child = spawn(binary, args, {
26
+ stdio: ['pipe', 'pipe', 'pipe'],
27
+ ...(bedrockEnv ? { env: { ...process.env, ...bedrockEnv } } : {}),
28
+ });
29
+ if (useStdin && child.stdin) {
30
+ child.stdin.on('error', () => { });
31
+ child.stdin.write(prompt, () => {
32
+ child.stdin?.end();
33
+ });
34
+ }
35
+ else {
36
+ child.stdin?.end();
37
+ }
38
+ let stdout = '';
39
+ let stderr = '';
40
+ let timedOut = false;
41
+ const timer = setTimeout(() => {
42
+ timedOut = true;
43
+ child.kill('SIGTERM');
44
+ }, timeoutMs);
45
+ child.stdout?.on('data', (chunk) => {
46
+ const text = chunk.toString();
47
+ stdout += text;
48
+ onOutput?.(text);
49
+ });
50
+ child.stderr?.on('data', (chunk) => {
51
+ stderr += chunk.toString();
52
+ });
53
+ child.on('close', (code, signal) => {
54
+ clearTimeout(timer);
55
+ const result = { exitCode: signal ? 1 : (code ?? 1), stdout, stderr, timedOut };
56
+ onDebugEvent?.('run.end', {
57
+ agent,
58
+ model,
59
+ durationMs: Date.now() - startedAt,
60
+ exitCode: result.exitCode,
61
+ signal,
62
+ timedOut,
63
+ stdoutLen: stdout.length,
64
+ stderrLen: stderr.length,
65
+ stderrTail: stderr.slice(-1000),
66
+ });
67
+ resolve(result);
68
+ });
69
+ });
70
+ }
@@ -0,0 +1,4 @@
1
+ export declare function readToolCallObjects(stdout: string): {
2
+ objects: Array<Record<string, unknown>>;
3
+ warnings: string[];
4
+ };
@@ -0,0 +1,54 @@
1
+ function findJsonObjectEnd(line) {
2
+ let depth = 0;
3
+ let inString = false;
4
+ let escaped = false;
5
+ for (let i = 0; i < line.length; i++) {
6
+ const ch = line[i];
7
+ if (escaped) {
8
+ escaped = false;
9
+ }
10
+ else if (ch === '\\' && inString) {
11
+ escaped = true;
12
+ }
13
+ else if (ch === '"') {
14
+ inString = !inString;
15
+ }
16
+ else if (!inString && ch === '{') {
17
+ depth++;
18
+ }
19
+ else if (!inString && ch === '}' && --depth === 0) {
20
+ return i;
21
+ }
22
+ }
23
+ return -1;
24
+ }
25
+ export function readToolCallObjects(stdout) {
26
+ const objects = [];
27
+ const warnings = [];
28
+ for (const raw of stdout.split('\n')) {
29
+ const line = raw.trim();
30
+ if (!line.startsWith('{'))
31
+ continue;
32
+ const end = findJsonObjectEnd(line);
33
+ if (end === -1) {
34
+ warnings.push(`unparseable line: ${line.slice(0, 120)}`);
35
+ continue;
36
+ }
37
+ let parsed;
38
+ try {
39
+ parsed = JSON.parse(line.slice(0, end + 1));
40
+ }
41
+ catch {
42
+ warnings.push(`unparseable line: ${line.slice(0, 120)}`);
43
+ continue;
44
+ }
45
+ const trailing = line.slice(end + 1);
46
+ if (trailing.trim()) {
47
+ warnings.push(`ignored trailing content after JSON: ${trailing.trim().slice(0, 120)}`);
48
+ }
49
+ if (typeof parsed === 'object' && parsed !== null && 'tool' in parsed) {
50
+ objects.push(parsed);
51
+ }
52
+ }
53
+ return { objects, warnings };
54
+ }
@@ -0,0 +1,2 @@
1
+ import type { ParsedMapTokenPropToolCalls } from '../../types/tool-calls.js';
2
+ export declare function parseMapTokenPropToolCallLines(stdout: string): ParsedMapTokenPropToolCalls;
@@ -0,0 +1,39 @@
1
+ function isStringArray(value) {
2
+ return Array.isArray(value) && value.every((v) => typeof v === 'string');
3
+ }
4
+ export function parseMapTokenPropToolCallLines(stdout) {
5
+ const calls = [];
6
+ const warnings = [];
7
+ for (const raw of stdout.split('\n')) {
8
+ const line = raw.trim();
9
+ if (!line.startsWith('{'))
10
+ continue;
11
+ let obj;
12
+ try {
13
+ obj = JSON.parse(line);
14
+ }
15
+ catch {
16
+ warnings.push(`unparseable line: ${line.slice(0, 120)}`);
17
+ continue;
18
+ }
19
+ if (typeof obj !== 'object' || obj === null || !('tool' in obj))
20
+ continue;
21
+ const rec = obj;
22
+ if (rec.tool !== 'map_token_prop')
23
+ continue;
24
+ if (typeof rec.component !== 'string' || !rec.component) {
25
+ warnings.push('map_token_prop missing component — skipped');
26
+ continue;
27
+ }
28
+ if (typeof rec.prop !== 'string' || !rec.prop) {
29
+ warnings.push(`map_token_prop '${rec.component}': missing prop — skipped`);
30
+ continue;
31
+ }
32
+ if (!isStringArray(rec.token_allowed) || rec.token_allowed.length === 0) {
33
+ warnings.push(`map_token_prop '${rec.component}.${String(rec.prop)}': missing or empty token_allowed — skipped`);
34
+ continue;
35
+ }
36
+ calls.push({ tool: 'map_token_prop', component: rec.component, prop: rec.prop, token_allowed: rec.token_allowed });
37
+ }
38
+ return { calls, warnings };
39
+ }
@@ -0,0 +1,2 @@
1
+ import type { ParsedToolCalls } from '../../types/tool-calls.js';
2
+ export declare function parsePropToolCallLines(stdout: string): ParsedToolCalls;