genaicode 2.3.0 → 2.4.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 (79) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +59 -11
  3. package/dist/agents/cli-agent.d.ts +28 -0
  4. package/dist/agents/cli-agent.js +57 -0
  5. package/dist/agents/cli-agent.js.map +1 -0
  6. package/dist/agents/discovery.d.ts +10 -0
  7. package/dist/agents/discovery.js +31 -0
  8. package/dist/agents/discovery.js.map +1 -0
  9. package/dist/agents/drivers/claude.d.ts +25 -0
  10. package/dist/agents/drivers/claude.js +184 -0
  11. package/dist/agents/drivers/claude.js.map +1 -0
  12. package/dist/agents/drivers/codex-live.d.ts +17 -0
  13. package/dist/agents/drivers/codex-live.js +182 -0
  14. package/dist/agents/drivers/codex-live.js.map +1 -0
  15. package/dist/agents/drivers/codex.d.ts +27 -0
  16. package/dist/agents/drivers/codex.js +176 -0
  17. package/dist/agents/drivers/codex.js.map +1 -0
  18. package/dist/agents/drivers/copilot.d.ts +27 -0
  19. package/dist/agents/drivers/copilot.js +199 -0
  20. package/dist/agents/drivers/copilot.js.map +1 -0
  21. package/dist/agents/drivers/cursor.d.ts +23 -0
  22. package/dist/agents/drivers/cursor.js +174 -0
  23. package/dist/agents/drivers/cursor.js.map +1 -0
  24. package/dist/agents/drivers/gemini.d.ts +18 -0
  25. package/dist/agents/drivers/gemini.js +118 -0
  26. package/dist/agents/drivers/gemini.js.map +1 -0
  27. package/dist/agents/drivers/json.d.ts +6 -0
  28. package/dist/agents/drivers/json.js +20 -0
  29. package/dist/agents/drivers/json.js.map +1 -0
  30. package/dist/agents/drivers/muse-live.d.ts +17 -0
  31. package/dist/agents/drivers/muse-live.js +112 -0
  32. package/dist/agents/drivers/muse-live.js.map +1 -0
  33. package/dist/agents/drivers/muse.d.ts +12 -0
  34. package/dist/agents/drivers/muse.js +87 -0
  35. package/dist/agents/drivers/muse.js.map +1 -0
  36. package/dist/agents/drivers/opencode.d.ts +17 -0
  37. package/dist/agents/drivers/opencode.js +103 -0
  38. package/dist/agents/drivers/opencode.js.map +1 -0
  39. package/dist/agents/env.d.ts +16 -0
  40. package/dist/agents/env.js +46 -0
  41. package/dist/agents/env.js.map +1 -0
  42. package/dist/agents/event-queue.d.ts +44 -0
  43. package/dist/agents/event-queue.js +123 -0
  44. package/dist/agents/event-queue.js.map +1 -0
  45. package/dist/agents/hosted.d.ts +33 -0
  46. package/dist/agents/hosted.js +129 -0
  47. package/dist/agents/hosted.js.map +1 -0
  48. package/dist/agents/live-agent.d.ts +37 -0
  49. package/dist/agents/live-agent.js +142 -0
  50. package/dist/agents/live-agent.js.map +1 -0
  51. package/dist/agents/prepare.d.ts +33 -0
  52. package/dist/agents/prepare.js +52 -0
  53. package/dist/agents/prepare.js.map +1 -0
  54. package/dist/agents/process.d.ts +39 -0
  55. package/dist/agents/process.js +140 -0
  56. package/dist/agents/process.js.map +1 -0
  57. package/dist/agents/rpc.d.ts +29 -0
  58. package/dist/agents/rpc.js +101 -0
  59. package/dist/agents/rpc.js.map +1 -0
  60. package/dist/agents/runtime.d.ts +26 -0
  61. package/dist/agents/runtime.js +97 -0
  62. package/dist/agents/runtime.js.map +1 -0
  63. package/dist/agents/types.d.ts +158 -0
  64. package/dist/agents/types.js +2 -0
  65. package/dist/agents/types.js.map +1 -0
  66. package/dist/agents/verify.d.ts +36 -0
  67. package/dist/agents/verify.js +43 -0
  68. package/dist/agents/verify.js.map +1 -0
  69. package/dist/agents.d.ts +36 -0
  70. package/dist/agents.js +19 -0
  71. package/dist/agents.js.map +1 -0
  72. package/dist/providers/google-converter.js +30 -14
  73. package/dist/providers/google-converter.js.map +1 -1
  74. package/dist/providers/google.d.ts +8 -0
  75. package/dist/providers/google.js.map +1 -1
  76. package/docs/agents.md +269 -0
  77. package/docs/pivot.md +4 -0
  78. package/docs/semver.md +5 -0
  79. package/package.json +5 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ### Added
