@kodizm/acp 0.5.6 → 0.6.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 (3) hide show
  1. package/README.md +29 -33
  2. package/dist/index.js +57288 -30843
  3. package/package.json +22 -7
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # kodizm-acp
2
2
 
3
- ACP bridge that drives Claude Code, codex, and opencode CLIs through one canonical wire.
3
+ ACP bridge that drives the Claude Code and opencode CLIs through one canonical wire.
4
4
 
5
5
  ## What it is
6
6
 
7
7
  `@kodizm/acp` is the Kodizm runtime's Agent Client Protocol bridge. It speaks one canonical JSON-RPC surface to the orchestrator, then translates each turn down to whichever CLI backend the session was opened against. The orchestrator never branches on backend; the same `session/new`, `session/prompt`, and `sessionUpdate` shapes carry every feature across all three.
8
8
 
9
- Three CLIs are supported today: Claude Code (via `@anthropic-ai/claude-agent-sdk`), codex (via `codex app-server` subprocess), and opencode (via `createOpencodeServer` from `@opencode-ai/sdk`).
9
+ Two CLIs are supported: Claude Code (via `@anthropic-ai/claude-agent-sdk`) as the primary backend, and opencode (via `createOpencodeServer` from `@opencode-ai/sdk`) as the secondary one.
10
10
 
11
11
  ## How it works
12
12
 
@@ -25,27 +25,27 @@ The driver contract is a single TypeScript interface with seven methods. The ser
25
25
 
26
26
  ## Backend support
27
27
 
28
- | Feature | Claude | codex | opencode |
29
- |---------|:------:|:-----:|:--------:|
30
- | `session/new`, `session/prompt`, `session/cancel` | yes | yes | yes |
31
- | `session/load` (resume) | yes | yes | yes |
32
- | `session/fork` | yes | yes | yes |
33
- | `session/compact` (manual) | yes | yes | yes |
34
- | Image content blocks | yes | yes | yes |
35
- | Token + cost rollup (`usage` event) | yes | yes | yes |
36
- | `additionalDirectories` (sandbox) | yes | yes | n/a |
37
- | `mcpServers` injection | yes | yes | yes |
38
- | `systemPrompt` replace + append | yes | yes | yes |
39
- | `skills` pre-load | yes | n/a | n/a |
40
- | Permissions (`permission_request`) | yes | yes | yes |
41
- | `askUserQuestion` | yes | yes | yes |
42
- | Subagent events | yes | yes | yes |
43
- | Thinking events | yes | yes | yes |
44
- | Cross-process Pattern B resume | yes | yes | yes |
45
- | Debug capture | yes | yes | yes |
28
+ | Feature | Claude | opencode |
29
+ |---------|:------:|:--------:|
30
+ | `session/new`, `session/prompt`, `session/cancel` | yes | yes |
31
+ | `session/load` (resume) | yes | yes |
32
+ | `session/fork` | yes | yes |
33
+ | `session/compact` (manual) | yes | yes |
34
+ | Image content blocks | yes | yes |
35
+ | Token + cost rollup (`usage` event) | yes | yes |
36
+ | `additionalDirectories` (sandbox) | yes | n/a |
37
+ | `mcpServers` injection | yes | yes |
38
+ | `systemPrompt` replace + append | yes | yes |
39
+ | `skills` pre-load | yes | n/a |
40
+ | Permissions (`permission_request`) | yes | yes |
41
+ | `askUserQuestion` | yes | yes |
42
+ | Subagent events | yes | yes |
43
+ | Thinking events | yes | yes |
44
+ | Cross-process Pattern B resume | yes | yes |
45
+ | Debug capture | yes | yes |
46
46
 
47
47
  > [!NOTE]
