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.
- package/CHANGELOG.md +31 -0
- package/README.md +9 -9
- package/README.zh-CN.md +9 -9
- package/SECURITY.md +34 -77
- package/dist/src/gateway/acp-client.d.ts +117 -0
- package/dist/src/gateway/acp-client.js +382 -0
- package/dist/src/gateway/acp-client.js.map +1 -0
- package/dist/src/gateway/acp-provider.d.ts +65 -0
- package/dist/src/gateway/acp-provider.js +163 -0
- package/dist/src/gateway/acp-provider.js.map +1 -0
- package/dist/src/gateway/claude-helper-protocol.d.ts +3 -1
- package/dist/src/gateway/claude-helper-protocol.js +15 -5
- package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +3 -1
- package/dist/src/gateway/claude-helper-supervisor.js +16 -2
- package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
- package/dist/src/gateway/claude-helper.js +4 -3
- package/dist/src/gateway/claude-helper.js.map +1 -1
- package/dist/src/gateway/claude-peer.d.ts +1 -1
- package/dist/src/gateway/claude-peer.js +11 -13
- package/dist/src/gateway/claude-peer.js.map +1 -1
- package/dist/src/gateway/claude-runtime.d.ts +0 -20
- package/dist/src/gateway/claude-runtime.js +6 -127
- package/dist/src/gateway/claude-runtime.js.map +1 -1
- package/dist/src/gateway/cli-copy.en.d.ts +1 -1
- package/dist/src/gateway/cli-copy.en.js +2 -2
- package/dist/src/gateway/cli-copy.zh-CN.d.ts +1 -1
- package/dist/src/gateway/cli-copy.zh-CN.js +2 -2
- package/dist/src/gateway/cli.d.ts +1 -1
- package/dist/src/gateway/cli.js +26 -5
- package/dist/src/gateway/cli.js.map +1 -1
- package/dist/src/gateway/codex-app-server.d.ts +5 -74
- package/dist/src/gateway/codex-app-server.js +9 -597
- package/dist/src/gateway/codex-app-server.js.map +1 -1
- package/dist/src/gateway/codex-local-transport.d.ts +8 -26
- package/dist/src/gateway/codex-local-transport.js +26 -76
- package/dist/src/gateway/codex-local-transport.js.map +1 -1
- package/dist/src/gateway/compatibility.d.ts +6 -66
- package/dist/src/gateway/compatibility.js +14 -296
- package/dist/src/gateway/compatibility.js.map +1 -1
- package/dist/src/gateway/config.d.ts +9 -0
- package/dist/src/gateway/config.js +6 -2
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/control.d.ts +16 -1
- package/dist/src/gateway/control.js +89 -57
- package/dist/src/gateway/control.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.d.ts +1 -1
- package/dist/src/gateway/dashboard-copy.en.d.ts +14 -44
- package/dist/src/gateway/dashboard-copy.en.js +37 -67
- package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.js +14 -44
- package/dist/src/gateway/dashboard-copy.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +14 -44
- package/dist/src/gateway/dashboard-copy.zh-CN.js +37 -67
- package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/dashboard-model.d.ts +38 -76
- package/dist/src/gateway/dashboard-model.js +158 -256
- package/dist/src/gateway/dashboard-model.js.map +1 -1
- package/dist/src/gateway/dashboard.d.ts +0 -3
- package/dist/src/gateway/dashboard.js +75 -76
- package/dist/src/gateway/dashboard.js.map +1 -1
- package/dist/src/gateway/deepseek-detect.d.ts +7 -6
- package/dist/src/gateway/deepseek-detect.js +31 -115
- package/dist/src/gateway/deepseek-detect.js.map +1 -1
- package/dist/src/gateway/live-dashboard-app/app.js +166 -621
- package/dist/src/gateway/live-dashboard-command.js +2 -4
- package/dist/src/gateway/live-dashboard-command.js.map +1 -1
- package/dist/src/gateway/live-dashboard-http.d.ts +1 -2
- package/dist/src/gateway/live-dashboard-http.js +14 -15
- package/dist/src/gateway/live-dashboard-http.js.map +1 -1
- package/dist/src/gateway/progress-watch-machine.d.ts +1 -4
- package/dist/src/gateway/progress-watch-machine.js.map +1 -1
- package/dist/src/gateway/provenance-envelope.d.ts +3 -2
- package/dist/src/gateway/provenance-envelope.js +44 -11
- package/dist/src/gateway/provenance-envelope.js.map +1 -1
- package/dist/src/gateway/providers.d.ts +12 -84
- package/dist/src/gateway/providers.js +69 -806
- package/dist/src/gateway/providers.js.map +1 -1
- package/dist/src/gateway/server.d.ts +8 -9
- package/dist/src/gateway/server.js +51 -99
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service.d.ts +22 -49
- package/dist/src/gateway/service.js +196 -432
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/store.d.ts +20 -29
- package/dist/src/gateway/store.js +281 -827
- package/dist/src/gateway/store.js.map +1 -1
- package/dist/src/gateway/types.d.ts +55 -55
- package/dist/src/gateway/types.js +49 -91
- package/dist/src/gateway/types.js.map +1 -1
- package/docs/CONFIGURATION.md +11 -10
- package/docs/CONFIGURATION.zh-CN.md +10 -9
- package/docs/DASHBOARD.md +4 -38
- package/docs/DASHBOARD.zh-CN.md +4 -2
- package/docs/GATEWAY-ARCHITECTURE.md +61 -119
- package/package.json +1 -1
- 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)
|
|
13
13
|
[](package.json)
|
|
14
14
|
|
|
15
|
-
Your [Claude Code](https://code.claude.com) sessions
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
|
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` |
|
|
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
|
|
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)
|
|
13
13
|
[](package.json)
|
|
14
14
|
|
|
15
|
-
你的 [Claude Code](https://code.claude.com)
|
|
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
|
-
**前置要求:** macOS
|
|
28
|
+
**前置要求:** macOS 与 Node.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
|
-
|
|
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`
|
|
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
|
-
|
|
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
|
|
149
|
+
Embassy 将每个已注册的 Codex 任务以各自的 `codex-*` 对等方身份发布到 Claude Code 的实时会话注册表中。Claude 会话通过 `ListAgents` 发现这些任务;Codex 使用托管 App Server。DeepSeek 与 Grok Build 是启动时登记的 ACP 路由,其自有子进程与单个路由本地会话会在首次投递时惰性启动。
|
|
150
150
|
|
|
151
|
-
|
|
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` |
|
|
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
|
-
-
|
|
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
|
|
101
|
-
|
|
102
|
-
path, ownership, protocol,
|
|
103
|
-
|
|
104
|
-
for an unsafe or lost singleton lease, corrupt controller state, or unsafe
|
|
105
|
-
OS
|
|
106
|
-
|
|
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
|
|
176
|
-
|
|
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
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
|
203
|
-
|
|
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.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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 {};
|