6
+
7
+ - `genaicode/agents` subpath (experimental): run installed coding-agent CLIs behind one
8
+ `CodingAgent` interface. Drivers `claude()`, `codex()`, `muse()`; agent-neutral
9
+ `AgentEvent` stream and `AgentResult`; abort, timeout and process-group kill;
10
+ `detectAgents` / `findExecutable`; `cliAgent()` for custom drivers. See
11
+ [docs/agents.md](docs/agents.md).
12
+ - Live agent sessions over JSON-RPC: `codexLive()` (`codex app-server`) and `museLive()`
13
+ (`muse serve`) with `AgentRun.steer()` and `AgentTask.onApproval`; `liveAgent()` and
14
+ `RpcPeer` for custom live drivers; `approval-resolved` event.
15
+ - `AgentTask.mcpServers` (HTTP and stdio) for `claude`, `codex` and `codexLive`; header
16
+ secrets stay out of argv. Drivers can set up and clean up per task via `prepare`.
17
+ - `scrubEnv`, `withoutProviderCredentials` and `PROVIDER_CREDENTIAL_VARS` for child
18
+ environments; `runWithVerify` verify-and-repair loop.
19
+ - Drivers `gemini()`, `cursor()` and `opencode()`; `hostedAgent()` adapts a
20
+ `HostedAgentProvider` (start / poll / send / cancel) to `CodingAgent`.
21
+ - Driver `copilot()` for GitHub Copilot CLI (`--output-format json`), with MCP servers via
22
+ `--additional-mcp-config` and `allowTools` / `denyTools` permission patterns.
23
+
24
+ ### Notes
25
+
26
+ - The core `genaicode` entry is unchanged and still spawns nothing.
27
+
3
28
  ## 2.2.0 — 2026-07-26
4
29
 
5
30
  ### Added
package/README.md CHANGED
@@ -12,7 +12,10 @@ GenAIcode is a small TypeScript toolkit for using LLMs in backend code.
12
12
 
13
13
  It sits between raw provider SDKs and full agent frameworks: one prompt representation,
14
14
  thin provider adapters, a convenient request API, and lightweight conversation chains.
