@axiom-lattice/cli-a2a 0.1.1

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 (63) hide show
  1. package/.turbo/turbo-build.log +51 -0
  2. package/CHANGELOG.md +7 -0
  3. package/LICENSE +201 -0
  4. package/README.md +290 -0
  5. package/__tests__/opencode-executor.test.ts +159 -0
  6. package/agents/opencode-example/config.json +64 -0
  7. package/dist/bridge-7ZUDKCZT.mjs +271 -0
  8. package/dist/bridge-7ZUDKCZT.mjs.map +1 -0
  9. package/dist/chunk-35NFMGMS.mjs +27 -0
  10. package/dist/chunk-35NFMGMS.mjs.map +1 -0
  11. package/dist/chunk-G7AGL2QA.mjs +284 -0
  12. package/dist/chunk-G7AGL2QA.mjs.map +1 -0
  13. package/dist/chunk-LXL47XMZ.mjs +43 -0
  14. package/dist/chunk-LXL47XMZ.mjs.map +1 -0
  15. package/dist/chunk-NQIDRU47.mjs +178 -0
  16. package/dist/chunk-NQIDRU47.mjs.map +1 -0
  17. package/dist/chunk-VSZ3DACI.mjs +179 -0
  18. package/dist/chunk-VSZ3DACI.mjs.map +1 -0
  19. package/dist/chunk-VZEH3EPJ.mjs +56 -0
  20. package/dist/chunk-VZEH3EPJ.mjs.map +1 -0
  21. package/dist/chunk-WNCDOYZS.mjs +187 -0
  22. package/dist/chunk-WNCDOYZS.mjs.map +1 -0
  23. package/dist/cli.d.mts +1 -0
  24. package/dist/cli.d.ts +1 -0
  25. package/dist/cli.js +1562 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/cli.mjs +293 -0
  28. package/dist/cli.mjs.map +1 -0
  29. package/dist/executor-OWPVDUXH.mjs +11 -0
  30. package/dist/executor-OWPVDUXH.mjs.map +1 -0
  31. package/dist/executor-RVBGAWUF.mjs +11 -0
  32. package/dist/executor-RVBGAWUF.mjs.map +1 -0
  33. package/dist/executor-XWHWUVQ3.mjs +11 -0
  34. package/dist/executor-XWHWUVQ3.mjs.map +1 -0
  35. package/dist/executors-QIIKBUMJ.mjs +15 -0
  36. package/dist/executors-QIIKBUMJ.mjs.map +1 -0
  37. package/dist/index.d.mts +295 -0
  38. package/dist/index.d.ts +295 -0
  39. package/dist/index.js +942 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/index.mjs +44 -0
  42. package/dist/index.mjs.map +1 -0
  43. package/jest.config.js +16 -0
  44. package/package.json +63 -0
  45. package/src/bridge.ts +355 -0
  46. package/src/cli.ts +384 -0
  47. package/src/config/defaults.ts +109 -0
  48. package/src/config/index.ts +16 -0
  49. package/src/config/loader.ts +121 -0
  50. package/src/config/types.ts +163 -0
  51. package/src/executors/claude/client.ts +138 -0
  52. package/src/executors/claude/executor.ts +111 -0
  53. package/src/executors/codex/client.ts +139 -0
  54. package/src/executors/codex/executor.ts +118 -0
  55. package/src/executors/events.ts +117 -0
  56. package/src/executors/index.ts +54 -0
  57. package/src/executors/opencode/client.ts +149 -0
  58. package/src/executors/opencode/executor.ts +112 -0
  59. package/src/index.ts +54 -0
  60. package/src/logger.ts +78 -0
  61. package/src/server/agent-card.ts +51 -0
  62. package/src/server/index.ts +124 -0
  63. package/tsconfig.json +21 -0