48
- > The published bin (`kodizm-acp` from `dist/index.js`) currently wires only `KODIZM_BACKEND=claude`. Codex and opencode drivers are fully implemented and tested, but reaching them today requires programmatic embedding (see [API reference](#api-reference)).
48
+ > The published bin (`kodizm-acp` from `dist/index.js`) wires both backends: set `KODIZM_BACKEND` to `claude` or `opencode` and the bin resolves the matching driver itself.
49
49
 
50
50
  ## Install
51
51
 
@@ -53,7 +53,7 @@ The driver contract is a single TypeScript interface with seven methods. The ser
53
53
  bun add @kodizm/acp
54
54
  ```
55
55
 
56
- Requires Bun >= 1.1.0. The `codex` and `opencode` CLIs must be installed separately when you use those backends.
56
+ Requires Bun >= 1.1.0. The `opencode` CLI must be installed separately when you use that backend.
57
57
 
58
58
  ## Quick start
59
59
 
@@ -75,17 +75,16 @@ Replace the credential pair with `ANTHROPIC_API_KEY=...` for the api-key path.
75
75
 
76
76
  | Variable | Required | Description |
77
77
  |----------|:--------:|-------------|
78
- | `KODIZM_BACKEND` | yes | `claude` / `codex` / `opencode` |
78
+ | `KODIZM_BACKEND` | yes | `claude` / `opencode` |
79
79
  | `CLAUDE_CODE_OAUTH_TOKEN` + `CLAUDE_CODE_REMOTE=1` | claude (sub) | Subscription auth |
80
80
  | `ANTHROPIC_API_KEY` | claude (api) | API key auth |
81
81
  | `CLAUDE_CODE_PATH` | optional | Path to claude binary (default `/usr/local/bin/claude`) |
82
- | `OPENAI_API_KEY` or `CODEX_API_KEY` | codex (api) | api-key path. Without it, codex falls back to chatgpt-mode auth in `~/.codex/auth.json` |
83
82
  | `OPENCODE_AUTH_CONTENT` | opencode (env) | JSON keyed by providerID. Layered onto subprocess env for the bridge lifetime only. Without it, opencode reads `~/.local/share/opencode/auth.json` |
84
83
  | `KODIZM_LOG_LEVEL` | optional | `debug` / `info` / `warn` / `error`. Default `info` |
85
84
  | `KODIZM_DEBUG` | optional | `1` enables process-wide debug capture |
86
85
  | `KODIZM_DEBUG_DIR` | optional | Forensic JSONL dir, default `/tmp/kodizm-debug` |
87
86
  | `KODIZM_DEBUG_RAW_SECRETS` | incident-only | `1` disables redaction. Never set in production |
88
- | `KODIZM_ACP_FORWARD_STDERR` | optional | `1` tees codex subprocess stderr to parent stderr |
87
+ | `KODIZM_ACP_FORWARD_STDERR` | optional | `1` tees a spawned backend subprocess's stderr to parent stderr |
89
88
 
90
89
  Stdout is reserved for ACP frames. Logs go to stderr.
91
90
 
@@ -117,7 +116,7 @@ type NewSessionRequest = {
117
116
  > `permissionTimeoutMs` and `permissionDeferTimeoutMs` are mutually exclusive. Pick hard-deny on timeout OR soft-defer on timeout, not both. The schema rejects the conflict with a clear error.
118
117
 
119
118
  > [!NOTE]
120
- > `settingSources` is the claude-only opt-out for filesystem config layering. When omitted the SDK's own default fires, matching the standalone Claude Code CLI: project `CLAUDE.md` + `.claude/CLAUDE.md` + `.claude/rules/*.md` load from `cwd` walking up; user `~/.claude/CLAUDE.md` + `~/.claude/rules/*.md` and `CLAUDE.local.md` load too. Pass `[]` to disable every fs scope; pass a selective subset like `['project']` to load only project-tracked files. Codex (`AGENTS.md` from `cwd`) and opencode (`AGENTS.md` / `CLAUDE.md` / `CONTEXT.md` from session `directory`) have no parallel field and ignore this option.
119
+ > `settingSources` is the claude-only opt-out for filesystem config layering. When omitted the SDK's own default fires, matching the standalone Claude Code CLI: project `CLAUDE.md` + `.claude/CLAUDE.md` + `.claude/rules/*.md` load from `cwd` walking up; user `~/.claude/CLAUDE.md` + `~/.claude/rules/*.md` and `CLAUDE.local.md` load too. Pass `[]` to disable every fs scope; pass a selective subset like `['project']` to load only project-tracked files. Opencode (`AGENTS.md` / `CLAUDE.md` / `CONTEXT.md` from session `directory`) has no parallel field and ignores this option.
121
120
 
122
121
  ### Tool policy
123
122
 
@@ -143,7 +142,7 @@ type McpServer = {
143
142
  }
144
143
  ```
145
144
 
146
- Phase 1 ships the `http` transport. The codex driver writes per-server entries into a temporary `~/.codex/config.toml`; opencode adds servers via `sdk.mcp.add` per session.
145
+ The `http` transport ships today. Opencode adds servers via `sdk.mcp.add` per session.
147
146
 
148
147
  ## API reference
149
148
 
@@ -183,7 +182,7 @@ The bin (`src/index.ts`) is the only public surface. Importers get the runtime h
183
182
 
184
183
  | Export | Purpose |
185
184
  |--------|---------|
186
- | `SupportedBackend` | `'claude' \| 'codex' \| 'opencode'` |
185
+ | `SupportedBackend` | `'claude' \| 'opencode'` |
187
186
  | `BackendNotConfiguredError`, `UnknownBackendError` | startup-time errors |
188
187
  | `resolveBackendFromEnv(env)` | parse `KODIZM_BACKEND` from a captured env |
189
188
  | `installShutdownHook()` | wire SIGTERM + SIGINT to graceful shutdown |
@@ -217,7 +216,7 @@ const server = createAcpServer({
217
216
  await server.serve()
218
217
  ```
219
218
 
220
- The `codex` and `opencode` drivers follow the same shape; their constructors take backend-specific factories (`spawnFactory` for codex, no factory for opencode since the SDK helper handles it).
219
+ The `opencode` driver follows the same shape; it takes no spawn factory, since the SDK helper handles the subprocess.
221
220
 
222
221
  ## Wire reference
223
222
 
@@ -251,7 +250,7 @@ The `SessionUpdateEvent` discriminated union has 21 variants:
251
250
  | `subagent_spawn` / `subagent_complete` | nested agent lifecycle |
252
251
  | `skill_activation` | a skill loaded mid-turn (claude only) |
253
252
  | `model_advertisement` | the actual model the backend chose |
254
- | `process_died` | subprocess crash (codex / opencode) |
253
+ | `process_died` | subprocess crash (opencode) |
255
254
  | `cancelled` | turn was cancelled |
256
255
  | `compaction_started` / `compaction_completed` | context compaction; `trigger: 'manual' \| 'auto'` |
257
256
  | `debug_log` | one of 10 stages: `rpc.in`, `rpc.out`, `sdk.message`, `sdk.error`, `tool.permission_request`, `tool.permission_response`, `session.config`, `driver.state_change`, `transport.spawn`, `transport.exit` |
@@ -265,8 +264,6 @@ The `SessionUpdateEvent` discriminated union has 21 variants:
265
264
  | `sessionUpdate` | every event above flows as a notification |
266
265
  | `session/request_permission` | orchestrator decides on a `permission_request` |
267
266
  | `session/ask_user_question` | orchestrator answers a `question_request` |
268
- | `session/dynamic_tool_call` | codex orchestrator-hosted tool dispatch |
269
- | `session/codex_chatgpt_token_refresh` | codex chatgpt-mode token rotation |
270
267
  | `session/permission_deferred_persist` | Pattern B write fallback when no `deferredStore` |
271
268
  | `session/permission_deferred_state` | Pattern B read fallback when no `deferredStore` |
272
269
 
@@ -277,7 +274,6 @@ The permission and ask-question RPC names have legacy aliases (`requestPermissio
277
274
  A driver instance can resume a session that an earlier process started. Useful when a container restart, deploy, or crash interrupts an active turn.
278
275
 
279
276
  - **claude**: standard `session/load` against the SDK's resume mode; the JSONL transcript on disk is authoritative.
280
- - **codex**: `CodexDriver.hydrateSession({ sessionId, codexThreadId, ... })` replays codex's `thread/resume` against the persisted threadId.
281
277
  - **opencode**: `OpencodeDriver.loadSession({ sessionId, _meta: { opencodeSessionId } })`; opencode's SQLite persistence survives process death.
282
278
 
283
279
  Deferred permissions (the orchestrator decided to "ask later" on a tool gate) are persisted via either an injected `DeferredPermissionStore` or the `session/permission_deferred_persist` outbound RPC. The next process picks up where the prior one left off and emits `permission_resumed`.