agent-embassy 1.6.0 → 1.7.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 (97) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +9 -9
  3. package/README.zh-CN.md +9 -9
  4. package/SECURITY.md +34 -77
  5. package/dist/src/gateway/acp-client.d.ts +117 -0
  6. package/dist/src/gateway/acp-client.js +382 -0
  7. package/dist/src/gateway/acp-client.js.map +1 -0
  8. package/dist/src/gateway/acp-provider.d.ts +65 -0
  9. package/dist/src/gateway/acp-provider.js +163 -0
  10. package/dist/src/gateway/acp-provider.js.map +1 -0
  11. package/dist/src/gateway/claude-helper-protocol.d.ts +3 -1
  12. package/dist/src/gateway/claude-helper-protocol.js +15 -5
  13. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  14. package/dist/src/gateway/claude-helper-supervisor.d.ts +3 -1
  15. package/dist/src/gateway/claude-helper-supervisor.js +16 -2
  16. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  17. package/dist/src/gateway/claude-helper.js +4 -3
  18. package/dist/src/gateway/claude-helper.js.map +1 -1
  19. package/dist/src/gateway/claude-peer.d.ts +1 -1
  20. package/dist/src/gateway/claude-peer.js +11 -13
  21. package/dist/src/gateway/claude-peer.js.map +1 -1
  22. package/dist/src/gateway/claude-runtime.d.ts +0 -20
  23. package/dist/src/gateway/claude-runtime.js +6 -127
  24. package/dist/src/gateway/claude-runtime.js.map +1 -1
  25. package/dist/src/gateway/cli-copy.en.d.ts +1 -1
  26. package/dist/src/gateway/cli-copy.en.js +2 -2
  27. package/dist/src/gateway/cli-copy.zh-CN.d.ts +1 -1
  28. package/dist/src/gateway/cli-copy.zh-CN.js +2 -2
  29. package/dist/src/gateway/cli.d.ts +1 -1
  30. package/dist/src/gateway/cli.js +26 -5
  31. package/dist/src/gateway/cli.js.map +1 -1
  32. package/dist/src/gateway/codex-app-server.d.ts +5 -74
  33. package/dist/src/gateway/codex-app-server.js +9 -597
  34. package/dist/src/gateway/codex-app-server.js.map +1 -1
  35. package/dist/src/gateway/codex-local-transport.d.ts +8 -26
  36. package/dist/src/gateway/codex-local-transport.js +26 -76
  37. package/dist/src/gateway/codex-local-transport.js.map +1 -1
  38. package/dist/src/gateway/compatibility.d.ts +6 -66
  39. package/dist/src/gateway/compatibility.js +14 -296
  40. package/dist/src/gateway/compatibility.js.map +1 -1
  41. package/dist/src/gateway/config.d.ts +9 -0
  42. package/dist/src/gateway/config.js +6 -2
  43. package/dist/src/gateway/config.js.map +1 -1
  44. package/dist/src/gateway/control.d.ts +16 -1
  45. package/dist/src/gateway/control.js +89 -57
  46. package/dist/src/gateway/control.js.map +1 -1
  47. package/dist/src/gateway/dashboard-copy.d.ts +1 -1
  48. package/dist/src/gateway/dashboard-copy.en.d.ts +14 -44
  49. package/dist/src/gateway/dashboard-copy.en.js +37 -67
  50. package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
  51. package/dist/src/gateway/dashboard-copy.js +14 -44
  52. package/dist/src/gateway/dashboard-copy.js.map +1 -1
  53. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +14 -44
  54. package/dist/src/gateway/dashboard-copy.zh-CN.js +37 -67
  55. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
  56. package/dist/src/gateway/dashboard-model.d.ts +38 -76
  57. package/dist/src/gateway/dashboard-model.js +158 -256
  58. package/dist/src/gateway/dashboard-model.js.map +1 -1
  59. package/dist/src/gateway/dashboard.d.ts +0 -3
  60. package/dist/src/gateway/dashboard.js +75 -76
  61. package/dist/src/gateway/dashboard.js.map +1 -1
  62. package/dist/src/gateway/deepseek-detect.d.ts +7 -6
  63. package/dist/src/gateway/deepseek-detect.js +31 -115
  64. package/dist/src/gateway/deepseek-detect.js.map +1 -1
  65. package/dist/src/gateway/live-dashboard-app/app.js +166 -621
  66. package/dist/src/gateway/live-dashboard-command.js +2 -4
  67. package/dist/src/gateway/live-dashboard-command.js.map +1 -1
  68. package/dist/src/gateway/live-dashboard-http.d.ts +1 -2
  69. package/dist/src/gateway/live-dashboard-http.js +14 -15
  70. package/dist/src/gateway/live-dashboard-http.js.map +1 -1
  71. package/dist/src/gateway/progress-watch-machine.d.ts +1 -4
  72. package/dist/src/gateway/progress-watch-machine.js.map +1 -1
  73. package/dist/src/gateway/provenance-envelope.d.ts +3 -2
  74. package/dist/src/gateway/provenance-envelope.js +44 -11
  75. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  76. package/dist/src/gateway/providers.d.ts +12 -84
  77. package/dist/src/gateway/providers.js +69 -806
  78. package/dist/src/gateway/providers.js.map +1 -1
  79. package/dist/src/gateway/server.d.ts +8 -9
  80. package/dist/src/gateway/server.js +51 -99
  81. package/dist/src/gateway/server.js.map +1 -1
  82. package/dist/src/gateway/service.d.ts +22 -49
  83. package/dist/src/gateway/service.js +196 -432
  84. package/dist/src/gateway/service.js.map +1 -1
  85. package/dist/src/gateway/store.d.ts +20 -29
  86. package/dist/src/gateway/store.js +281 -827
  87. package/dist/src/gateway/store.js.map +1 -1
  88. package/dist/src/gateway/types.d.ts +55 -55
  89. package/dist/src/gateway/types.js +49 -91
  90. package/dist/src/gateway/types.js.map +1 -1
  91. package/docs/CONFIGURATION.md +11 -10
  92. package/docs/CONFIGURATION.zh-CN.md +10 -9
  93. package/docs/DASHBOARD.md +4 -38
  94. package/docs/DASHBOARD.zh-CN.md +4 -2
  95. package/docs/GATEWAY-ARCHITECTURE.md +61 -119
  96. package/package.json +1 -1
  97. package/skills/embassy-peer/SKILL.md +6 -6
package/CHANGELOG.md CHANGED
@@ -4,6 +4,37 @@ All notable changes to this project are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
6
 