@@ -0,0 +1,284 @@
1
+ import {
2
+ createExecutor
3
+ } from "./chunk-35NFMGMS.mjs";
4
+ import {
5
+ logger
6
+ } from "./chunk-VZEH3EPJ.mjs";
7
+
8
+ // src/config/loader.ts
9
+ import { readFileSync, existsSync } from "fs";
10
+ import { resolve, dirname } from "path";
11
+
12
+ // src/config/defaults.ts
13
+ function withDefaults(partial, defaults) {
14
+ const result = { ...defaults };
15
+ for (const key of Object.keys(partial)) {
16
+ const val = partial[key];
17
+ if (val !== void 0 && val !== null) {
18
+ if (typeof val === "object" && !Array.isArray(val) && typeof defaults[key] === "object" && !Array.isArray(defaults[key])) {
19
+ result[key] = {
20
+ ...defaults[key],
21
+ ...val
22
+ };
23
+ } else {
24
+ result[key] = val;
25
+ }
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ var DEFAULTS = Object.freeze({
31
+ provider: "opencode",
32
+ agentCard: {
33
+ name: "CLI A2A Agent",
34
+ description: "A multi-provider A2A agent driven by local CLI coding tools.",
35
+ protocolVersion: "0.3.0",
36
+ version: "0.1.0",
37
+ skills: [],
38
+ defaultInputModes: ["text"],
39
+ defaultOutputModes: ["text"],
40
+ streaming: true,
41
+ pushNotifications: false
42
+ },
43
+ server: {
44
+ port: 3e3,
45
+ hostname: "0.0.0.0",
46
+ advertiseHost: "localhost",
47
+ advertiseProtocol: "http"
48
+ },
49
+ session: {
50
+ titlePrefix: "A2A Session",
51
+ reuseByContext: true,
52
+ ttl: 36e5,
53
+ cleanupInterval: 3e5
54
+ },
55
+ features: {
56
+ autoApprovePermissions: true,
57
+ autoAnswerQuestions: true,
58
+ streamArtifactChunks: false,
59
+ enablePollingFallback: true
60
+ },
61
+ timeouts: {
62
+ prompt: 6e5,
63
+ pollingInterval: 2e3,
64
+ healthCheck: 3e4
65
+ },
66
+ logging: {
67
+ level: "info"
68
+ },
69
+ opencode: {
70
+ baseUrl: "http://localhost:4096",
71
+ projectDirectory: "",
72
+ model: "",
73
+ agent: "",
74
+ systemPrompt: "",
75
+ systemPromptMode: "append",
76
+ contextFile: "context.md",
77
+ contextPrompt: ""
78
+ },
79
+ codex: {
80
+ cliPath: "codex",
81
+ workdir: process.cwd(),
82
+ model: "",
83
+ apiKey: ""
84
+ },
85
+ claude: {
86
+ cliPath: "claude",
87
+ workdir: process.cwd(),
88
+ model: "",
89
+ apiKey: ""
90
+ },
91
+ configDir: void 0
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ });
94
+ function resolveDefaults(overrides) {
95
+ return withDefaults(overrides, DEFAULTS);
96
+ }
97
+
98
+ // src/config/loader.ts
99
+ var log = logger.child("config");
100
+ function loadConfigFile(filePath) {
101
+ const absPath = resolve(filePath);
102
+ if (!existsSync(absPath)) {
103
+ throw new Error(`Config file not found: ${absPath}`);
104
+ }
105
+ try {
106
+ const raw = readFileSync(absPath, "utf-8");
107
+ return JSON.parse(raw);
108
+ } catch (err) {
109
+ const msg = err instanceof SyntaxError ? `Invalid JSON in config file: ${err.message}` : `Failed to read config file: ${err.message}`;
110
+ throw new Error(msg);
111
+ }
112
+ }
113
+ function loadEnvOverrides() {
114
+ const overrides = {
115
+ opencode: {},
116
+ codex: {},
117
+ claude: {}
118
+ };
119
+ if (process.env.OPENCODE_URL) overrides.opencode.baseUrl = process.env.OPENCODE_URL;
120
+ if (process.env.OPENCODE_DIRECTORY) overrides.opencode.projectDirectory = process.env.OPENCODE_DIRECTORY;
121
+ if (process.env.OPENCODE_MODEL) overrides.opencode.model = process.env.OPENCODE_MODEL;
122
+ if (process.env.OPENCODE_AGENT) overrides.opencode.agent = process.env.OPENCODE_AGENT;
123
+ if (process.env.OPENCODE_SYSTEM_PROMPT) overrides.opencode.systemPrompt = process.env.OPENCODE_SYSTEM_PROMPT;
124
+ if (process.env.OPENAI_API_KEY) overrides.codex.apiKey = process.env.OPENAI_API_KEY;
125
+ if (process.env.CODEX_MODEL) overrides.codex.model = process.env.CODEX_MODEL;
126
+ if (process.env.ANTHROPIC_API_KEY) overrides.claude.apiKey = process.env.ANTHROPIC_API_KEY;
127
+ if (process.env.CLAUDE_MODEL) overrides.claude.model = process.env.CLAUDE_MODEL;
128
+ return overrides;
129
+ }
130
+ function resolveConfig(configPath, cliOverrides) {
131
+ let fileConfig = {};
132
+ if (configPath) {
133
+ fileConfig = loadConfigFile(configPath);
134
+ log.info("Loaded config file", { path: configPath });
135
+ }
136
+ const envOverrides = loadEnvOverrides();
137
+ const cliConfig = cliOverrides ?? {};
138
+ const cloned = structuredClone(resolveDefaults(fileConfig));
139
+ const base = cloned;
140
+ mergeOverrides(base, envOverrides);
141
+ mergeOverrides(base, cliConfig);
142
+ if (configPath) {
143
+ base.configDir = dirname(resolve(configPath));
144
+ }
145
+ return base;
146
+ }
147
+ function mergeOverrides(target, source) {
148
+ for (const key of Object.keys(source)) {
149
+ const srcVal = source[key];
150
+ const tgtVal = target[key];
151
+ if (srcVal !== void 0 && srcVal !== null && typeof srcVal === "object" && !Array.isArray(srcVal) && tgtVal !== void 0 && typeof tgtVal === "object" && !Array.isArray(tgtVal)) {
152
+ if (Object.keys(srcVal).length > 0) {
153
+ mergeOverrides(tgtVal, srcVal);
154
+ }
155
+ } else if (srcVal !== void 0 && srcVal !== null) {
156
+ target[key] = srcVal;
157
+ }
158
+ }
159
+ }
160
+
161
+ // src/server/index.ts
162
+ import express from "express";
163
+ import { AGENT_CARD_PATH } from "@a2a-js/sdk";
164
+ import { DefaultRequestHandler, InMemoryTaskStore } from "@a2a-js/sdk/server";
165
+ import {
166
+ jsonRpcHandler,
167
+ restHandler,
168
+ UserBuilder
169
+ } from "@a2a-js/sdk/server/express";
170
+
171
+ // src/server/agent-card.ts
172
+ var log2 = logger.child("agent-card");
173
+ function buildAgentCard(config) {
174
+ const { agentCard, server } = config;
175
+ const proto = server.advertiseProtocol ?? "http";
176
+ const host = server.advertiseHost ?? "localhost";
177
+ const port = server.port ?? 3e3;
178
+ const baseUrl = `${proto}://${host}:${port}`;
179
+ const skills = (agentCard.skills ?? []).map((s) => ({
180
+ id: s.id,
181
+ name: s.name,
182
+ description: s.description,
183
+ tags: s.tags ?? [],
184
+ examples: s.examples ?? []
185
+ }));
186
+ const card = {
187
+ name: agentCard.name,
188
+ description: agentCard.description,
189
+ protocolVersion: agentCard.protocolVersion ?? "0.3.0",
190
+ version: agentCard.version ?? "1.0.0",
191
+ url: `${baseUrl}/a2a/jsonrpc`,
192
+ // Default input/output modes (A2A v1.0 normalized names)
193
+ defaultInputModes: agentCard.defaultInputModes ?? ["text"],
194
+ defaultOutputModes: agentCard.defaultOutputModes ?? ["text"],
195
+ skills,
196
+ capabilities: {
197
+ streaming: agentCard.streaming ?? true,
198
+ pushNotifications: agentCard.pushNotifications ?? false
199
+ },
200
+ // Additional interfaces advertised to orchestrators
201
+ additionalInterfaces: [
202
+ { transport: "JSONRPC", url: `${baseUrl}/a2a/jsonrpc` },
203
+ { transport: "REST", url: `${baseUrl}/a2a/rest` }
204
+ ]
205
+ };
206
+ log2.info("Agent card built", { name: card.name, url: card.url, skills: card.skills?.length ?? 0 });
207
+ return card;
208
+ }
209
+
210
+ // src/server/index.ts
211
+ var log3 = logger.child("server");
212
+ async function createA2AServer(config) {
213
+ const srv = config.server;
214
+ const port = srv.port ?? 3e3;
215
+ const hostname = srv.hostname ?? "0.0.0.0";
216
+ const advertiseHost = srv.advertiseHost ?? "localhost";
217
+ const advertiseProto = srv.advertiseProtocol ?? "http";
218
+ const executor = createExecutor(config);
219
+ await executor.initialize();
220
+ const agentCard = buildAgentCard(config);
221
+ const taskStore = new InMemoryTaskStore();
222
+ const requestHandler = new DefaultRequestHandler(agentCard, taskStore, executor);
223
+ const app = express();
224
+ app.use((_req, res, next) => {
225
+ res.setHeader("A2A-Version", "0.3");
226
+ next();
227
+ });
228
+ app.get("/health", (_req, res) => {
229
+ res.json({ status: "healthy", agent: agentCard.name, provider: config.provider });
230
+ });
231
+ const serveAgentCard = (req, res) => {
232
+ const host = req.headers.host || `${advertiseHost}:${port}`;
233
+ const proto = req.headers["x-forwarded-proto"] || advertiseProto;
234
+ const dynamicBase = `${proto}://${host}`;
235
+ res.json({
236
+ ...agentCard,
237
+ url: `${dynamicBase}/a2a/jsonrpc`,
238
+ additionalInterfaces: [
239
+ { transport: "JSONRPC", url: `${dynamicBase}/a2a/jsonrpc` },
240
+ { transport: "REST", url: `${dynamicBase}/a2a/rest` }
241
+ ]
242
+ });
243
+ };
244
+ app.get(`/${AGENT_CARD_PATH}`, serveAgentCard);
245
+ app.get("/.well-known/agent.json", serveAgentCard);
246
+ app.get("/.well-known/agent-json", serveAgentCard);
247
+ app.use("/a2a/jsonrpc", jsonRpcHandler({ requestHandler, userBuilder: UserBuilder.noAuthentication }));
248
+ app.use("/a2a/rest", restHandler({ requestHandler, userBuilder: UserBuilder.noAuthentication }));
249
+ const httpServer = app.listen(port, hostname, () => {
250
+ log3.info("A2A server started", { bind: hostname, port, proto: advertiseProto });
251
+ const banner = [
252
+ "",
253
+ "\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557",
254
+ `\u2551 CLI A2A Gateway \u2014 ${config.provider.padEnd(28)}\u2551`,
255
+ "\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563",
256
+ `\u2551 Agent: ${agentCard.name}`,
257
+ `\u2551 Bind: ${hostname}:${port}`,
258
+ `\u2551 Agent Card: ${advertiseProto}://${advertiseHost}:${port}/${AGENT_CARD_PATH}`,
259
+ `\u2551 JSON-RPC: ${advertiseProto}://${advertiseHost}:${port}/a2a/jsonrpc`,
260
+ `\u2551 REST: ${advertiseProto}://${advertiseHost}:${port}/a2a/rest`,
261
+ `\u2551 Health: ${advertiseProto}://${advertiseHost}:${port}/health`,
262
+ "\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563",
263
+ "\u2551 Ready. Press Ctrl+C to stop. \u2551",
264
+ "\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
265
+ ].join("\n");
266
+ console.log(banner);
267
+ });
268
+ return {
269
+ app,
270
+ server: httpServer,
271
+ async shutdown() {
272
+ httpServer.close();
273
+ await executor.shutdown();
274
+ log3.info("Server shut down");
275
+ }
276
+ };
277
+ }
278
+
279
+ export {
280
+ loadConfigFile,
281
+ resolveConfig,
282
+ createA2AServer
283
+ };
284
+ //# sourceMappingURL=chunk-G7AGL2QA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/loader.ts","../src/config/defaults.ts","../src/server/index.ts","../src/server/agent-card.ts"],"sourcesContent":["/**\n * Config loader — reads JSON config files and resolves the final config\n * by merging layers: defaults ← config file ← env overrides ← CLI args.\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport { resolveDefaults } from './defaults.js';\nimport type { AgentConfig } from './types.js';\nimport { logger } from '../logger.js';\n\nconst log = logger.child('config');\n\n/**\n * Read and parse a JSON config file.\n */\nexport function loadConfigFile(filePath: string): Partial<AgentConfig> {\n const absPath = resolve(filePath);\n if (!existsSync(absPath)) {\n throw new Error(`Config file not found: ${absPath}`);\n }\n try {\n const raw = readFileSync(absPath, 'utf-8');\n return JSON.parse(raw) as Partial<AgentConfig>;\n } catch (err) {\n const msg = err instanceof SyntaxError\n ? `Invalid JSON in config file: ${err.message}`\n : `Failed to read config file: ${(err as Error).message}`;\n throw new Error(msg);\n }\n}\n\n/**\n * Load env overrides for provider configs.\n */\nfunction loadEnvOverrides(): Partial<AgentConfig> {\n const overrides: Partial<AgentConfig> = {\n opencode: {},\n codex: {},\n claude: {},\n };\n\n // OpenCode\n if (process.env.OPENCODE_URL) overrides.opencode!.baseUrl = process.env.OPENCODE_URL;\n if (process.env.OPENCODE_DIRECTORY) overrides.opencode!.projectDirectory = process.env.OPENCODE_DIRECTORY;\n if (process.env.OPENCODE_MODEL) overrides.opencode!.model = process.env.OPENCODE_MODEL;\n if (process.env.OPENCODE_AGENT) overrides.opencode!.agent = process.env.OPENCODE_AGENT;\n if (process.env.OPENCODE_SYSTEM_PROMPT) overrides.opencode!.systemPrompt = process.env.OPENCODE_SYSTEM_PROMPT;\n\n // Codex\n if (process.env.OPENAI_API_KEY) overrides.codex!.apiKey = process.env.OPENAI_API_KEY;\n if (process.env.CODEX_MODEL) overrides.codex!.model = process.env.CODEX_MODEL;\n\n // Claude Code\n if (process.env.ANTHROPIC_API_KEY) overrides.claude!.apiKey = process.env.ANTHROPIC_API_KEY;\n if (process.env.CLAUDE_MODEL) overrides.claude!.model = process.env.CLAUDE_MODEL;\n\n return overrides;\n}\n\n/**\n * Resolve full config from defaults + file + env.\n */\nexport function resolveConfig(\n configPath?: string,\n cliOverrides?: Partial<AgentConfig>,\n): Required<AgentConfig> {\n // Layer 1: File\n let fileConfig: Partial<AgentConfig> = {};\n if (configPath) {\n fileConfig = loadConfigFile(configPath);\n log.info('Loaded config file', { path: configPath });\n }\n\n // Layer 2: Env\n const envOverrides = loadEnvOverrides();\n\n // Layer 3: CLI\n const cliConfig = cliOverrides ?? {};\n\n // Deep merge: defaults ← file ← env ← CLI\n // Start with a proper deep copy of merged defaults+file to avoid mutating the frozen defaults\n const cloned = structuredClone(resolveDefaults(fileConfig)) as Required<AgentConfig>;\n const base = cloned;\n\n // Then merge env overrides\n mergeOverrides(base, envOverrides);\n\n // Then merge CLI overrides\n mergeOverrides(base, cliConfig);\n\n // Populate configDir\n if (configPath) {\n base.configDir = dirname(resolve(configPath));\n }\n\n return base;\n}\n\nfunction mergeOverrides(target: Record<string, unknown>, source: Record<string, unknown>): void {\n for (const key of Object.keys(source)) {\n const srcVal = source[key];\n const tgtVal = target[key];\n if (\n srcVal !== undefined &&\n srcVal !== null &&\n typeof srcVal === 'object' &&\n !Array.isArray(srcVal) &&\n tgtVal !== undefined &&\n typeof tgtVal === 'object' &&\n !Array.isArray(tgtVal)\n ) {\n // Do not merge empty override objects\n if (Object.keys(srcVal as Record<string, unknown>).length > 0) {\n mergeOverrides(tgtVal as Record<string, unknown>, srcVal as Record<string, unknown>);\n }\n } else if (srcVal !== undefined && srcVal !== null) {\n target[key] = srcVal;\n }\n }\n}\n","/**\n * Default configuration values.\n *\n * Every field has a sensible default so the agent runs without a config file.\n */\n\nimport type { AgentConfig } from './types.js';\n\nfunction withDefaults<T extends Record<string, unknown>>(\n partial: Partial<T>,\n defaults: Required<T>,\n): Required<T> {\n const result = { ...defaults } as Record<string, unknown>;\n for (const key of Object.keys(partial) as Array<keyof T>) {\n const val = partial[key] as unknown;\n if (val !== undefined && val !== null) {\n if (\n typeof val === 'object' &&\n !Array.isArray(val) &&\n typeof defaults[key] === 'object' &&\n !Array.isArray(defaults[key])\n ) {\n result[key as string] = {\n ...(defaults[key] as Record<string, unknown>),\n ...(val as Record<string, unknown>),\n };\n } else {\n result[key as string] = val;\n }\n }\n }\n return result as unknown as Required<T>;\n}\n\ntype ResolvedConfig = Omit<Required<AgentConfig>, 'opencode' | 'codex' | 'claude' | 'configDir'> & {\n opencode: Required<Required<AgentConfig>['opencode']>;\n codex: Required<Required<AgentConfig>['codex']>;\n claude: Required<Required<AgentConfig>['claude']>;\n configDir: string | undefined;\n};\n\nconst DEFAULTS: Readonly<ResolvedConfig> = Object.freeze({\n provider: 'opencode' as const,\n agentCard: {\n name: 'CLI A2A Agent',\n description: 'A multi-provider A2A agent driven by local CLI coding tools.',\n protocolVersion: '0.3.0',\n version: '0.1.0',\n skills: [],\n defaultInputModes: ['text'],\n defaultOutputModes: ['text'],\n streaming: true,\n pushNotifications: false,\n },\n server: {\n port: 3000,\n hostname: '0.0.0.0',\n advertiseHost: 'localhost',\n advertiseProtocol: 'http',\n },\n session: {\n titlePrefix: 'A2A Session',\n reuseByContext: true,\n ttl: 3_600_000,\n cleanupInterval: 300_000,\n },\n features: {\n autoApprovePermissions: true,\n autoAnswerQuestions: true,\n streamArtifactChunks: false,\n enablePollingFallback: true,\n },\n timeouts: {\n prompt: 600_000,\n pollingInterval: 2_000,\n healthCheck: 30_000,\n },\n logging: {\n level: 'info',\n },\n opencode: {\n baseUrl: 'http://localhost:4096',\n projectDirectory: '',\n model: '',\n agent: '',\n systemPrompt: '',\n systemPromptMode: 'append',\n contextFile: 'context.md',\n contextPrompt: '',\n },\n codex: {\n cliPath: 'codex',\n workdir: process.cwd(),\n model: '',\n apiKey: '',\n },\n claude: {\n cliPath: 'claude',\n workdir: process.cwd(),\n model: '',\n apiKey: '',\n },\n configDir: undefined,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n} as any);\n\nexport function resolveDefaults(overrides: Partial<AgentConfig>): Required<AgentConfig> {\n return withDefaults(overrides, DEFAULTS) as unknown as Required<AgentConfig>;\n}\n","/**\n * A2A HTTP Server\n *\n * Creates an Express server with standard A2A endpoints:\n * - GET /.well-known/agent-card.json → Agent Card\n * - POST /a2a/jsonrpc → JSON-RPC transport\n * - POST /a2a/rest → REST transport\n * - GET /health → Health check\n */\n\nimport express, { type RequestHandler } from 'express';\nimport { AGENT_CARD_PATH } from '@a2a-js/sdk';\nimport { DefaultRequestHandler, InMemoryTaskStore } from '@a2a-js/sdk/server';\nimport {\n jsonRpcHandler,\n restHandler,\n UserBuilder,\n} from '@a2a-js/sdk/server/express';\n\nimport type { AgentConfig } from '../config/types.js';\nimport { buildAgentCard } from './agent-card.js';\nimport { createExecutor } from '../executors/index.js';\nimport { logger } from '../logger.js';\n\nconst log = logger.child('server');\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface ServerHandle {\n app: ReturnType<typeof express>;\n server: ReturnType<ReturnType<typeof express>['listen']>;\n shutdown(): Promise<void>;\n}\n\n// ─── Server Factory ─────────────────────────────────────────────────────────\n\nexport async function createA2AServer(config: Required<AgentConfig>): Promise<ServerHandle> {\n const srv = config.server;\n const port = srv.port ?? 3000;\n const hostname = srv.hostname ?? '0.0.0.0';\n const advertiseHost = srv.advertiseHost ?? 'localhost';\n const advertiseProto = srv.advertiseProtocol ?? 'http';\n\n // 1. Create executor\n const executor = createExecutor(config);\n await executor.initialize();\n\n // 2. Build agent card\n const agentCard = buildAgentCard(config);\n\n // 3. A2A request handler\n const taskStore = new InMemoryTaskStore();\n const requestHandler = new DefaultRequestHandler(agentCard, taskStore, executor);\n\n // 4. Express app\n const app = express();\n\n // A2A-Version header\n app.use((_req, res, next) => {\n res.setHeader('A2A-Version', '0.3');\n next();\n });\n\n // Health check\n app.get('/health', (_req, res) => {\n res.json({ status: 'healthy', agent: agentCard.name, provider: config.provider });\n });\n\n // Agent card — dynamic URL rewriting for reverse proxy support\n const serveAgentCard: RequestHandler = (req, res) => {\n const host = req.headers.host || `${advertiseHost}:${port}`;\n const proto = (req.headers['x-forwarded-proto'] as string) || advertiseProto;\n const dynamicBase = `${proto}://${host}`;\n res.json({\n ...agentCard,\n url: `${dynamicBase}/a2a/jsonrpc`,\n additionalInterfaces: [\n { transport: 'JSONRPC', url: `${dynamicBase}/a2a/jsonrpc` },\n { transport: 'REST', url: `${dynamicBase}/a2a/rest` },\n ],\n });\n };\n\n app.get(`/${AGENT_CARD_PATH}`, serveAgentCard);\n app.get('/.well-known/agent.json', serveAgentCard);\n app.get('/.well-known/agent-json', serveAgentCard);\n\n // A2A transport handlers\n app.use('/a2a/jsonrpc', jsonRpcHandler({ requestHandler, userBuilder: UserBuilder.noAuthentication }));\n app.use('/a2a/rest', restHandler({ requestHandler, userBuilder: UserBuilder.noAuthentication }));\n\n // 5. Start listening\n const httpServer = app.listen(port, hostname, () => {\n log.info('A2A server started', { bind: hostname, port, proto: advertiseProto });\n\n const banner = [\n '',\n '╔══════════════════════════════════════════════════════════════╗',\n `║ CLI A2A Gateway — ${config.provider.padEnd(28)}║`,\n '╠══════════════════════════════════════════════════════════════╣',\n `║ Agent: ${agentCard.name}`,\n `║ Bind: ${hostname}:${port}`,\n `║ Agent Card: ${advertiseProto}://${advertiseHost}:${port}/${AGENT_CARD_PATH}`,\n `║ JSON-RPC: ${advertiseProto}://${advertiseHost}:${port}/a2a/jsonrpc`,\n `║ REST: ${advertiseProto}://${advertiseHost}:${port}/a2a/rest`,\n `║ Health: ${advertiseProto}://${advertiseHost}:${port}/health`,\n '╠══════════════════════════════════════════════════════════════╣',\n '║ Ready. Press Ctrl+C to stop. ║',\n '╚══════════════════════════════════════════════════════════════╝',\n ].join('\\n');\n console.log(banner);\n });\n\n // 6. Return handle\n return {\n app,\n server: httpServer,\n async shutdown() {\n httpServer.close();\n await executor.shutdown();\n log.info('Server shut down');\n },\n };\n}\n","/**\n * Agent Card builder.\n *\n * Builds an A2A-compliant AgentCard from the resolved config.\n */\n\nimport type { AgentCard, AgentSkill } from '@a2a-js/sdk';\nimport type { AgentConfig } from '../config/types.js';\nimport { logger } from '../logger.js';\n\nconst log = logger.child('agent-card');\n\nexport function buildAgentCard(config: Required<AgentConfig>): AgentCard {\n const { agentCard, server } = config;\n const proto = server.advertiseProtocol ?? 'http';\n const host = server.advertiseHost ?? 'localhost';\n const port = server.port ?? 3000;\n const baseUrl = `${proto}://${host}:${port}`;\n\n const skills: AgentSkill[] = (agentCard.skills ?? []).map((s) => ({\n id: s.id,\n name: s.name,\n description: s.description,\n tags: s.tags ?? [],\n examples: s.examples ?? [],\n }));\n\n const card: AgentCard = {\n name: agentCard.name,\n description: agentCard.description,\n protocolVersion: agentCard.protocolVersion ?? '0.3.0',\n version: agentCard.version ?? '1.0.0',\n url: `${baseUrl}/a2a/jsonrpc`,\n // Default input/output modes (A2A v1.0 normalized names)\n defaultInputModes: (agentCard.defaultInputModes as Array<'text' | 'file' | 'image' | 'audio'>) ?? ['text'],\n defaultOutputModes: (agentCard.defaultOutputModes as Array<'text' | 'file' | 'image' | 'audio'>) ?? ['text'],\n skills,\n capabilities: {\n streaming: agentCard.streaming ?? true,\n pushNotifications: agentCard.pushNotifications ?? false,\n },\n // Additional interfaces advertised to orchestrators\n additionalInterfaces: [\n { transport: 'JSONRPC', url: `${baseUrl}/a2a/jsonrpc` },\n { transport: 'REST', url: `${baseUrl}/a2a/rest` },\n ],\n };\n\n log.info('Agent card built', { name: card.name, url: card.url, skills: card.skills?.length ?? 0 });\n return card;\n}\n"],"mappings":";;;;;;;;AAKA,SAAS,cAAc,kBAAkB;AACzC,SAAS,SAAS,eAAe;;;ACEjC,SAAS,aACP,SACA,UACa;AACb,QAAM,SAAS,EAAE,GAAG,SAAS;AAC7B,aAAW,OAAO,OAAO,KAAK,OAAO,GAAqB;AACxD,UAAM,MAAM,QAAQ,GAAG;AACvB,QAAI,QAAQ,UAAa,QAAQ,MAAM;AACrC,UACE,OAAO,QAAQ,YACf,CAAC,MAAM,QAAQ,GAAG,KAClB,OAAO,SAAS,GAAG,MAAM,YACzB,CAAC,MAAM,QAAQ,SAAS,GAAG,CAAC,GAC5B;AACA,eAAO,GAAa,IAAI;AAAA,UACtB,GAAI,SAAS,GAAG;AAAA,UAChB,GAAI;AAAA,QACN;AAAA,MACF,OAAO;AACL,eAAO,GAAa,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AASA,IAAM,WAAqC,OAAO,OAAO;AAAA,EACvD,UAAU;AAAA,EACV,WAAW;AAAA,IACT,MAAM;AAAA,IACN,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,QAAQ,CAAC;AAAA,IACT,mBAAmB,CAAC,MAAM;AAAA,IAC1B,oBAAoB,CAAC,MAAM;AAAA,IAC3B,WAAW;AAAA,IACX,mBAAmB;AAAA,EACrB;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,eAAe;AAAA,IACf,mBAAmB;AAAA,EACrB;AAAA,EACA,SAAS;AAAA,IACP,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,KAAK;AAAA,IACL,iBAAiB;AAAA,EACnB;AAAA,EACA,UAAU;AAAA,IACR,wBAAwB;AAAA,IACxB,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,IACtB,uBAAuB;AAAA,EACzB;AAAA,EACA,UAAU;AAAA,IACR,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,aAAa;AAAA,EACf;AAAA,EACA,SAAS;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,IACT,kBAAkB;AAAA,IAClB,OAAO;AAAA,IACP,OAAO;AAAA,IACP,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,QAAQ,IAAI;AAAA,IACrB,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,SAAS,QAAQ,IAAI;AAAA,IACrB,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,WAAW;AAAA;AAEb,CAAQ;AAED,SAAS,gBAAgB,WAAwD;AACtF,SAAO,aAAa,WAAW,QAAQ;AACzC;;;ADjGA,IAAM,MAAM,OAAO,MAAM,QAAQ;AAK1B,SAAS,eAAe,UAAwC;AACrE,QAAM,UAAU,QAAQ,QAAQ;AAChC,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,UAAM,IAAI,MAAM,0BAA0B,OAAO,EAAE;AAAA,EACrD;AACA,MAAI;AACF,UAAM,MAAM,aAAa,SAAS,OAAO;AACzC,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,cACvB,gCAAgC,IAAI,OAAO,KAC3C,+BAAgC,IAAc,OAAO;AACzD,UAAM,IAAI,MAAM,GAAG;AAAA,EACrB;AACF;AAKA,SAAS,mBAAyC;AAChD,QAAM,YAAkC;AAAA,IACtC,UAAU,CAAC;AAAA,IACX,OAAO,CAAC;AAAA,IACR,QAAQ,CAAC;AAAA,EACX;AAGA,MAAI,QAAQ,IAAI,aAAc,WAAU,SAAU,UAAU,QAAQ,IAAI;AACxE,MAAI,QAAQ,IAAI,mBAAoB,WAAU,SAAU,mBAAmB,QAAQ,IAAI;AACvF,MAAI,QAAQ,IAAI,eAAgB,WAAU,SAAU,QAAQ,QAAQ,IAAI;AACxE,MAAI,QAAQ,IAAI,eAAgB,WAAU,SAAU,QAAQ,QAAQ,IAAI;AACxE,MAAI,QAAQ,IAAI,uBAAwB,WAAU,SAAU,eAAe,QAAQ,IAAI;AAGvF,MAAI,QAAQ,IAAI,eAAgB,WAAU,MAAO,SAAS,QAAQ,IAAI;AACtE,MAAI,QAAQ,IAAI,YAAa,WAAU,MAAO,QAAQ,QAAQ,IAAI;AAGlE,MAAI,QAAQ,IAAI,kBAAmB,WAAU,OAAQ,SAAS,QAAQ,IAAI;AAC1E,MAAI,QAAQ,IAAI,aAAc,WAAU,OAAQ,QAAQ,QAAQ,IAAI;AAEpE,SAAO;AACT;AAKO,SAAS,cACd,YACA,cACuB;AAEvB,MAAI,aAAmC,CAAC;AACxC,MAAI,YAAY;AACd,iBAAa,eAAe,UAAU;AACtC,QAAI,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAAA,EACrD;AAGE,QAAM,eAAe,iBAAiB;AAGtC,QAAM,YAAY,gBAAgB,CAAC;AAInC,QAAM,SAAS,gBAAgB,gBAAgB,UAAU,CAAC;AAC1D,QAAM,OAAO;AAGf,iBAAe,MAAM,YAAY;AAGjC,iBAAe,MAAM,SAAS;AAG9B,MAAI,YAAY;AACd,SAAK,YAAY,QAAQ,QAAQ,UAAU,CAAC;AAAA,EAC9C;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,QAAiC,QAAuC;AAC9F,aAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,UAAM,SAAS,OAAO,GAAG;AACzB,UAAM,SAAS,OAAO,GAAG;AACzB,QACE,WAAW,UACX,WAAW,QACX,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,MAAM,KACrB,WAAW,UACX,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,MAAM,GACrB;AAEA,UAAI,OAAO,KAAK,MAAiC,EAAE,SAAS,GAAG;AAC7D,uBAAe,QAAmC,MAAiC;AAAA,MACrF;AAAA,IACF,WAAW,WAAW,UAAa,WAAW,MAAM;AAClD,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AACF;;;AE9GA,OAAO,aAAsC;AAC7C,SAAS,uBAAuB;AAChC,SAAS,uBAAuB,yBAAyB;AACzD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACPP,IAAMA,OAAM,OAAO,MAAM,YAAY;AAE9B,SAAS,eAAe,QAA0C;AACvE,QAAM,EAAE,WAAW,OAAO,IAAI;AAC9B,QAAM,QAAQ,OAAO,qBAAqB;AAC1C,QAAM,OAAO,OAAO,iBAAiB;AACrC,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAM,UAAU,GAAG,KAAK,MAAM,IAAI,IAAI,IAAI;AAE1C,QAAM,UAAwB,UAAU,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,IAChE,IAAI,EAAE;AAAA,IACN,MAAM,EAAE;AAAA,IACR,aAAa,EAAE;AAAA,IACf,MAAM,EAAE,QAAQ,CAAC;AAAA,IACjB,UAAU,EAAE,YAAY,CAAC;AAAA,EAC3B,EAAE;AAEF,QAAM,OAAkB;AAAA,IACtB,MAAM,UAAU;AAAA,IAChB,aAAa,UAAU;AAAA,IACvB,iBAAiB,UAAU,mBAAmB;AAAA,IAC9C,SAAS,UAAU,WAAW;AAAA,IAC9B,KAAK,GAAG,OAAO;AAAA;AAAA,IAEf,mBAAoB,UAAU,qBAAoE,CAAC,MAAM;AAAA,IACzG,oBAAqB,UAAU,sBAAqE,CAAC,MAAM;AAAA,IAC3G;AAAA,IACA,cAAc;AAAA,MACZ,WAAW,UAAU,aAAa;AAAA,MAClC,mBAAmB,UAAU,qBAAqB;AAAA,IACpD;AAAA;AAAA,IAEA,sBAAsB;AAAA,MACpB,EAAE,WAAW,WAAW,KAAK,GAAG,OAAO,eAAe;AAAA,MACtD,EAAE,WAAW,QAAQ,KAAK,GAAG,OAAO,YAAY;AAAA,IAClD;AAAA,EACF;AAEA,EAAAA,KAAI,KAAK,oBAAoB,EAAE,MAAM,KAAK,MAAM,KAAK,KAAK,KAAK,QAAQ,KAAK,QAAQ,UAAU,EAAE,CAAC;AACjG,SAAO;AACT;;;AD1BA,IAAMC,OAAM,OAAO,MAAM,QAAQ;AAYjC,eAAsB,gBAAgB,QAAsD;AAC1F,QAAM,MAAM,OAAO;AACnB,QAAM,OAAO,IAAI,QAAQ;AACzB,QAAM,WAAW,IAAI,YAAY;AACjC,QAAM,gBAAgB,IAAI,iBAAiB;AAC3C,QAAM,iBAAiB,IAAI,qBAAqB;AAGhD,QAAM,WAAW,eAAe,MAAM;AACtC,QAAM,SAAS,WAAW;AAG1B,QAAM,YAAY,eAAe,MAAM;AAGvC,QAAM,YAAY,IAAI,kBAAkB;AACxC,QAAM,iBAAiB,IAAI,sBAAsB,WAAW,WAAW,QAAQ;AAG/E,QAAM,MAAM,QAAQ;AAGpB,MAAI,IAAI,CAAC,MAAM,KAAK,SAAS;AAC3B,QAAI,UAAU,eAAe,KAAK;AAClC,SAAK;AAAA,EACP,CAAC;AAGD,MAAI,IAAI,WAAW,CAAC,MAAM,QAAQ;AAChC,QAAI,KAAK,EAAE,QAAQ,WAAW,OAAO,UAAU,MAAM,UAAU,OAAO,SAAS,CAAC;AAAA,EAClF,CAAC;AAGD,QAAM,iBAAiC,CAAC,KAAK,QAAQ;AACnD,UAAM,OAAO,IAAI,QAAQ,QAAQ,GAAG,aAAa,IAAI,IAAI;AACzD,UAAM,QAAS,IAAI,QAAQ,mBAAmB,KAAgB;AAC9D,UAAM,cAAc,GAAG,KAAK,MAAM,IAAI;AACtC,QAAI,KAAK;AAAA,MACP,GAAG;AAAA,MACH,KAAK,GAAG,WAAW;AAAA,MACnB,sBAAsB;AAAA,QACpB,EAAE,WAAW,WAAW,KAAK,GAAG,WAAW,eAAe;AAAA,QAC1D,EAAE,WAAW,QAAQ,KAAK,GAAG,WAAW,YAAY;AAAA,MACtD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,IAAI,IAAI,eAAe,IAAI,cAAc;AAC7C,MAAI,IAAI,2BAA2B,cAAc;AACjD,MAAI,IAAI,2BAA2B,cAAc;AAGjD,MAAI,IAAI,gBAAgB,eAAe,EAAE,gBAAgB,aAAa,YAAY,iBAAiB,CAAC,CAAC;AACrG,MAAI,IAAI,aAAa,YAAY,EAAE,gBAAgB,aAAa,YAAY,iBAAiB,CAAC,CAAC;AAG/F,QAAM,aAAa,IAAI,OAAO,MAAM,UAAU,MAAM;AAClD,IAAAA,KAAI,KAAK,sBAAsB,EAAE,MAAM,UAAU,MAAM,OAAO,eAAe,CAAC;AAE9E,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA,uCAA6B,OAAO,SAAS,OAAO,EAAE,CAAC;AAAA,MACvD;AAAA,MACA,0BAAqB,UAAU,IAAI;AAAA,MACnC,0BAAqB,QAAQ,IAAI,IAAI;AAAA,MACrC,0BAAqB,cAAc,MAAM,aAAa,IAAI,IAAI,IAAI,eAAe;AAAA,MACjF,0BAAqB,cAAc,MAAM,aAAa,IAAI,IAAI;AAAA,MAC9D,0BAAqB,cAAc,MAAM,aAAa,IAAI,IAAI;AAAA,MAC9D,0BAAqB,cAAc,MAAM,aAAa,IAAI,IAAI;AAAA,MAC9D;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AACX,YAAQ,IAAI,MAAM;AAAA,EACpB,CAAC;AAGD,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,WAAW;AACf,iBAAW,MAAM;AACjB,YAAM,SAAS,SAAS;AACxB,MAAAA,KAAI,KAAK,kBAAkB;AAAA,IAC7B;AAAA,EACF;AACF;","names":["log","log"]}
@@ -0,0 +1,43 @@
1
+ // src/executors/events.ts
2
+ import { v4 as uuidv4 } from "uuid";
3
+ function publishTask(bus, taskId, contextId) {
4
+ bus.publish({
5
+ kind: "task",
6
+ taskId,
7
+ contextId
8
+ });
9
+ }
10
+ function publishStatus(bus, taskId, contextId, state, messageText, final) {
11
+ const event = {
12
+ kind: "task-status-update",
13
+ taskId,
14
+ contextId,
15
+ status: {
16
+ state,
17
+ message: messageText ? { role: "agent", parts: [{ kind: "text", text: messageText }] } : void 0
18
+ },
19
+ final: final ?? false
20
+ };
21
+ bus.publish(event);
22
+ }
23
+ function publishFinalArtifact(bus, taskId, contextId, text) {
24
+ const artifactId = uuidv4();
25
+ const event = {
26
+ kind: "task-artifact-update",
27
+ taskId,
28
+ contextId,
29
+ artifact: {
30
+ artifactId,
31
+ parts: [{ kind: "text", text }]
32
+ },
33
+ lastChunk: true
34
+ };
35
+ bus.publish(event);
36
+ }
37
+
38
+ export {
39
+ publishTask,
40
+ publishStatus,
41
+ publishFinalArtifact
42
+ };
43
+ //# sourceMappingURL=chunk-LXL47XMZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/executors/events.ts"],"sourcesContent":["/**\n * A2A event publishing helpers.\n *\n * Thin wrappers around ExecutionEventBus.publish() that construct\n * spec-compliant A2A task status and artifact update events.\n */\n\nimport { TaskState } from '@a2a-js/sdk';\nimport type { TaskStatusUpdateEvent, TaskArtifactUpdateEvent } from '@a2a-js/sdk';\nimport type { ExecutionEventBus } from '@a2a-js/sdk/server';\nimport { v4 as uuidv4 } from 'uuid';\n\n/**\n * Register a task with the execution event bus before publishing any events.\n */\nexport function publishTask(bus: ExecutionEventBus, taskId: string, contextId: string): void {\n bus.publish({\n kind: 'task',\n taskId,\n contextId,\n } as unknown as TaskStatusUpdateEvent);\n}\n\n/**\n * Publish a task status update.\n */\nexport function publishStatus(\n bus: ExecutionEventBus,\n taskId: string,\n contextId: string,\n state: TaskState | string,\n messageText?: string,\n final?: boolean,\n): void {\n const event: TaskStatusUpdateEvent = {\n kind: 'task-status-update',\n taskId,\n contextId,\n status: {\n state: state as TaskState,\n message: messageText\n ? { role: 'agent', parts: [{ kind: 'text', text: messageText }] }\n : undefined,\n },\n final: final ?? false,\n } as unknown as TaskStatusUpdateEvent;\n bus.publish(event);\n}\n\n/**\n * Publish a complete artifact (non-streaming).\n */\nexport function publishFinalArtifact(\n bus: ExecutionEventBus,\n taskId: string,\n contextId: string,\n text: string,\n): void {\n const artifactId = uuidv4();\n const event: TaskArtifactUpdateEvent = {\n kind: 'task-artifact-update',\n taskId,\n contextId,\n artifact: {\n artifactId,\n parts: [{ kind: 'text', text }],\n },\n lastChunk: true,\n } as unknown as TaskArtifactUpdateEvent;\n bus.publish(event);\n}\n\n/**\n * Publish a streaming artifact chunk.\n */\nexport function publishStreamingChunk(\n bus: ExecutionEventBus,\n taskId: string,\n contextId: string,\n artifactId: string,\n chunkText: string,\n): void {\n const event: TaskArtifactUpdateEvent = {\n kind: 'task-artifact-update',\n taskId,\n contextId,\n artifact: {\n artifactId,\n parts: [{ kind: 'text', text: chunkText }],\n },\n lastChunk: false,\n } as unknown as TaskArtifactUpdateEvent;\n bus.publish(event);\n}\n\n/**\n * Publish the final streaming chunk with full accumulated text.\n */\nexport function publishLastChunkMarker(\n bus: ExecutionEventBus,\n taskId: string,\n contextId: string,\n artifactId: string,\n fullText: string,\n): void {\n const event: TaskArtifactUpdateEvent = {\n kind: 'task-artifact-update',\n taskId,\n contextId,\n artifact: {\n artifactId,\n parts: [{ kind: 'text', text: fullText }],\n },\n lastChunk: true,\n } as unknown as TaskArtifactUpdateEvent;\n bus.publish(event);\n}\n"],"mappings":";AAUA,SAAS,MAAM,cAAc;AAKtB,SAAS,YAAY,KAAwB,QAAgB,WAAyB;AAC3F,MAAI,QAAQ;AAAA,IACV,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,CAAqC;AACvC;AAKO,SAAS,cACd,KACA,QACA,WACA,OACA,aACA,OACM;AACN,QAAM,QAA+B;AAAA,IACnC,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,MACA,SAAS,cACL,EAAE,MAAM,SAAS,OAAO,CAAC,EAAE,MAAM,QAAQ,MAAM,YAAY,CAAC,EAAE,IAC9D;AAAA,IACN;AAAA,IACA,OAAO,SAAS;AAAA,EAClB;AACA,MAAI,QAAQ,KAAK;AACnB;AAKO,SAAS,qBACd,KACA,QACA,WACA,MACM;AACN,QAAM,aAAa,OAAO;AAC1B,QAAM,QAAiC;AAAA,IACrC,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,UAAU;AAAA,MACR;AAAA,MACA,OAAO,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,IAChC;AAAA,IACA,WAAW;AAAA,EACb;AACA,MAAI,QAAQ,KAAK;AACnB;","names":[]}
@@ -0,0 +1,178 @@
1
+ import {
2
+ publishFinalArtifact,
3
+ publishStatus,
4
+ publishTask
5
+ } from "./chunk-LXL47XMZ.mjs";
6
+ import {
7
+ logger
8
+ } from "./chunk-VZEH3EPJ.mjs";
9
+
10
+ // src/executors/claude/client.ts
11
+ import { spawn } from "child_process";
12
+ var log = logger.child("claude:client");
13
+ var ClaudeClient = class {
14
+ constructor(config) {
15
+ this.config = config;
16
+ this.currentChild = null;
17
+ }
18
+ abort() {
19
+ if (this.currentChild) {
20
+ this.currentChild.kill("SIGTERM");
21
+ setTimeout(() => {
22
+ if (this.currentChild?.exitCode === null) {
23
+ this.currentChild.kill("SIGKILL");
24
+ }
25
+ }, 5e3);
26
+ this.currentChild = null;
27
+ }
28
+ }
29
+ /**
30
+ * Execute a prompt via the Claude Code CLI and return the response text.
31
+ */
32
+ async execute(prompt) {
33
+ const cliPath = this.config.cliPath || "claude";
34
+ const timeout = this.config.timeout ?? 3e5;
35
+ const MAX_PROMPT = 1e5;
36
+ if (prompt.length > MAX_PROMPT) {
37
+ throw new Error(`Prompt too large (${prompt.length} chars, max ${MAX_PROMPT}). Split into smaller messages.`);
38
+ }
39
+ const env = {
40
+ PATH: process.env.PATH ?? "",
41
+ HOME: process.env.HOME ?? ""
42
+ };
43
+ for (const key of ["HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "no_proxy"]) {
44
+ if (process.env[key]) env[key] = process.env[key];
45
+ }
46
+ if (this.config.apiKey) {
47
+ env["ANTHROPIC_API_KEY"] = this.config.apiKey;
48
+ }
49
+ const args = ["-p"];
50
+ if (this.config.model) {
51
+ args.push("--model", this.config.model);
52
+ }
53
+ args.push(prompt);
54
+ log.info("Spawning claude", { cliPath, workdir: this.config.workdir, model: this.config.model });
55
+ return new Promise((resolve, reject) => {
56
+ const child = spawn(cliPath, args, {
57
+ cwd: this.config.workdir || process.cwd(),
58
+ env,
59
+ stdio: ["ignore", "pipe", "pipe"]
60
+ });
61
+ this.currentChild = child;
62
+ let stdout = "";
63
+ let stderr = "";
64
+ const MAX_OUTPUT = 1e7;
65
+ const timer = setTimeout(() => {
66
+ child.kill("SIGTERM");
67
+ const forceTimer = setTimeout(() => {
68
+ if (child.exitCode === null) child.kill("SIGKILL");
69
+ }, 5e3);
70
+ child.on("close", () => clearTimeout(forceTimer));
71
+ reject(new Error(`Claude Code execution timed out after ${timeout}ms`));
72
+ }, timeout);
73
+ child.stdout?.on("data", (chunk) => {
74
+ stdout += chunk.toString();
75
+ if (stdout.length > MAX_OUTPUT) {
76
+ child.kill("SIGTERM");
77
+ setTimeout(() => {
78
+ if (child.exitCode === null) child.kill("SIGKILL");
79
+ }, 5e3);
80
+ }
81
+ });
82
+ child.stderr?.on("data", (chunk) => {
83
+ stderr += chunk.toString();
84
+ log.debug("Claude stderr", { text: chunk.toString().trim() });
85
+ });
86
+ child.on("close", (code) => {
87
+ clearTimeout(timer);
88
+ this.currentChild = null;
89
+ if (code === 0) {
90
+ resolve(stdout.trim());
91
+ } else {
92
+ const errMsg = stderr.trim() || stdout.trim() || `Claude Code exited with code ${code}`;
93
+ log.warn("Claude non-zero exit", { code, stderr: errMsg });
94
+ reject(new Error(errMsg));
95
+ }
96
+ });
97
+ child.on("error", (err) => {
98
+ clearTimeout(timer);
99
+ log.error("Claude spawn failed", { error: err.message });
100
+ reject(new Error(`Failed to start claude: ${err.message}. Install: npm i -g @anthropic-ai/claude-code`));
101
+ });
102
+ });
103
+ }
104
+ };
105
+
106
+ // src/executors/claude/executor.ts
107
+ var log2 = logger.child("claude:executor");
108
+ var ClaudeExecutor = class {
109
+ constructor(config) {
110
+ this.client = null;
111
+ this.initialized = false;
112
+ this.config = config;
113
+ }
114
+ async initialize() {
115
+ if (this.initialized) return;
116
+ const cc = this.config.claude;
117
+ this.client = new ClaudeClient({
118
+ cliPath: cc.cliPath,
119
+ workdir: cc.workdir,
120
+ model: cc.model || void 0,
121
+ apiKey: cc.apiKey || void 0,
122
+ timeout: this.config.timeouts.prompt ?? 6e5
123
+ });
124
+ this.initialized = true;
125
+ log2.info("Executor initialized", { cliPath: cc.cliPath, workdir: cc.workdir });
126
+ }
127
+ async shutdown() {
128
+ this.client = null;
129
+ this.initialized = false;
130
+ log2.info("Executor shut down");
131
+ }
132
+ async execute(ctx, bus) {
133
+ const { taskId, contextId, userMessage, task } = ctx;
134
+ await this.initialize();
135
+ try {
136
+ if (!task) {
137
+ publishTask(bus, taskId, contextId);
138
+ publishStatus(bus, taskId, contextId, "submitted");
139
+ }
140
+ publishStatus(bus, taskId, contextId, "working", "Processing request...");
141
+ const promptText = this.extractText(userMessage);
142
+ log2.info("Sending prompt to Claude Code", { taskId, len: promptText.length });
143
+ const response = await this.client.execute(promptText);
144
+ const finalText = response || "No response from Claude Code.";
145
+ publishFinalArtifact(bus, taskId, contextId, finalText);
146
+ publishStatus(bus, taskId, contextId, "completed", void 0, true);
147
+ bus.finished();
148
+ log2.info("Task completed", { taskId, len: finalText.length });
149
+ } catch (error) {
150
+ const msg = error.message ?? String(error);
151
+ log2.error("Execution failed", { taskId, error: msg });
152
+ publishStatus(bus, taskId, contextId, "failed", `Error: ${msg}`, true);
153
+ bus.finished();
154
+ }
155
+ }
156
+ async cancelTask(taskId, bus) {
157
+ log2.info("Cancel requested for Claude Code task", { taskId });
158
+ this.client?.abort();
159
+ publishStatus(bus, taskId, "", "canceled", "Claude Code task cancelled", true);
160
+ bus.finished();
161
+ }
162
+ extractText(message) {
163
+ return message.parts.filter((p) => {
164
+ const part = p;
165
+ const text = part.text;
166
+ return text !== void 0 && text !== null;
167
+ }).map((p) => p.text).join("\n");
168
+ }
169
+ };
170
+ function createClaudeExecutor(config) {
171
+ return new ClaudeExecutor(config);
172
+ }
173
+
174
+ export {
175
+ ClaudeExecutor,
176
+ createClaudeExecutor
177
+ };
178
+ //# sourceMappingURL=chunk-NQIDRU47.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/executors/claude/client.ts","../src/executors/claude/executor.ts"],"sourcesContent":["/**\n * Claude Code CLI client wrapper.\n *\n * Spawns the Anthropic Claude Code CLI as a child process in non-interactive\n * print mode (`-p`). Sends prompts, captures stdout as the response.\n * Supports configurable CLI path, working directory, model, and timeout.\n */\n\nimport { spawn } from 'node:child_process';\nimport { logger } from '../../logger.js';\n\nconst log = logger.child('claude:client');\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface ClaudeClientConfig {\n /** Path to the claude binary (default: \"claude\") */\n cliPath: string;\n /** Working directory for the process */\n workdir: string;\n /** Model identifier (e.g. \"claude-sonnet-4-20250514\") — passed via --model */\n model?: string;\n /** Anthropic API key — passed as ANTHROPIC_API_KEY env */\n apiKey?: string;\n /** Timeout in ms (default: 300_000 = 5 min) */\n timeout?: number;\n}\n\n// ─── Client ─────────────────────────────────────────────────────────────────\n\nexport class ClaudeClient {\n private currentChild: ReturnType<typeof spawn> | null = null;\n\n constructor(private config: ClaudeClientConfig) {}\n\n abort(): void {\n if (this.currentChild) {\n this.currentChild.kill('SIGTERM');\n setTimeout(() => {\n if (this.currentChild?.exitCode === null) {\n this.currentChild.kill('SIGKILL');\n }\n }, 5000);\n this.currentChild = null;\n }\n }\n\n /**\n * Execute a prompt via the Claude Code CLI and return the response text.\n */\n async execute(prompt: string): Promise<string> {\n const cliPath = this.config.cliPath || 'claude';\n const timeout = this.config.timeout ?? 300_000;\n const MAX_PROMPT = 100_000;\n\n if (prompt.length > MAX_PROMPT) {\n throw new Error(`Prompt too large (${prompt.length} chars, max ${MAX_PROMPT}). Split into smaller messages.`);\n }\n\n // Only pass relevant env vars to child process\n const env: Record<string, string> = {\n PATH: process.env.PATH ?? '',\n HOME: process.env.HOME ?? '',\n };\n // Forward common proxy/no-proxy settings\n for (const key of ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'http_proxy', 'https_proxy', 'no_proxy']) {\n if (process.env[key]) env[key] = process.env[key];\n }\n\n if (this.config.apiKey) {\n env['ANTHROPIC_API_KEY'] = this.config.apiKey;\n }\n\n const args: string[] = ['-p'];\n if (this.config.model) {\n args.push('--model', this.config.model);\n }\n args.push(prompt);\n\n log.info('Spawning claude', { cliPath, workdir: this.config.workdir, model: this.config.model });\n\n return new Promise<string>((resolve, reject) => {\n const child = spawn(cliPath, args, {\n cwd: this.config.workdir || process.cwd(),\n env,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n this.currentChild = child;\n\n let stdout = '';\n let stderr = '';\n const MAX_OUTPUT = 10_000_000;\n\n const timer = setTimeout(() => {\n child.kill('SIGTERM');\n // Force kill after 5s grace period\n const forceTimer = setTimeout(() => {\n if (child.exitCode === null) child.kill('SIGKILL');\n }, 5000);\n child.on('close', () => clearTimeout(forceTimer));\n reject(new Error(`Claude Code execution timed out after ${timeout}ms`));\n }, timeout);\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString();\n if (stdout.length > MAX_OUTPUT) {\n child.kill('SIGTERM');\n setTimeout(() => { if (child.exitCode === null) child.kill('SIGKILL'); }, 5000);\n }\n });\n\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString();\n log.debug('Claude stderr', { text: chunk.toString().trim() });\n });\n\n child.on('close', (code) => {\n clearTimeout(timer);\n this.currentChild = null;\n\n if (code === 0) {\n resolve(stdout.trim());\n } else {\n const errMsg = stderr.trim() || stdout.trim() || `Claude Code exited with code ${code}`;\n log.warn('Claude non-zero exit', { code, stderr: errMsg });\n reject(new Error(errMsg));\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n log.error('Claude spawn failed', { error: err.message });\n reject(new Error(`Failed to start claude: ${err.message}. Install: npm i -g @anthropic-ai/claude-code`));\n });\n });\n }\n}\n","/**\n * Claude Code A2A Executor\n *\n * Bridges the local Claude Code CLI to the A2A protocol. Spawns Claude Code\n * in non-interactive print mode (`-p`) for each request and captures stdout\n * as the response.\n */\n\nimport type { A2AExecutor } from '../index.js';\nimport type { RequestContext, ExecutionEventBus } from '@a2a-js/sdk/server';\nimport type { Message as A2AMessage } from '@a2a-js/sdk';\n\nimport type { AgentConfig } from '../../config/types.js';\nimport { logger } from '../../logger.js';\nimport { ClaudeClient } from './client.js';\nimport {\n publishTask,\n publishStatus,\n publishFinalArtifact,\n} from '../events.js';\n\nconst log = logger.child('claude:executor');\n\n// ─── Executor ───────────────────────────────────────────────────────────────\n\nexport class ClaudeExecutor implements A2AExecutor {\n private config: Required<AgentConfig>;\n private client: ClaudeClient | null = null;\n private initialized = false;\n\n constructor(config: Required<AgentConfig>) {\n this.config = config;\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n const cc = this.config.claude;\n this.client = new ClaudeClient({\n cliPath: cc.cliPath!,\n workdir: cc.workdir!,\n model: cc.model || undefined,\n apiKey: cc.apiKey || undefined,\n timeout: this.config.timeouts.prompt ?? 600_000,\n });\n\n this.initialized = true;\n log.info('Executor initialized', { cliPath: cc.cliPath, workdir: cc.workdir });\n }\n\n async shutdown(): Promise<void> {\n this.client = null;\n this.initialized = false;\n log.info('Executor shut down');\n }\n\n async execute(ctx: RequestContext, bus: ExecutionEventBus): Promise<void> {\n const { taskId, contextId, userMessage, task } = ctx;\n await this.initialize();\n\n try {\n if (!task) {\n publishTask(bus, taskId, contextId);\n publishStatus(bus, taskId, contextId, 'submitted');\n }\n\n publishStatus(bus, taskId, contextId, 'working', 'Processing request...');\n\n const promptText = this.extractText(userMessage);\n log.info('Sending prompt to Claude Code', { taskId, len: promptText.length });\n\n const response = await this.client!.execute(promptText);\n\n const finalText = response || 'No response from Claude Code.';\n publishFinalArtifact(bus, taskId, contextId, finalText);\n publishStatus(bus, taskId, contextId, 'completed', undefined, true);\n bus.finished();\n log.info('Task completed', { taskId, len: finalText.length });\n\n } catch (error) {\n const msg = (error as Error).message ?? String(error);\n log.error('Execution failed', { taskId, error: msg });\n publishStatus(bus, taskId, contextId, 'failed', `Error: ${msg}`, true);\n bus.finished();\n }\n }\n\n async cancelTask(taskId: string, bus: ExecutionEventBus): Promise<void> {\n log.info('Cancel requested for Claude Code task', { taskId });\n this.client?.abort();\n publishStatus(bus, taskId, '', 'canceled', 'Claude Code task cancelled', true);\n bus.finished();\n }\n\n private extractText(message: A2AMessage): string {\n return message.parts\n .filter((p) => {\n const part = p as unknown as Record<string, unknown>;\n const text = part.text as string | undefined;\n return text !== undefined && text !== null;\n })\n .map((p) => (p as unknown as { text: string }).text)\n .join('\\n');\n }\n}\n\n// ─── Factory ────────────────────────────────────────────────────────────────\n\nexport function createClaudeExecutor(config: Required<AgentConfig>): A2AExecutor {\n return new ClaudeExecutor(config);\n}\n"],"mappings":"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","names":["log"]}