15
- It does not inspect repositories, execute shell commands, edit files, or run an agent UI.
15
+ The core does not inspect repositories, execute shell commands, edit files, or run an agent UI.
16
+ The opt-in [`genaicode/agents`](#coding-agents) subpath drives the coding-agent CLIs you
17
+ already have (Claude Code, Codex, GitHub Copilot CLI, Cursor, Gemini CLI, opencode, Muse)
18
+ behind one task and event API, so you can orchestrate them from backend code.
16
19
 
17
20
  **Like jQuery**, the common case starts with one small function and becomes more specific
18
21
  through chaining—configure a request, follow up across multiple prompts, and keep history
@@ -81,6 +84,53 @@ const short = await releaseNote.maxOutputTokens(200).text();
81
84
  const long = await releaseNote.maxOutputTokens(800).text();
82
85
  ```
83
86
 
87
+ ## Coding agents
88
+
89
+ `genaicode/agents` turns the coding-agent CLIs installed on a machine into one API. Give
90
+ any of them a task (a prompt and a working directory) and get back the same event stream
91
+ and result, whichever agent does the work. It is how you script, compare, or chain coding
92
+ agents from a job, a bot, or a CI step without writing a parser per vendor.
93
+
94
+ ```ts
95
+ import { claude, codex, copilot, cursor, detectAgents } from 'genaicode/agents';
96
+
97
+ const [found] = detectAgents([claude(), codex(), copilot(), cursor()]).filter(({ path }) => path);
98
+ if (!found) throw new Error('No coding agent installed.');
99
+
100
+ const run = found.agent.run({ prompt: 'Add a unit test for parseDate', cwd: '/path/to/repo', timeoutMs: 20 * 60_000 });
101
+ for await (const event of run) {
102
+ if (event.type === 'tool-start') console.log('⚙', event.name);
103
+ if (event.type === 'file-change') console.log('edited', event.paths.join(', '));
104
+ }
105
+ const result = await run.result; // { status, ok, text, sessionId, usage, error, ... }
106
+ ```
107
+
108
+ | Agent | Driver | Extras |
109
+ | ---------------- | ----------------------------- | ------------------------------------------ |
110
+ | Claude Code | `claude()` | MCP servers, max turns, effort, cost |
111
+ | Codex | `codex()`, `codexLive()` | MCP servers; live: `steer()`, approvals |
112
+ | GitHub Copilot | `copilot()` | MCP servers, allow/deny tool patterns |
113
+ | Cursor | `cursor()` | streamed text deltas |
114
+ | Gemini CLI | `gemini()` | approval mode |
115
+ | opencode | `opencode()` | `provider/model` ids, variants |
116
+ | Muse | `muse()`, `museLive()` | max turns; live: `steer()` |
117
+ | Your own CLI/API | `cliAgent()`, `hostedAgent()` | plug in any JSON-lines CLI or hosted agent |
118
+
119
+ On top of the drivers:
120
+
121
+ - **Steer a running task** with `run.steer(text)`, and answer permission prompts with
122
+ `onApproval` (live drivers).
123
+ - **Attach MCP servers per task** with `mcpServers`. Header secrets stay out of argv.
124
+ - **Verify and repair**: `runWithVerify` runs your check (tests, lint) after the agent and
125
+ sends failures back for another attempt.
126
+ - **Keep credentials apart**: `withoutProviderCredentials()` strips your app's LLM API keys
127
+ from the agent's environment, so it bills its own login.
128
+
129
+ Importing `genaicode` never spawns anything; only `genaicode/agents` does. The agent uses
130
+ its own credentials, billing, and permission settings. GenAIcode does not sandbox it,
131
+ choose a model, or retry it. See [docs/agents.md](docs/agents.md) for events, options per
132
+ driver, and writing your own driver.
133
+
84
134
  ## Chaining prompts
85
135
 
86
136
  A chain remembers successful user and assistant turns. Each new prompt sees the complete
@@ -180,8 +230,10 @@ const verdict = await ai(promptText)
180
230
  - `thinking`: `false` to disable, or `{ budgetTokens?, level? }` (`minimal` |
181
231
  `low` | `medium` | `high`). Prefer one of budget or level — some providers reject both.
182
232
  On Google/Gemini, `false` and `budgetTokens: 0` map to `thinkingLevel: MINIMAL`
233
+ (or `LOW` for models like Gemini 3.7 and Gemini 3 Pro where `MINIMAL` is unsupported)
183
234
  because Gemini 3 rejects `thinkingBudget: 0`. JSON `responseFormat` without an
184
- explicit `thinking` setting also defaults Google to `MINIMAL`.
235
+ explicit `thinking` setting or provider `generationConfig.thinkingConfig` default also
236
+ defaults Google thinking to `MINIMAL` (or `LOW` on Gemini 3.7 / Pro).
185
237
 
186
238
  Providers map what they support and ignore the rest. `ProviderCapabilities.jsonResponse`
187
239
  and `ProviderCapabilities.thinking` advertise support. Vendor-specific escapes such as
@@ -268,13 +320,7 @@ Hook-style plugins remain the extension point. Built-in helpers cover common bac
268
320
  needs without restoring a global registry:
269
321
 
270
322
  ```ts
271
- import {
272
- cachePlugin,
273
- fallbackPlugin,
274
- genaicode,
275
- rateLimitPlugin,
276
- timingPlugin,
277
- } from 'genaicode';
323
+ import { cachePlugin, fallbackPlugin, genaicode, rateLimitPlugin, timingPlugin } from 'genaicode';
278
324
  import { anthropic, openai } from 'genaicode/providers';
279
325
 
280
326
  const ai = genaicode(openai({ model: 'your-model-name' }), {
@@ -442,14 +488,16 @@ Framework-shaped examples live under `examples/` (`http-handler`, `queue-worker`
442
488
 
443
489
  ## Design boundaries
444
490
 
445
- - Backend library, not a coding agent.
491
+ - Backend library, not a coding agent. `genaicode/agents` drives external agent CLIs; it
492
+ adds no agent loop, prompts, or repository tools of its own.
446
493
  - Provider-neutral core with no global configuration.
447
494
  - Explicit models and credentials; environment variables are only provider defaults.
448
495
  - Immutable request builders.
449
496
  - Conversation history is explicit; loops remain ordinary application code.
450
497
  - No hidden tool execution or hidden retries.
451
498
  - Third-party providers and middleware use stable TypeScript contracts.
452
- - Provider SDKs stay behind the `genaicode/providers` subpath.
499
+ - Provider SDKs stay behind the `genaicode/providers` subpath; process spawning stays
500
+ behind `genaicode/agents`.
453
501
 
454
502
  ## Migration from 1.x
455
503
 
@@ -0,0 +1,28 @@
1
+ import { type PreparedRun } from './prepare.js';
2
+ import { type AgentOutcome } from './runtime.js';
3
+ import type { AgentCapabilities, AgentEvent, AgentTask, CodingAgent } from './types.js';
4
+ export type { AgentOutcome } from './runtime.js';
5
+ /** Per-run decoder for one vendor's JSON event stream. */
6
+ export interface AgentOutputParser {
7
+ /** Map one parsed stdout JSON value to zero or more events. */
8
+ event(value: unknown): AgentEvent[];
9
+ /** The terminal verdict the agent itself reported, if it reported one. */
10
+ outcome?(): AgentOutcome | undefined;
11
+ }
12
+ export interface CliAgentDefinition {
13
+ name: string;
14
+ command: string;
15
+ capabilities?: AgentCapabilities;
16
+ /** Full argument list for a task, prompt included. */
17
+ args(task: AgentTask): string[];
18
+ /** Replaces `args` when a task needs setup: extra env, temp files to clean up. */
19
+ prepare?(task: AgentTask): PreparedRun;
20
+ createParser(): AgentOutputParser;
21
+ /** Adjust the child environment (the caller's `task.env` or `process.env`). */
22
+ env?(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
23
+ }
24
+ /**
25
+ * Build a `CodingAgent` from a headless CLI: spawn, decode its JSON lines, and
26
+ * fold them into an `AgentResult`. Drivers such as `claude()` are thin definitions.
27
+ */
28
+ export declare function cliAgent(definition: CliAgentDefinition): CodingAgent;
@@ -0,0 +1,57 @@
1
+ import { planSpawn } from './prepare.js';
2
+ import { startProcess } from './process.js';
3
+ import { invalidCwd, RunRecorder } from './runtime.js';
4
+ /**
5
+ * Build a `CodingAgent` from a headless CLI: spawn, decode its JSON lines, and
6
+ * fold them into an `AgentResult`. Drivers such as `claude()` are thin definitions.
7
+ */
8
+ export function cliAgent(definition) {
9
+ return {
10
+ name: definition.name,
11
+ command: definition.command,
12
+ capabilities: definition.capabilities ?? {},
13
+ run: (task) => runCliAgent(definition, task),
14
+ };
15
+ }
16
+ function runCliAgent(definition, task) {
17
+ const recorder = new RunRecorder(definition.name, definition.command);
18
+ const iterate = () => recorder.events.iterate();
19
+ const plan = planSpawn(definition, task, invalidCwd(task.cwd));
20
+ if (!plan.ok) {
21
+ const result = recorder.finish({ exitCode: null, signal: null, reason: 'spawn-error', error: new Error(plan.error) }, undefined);
22
+ return { result: Promise.resolve(result), abort() { }, [Symbol.asyncIterator]: iterate };
23
+ }
24
+ const parser = definition.createParser();
25
+ const handle = startProcess({
26
+ command: definition.command,
27
+ args: plan.args,
28
+ cwd: task.cwd,
29
+ env: plan.env,
30
+ timeoutMs: task.timeoutMs,
31
+ signal: task.signal,
32
+ onLine(line) {
33
+ let value;
34
+ try {
35
+ value = JSON.parse(line);
36
+ }
37
+ catch {
38
+ recorder.emit({ type: 'raw', line });
39
+ return;
40
+ }
41
+ for (const event of parser.event(value))
42
+ recorder.emit(event);
43
+ },
44
+ onStderr: (text) => recorder.emit({ type: 'stderr', text }),
45
+ });
46
+ // A consumer that falls behind pauses the agent instead of buffering its output without bound.
47
+ recorder.events.onPressure = (paused) => (paused ? handle.pause() : handle.resume());
48
+ return {
49
+ result: handle.exit.then((exit) => {
50
+ plan.cleanup();
51
+ return recorder.finish(exit, parser.outcome?.());
52
+ }),
53
+ abort: handle.kill,
54
+ [Symbol.asyncIterator]: iterate,
55
+ };
56
+ }
57
+ //# sourceMappingURL=cli-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-agent.js","sourceRoot":"","sources":["../../src/agents/cli-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAqB,MAAM,cAAc,CAAC;AA0B1E;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,UAA8B;IACrD,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,YAAY,EAAE,UAAU,CAAC,YAAY,IAAI,EAAE;QAC3C,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,UAA8B,EAAE,IAAe;IAClE,MAAM,QAAQ,GAAG,IAAI,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IAEhD,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAC5B,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EACrF,SAAS,CACV,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,KAAI,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1F,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,CAAC,IAAI;YACT,IAAI,KAAc,CAAC;YACnB,IAAI,CAAC;gBACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChE,CAAC;QACD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KAC5D,CAAC,CAAC;IAEH,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAErF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YAChC,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC;QACF,KAAK,EAAE,MAAM,CAAC,IAAI;QAClB,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO;KAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { CodingAgent } from './types.js';
2
+ /** Resolve an executable the way a shell would: absolute path, or the first match on PATH. */
3
+ export declare function findExecutable(command: string, env?: NodeJS.ProcessEnv): string | null;
4
+ export interface AgentAvailability {
5
+ agent: CodingAgent;
6
+ /** Resolved executable, or null when the agent's command is not installed. */
7
+ path: string | null;
8
+ }
9
+ /** Report which agents have their CLI installed. Presence only; login and flags are the agent's concern. */
10
+ export declare function detectAgents(agents: readonly CodingAgent[], env?: NodeJS.ProcessEnv): AgentAvailability[];
@@ -0,0 +1,31 @@
1
+ import { accessSync, constants, statSync } from 'node:fs';
2
+ import { delimiter, isAbsolute, join } from 'node:path';
3
+ /** Resolve an executable the way a shell would: absolute path, or the first match on PATH. */
4
+ export function findExecutable(command, env = process.env) {
5
+ const windows = process.platform === 'win32';
6
+ const extensions = windows ? ['', ...(env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM').split(';')] : [''];
7
+ const candidates = isAbsolute(command)
8
+ ? extensions.map((extension) => command + extension)
9
+ : (env.PATH ?? env.Path ?? '')
10
+ .split(delimiter)
11
+ .filter(Boolean)
12
+ .flatMap((dir) => extensions.map((extension) => join(dir, command + extension)));
13
+ for (const candidate of candidates) {
14
+ try {
15
+ if (!statSync(candidate).isFile())
16
+ continue;
17
+ if (!windows)
18
+ accessSync(candidate, constants.X_OK);
19
+ return candidate;
20
+ }
21
+ catch {
22
+ continue;
23
+ }
24
+ }
25
+ return null;
26
+ }
27
+ /** Report which agents have their CLI installed. Presence only; login and flags are the agent's concern. */
28
+ export function detectAgents(agents, env = process.env) {
29
+ return agents.map((agent) => ({ agent, path: findExecutable(agent.command, env) }));
30
+ }
31
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/agents/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGxD,8FAA8F;AAC9F,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,MAAyB,OAAO,CAAC,GAAG;IAClF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,qBAAqB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/F,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC;QACpC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,GAAG,SAAS,CAAC;QACpD,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;aACzB,KAAK,CAAC,SAAS,CAAC;aAChB,MAAM,CAAC,OAAO,CAAC;aACf,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACvF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE;gBAAE,SAAS;YAC5C,IAAI,CAAC,OAAO;gBAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAQD,4GAA4G;AAC5G,MAAM,UAAU,YAAY,CAC1B,MAA8B,EAC9B,MAAyB,OAAO,CAAC,GAAG;IAEpC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AACtF,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type AgentOutputParser } from '../cli-agent.js';
2
+ import type { AgentTask, CodingAgent, McpServer } from '../types.js';
3
+ export type ClaudePermissionMode = 'acceptEdits' | 'auto' | 'bypassPermissions' | 'dontAsk' | 'manual' | 'plan' | (string & Record<never, never>);
4
+ export interface ClaudeAgentOptions {
5
+ /** Executable name or path. Default `claude`. */
6
+ command?: string;
7
+ /** Default `acceptEdits`: file edits run unattended, other tools follow Claude Code settings. */
8
+ permissionMode?: ClaudePermissionMode;
9
+ /** Passed as `--allowedTools`. */
10
+ allowedTools?: readonly string[];
11
+ /** Passed as `--disallowedTools`. */
12
+ disallowedTools?: readonly string[];
13
+ /** With `task.mcpServers`: ignore MCP servers from the user's own Claude Code config. Default false. */
14
+ strictMcpConfig?: boolean;
15
+ /** With `task.mcpServers`: pre-allow every tool of those servers. Default true (headless runs cannot ask). */
16
+ allowMcpTools?: boolean;
17
+ }
18
+ /** Claude Code in print mode (`claude -p --output-format stream-json`). */
19
+ export declare function claude(options?: ClaudeAgentOptions): CodingAgent;
20
+ /** The `--mcp-config` document for a set of servers. */
21
+ export declare function claudeMcpConfig(servers: readonly McpServer[]): {
22
+ mcpServers: Record<string, unknown>;
23
+ };
24
+ export declare function claudeArgs(task: AgentTask, options?: ClaudeAgentOptions, mcpConfigPath?: string): string[];
25
+ export declare function createClaudeParser(): AgentOutputParser;
@@ -0,0 +1,184 @@
1
+ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { cliAgent } from '../cli-agent.js';
5
+ import { isHttpServer } from '../prepare.js';
6
+ import { isObject, numberField, positionalPrompt, stringField } from './json.js';
7
+ const EDIT_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
8
+ /** Claude Code in print mode (`claude -p --output-format stream-json`). */
9
+ export function claude(options = {}) {
10
+ return cliAgent({
11
+ name: 'claude',
12
+ command: options.command ?? 'claude',
13
+ capabilities: { effort: ['low', 'medium', 'high', 'xhigh', 'max'], maxTurns: true, usage: true, mcp: true },
14
+ args: (task) => claudeArgs(task, options),
15
+ prepare: (task) => prepareClaude(task, options),
16
+ createParser: createClaudeParser,
17
+ });
18
+ }
19
+ /** Write the task's MCP servers to a private temp file, so header secrets stay out of argv. */
20
+ function prepareClaude(task, options) {
21
+ if (!task.mcpServers?.length)
22
+ return { args: claudeArgs(task, options) };
23
+ const dir = mkdtempSync(join(tmpdir(), 'genaicode-claude-mcp-'));
24
+ const file = join(dir, 'mcp.json');
25
+ writeFileSync(file, JSON.stringify(claudeMcpConfig(task.mcpServers)), { mode: 0o600 });
26
+ return {
27
+ args: claudeArgs(task, options, file),
28
+ cleanup: () => rmSync(dir, { recursive: true, force: true }),
29
+ };
30
+ }
31
+ /** The `--mcp-config` document for a set of servers. */
32
+ export function claudeMcpConfig(servers) {
33
+ const mcpServers = {};
34
+ for (const server of servers) {
35
+ mcpServers[server.name] = isHttpServer(server)
36
+ ? { type: 'http', url: server.url, ...(server.headers ? { headers: server.headers } : {}) }
37
+ : {
38
+ command: server.command,
39
+ args: [...(server.args ?? [])],
40
+ ...(server.env ? { env: server.env } : {}),
41
+ };
42
+ }
43
+ return { mcpServers };
44
+ }
45
+ export function claudeArgs(task, options = {}, mcpConfigPath) {
46
+ const args = ['-p', '--verbose'];
47
+ // Multi-value flags come first: a single-value flag must follow them before the prompt.
48
+ if (mcpConfigPath)
49
+ args.push('--mcp-config', mcpConfigPath);
50
+ if (mcpConfigPath && options.strictMcpConfig)
51
+ args.push('--strict-mcp-config');
52
+ const allowed = [
53
+ ...(options.allowedTools ?? []),
54
+ ...(mcpConfigPath && (options.allowMcpTools ?? true) ? (task.mcpServers ?? []).map((s) => `mcp__${s.name}`) : []),
55
+ ];
56
+ if (allowed.length)
57
+ args.push('--allowedTools', allowed.join(','));
58
+ if (options.disallowedTools?.length)
59
+ args.push('--disallowedTools', options.disallowedTools.join(','));
60
+ args.push('--output-format', 'stream-json', '--permission-mode', options.permissionMode ?? 'acceptEdits');
61
+ if (task.model)
62
+ args.push('--model', task.model);
63
+ if (task.effort)
64
+ args.push('--effort', task.effort);
65
+ if (task.maxTurns !== undefined)
66
+ args.push('--max-turns', String(task.maxTurns));
67
+ if (task.extraArgs)
68
+ args.push(...task.extraArgs);
69
+ return [...args, ...positionalPrompt(task.prompt)];
70
+ }
71
+ export function createClaudeParser() {
72
+ const toolNames = new Map();
73
+ let outcome;
74
+ let sessionSent = false;
75
+ let lastMessage;
76
+ return {
77
+ outcome: () => outcome,
78
+ event(value) {
79
+ if (!isObject(value))
80
+ return [];
81
+ const events = [];
82
+ const sessionId = stringField(value, 'session_id');
83
+ if (sessionId && !sessionSent) {
84
+ sessionSent = true;
85
+ events.push({ type: 'session', sessionId, ...modelOf(value) });
86
+ }
87
+ switch (value.type) {
88
+ case 'assistant':
89
+ for (const block of contentBlocks(value.message)) {
90
+ if (block.type === 'text' && typeof block.text === 'string' && block.text.trim()) {
91
+ lastMessage = block.text;
92
+ events.push({ type: 'message', text: block.text });
93
+ }
94
+ else if (block.type === 'tool_use' && typeof block.name === 'string') {
95
+ const id = typeof block.id === 'string' ? block.id : undefined;
96
+ if (id)
97
+ toolNames.set(id, block.name);
98
+ events.push({ type: 'tool-start', ...(id ? { id } : {}), name: block.name, input: block.input });
99
+ const path = stringField(block.input, 'file_path') ?? stringField(block.input, 'notebook_path');
100
+ if (EDIT_TOOLS.has(block.name) && path)
101
+ events.push({ type: 'file-change', paths: [path] });
102
+ }
103
+ }
104
+ break;
105
+ case 'user':
106
+ for (const block of contentBlocks(value.message)) {
107
+ if (block.type !== 'tool_result')
108
+ continue;
109
+ const id = typeof block.tool_use_id === 'string' ? block.tool_use_id : undefined;
110
+ const name = id ? toolNames.get(id) : undefined;
111
+ const output = toolOutput(block.content);
112
+ events.push({
113
+ type: 'tool-end',
114
+ ...(id ? { id } : {}),
115
+ ...(name ? { name } : {}),
116
+ isError: block.is_error === true,
117
+ ...(output !== undefined ? { output } : {}),
118
+ });
119
+ }
120
+ break;
121
+ case 'stream_event': {
122
+ const delta = isObject(value.event) ? value.event.delta : undefined;
123
+ const text = stringField(delta, 'text');
124
+ if (stringField(delta, 'type') === 'text_delta' && text)
125
+ events.push({ type: 'text-delta', text });
126
+ break;
127
+ }
128
+ case 'result': {
129
+ const failed = value.is_error === true || (value.subtype !== undefined && value.subtype !== 'success');
130
+ const text = stringField(value, 'result');
131
+ outcome = failed
132
+ ? { ok: false, error: text || `Claude stopped: ${String(value.subtype ?? 'error')}.` }
133
+ : { ok: true };
134
+ const usage = value.usage;
135
+ if (isObject(usage)) {
136
+ const inputTokens = numberField(usage, 'input_tokens');
137
+ const outputTokens = numberField(usage, 'output_tokens');
138
+ const cachedInputTokens = numberField(usage, 'cache_read_input_tokens');
139
+ const costUsd = numberField(value, 'total_cost_usd');
140
+ events.push({
141
+ type: 'usage',
142
+ usage: {
143
+ ...(inputTokens !== undefined ? { inputTokens } : {}),
144
+ ...(outputTokens !== undefined ? { outputTokens } : {}),
145
+ ...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),
146
+ ...(inputTokens !== undefined && outputTokens !== undefined
147
+ ? { totalTokens: inputTokens + outputTokens }
148
+ : {}),
149
+ },
150
+ ...(costUsd !== undefined ? { costUsd } : {}),
151
+ });
152
+ }
153
+ // The result repeats the last assistant message; only surface it when it differs.
154
+ if (!failed && text && text !== lastMessage)
155
+ events.push({ type: 'message', text });
156
+ if (failed)
157
+ events.push({ type: 'error', message: outcome.error });
158
+ break;
159
+ }
160
+ }
161
+ return events;
162
+ },
163
+ };
164
+ }
165
+ function contentBlocks(message) {
166
+ const content = isObject(message) ? message.content : undefined;
167
+ return Array.isArray(content) ? content.filter(isObject) : [];
168
+ }
169
+ function modelOf(value) {
170
+ const model = stringField(value, 'model');
171
+ return model ? { model } : {};
172
+ }
173
+ function toolOutput(content) {
174
+ if (typeof content === 'string')
175
+ return content;
176
+ if (!Array.isArray(content))
177
+ return undefined;
178
+ const text = content
179
+ .map((part) => stringField(part, 'text'))
180
+ .filter((part) => part !== undefined)
181
+ .join('\n');
182
+ return text || undefined;
183
+ }
184
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/agents/drivers/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { AgentEvent, CodingAgent } from '../types.js';
2
+ import { type CodexSandbox } from './codex.js';
3
+ export interface CodexLiveOptions {
4
+ /** Executable name or path. Default `codex`. */
5
+ command?: string;
6
+ /** Default `workspace-write`. */
7
+ sandbox?: CodexSandbox;
8
+ /** How long to wait for the server to acknowledge each request. Default 60 s. */
9
+ requestTimeoutMs?: number;
10
+ }
11
+ /**
12
+ * Codex over its app server (`codex app-server`, JSON-RPC on stdio).
13
+ * Supports `steer()` and routes command and file-change approvals to `task.onApproval`.
14
+ */
15
+ export declare function codexLive(options?: CodexLiveOptions): CodingAgent;
16
+ /** Map one app-server notification to agent events. */
17
+ export declare function codexNotification(method: string, params: unknown): AgentEvent[];