7
+ ## [1.7.0] - 2026-08-16
8
+
9
+ ### Added
10
+
11
+ - DeepSeek and Grok Build are routable providers. Four providers — Claude Code, Codex, DeepSeek, Grok Build — give twelve ordered directions, each requiring an explicit consent edge. New providers ride ACP, the open Agent Client Protocol: a minimal spawn-owned client (`initialize`, `session/new`, `session/prompt`, `session/cancel`; permission requests always denied; all five stop reasons preserved; subprocess death settles the honest `UNKNOWN`) plus a per-provider launch definition. Grok Build launches from the ACP registry's exact pin; DeepSeek launches from a local harness checkout (`DSH_HOME`, default `~/.dsh`) and its `end_turn` receipts deliberately settle `unconfirmed`/`ACP_OUTCOME_COARSE` because that adapter collapses failure outcomes upstream — the receipt stays honest until the adapter does.
12
+ - A strict generic pairing arm (`{aliases:[a,b]}`) beside the byte-preserved legacy Claude/Codex arm; deliveries UI gains independent from-provider/to-provider selectors; routed messages carry an additive `from-provider` attribute in the broker-owned envelope.
13
+ - A release-owned provider support matrix (`support/provider-support-matrix.json`) records what each release was tested with; a test proves the running broker never imports it.
14
+ - An offline ACP protocol-core conformance suite (framing, correlation, generation isolation, permission/cancel races, process-death phases, no-replay-after-uncertainty, reply bounds).
15
+
16
+ ### Removed
17
+
18
+ - Online compatibility certification, in full: evidence tiers, boot compatibility probes, adapter certification APIs, version-gated quarantine providers, the Codex write-attestation probe and its capacity ledger, and the two-factor write gate. Runtime version and build strings are unverified metadata and never grant or withhold anything; authority is consent plus exact owned route identity; results are what the correlated operation proved. Net for this release: about 8,500 lines removed while two providers were added.
19
+ - The bounded `claude --version` subprocess: an interop proof showed the version field was never load-bearing; version is now the attested launcher leaf or `unknown`.
20
+
21
+ ### Changed
22
+
23
+ - Native persisted state is schema v2 with one role-neutral `consentEdges` table. Pre-v1.7 state fails ordinary strict parsing with a clear error and no in-binary migration — single-user installs re-pair once after upgrading (minutes; registration and pairing are two commands per route).
24
+ - The Codex integration resolves and attests the exact managed `current` release (ownership, layout, architecture, endpoint generation) instead of consulting a version allowlist; exact-generation activation replaces certification at endpoint refresh.
25
+ - The dashboard and site describe only observable truth: route staleness, connector health, last safe codes, consent edges, and the tested-with matrix.
26
+
27
+ ## [1.6.1] - 2026-08-16
28
+
29
+ ### Added
30
+
31
+ - A stable, schema-attested Codex App Server whose write attestation passed may now hold writable routes, under a two-factor gate: durable write-covered attestation evidence AND a current-generation, process-local write-attestation pass. Neither factor alone enables writes — a recorded pass from an earlier daemon generation cannot authorize the current one — and prerelease versions remain fenced regardless of evidence.
32
+ - Write-probe capacity exhaustion now reports the honest `CODEX_WRITE_PROBE_CAPACITY_EXHAUSTED` instead of a thread-setup failure. Only attempts that could have spent tokens occupy the fixed per-process bound; the two provably zero-spend declines (model pin unavailable, rate limit constrained) release their slot into one retryable decline slot so a transient constraint does not burn permanent capacity.
33
+
34
+ ### Changed
35
+
36
+ - A monitor-only Codex provider now refuses route selection up front (`CODEX_PROVIDER_UNAVAILABLE`) instead of accepting a route whose every dispatch would fail; no transport is spawned for observation-only providers.
37
+
7
38
  ## [1.6.0] - 2026-08-16
8
39
 
9
40
  ### Fixed
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
13
13
  [![Node ≥ 20](https://img.shields.io/badge/node-%E2%89%A520-43853d)](package.json)
14
14
 
15
- Your [Claude Code](https://code.claude.com) sessions and [Codex](https://chatgpt.com/codex) desktop tasks can't talk to each other. When one needs the other's perspective, you carry context between windows yourself. Embassy is a small local broker that lets them find each other by name and exchange messages in both directions — no plugins, no API keys, no cloud relay.
15
+ Your [Claude Code](https://code.claude.com) sessions, [Codex](https://chatgpt.com/codex) desktop tasks, local DeepSeek Harness, and Grok Build agent do not share one routing surface. Embassy is a small local broker that gives all four providers named routes and explicit consent edges — no plugins, no API keys handled by Embassy, and no cloud relay.
16
16
 
17
17
  ```bash
18
18
  npm install -g agent-embassy
@@ -25,7 +25,7 @@ Embassy is built for one person, one macOS account, and agents you already trust
25
25
 
26
26
  ## Quickstart
27
27
 
28
- **Requirements:** macOS, Node.js 20+, Claude Code on the supported 2.x major with peer protocol 1, and Codex desktop configured to use its managed standalone App Server. Embassy was last live-tested with Claude Code 2.1.227 and Codex App Server 0.147.0; those patch versions are evidence, not startup pins:
28
+ **Requirements:** macOS and Node.js 20+. Claude routes require peer protocol 1; Codex routes require Desktop configured to use its managed standalone App Server. DeepSeek is optional and launches from `DSH_HOME` (default `~/.dsh`) through the checkout's `demo:acp` script; Grok Build is optional and launches the release-pinned ACP package. The release-owned [support matrix](support/provider-support-matrix.json) records the exact artifacts and capabilities tested for all four providers; it is release evidence, never a runtime allowlist:
29
29
 
30
30
  ```bash
31
31
  ~/.codex/packages/standalone/current/codex app-server daemon start
@@ -36,7 +36,7 @@ The first command starts the managed daemon if it is not already running (`resta
36
36
 
37
37
  Desktop attaches to the managed standalone App Server when it launches. If the daemon restarts while Desktop is already open, waiting alone does not reconnect that app process: fully quit Desktop, rerun `/usr/bin/open --env CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 -a ChatGPT`, and reopen the exact task.
38
38
 
39
- Provider compatibility needs no separate operator step. `embassy serve` attests the resolved installations and applies one evidence ladder to both providers. A certified same-major build is writable; a same-major build outside this release's tested inventory is shown as `schema_attested` when every bounded live-schema probe passes and is writable only when those probes cover its write path. Claude's probes cover its native write path. Ordinary Codex compatibility and registration reads remain read-only: they may include `initialize`, `thread/loaded/list`, and registration-time `thread/resume`, but do not invoke `turn/start`. The optional Codex write-attestation probe is the sole exception. It may create at most one disposable broker-owned thread per attempt, under a bounded write fence with zero user-thread contact; every created probe thread is archived and confirmed absent from the loaded set. The probe resolves the pinned model's lowest advertised effort. Whenever that model/effort pin cannot resolve, it declines in a zero-spend fail-safe before creating any thread or model turn. Untested Codex 0.x therefore stays monitor-only pending a certified write schema. Failed probes, a different major, or version evidence that cannot establish a safe major leave only that provider degraded, monitor-only, and write-fenced. Probes never promote across a major or compensate for unknown major evidence; a different-major alert names the observed/tested versions and supported major and says that an Embassy release supporting the observed major is required. In every degraded case, the broker, control/dashboard surfaces, and other provider keep running. Only unsafe OS evidence for Embassy-owned or executed artifacts and Embassy callback, control, or state paths refuses broker startup; unsafe UID or mode evidence on Claude's external sessions registry root quarantines only Claude. A Claude session record whose peer protocol is not 1 is rejected in isolation and counted.
39
+ Runtime delivery is best effort. Version and build strings are unverified metadata and never grant or withhold routing authority. Consent plus exact owned route/session identity authorizes an attempt; the current connector, route state, and correlated operation determine its honest result. Unsupported or changed interfaces therefore fail with provider-local safe codes instead of an online compatibility tier. Embassy still validates the trust boundary: exact owned executable and state paths, endpoint generations, strict consumed protocol fields, Claude peer protocol 1, bounded queues, and no replay after an ambiguous write.
40
40
 
41
41
  > **Known limitation:** Embassy can reach Codex tasks only while Desktop uses the managed standalone App Server. In that mode, tasks currently cannot connect to Desktop's built-in in-app browser (`@Browser` loads but does not attach). Switching Desktop back to its default private App Server restores the built-in browser immediately — but makes those tasks unreachable by Embassy. No other capability regressions have been identified, though this was not an exhaustive parity test.
42
42
 
@@ -70,7 +70,7 @@ embassy register-codex --alias codex-reviewer@this-mac
70
70
 
71
71
  You should see `"accepted":true`. The `codex-` prefix is required for Claude discovery. To retire the task later, run `embassy unregister-codex --alias codex-reviewer@this-mac` from inside that same task.
72
72
 
73
- Managed App Server generation changes and `embassy serve` restarts both use exact-task reactivation. Each replacement starts monitor-only; only a fresh initialize plus `thread/loaded/list` result that finds the byte-identical task exactly once may re-anchor the alias, and writes stay fenced until that exact generation is activated. A normal broker restart therefore needs no manual registration. An incompatible endpoint or a missing or duplicate exact task leaves the route stale with `REOBSERVATION_REQUIRED`; once that task is observable, rerun `embassy register-codex --alias codex-reviewer@this-mac` from the exact task without unregistering first. Embassy never retargets by alias or replays an ambiguously written body.
73
+ Managed App Server generation changes and `embassy serve` restarts both use exact-task reactivation. A fresh initialize negotiates the connection; `thread/loaded/list` must find the byte-identical task exactly once before Embassy re-anchors the alias on that exact generation. A normal broker restart therefore needs no manual registration. A missing or duplicate exact task, changed generation, or failed negotiation leaves the route stale with a safe code; once that task is observable, rerun `embassy register-codex --alias codex-reviewer@this-mac` from the exact task without unregistering first. Embassy never retargets by alias or replays an ambiguously written body.
74
74
 
75
75
  ### 3. Select a Claude destination
76
76
 
@@ -84,7 +84,7 @@ Run this from the operator terminal, or from inside the Codex task — either wo
84
84
 
85
85
  You should see `"accepted":true`. Registration and selection together form a pair — this Claude session and this Codex task can now exchange messages through Embassy.
86
86
 
87
- Once you have more than one registered task, name both ends explicitly with `embassy pair --claude <name@host> --codex <codex-alias>`; many pairs can coexist. Unlike `select-claude`, `pair` and `unpair` must run **inside the Codex task**, the same way `register-codex` does. From a plain terminal they fail `CODEX_IDENTITY_REQUIRED`, and from inside a Claude session they fail `CALLER_IDENTITY_CONFLICT`.
87
+ To connect any two routes from different providers, name both ends explicitly with `embassy pair --from <alias> --to <alias>`; many edges can coexist. The command must run under an inherited endpoint identity that belongs to the requested edge. The live dashboard offers the same bounded, confirmed operation to the local operator.
88
88
 
89
89
  ### 4. Send a message
90
90
 
@@ -169,9 +169,9 @@ The broker also publishes mode-0600 static snapshots as `gateway-dashboard.html`
169
169
  └───────────────────────────────────────────────────────────┘
170
170
  ```
171
171
 
172
- Embassy publishes each registered Codex task into Claude Code's live-session registry as its own `codex-*` peer. Compatible Claude sessions discover them through their native `ListAgents` and contact them with `SendMessage` no plugin, MCP server, or settings change required.
172
+ Embassy publishes each registered Codex task into Claude Code's live-session registry as its own `codex-*` peer. Claude sessions discover those tasks through `ListAgents`; Codex uses its managed App Server. DeepSeek and Grok Build are boot-registered ACP routes whose owned subprocess and one route-local session start lazily on first dispatch.
173
173
 
174
- A pair is one explicit permission edge between one Claude session and one Codex task — and pairs are many-to-many: one Claude session may hold edges to several Codex tasks, and one Codex task to several Claude sessions (bounded at 128 pairs by default). Every edge is created explicitly, with `pair` or the one-task `select-claude` shorthand; nothing is ever implied. Without an edge, a sender settles terminally as `SENDER_NOT_PAIRED`. `embassy serve --inbound open` is the explicit opt-out that restores any-session inbound.
174
+ A pair is one explicit permission edge between two named routes from different providers, bounded at 128 edges by default. Every edge is created explicitly with generic `pair --from/--to`; `select-claude` remains the one-Codex-task shorthand for a Claude↔Codex edge. Nothing is implied. Without an edge, a sender settles terminally as `SENDER_NOT_PAIRED`. `embassy serve --inbound open` is the explicit opt-out for supported native inbound senders.
175
175
 
176
176
  Delivery timing is directional. Once routing and pre-write checks pass, every Claude-bound body is written immediately to Claude's native mailbox regardless of its observed busy or idle state. `transport_written` records that mailbox write and is the Claude-bound terminal `delivered` boundary; it does not mean Claude read or consumed the body. Codex-bound ordinary bodies instead queue while the task is busy and start a turn when it goes idle. In the Claude-to-Codex direction only, a body with an exact leading `STEER:` prefix may enter the active turn at the App Server's next tool-call boundary; if that boundary is unavailable, the message returns to the normal queue.
177
177
 
@@ -217,7 +217,7 @@ Codex tasks can then be prompted with `$embassy-peer`; Claude Code discovers it
217
217
  | `wait-delivery` | either provider | Wait for that tracker to settle, up to the delivery deadline |
218
218
  | `untrack` | either provider | Close one active progress watch: `embassy untrack --conversation conv_<token>` |
219
219
  | `register-codex` / `unregister-codex` | Codex task | Advertise or retire that exact task; both take `--alias <codex-alias>`, and `embassy register-codex --alias codex-successor@this-mac --succeeds codex-reviewer@this-mac` hands the registration to a different task |
220
- | `pair` / `unpair` | Codex task | Add or remove one explicit Claude↔Codex edge by naming both ends: `embassy pair --claude advisor@this-mac --codex codex-reviewer@this-mac`. Like `register-codex`, it must run inside the Codex task |
220
+ | `pair` / `unpair` | endpoint participant | Add or remove one cross-provider edge by naming both ends: `embassy pair --from advisor@this-mac --to grok-main@this-mac`; the inherited caller must belong to the edge |
221
221
  | `select-claude` / `unselect-claude` | operator or Codex task | One-task shorthand for `pair`/`unpair`, taking `--alias <name@host>` or `--session <uuid>`: resolves the Codex end only when it is unambiguous (inherited or sole registered task), otherwise fails closed |
222
222
  | `send-to-claude` | registered Codex task | Send one bounded message to a paired Claude session: `--from <codex-alias> --to <claude-alias>`, body on stdin, optional `--expects-reply` and `--track [--idle-minutes <n>]` |
223
223
  | `send-to-codex` | Claude session | Same flags and stdin body, using the inherited native reply identity |
@@ -233,7 +233,7 @@ or by replying with a leading `DONE:`. See [Delivery](docs/DELIVERY.md).
233
233
 
234
234
  - **Local broker, stable loopback dashboard.** `embassy serve` listens on private Unix-domain sockets and makes no provider API call. The opt-in `embassy dashboard --live` companion is a separate process and the only listener Embassy can create, bound to exact `127.0.0.1` on stable port `41961` by default (or the per-invocation `--port <n>`). It is deliberately unauthenticated local HTTP for a trusted single-user machine; Host, Origin, and sentinel checks constrain browser-origin requests but do not authenticate local processes or OS users.
235
235
  - **Same-UID containment, not authentication.** Caller identity is inherited from the local process environment. Route ownership and generation checks reduce mistakes, but are not a defense against code already running as your OS user.
236
- - **Compatibility follows evidence, not patch pins.** Broker/provider startup attests exact filesystem ownership and paths, then applies the evidence ladder. Certified same-major builds are writable; fully probed same-major builds are `schema_attested` and writable only when the probes cover writes. Ordinary Codex compatibility and registration reads remain read-only: they may include `initialize`, `thread/loaded/list`, and registration-time `thread/resume`, but do not invoke `turn/start`. The optional Codex write-attestation probe is the sole exception. It may create at most one disposable broker-owned thread per attempt, under a bounded write fence with zero user-thread contact; every created probe thread is archived and confirmed absent from the loaded set. The probe resolves the pinned model's lowest advertised effort. Whenever that model/effort pin cannot resolve, it declines in a zero-spend fail-safe before creating any thread or model turn. Untested Codex 0.x therefore remains monitor-only. Failed probes, a different major, or unknown version evidence fence only that provider while the broker and other provider keep running. Probes never promote across a major or unknown version. Unsafe Embassy-owned/executed artifacts and Embassy callback/control/state paths still refuse startup; an unsafe Claude-owned sessions registry root quarantines only Claude.
236
+ - **Compatibility is tested offline; runtime is best effort.** The release-owned support matrix records exact tested artifacts, protocols, capabilities, stop fidelity, limitations, and test dates. Runtime never imports that matrix and never turns a version fact into authority. It validates exact owned boundaries and protocol facts, attempts the current operation, and reports provider-local health, route staleness, and safe codes without replaying uncertainty.
237
237
  - **Native permissions stay native.** Embassy sends no Codex approval or sandbox overrides and answers no approval request. `crossSessionInbound` remains Claude's own control; Embassy cannot override it.
238
238
  - **Provenance is marked, not authenticated.** Routed bodies carry one broker-owned cross-session marker with the verified sender alias; it distinguishes the transport path for the receiving model but cannot make untrusted text safe or authenticate against code already running as your OS user.
239
239
  - **Bodies stored, bounded, and yours.** Message bodies persist in the broker's private mode-0600 state under bounded retention so the ledger can show you the mail itself; queued mail survives a broker restart and re-sends exactly once. Raw provider frames stay memory-only. The static dashboard files remain metadata-only; the live dashboard shows retained bodies.
package/README.zh-CN.md CHANGED
@@ -12,7 +12,7 @@
12
12
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
13
13
  [![Node ≥ 20](https://img.shields.io/badge/node-%E2%89%A520-43853d)](package.json)
14
14
 
15
- 你的 [Claude Code](https://code.claude.com) 会话和 [Codex](https://chatgpt.com/codex) 桌面任务彼此无法对话。当一方需要另一方的视角时,你只能在窗口之间手动搬运上下文。Embassy 是一个小型本地代理,让它们按名称互相发现并双向交换消息——无需插件、无需 API 密钥、无需云端中继。
15
+ 你的 [Claude Code](https://code.claude.com) 会话、[Codex](https://chatgpt.com/codex) 桌面任务、本地 DeepSeek Harness 与 Grok Build 代理没有共同路由面。Embassy 是一个小型本地代理,为四种提供方提供具名路由与显式同意边——无需插件,Embassy 不处理 API 密钥,也无需云端中继。
16
16
 
17
17
  ```bash
18
18
  npm install -g agent-embassy
@@ -25,7 +25,7 @@ Embassy 专为单人、单一 macOS 账户以及你已信任以该用户身份
25
25
 
26
26
  ## 快速开始
27
27
 
28
- **前置要求:** macOSNode.js 20+、使用已支持 2.x 主版本且对等协议为 1 Claude Code,以及配置为使用托管独立 App Server Codex 桌面应用。Embassy 最近完成实机测试的版本是 Claude Code 2.1.227 Codex App Server 0.147.0;这些补丁版本是测试证据,而非启动固定值:
28
+ **前置要求:** macOSNode.js 20+。Claude 路由要求对等协议 1;Codex 路由要求 Desktop 使用托管独立 App Server。DeepSeek 是可选提供方,通过 `DSH_HOME`(默认 `~/.dsh`)指向的本地 checkout `demo:acp` 脚本启动;Grok Build 也是可选提供方,通过发布版固定的 ACP 包启动。发布版自有的[支持矩阵](support/provider-support-matrix.json)记录四种提供方已测试的精确构件与能力;它只是发布证据,绝不是运行时允许列表:
29
29
 
30
30
  ```bash
31
31
  ~/.codex/packages/standalone/current/codex app-server daemon start
@@ -36,7 +36,7 @@ Embassy 专为单人、单一 macOS 账户以及你已信任以该用户身份
36
36
 
37
37
  Desktop 仅在启动时附着到托管独立 App Server。如果 Desktop 已打开时守护进程重启,单纯等待不会让该应用进程重新连接:请完全退出 Desktop,重新运行 `/usr/bin/open --env CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 -a ChatGPT`,再打开该确切任务。
38
38
 
39
- 提供方兼容性无需操作员执行额外步骤。`embassy serve` 会验证解析到的安装边界,并对两种提供方应用同一套证据阶梯:同主版本且在已认证清单中的构建可写;同主版本但不在本发布版已测清单中的构建,在全部有界实时结构探测通过后显示为 `schema_attested`,但只有探测覆盖写入路径时才可写。Claude 探测覆盖原生写入路径。常规 Codex 兼容性与注册读取仍保持只读:它们可能包括 `initialize`、`thread/loaded/list` 与注册时的 `thread/resume`,但不会调用 `turn/start`。唯一例外是可选的 Codex 写入认证探测:每次尝试最多可创建一个代理自有的临时线程,在有界写入围栏下运行且绝不接触用户线程;每个已创建的探测线程都会被归档,并确认已从已加载集合中清除。该探测会解析固定模型所公布的最低 effort。只要该模型/effort 固定项无法解析,探测就会以零消耗故障安全方式拒绝,并且不会创建任何线程或模型轮次。未测试的 Codex 0.x 在认证写入结构出现前保持仅监控。探测失败、主版本不同或版本证据无法建立安全主版本时,只有该提供方保持降级、仅监控并禁止写入,代理、控制面/仪表盘和另一提供方继续运行。探测绝不能跨主版本或未知主版本提升权限。主版本不同的告警会列出已观测/已测版本和支持主版本,并说明必须使用支持已观测主版本的 Embassy 发布版。只有 Embassy 自有或执行的构件及其回调、控制与状态路径出现不安全 OS 证据时才会拒绝代理启动;Claude 外部会话注册表根目录的 UID 或模式不安全时,只隔离 Claude。对等协议不是 1 的 Claude 会话记录会单独被拒绝并计数。
39
+ 运行时投递采用尽力而为模式。版本与构建字符串只是未经验证的元数据,绝不授予或撤销路由权限。同意加上精确的自有路由/会话身份会授权一次尝试;当前连接器、路由状态与相关操作决定诚实结果。接口不受支持或发生变化时,Embassy 会返回提供方局部的安全代码,而不是在线兼容性等级。Embassy 仍会验证信任边界:精确自有的可执行文件与状态路径、端点代际、被消费协议字段的严格结构、Claude 对等协议 1、有界队列,以及结果不确定的写入绝不重放。
40
40
 
41
41
  > **已知限制:** 仅当 Desktop 使用托管独立 App Server 时,Embassy 才能访问 Codex 任务。在该模式下,任务目前无法连接 Desktop 内置的应用内浏览器(`@Browser` 可加载但无法附着)。将 Desktop 切换回其默认的私有 App Server 会立即恢复内置浏览器——但会使这些任务对 Embassy 不可达。目前未发现其他能力回退,但这并非穷尽的能力对比测试。
42
42
 
@@ -67,7 +67,7 @@ embassy register-codex --alias codex-reviewer@this-mac
67
67
 
68
68
  你应看到 `"accepted":true`。`codex-` 前缀是 Claude 发现所必需的。之后若要注销该任务,请在同一个任务内运行 `embassy unregister-codex --alias codex-reviewer@this-mac`。
69
69
 
70
- 托管 App Server 端点代际变更与 `embassy serve` 重启都会使用精确任务重新激活。每个替代端点都从仅监控状态开始;只有重新初始化并通过 `thread/loaded/list` 恰好一次找到字节级一致的原任务时,才能重新锚定别名,而且在激活这个精确代际前写入始终保持封锁。因此,正常的代理重启不需要手动重新注册。端点不兼容,或精确任务缺失、重复,都会使路由以 `REOBSERVATION_REQUIRED` 保持陈旧;该任务恢复可观察后,请从精确任务内再次运行 `embassy register-codex --alias codex-reviewer@this-mac`,且不要先注销。Embassy 绝不会按别名改投其他任务,也不会重放写入结果不明确的正文。
70
+ 托管 App Server 端点代际变更与 `embassy serve` 重启都会使用精确任务重新激活。新的 `initialize` 用于协商连接;只有 `thread/loaded/list` 恰好一次找到字节级一致的原任务时,Embassy 才会在该精确代际上重新锚定别名。因此,正常的代理重启不需要手动重新注册。精确任务缺失或重复、代际变化或协商失败都会让路由以安全代码保持陈旧;任务恢复可观察后,请从精确任务内再次运行 `embassy register-codex --alias codex-reviewer@this-mac`,且不要先注销。Embassy 绝不会按别名改投其他任务,也不会重放写入结果不明确的正文。
71
71
 
72
72
  ### 3. 选择 Claude 目的地
73
73
 
@@ -81,7 +81,7 @@ embassy select-claude --alias advisor@this-mac
81
81
 
82
82
  你应看到 `"accepted":true`。注册和选择共同构成一个配对——现在这个 Claude 会话和这个 Codex 任务可以通过 Embassy 交换消息。
83
83
 
84
- 当你注册了多个任务后,请用 `embassy pair --claude <name@host> --codex <codex-alias>` 显式指定两端;多个配对可以并存。与 `select-claude` 不同,`pair` 和 `unpair` 必须**在 Codex 任务内部**运行,就像 `register-codex` 一样。在普通终端中它们会以 `CODEX_IDENTITY_REQUIRED` 失败,在 Claude 会话内则以 `CALLER_IDENTITY_CONFLICT` 失败。
84
+ 要连接来自不同提供方的任意两条路由,请用 `embassy pair --from <alias> --to <alias>` 显式指定两端;多条边可以并存。命令必须在属于该请求边的继承端点身份下运行。本地操作者也可在实时仪表盘中执行同样的有界确认操作。
85
85
 
86
86
  ### 4. 发送消息
87
87
 
@@ -146,9 +146,9 @@ Embassy 会在实际写入提供方之前,为双向路由消息添加一个由
146
146
  └───────────────────────────────────────────────────────────┘
147
147
  ```
148
148
 
149
- Embassy 将每个已注册的 Codex 任务以各自的 `codex-*` 对等方身份发布到 Claude Code 的实时会话注册表中。兼容的 Claude 会话通过原生的 `ListAgents` 发现它们,并通过 `SendMessage` 与之通信——无需插件、MCP 服务器或设置更改。
149
+ Embassy 将每个已注册的 Codex 任务以各自的 `codex-*` 对等方身份发布到 Claude Code 的实时会话注册表中。Claude 会话通过 `ListAgents` 发现这些任务;Codex 使用托管 App Server。DeepSeek 与 Grok Build 是启动时登记的 ACP 路由,其自有子进程与单个路由本地会话会在首次投递时惰性启动。
150
150
 
151
- 配对是一个 Claude 会话与一个 Codex 任务之间的单一显式权限边,而配对关系是多对多的:一个 Claude 会话可以与多个 Codex 任务建立边,一个 Codex 任务也可以与多个 Claude 会话建立边(默认上限 128 个配对)。每条边都通过 `pair` 或单任务简写 `select-claude` 显式创建;一切都不会被隐式推断。没有边时,发送方以 `SENDER_NOT_PAIRED` 终局结算。`embassy serve --inbound open` 是显式的退出选项,可恢复任意会话入站。
151
+ 配对是来自不同提供方的两条具名路由之间的单一显式权限边,默认上限 128 条。每条边都通过通用的 `pair --from/--to` 显式创建;`select-claude` 保留为单 Codex 任务建立 Claude↔Codex 边的简写。一切都不会被隐式推断。没有边时,发送方以 `SENDER_NOT_PAIRED` 终局结算。`embassy serve --inbound open` 是针对受支持原生入站发送方的显式退出选项。
152
152
 
153
153
  投递时机因方向而异。通过路由与写前检查后,所有朝向 Claude 的正文都会立即写入 Claude 的原生邮箱,无论观测到 Claude 正繁忙还是空闲。`transport_written` 记录这次邮箱写入,并且就是朝向 Claude 的终局 `delivered` 边界;它不表示 Claude 已读取或消费正文。朝向 Codex 的普通正文则在任务忙碌时排队,并在任务空闲后启动轮次。仅在 Claude→Codex 方向,正文以精确 `STEER:` 开头的消息可以在 App Server 的下一个工具调用边界进入当前轮次;若该边界不可用,消息会回到普通队列。
154
154
 
@@ -192,7 +192,7 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
192
192
  | `wait-delivery` | 任一提供方 | 等待该跟踪器结算,直至投递截止时间 |
193
193
  | `untrack` | 任一提供方 | 关闭一个活跃的进度监视:`embassy untrack --conversation conv_<token>` |
194
194
  | `register-codex` / `unregister-codex` | Codex 任务 | 通告或注销该任务;两者都需要 `--alias <codex-alias>`,而 `embassy register-codex --alias codex-successor@this-mac --succeeds codex-reviewer@this-mac` 会将注册转交给另一个任务 |
195
- | `pair` / `unpair` | Codex 任务 | 显式指定两端来添加或移除一条 Claude↔Codex 边:`embassy pair --claude advisor@this-mac --codex codex-reviewer@this-mac`。与 `register-codex` 一样,它必须在 Codex 任务内部运行 |
195
+ | `pair` / `unpair` | 端点参与方 | 显式指定两端来添加或移除一条跨提供方边:`embassy pair --from advisor@this-mac --to grok-main@this-mac`;继承调用方必须属于该边 |
196
196
  | `select-claude` / `unselect-claude` | 操作员或 Codex 任务 | `pair`/`unpair` 的单任务简写,接受 `--alias <name@host>` 或 `--session <uuid>`:仅在 Codex 端无歧义(继承标识或唯一已注册任务)时解析,否则以关闭状态失败 |
197
197
  | `send-to-claude` | 已注册的 Codex 任务 | 向已配对的 Claude 会话发送一条有界消息:`--from <codex-alias> --to <claude-alias>`,正文从标准输入读取,可选 `--expects-reply` 与 `--track [--idle-minutes <n>]` |
198
198
  | `send-to-codex` | Claude 会话 | 标志与正文输入方式相同,使用继承的原生回复标识 |
@@ -204,7 +204,7 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
204
204
 
205
205
  - **本地代理,稳定的 loopback 仪表盘。** `embassy serve` 仅监听私有 Unix 域套接字,不发起任何提供商 API 调用。可选启用的 `embassy dashboard --live` 组件是一个独立进程,也是 Embassy 能创建的唯一监听器;它精确绑定 `127.0.0.1`,默认使用稳定端口 `41961`(也可为本次启动传入 `--port <n>`)。它是在可信单用户机器上有意不设身份认证的本地 HTTP;Host、Origin 与哨兵检查约束浏览器来源的请求,但不认证本地进程或 OS 用户。
206
206
  - **同 UID 隔离,而非身份认证。** 调用者身份继承自本地进程环境。路由所有权和生成号检查能减少误操作,但不是对已以你的 OS 用户身份运行的代码的防御。
207
- - **兼容性依据证据,而非固定补丁版本。** 代理/提供方启动先验证精确的 OS 边界,再应用证据阶梯。同主版本的已认证构建可写;全部探测通过的同主版本构建显示为 `schema_attested`,且仅在探测覆盖写入时才可写。常规 Codex 兼容性与注册读取仍保持只读:它们可能包括 `initialize`、`thread/loaded/list` 与注册时的 `thread/resume`,但不会调用 `turn/start`。唯一例外是可选的 Codex 写入认证探测:每次尝试最多可创建一个代理自有的临时线程,在有界写入围栏下运行且绝不接触用户线程;每个已创建的探测线程都会被归档,并确认已从已加载集合中清除。该探测会解析固定模型所公布的最低 effort。只要该模型/effort 固定项无法解析,探测就会以零消耗故障安全方式拒绝,并且不会创建任何线程或模型轮次。未测试的 Codex 0.x 保持仅监控。探测失败、主版本不同或版本证据未知时,只封锁该提供方,代理和另一提供方继续运行。探测绝不能跨主版本或未知版本提升权限。Embassy 自有或执行的构件及其回调、控制与状态路径不安全时仍拒绝启动;Claude 外部会话注册表根目录不安全时只隔离 Claude。
207
+ - **兼容性在离线阶段测试;运行时尽力而为。** 发布版自有支持矩阵记录精确已测构件、协议、能力、停止保真度、限制与测试日期。运行时从不导入该矩阵,也绝不会把版本事实变成权限。它验证精确自有边界与协议事实,尝试当前操作,并以提供方局部健康度、路由陈旧状态和安全代码报告结果,且绝不重放不确定写入。
208
208
  - **来源标记是提示,不是签名。** Embassy 在提供方写入边界生成跨会话来源封装,让接收模型能够区分代理路由消息及其已验证发送方别名;这不是密码学证明,也不会把不可信正文变成可信指令。
209
209
  - **原生权限保持原生。** Embassy 不发送任何 Codex 审批或沙盒覆盖,也不应答任何审批请求。`crossSessionInbound` 仍是 Claude 自身的控制机制;Embassy 无法覆盖它。
210
210
  - **消息体有界保存,属于你。** 消息体以有界保留策略持久化在 broker 的私有 mode-0600 状态中,让台账能够展示邮件本身;排队中的邮件在 broker 重启后幸存并恰好重发一次。原始提供方帧仍仅存于内存。静态仪表盘文件保持仅元数据;实时仪表盘展示保留的正文。
package/SECURITY.md CHANGED
@@ -97,14 +97,13 @@ review, and audit work.
97
97
  browser can issue or read across origins. They do not authenticate a loopback
98
98
  caller, its process, or its UID; the live dashboard assumes a trusted
99
99
  single-user machine.
100
- - **Predictions based on version strings.** A version string is a compatibility
101
- observation, never security evidence or attack detection. Directly observed
102
- path, ownership, protocol, schema, and generation facts outrank prediction
103
- from a version string. Within the security boundary, boot refusal is reserved
104
- for an unsafe or lost singleton lease, corrupt controller state, or unsafe
105
- OS-boundary attestation. Version drift, an unparseable version, failed probes,
106
- or one incompatible provider degrades and write-fences that surface; it does
107
- not take down the broker or the other provider.
100
+ - **Predictions based on version strings.** A version string is diagnostic
101
+ metadata, never routing authority, security evidence, or attack detection.
102
+ Current path, ownership, protocol, interface, generation, and correlated
103
+ operation facts decide what Embassy can safely do. Boot refusal is reserved
104
+ for an unsafe or lost singleton lease, corrupt controller state, or an unsafe
105
+ OS boundary. Interface drift or one unavailable optional provider degrades
106
+ that surface; it does not take down the broker or the other providers.
108
107
 
109
108
  ### Audit rule
110
109
 
@@ -172,51 +171,28 @@ broker.
172
171
  only listeners are private Unix-domain sockets. The opt-in
173
172
  `embassy dashboard --live` companion is a separate process with its own
174
173
  loopback HTTP listener — see "Live companion boundary" below.
175
- - Provider compatibility is evidence-gated rather than patch-version-pinned.
176
- Provider startup first validates exact OS ownership, path, symlink, lease,
177
- state, and generation evidence. Unsafe evidence for Embassy-owned or executed
174
+ - Provider startup validates exact OS ownership, path, symlink, lease, state,
175
+ and generation evidence. Unsafe evidence for Embassy-owned or executed
178
176
  artifacts and Embassy callback, control, or state paths refuses broker
179
177
  startup; unsafe UID or mode evidence for Claude's external sessions registry
180
- root quarantines and write-fences only Claude.
181
- A certified same-major provider build is writable. A same-major build whose
182
- bounded live-schema probes all pass is `schema_attested` and writable only
183
- when those probes cover the write path. Claude's probes cover its native
184
- write path. Ordinary Codex compatibility and registration reads remain
185
- read-only: they may include `initialize`, `thread/loaded/list`, and
186
- registration-time `thread/resume`, but do not invoke `turn/start`. The
187
- optional Codex write-attestation probe is the sole exception. It may create
188
- at most one disposable broker-owned thread per attempt, under a bounded write
189
- fence with zero user-thread contact; every created probe thread is archived
190
- and confirmed absent from the loaded set. The probe resolves the pinned
191
- model's lowest advertised effort. Whenever that model/effort pin cannot
192
- resolve, it declines in a zero-spend fail-safe before creating any thread or
193
- model turn. Untested Codex 0.x therefore stays monitor-only pending a
194
- certified write schema. Failed
195
- probes, a different major, or version evidence that cannot establish a safe
196
- major leave only that
197
- provider degraded, monitor-only, and write-fenced while the broker,
198
- control/dashboard surfaces, and other provider remain available; probes
199
- never promote across a major or unknown version. A Claude
200
- session record whose peer protocol is not 1 is rejected in isolation and
178
+ root quarantines only Claude. A provider version is best-effort diagnostic
179
+ metadata and carries no routing authority. Runtime authority comes from an
180
+ explicit pair, exact owned route and session identity, current connector and
181
+ generation facts, strict protocol handling, and correlated operation results.
182
+ A Claude record whose peer protocol is not 1 is rejected in isolation and
201
183
  included in bounded rejection evidence. Every replacement Codex endpoint
202
- generation remains write-fenced until its fresh initialize and exact-task
203
- listing checks pass and the controller activates it.
184
+ generation must negotiate its current interface and re-observe the exact task
185
+ before the controller re-anchors it.
204
186
  - Embassy publishes at most one process-owned `codex-*` record in Claude's
205
187
  registry with the supported explicit versioned Embassy-advertisement marker.
206
188
  The prefix is a visible alias convention, not the discriminator: an unmarked
207
189
  genuine Claude session named `codex-*` remains discoverable. Embassy creates
208
190
  one callback socket and removes only exact-owned artifacts whose generation
209
191
  still matches during graceful shutdown.
210
- - App Server methods are allowlisted. Ordinary connectors expose no archive,
211
- deletion, shell, configuration, authentication, plugin, history,
212
- approval-response, or generic RPC method. The optional write-attestation
213
- probe alone may call `thread/archive`, only for its validated disposable
214
- broker-owned probe thread; it then confirms that thread is absent from the
215
- loaded set. The probe resolves the pinned model's lowest advertised effort.
216
- Whenever that model/effort pin cannot resolve, it declines in a zero-spend
217
- fail-safe before creating any thread or model turn. No archive method is
218
- exposed to ordinary routes, and the other excluded method classes remain
219
- excluded everywhere.
192
+ - App Server methods are allowlisted. Connectors expose no archive, deletion,
193
+ shell, configuration, authentication, plugin, history, approval-response, or
194
+ generic RPC method. ACP permission requests are always denied or cancelled;
195
+ Embassy never turns them into an approval surface.
220
196
  - `turn/steer` is reachable only for an exact leading `STEER:` body in the
221
197
  Claude-to-Codex direction, with an exact observed active-turn ID. App Server
222
198
  admits it at the next tool-call boundary; Embassy never interrupts or injects
@@ -353,39 +329,20 @@ because this surface intentionally has no such authentication boundary.
353
329
  Routine tests use temporary directories, fake peers, and fake App Server
354
330
  transports. They do not inspect live provider state or contact a model.
355
331
 
356
- Compatibility admission is automatic and evidence-gated. Broker/provider
357
- startup owns bounded read-only validation of the configured installations,
358
- exact OS boundaries, provider majors, declared protocol constants, and live
359
- schemas. Unsafe Embassy-owned/executed artifacts or Embassy callback, control,
360
- or state paths remain startup-fatal; unsafe UID or mode evidence on Claude's
361
- external sessions registry root quarantines only that provider. Certified
362
- same-major builds are writable. Fully probed same-major
363
- builds are `schema_attested` and writable only where the probes cover writes.
364
- Ordinary Codex compatibility and registration reads remain read-only: they may
365
- include `initialize`, `thread/loaded/list`, and registration-time
366
- `thread/resume`, but do not invoke `turn/start`. The optional Codex
367
- write-attestation probe is the sole exception. It may create at most one
368
- disposable broker-owned thread per attempt, under a bounded write fence with
369
- zero user-thread contact; every created probe thread is archived and confirmed
370
- absent from the loaded set. The probe resolves the pinned model's lowest
371
- advertised effort. Whenever that model/effort pin cannot resolve, it declines
372
- in a zero-spend fail-safe before creating any thread or model turn. Untested
373
- Codex 0.x therefore remains monitor-only. Failed
374
- probes, different majors, and
375
- version evidence that cannot establish a safe major remain provider-local
376
- monitor-only states; the
377
- broker and other provider stay available, and no probe can promote across a
378
- major or unknown version. Different-major guidance
379
- names the observed/tested versions and supported major and requires an Embassy
380
- release supporting the observed major. These checks do not route a user
381
- message or start a model turn. Claude
382
- registry parsing remains strict for every required and consumed field while
383
- ignoring unknown top-level fields; bounded rejected-record counts and an
384
- observed-empty registry are surfaced instead of hidden. A replacement Codex
385
- endpoint generation receives its own fresh monitor-only initialize and
386
- exact-task listing check, while the write gate stays closed until controller
387
- activation. Runtime record, frame, response, identity, generation, and
388
- deadline checks remain mandatory after admission.
332
+ Broker/provider startup owns bounded validation of configured installations and
333
+ exact OS boundaries. Unsafe Embassy-owned or executed artifacts, callback,
334
+ control, or state paths remain startup-fatal; unsafe UID or mode evidence on
335
+ Claude's external sessions registry root quarantines only that provider.
336
+ Runtime does not import the release-owned support matrix or derive authority
337
+ from version metadata. It reports best-effort connector health, route
338
+ staleness, observed metadata, and last safe codes while strict record, frame,
339
+ response, identity, generation, correlation, and deadline checks decide each
340
+ operation. Claude registry parsing remains strict for every required and
341
+ consumed field while ignoring unknown top-level fields; bounded rejected-record
342
+ counts and an observed-empty registry are surfaced instead of hidden. A
343
+ replacement Codex endpoint negotiates its current interface and re-observes the
344
+ exact registered task before re-anchoring. No validation traffic routes a user
345
+ message or starts a model turn.
389
346
 
390
347
  Passive live discovery, a live provider connection, a native message, and an
391
348
  App Server turn are distinct authorization gates. Each requires an explicit
@@ -0,0 +1,117 @@
1
+ import { type ChildProcessWithoutNullStreams, type SpawnOptionsWithoutStdio } from "node:child_process";
2
+ export declare const ACP_MAX_REPLY_BYTES: number;
3
+ type JsonObject = Record<string, unknown>;
4
+ type AcpChild = Pick<ChildProcessWithoutNullStreams, "exitCode" | "kill" | "off" | "once" | "signalCode" | "stderr" | "stdin" | "stdout">;
5
+ export type AcpSpawn = (command: string, args: readonly string[], options: SpawnOptionsWithoutStdio) => AcpChild;
6
+ type AcpLaunchCommon = Readonly<{
7
+ args?: readonly string[];
8
+ cwd?: string;
9
+ }>;
10
+ export type AcpLaunchSpec = (AcpLaunchCommon & Readonly<{
11
+ kind: "npx";
12
+ package: string;
13
+ }>) | (AcpLaunchCommon & Readonly<{
14
+ kind: "binary";
15
+ path: string;
16
+ /** Registry metadata; artifact installation/verification is not this client's job. */
17
+ sha256: string;
18
+ }>) | (AcpLaunchCommon & Readonly<{
19
+ kind: "local-checkout";
20
+ command: string;
21
+ }>);
22
+ export type AcpAgentCapabilities = Readonly<JsonObject>;
23
+ export type AcpConnectionInfo = Readonly<{
24
+ protocolVersion: number;
25
+ agentCapabilities: AcpAgentCapabilities;
26
+ authMethods: readonly unknown[];
27
+ }>;
28
+ export type AcpRpcErrorDetail = Readonly<{
29
+ code: number;
30
+ message: string;
31
+ data?: unknown;
32
+ }>;
33
+ export type AcpPromptReceipt = Readonly<{
34
+ terminalState: "delivered";
35
+ stopReason: "end_turn";
36
+ text: string;
37
+ textTruncated: boolean;
38
+ }> | Readonly<{
39
+ terminalState: "failed";
40
+ stopReason: "max_tokens" | "max_turn_requests" | "refusal";
41
+ text: string;
42
+ textTruncated: boolean;
43
+ }> | Readonly<{
44
+ terminalState: "cancelled";
45
+ stopReason: "cancelled";
46
+ text: string;
47
+ textTruncated: boolean;
48
+ }> | Readonly<{
49
+ terminalState: "failed";
50
+ error: AcpRpcErrorDetail;
51
+ reportOnly: boolean;
52
+ text: string;
53
+ textTruncated: boolean;
54
+ }> | Readonly<{
55
+ /** Process loss cannot prove whether the outstanding prompt completed. */
56
+ terminalState: "unknown";
57
+ text: string;
58
+ textTruncated: boolean;
59
+ }>;
60
+ export type AcpOptionalResult<T> = Readonly<{
61
+ available: true;
62
+ value: T;
63
+ }> | Readonly<{
64
+ available: false;
65
+ reason: "not_advertised" | "method_not_found";
66
+ }>;
67
+ export type AcpSessionOptions = Readonly<{
68
+ sessionId: string;
69
+ cwd: string;
70
+ mcpServers?: readonly unknown[];
71
+ }>;
72
+ export declare class AcpRequestError extends Error {
73
+ readonly detail: AcpRpcErrorDetail;
74
+ constructor(detail: AcpRpcErrorDetail);
75
+ }
76
+ export declare class AcpClient {
77
+ private readonly child;
78
+ private readonly pending;
79
+ private readonly disabledMethods;
80
+ private readonly activePrompts;
81
+ private readonly lines;
82
+ private nextRequestId;
83
+ private writeChain;
84
+ private exited;
85
+ private infoValue;
86
+ private constructor();
87
+ static spawn(launch: AcpLaunchSpec, options?: Readonly<{
88
+ spawn?: AcpSpawn;
89
+ }>): Promise<AcpClient>;
90
+ get connectionInfo(): AcpConnectionInfo;
91
+ newSession(cwd: string, mcpServers?: readonly unknown[]): Promise<Readonly<{
92
+ sessionId: string;
93
+ }>>;
94
+ prompt(sessionId: string, text: string): Promise<AcpPromptReceipt>;
95
+ cancel(sessionId: string): Promise<void>;
96
+ authenticate(methodId: string): Promise<void>;
97
+ listSessions(params?: Readonly<{
98
+ cwd?: string;
99
+ cursor?: string;
100
+ }>): Promise<AcpOptionalResult<unknown>>;
101
+ resumeSession(options: AcpSessionOptions): Promise<AcpOptionalResult<unknown>>;
102
+ loadSession(options: AcpSessionOptions): Promise<AcpOptionalResult<unknown>>;
103
+ close(): void;
104
+ private initialize;
105
+ private optionalRequest;
106
+ private request;
107
+ private notify;
108
+ private write;
109
+ private handleLine;
110
+ private handleInbound;
111
+ private consumeSessionUpdate;
112
+ private handleProcessExit;
113
+ }
114
+ export declare function spawnAcpClient(launch: AcpLaunchSpec, options?: Readonly<{
115
+ spawn?: AcpSpawn;
116
+ }>): Promise<AcpClient>;
117
+ export {};