agent-embassy 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/CONTRIBUTING.md +50 -16
- package/README.md +57 -25
- package/README.zh-CN.md +45 -23
- package/SECURITY.md +68 -48
- package/dist/src/gateway/claude-helper-protocol.d.ts +1 -0
- package/dist/src/gateway/claude-helper-protocol.js +4 -2
- package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +1 -0
- package/dist/src/gateway/claude-helper-supervisor.js +3 -1
- package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
- package/dist/src/gateway/claude-runtime.d.ts +0 -2
- package/dist/src/gateway/claude-runtime.js +6 -17
- package/dist/src/gateway/claude-runtime.js.map +1 -1
- package/dist/src/gateway/cli-copy.d.ts +1 -1
- package/dist/src/gateway/cli-copy.en.d.ts +4 -1
- package/dist/src/gateway/cli-copy.en.js +7 -3
- package/dist/src/gateway/cli-copy.en.js.map +1 -1
- package/dist/src/gateway/cli-copy.js +3 -0
- package/dist/src/gateway/cli-copy.js.map +1 -1
- package/dist/src/gateway/cli-copy.zh-CN.d.ts +4 -1
- package/dist/src/gateway/cli-copy.zh-CN.js +7 -3
- package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/cli.d.ts +2 -5
- package/dist/src/gateway/cli.js +41 -67
- package/dist/src/gateway/cli.js.map +1 -1
- package/dist/src/gateway/codex-app-server.d.ts +2 -8
- package/dist/src/gateway/codex-app-server.js +36 -62
- package/dist/src/gateway/codex-app-server.js.map +1 -1
- package/dist/src/gateway/codex-local-transport.d.ts +4 -10
- package/dist/src/gateway/codex-local-transport.js +13 -16
- package/dist/src/gateway/codex-local-transport.js.map +1 -1
- package/dist/src/gateway/compatibility.d.ts +0 -27
- package/dist/src/gateway/compatibility.js +1 -101
- package/dist/src/gateway/compatibility.js.map +1 -1
- package/dist/src/gateway/config.d.ts +1 -4
- package/dist/src/gateway/config.js +0 -10
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/control.d.ts +2 -21
- package/dist/src/gateway/control.js +7 -36
- 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 +21 -8
- package/dist/src/gateway/dashboard-copy.en.js +40 -27
- package/dist/src/gateway/dashboard-copy.en.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.js +21 -8
- package/dist/src/gateway/dashboard-copy.js.map +1 -1
- package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +21 -8
- package/dist/src/gateway/dashboard-copy.zh-CN.js +40 -27
- package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -1
- package/dist/src/gateway/dashboard-model.d.ts +4 -9
- package/dist/src/gateway/dashboard-model.js +159 -46
- package/dist/src/gateway/dashboard-model.js.map +1 -1
- package/dist/src/gateway/dashboard.js +27 -16
- package/dist/src/gateway/dashboard.js.map +1 -1
- package/dist/src/gateway/instance-lease.d.ts +2 -3
- package/dist/src/gateway/instance-lease.js +17 -140
- package/dist/src/gateway/instance-lease.js.map +1 -1
- package/dist/src/gateway/live-dashboard-app/app.js +62 -63
- package/dist/src/gateway/live-dashboard-command.d.ts +5 -1
- package/dist/src/gateway/live-dashboard-command.js +8 -6
- package/dist/src/gateway/live-dashboard-command.js.map +1 -1
- package/dist/src/gateway/live-dashboard-http.d.ts +0 -4
- package/dist/src/gateway/live-dashboard-http.js +20 -94
- package/dist/src/gateway/live-dashboard-http.js.map +1 -1
- package/dist/src/gateway/live-dashboard-protocol.d.ts +1 -5
- package/dist/src/gateway/live-dashboard-protocol.js +0 -42
- package/dist/src/gateway/live-dashboard-protocol.js.map +1 -1
- package/dist/src/gateway/live-dashboard-server.d.ts +2 -2
- package/dist/src/gateway/live-dashboard-server.js +18 -4
- package/dist/src/gateway/live-dashboard-server.js.map +1 -1
- package/dist/src/gateway/live-dashboard.d.ts +3 -6
- package/dist/src/gateway/live-dashboard.js +6 -42
- package/dist/src/gateway/live-dashboard.js.map +1 -1
- package/dist/src/gateway/progress-watch-machine.d.ts +6 -5
- package/dist/src/gateway/progress-watch-machine.js +6 -6
- package/dist/src/gateway/progress-watch-machine.js.map +1 -1
- package/dist/src/gateway/provenance-envelope.d.ts +1 -0
- package/dist/src/gateway/provenance-envelope.js +11 -4
- package/dist/src/gateway/provenance-envelope.js.map +1 -1
- package/dist/src/gateway/providers.d.ts +2 -21
- package/dist/src/gateway/providers.js +21 -261
- package/dist/src/gateway/providers.js.map +1 -1
- package/dist/src/gateway/server.js +0 -3
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service.d.ts +5 -15
- package/dist/src/gateway/service.js +101 -265
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/store.d.ts +9 -21
- package/dist/src/gateway/store.js +360 -140
- package/dist/src/gateway/store.js.map +1 -1
- package/dist/src/gateway/types.d.ts +1 -6
- package/dist/src/gateway/types.js.map +1 -1
- package/docs/CONFIGURATION.md +102 -0
- package/docs/CONFIGURATION.zh-CN.md +72 -0
- package/docs/DASHBOARD.md +103 -0
- package/docs/DASHBOARD.zh-CN.md +47 -0
- package/docs/DELIVERY.md +84 -0
- package/docs/DELIVERY.zh-CN.md +53 -0
- package/docs/GATEWAY-ARCHITECTURE.md +249 -153
- package/package.json +8 -4
- package/skills/embassy-peer/SKILL.md +25 -10
- package/dist/src/gateway/claude-compatibility-scratch.d.ts +0 -18
- package/dist/src/gateway/claude-compatibility-scratch.js +0 -158
- package/dist/src/gateway/claude-compatibility-scratch.js.map +0 -1
- package/dist/src/gateway/live-dashboard-bootstrap.d.ts +0 -36
- package/dist/src/gateway/live-dashboard-bootstrap.js +0 -176
- package/dist/src/gateway/live-dashboard-bootstrap.js.map +0 -1
- package/docs/DESIGN.md +0 -134
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,47 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.4.0] - 2026-08-11
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- A `STEER:` message can now reach a turn that began before Embassy attached to the task. `turn/steer` requires the exact active turn ID, and the connector only learned one by witnessing that turn start — so a route registered mid-turn, which is precisely the session-recovery case, deferred every steering message until the turn ended on its own. The connector now adopts the exact turn ID from an `item/completed` frame when the resumed route is active, unowned, and has no observed turn, retaining no item content and never interrupting. A message deferred this way retries on the ordinary cadence and enters the turn at the next tool-call boundary.
|
|
14
|
+
- A degraded or unavailable pair renders as a pair with a reason instead of disappearing. The dashboard previously reported that no consent edge existed while durable state held one whose Codex route had gone stale, and an endpoint on a degraded edge was counted as unpaired. Byte-budget truncation is reported as edges omitted rather than edges absent.
|
|
15
|
+
- `REOBSERVATION_REQUIRED` and `CODEX_BOOT_REACTIVATION_SKIPPED` are presented as the single condition they describe, worded to what the broker can prove — the saved route has no current live endpoint proof — with the exact recovery command attached and the evidence of the attempted re-anchor retained. A disabled route no longer claims it will re-anchor on its own.
|
|
16
|
+
- `CONTROL_INVALID_RESPONSE` names client/broker version skew as the likely cause and rebuilding or repointing the client as the fix, rather than directing the operator to restart a healthy broker.
|
|
17
|
+
- `embassy --help` lists `untrack` in both locales. The command has been real and documented since v1.0.0, but was missing from the usage text, so the one way to close a progress watch from the CLI was undiscoverable from the CLI.
|
|
18
|
+
- Progress supervision now keeps at most one active watch on an exact consent edge, lets either the worker or owner close that watch with `DONE:`, and refuses a counterparty `TRACK:` replacement with explicit `untrack` guidance. When an older state contains duplicate watches for one edge, upgrade settles the superseded watches deterministically and records each settlement in history.
|
|
19
|
+
- The security policy, contributor guide, and architecture reference claimed message bodies were memory-only and discarded on restart. That stopped being true when v1.2 made the queue durable: queued and recently delivered bodies are retained under bounded caps in the mode-0600 state file, which is what lets queued mail survive a restart and re-send exactly once. Denying it understated what software running as the same OS user can read.
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
|
|
23
|
+
- The deprecated `claude-codex-gateway` binary alias. v1.0.0 shipped it for exactly one release to carry the rename; four releases on, `embassy` is the single installed command, and it is the only name the README, the architecture doc, the bundled skill, and every error hint have ever printed. Anyone still typing the old name gets an honest "command not found" instead of a silent second spelling.
|
|
24
|
+
- The legacy prototype state-root compatibility read. v1.0.0 also promised one release of bounded-reading the exact pre-rename ownership marker under `~/.local/state/claude-agent-bridge/gateway` and holding that root's controller lock, so an unpublished prototype could not advertise a second Codex peer beside v1. Embassy no longer reads, creates, locks, or mutates anything under that path. The failure mode it covered — two foreground brokers for one login account — is fully held by the fixed kernel-held host lease at `~/.local/state/agent-embassy/.gateway-host.lock`, which is acquired before provider setup, is independent of `EMBASSY_STATE_DIR`, and is reclaimed automatically when a holder crashes. A prototype state directory left on disk is now inert and can simply be deleted.
|
|
25
|
+
|
|
26
|
+
## [1.3.0] - 2026-08-10
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- The live dashboard flags mail that was written but may not have been seen: a `delivered` Codex-to-Claude write older than two minutes whose recipient session is currently unobserved raises a warning pointing at that session's own window. The oldest unconsumed write owns the notice.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- `embassy dashboard --live` now uses the stable direct URL `http://127.0.0.1:41961/` by default, with a per-invocation `--port <n>` override accepting 1024–65535. Multiple windows and browsers can use the same companion (up to four concurrent live views); a port collision fails explicitly, points to `--port`, and never falls back.
|
|
35
|
+
- Claude-bound bodies are written to the recipient's native mailbox immediately after routing and pre-write checks, instead of waiting for an observed-idle gate that a busy Claude session could hold indefinitely. The receipt says exactly that: `delivered` toward Claude means the mailbox write completed, not that a model read or consumed the body.
|
|
36
|
+
- A Claude route that stops appearing in discovery is no longer auto-invalidated; only an actual discovery collision invalidates a selected route. Queued mail stays addressed to its session, and a write to a dead session socket fails fast with its exact safe code.
|
|
37
|
+
|
|
38
|
+
- A v1.2 state file loads cleanly: legacy `hopCount` fields are tolerated and stripped during migration.
|
|
39
|
+
|
|
40
|
+
### Removed
|
|
41
|
+
|
|
42
|
+
- Conversation hop accounting and `EMBASSY_MAX_HOPS`; caller identity, conversation membership, route policy, deadlines, rate limits, and bounded queues remain the delivery safeguards.
|
|
43
|
+
- The live dashboard's one-use fragment token, cookie/session exchange, random instance path, and bootstrap file.
|
|
44
|
+
- The operator compatibility workflow: `EMBASSY_COMPAT_POLICY`, tiered same-major admission, persisted certification evidence, `compat-check`, `compat-certify`, `--with-turn`, and the related LaunchAgent recipes. Compatibility is now automatic and exact-pinned at provider startup, with a fresh monitor-only check for each replacement Codex endpoint generation before writes can activate.
|
|
45
|
+
|
|
46
|
+
### Security
|
|
47
|
+
|
|
48
|
+
- The live dashboard now states its simpler trust boundary directly: it has no local-process or UID authentication and assumes a trusted single-user machine. Exact Host checks remain on every request; exact Origin plus `X-Embassy-Request` remain mandatory on every POST; `OPTIONS` and CORS remain disabled. These request guards constrain browser origins, not local software that can reach or spoof loopback.
|
|
49
|
+
|
|
9
50
|
## [1.2.0] - 2026-08-10
|
|
10
51
|
|
|
11
52
|
Deliverability over everything: a message you send arrives, or tells you loudly why it could not.
|
package/CONTRIBUTING.md
CHANGED
|
@@ -13,14 +13,23 @@ npm ci
|
|
|
13
13
|
npm run check
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
`npm run check` type-checks and runs the deterministic test suite
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
`npm run check` type-checks and runs the deterministic test suite; its `pretest`
|
|
17
|
+
hook rebuilds `dist` first, so the suite always runs against freshly compiled
|
|
18
|
+
output. Routine tests use fake Claude peers, fake App Server transports, and
|
|
19
|
+
temporary directories; they must not contact Anthropic, OpenAI, SSH hosts, live
|
|
20
|
+
provider sockets, or models.
|
|
21
|
+
|
|
22
|
+
`npm run soak` is the separate deliverability gate. It drives a seeded,
|
|
23
|
+
randomized churn of sends through scripted dispatch faults, busy/idle flips,
|
|
24
|
+
clock jumps, and full restarts, asserting that every accepted message settles
|
|
25
|
+
exactly once into an explicit terminal outcome. It is still deterministic and
|
|
26
|
+
offline; run it for any change to routing, the queue, settlement, or restart
|
|
27
|
+
recovery.
|
|
20
28
|
|
|
21
29
|
## Before opening a pull request
|
|
22
30
|
|
|
23
|
-
- Run `npm run check
|
|
31
|
+
- Run `npm run check`, and `npm run soak` as well for any delivery, queue,
|
|
32
|
+
settlement, or restart-recovery change.
|
|
24
33
|
- Add deterministic regression coverage for routing, protocol, persistence,
|
|
25
34
|
permission, process-lifecycle, or redaction changes.
|
|
26
35
|
- Keep the pull request focused and explain every security-boundary change.
|
|
@@ -38,8 +47,11 @@ models.
|
|
|
38
47
|
`codex-*` alias. Never add a thread-ID argument or global task-history scan.
|
|
39
48
|
- Codex-to-Claude sends require a previously selected compatible live session.
|
|
40
49
|
Do not auto-select during send.
|
|
41
|
-
-
|
|
42
|
-
native Codex peer without
|
|
50
|
+
- In the default `paired` inbound mode, a Claude session reaches the registered
|
|
51
|
+
native Codex peer only across an existing pair edge; a sender without one is
|
|
52
|
+
refused `SENDER_NOT_PAIRED` before admission and the refusal is journaled.
|
|
53
|
+
Only `serve --inbound open` admits any exact compatible live same-UID session.
|
|
54
|
+
Neither path makes the inbound session outbound-selected.
|
|
43
55
|
- Claude's session UUID is its stable logical identity. Current names are a
|
|
44
56
|
live index; do not add historical-name routing or PID/socket identity.
|
|
45
57
|
- Preserve current-name collision refusal and endpoint-generation fencing.
|
|
@@ -74,13 +86,17 @@ native. Do not route around a hold or refusal or fabricate a successful receipt.
|
|
|
74
86
|
|
|
75
87
|
### Delivery and state
|
|
76
88
|
|
|
77
|
-
-
|
|
89
|
+
- Reply addresses are transient. Bodies are bounded and durable: the queue and
|
|
90
|
+
the recent-delivery ledger both persist them under bounded retention caps.
|
|
78
91
|
- Queue while a Codex task is busy; do not interrupt an unrelated turn.
|
|
79
92
|
- Distinguish gateway acceptance, transport progress, destination acceptance,
|
|
80
93
|
terminal failure, ambiguity, expiry, and restart abandonment.
|
|
81
94
|
- Never retry an ambiguous provider write. Requeue only a confirmed clean
|
|
82
95
|
deferral that has not crossed an ambiguous mutation boundary.
|
|
83
|
-
- Restarts
|
|
96
|
+
- Restarts keep queued bodies under bounded retention and re-send each exactly
|
|
97
|
+
once when its exact route is re-observed. A message in flight at the moment of
|
|
98
|
+
a crash settles `ambiguous`; a message whose target authority was transient is
|
|
99
|
+
abandoned rather than reconstructed. Restored routes stay stale until exact
|
|
84
100
|
re-observation.
|
|
85
101
|
- Persist native route identifiers only in the closed private binding schema.
|
|
86
102
|
Keep them out of events, snapshots, dashboard rows, logs, errors, and CLI
|
|
@@ -92,13 +108,17 @@ native. Do not route around a hold or refusal or fabricate a successful receipt.
|
|
|
92
108
|
`embassy serve` may use one private same-user control UDS and publish two inert,
|
|
93
109
|
metadata-only static dashboard files. It must not listen on TCP or HTTP. The
|
|
94
110
|
only reviewed exception is the separately invoked foreground
|
|
95
|
-
`embassy dashboard --live` companion, which binds
|
|
96
|
-
port
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
`embassy dashboard --live` companion, which binds exact IPv4 loopback on stable
|
|
112
|
+
port `41961` by default or the validated per-invocation `--port <n>`. It has no
|
|
113
|
+
local-process or UID authentication and therefore assumes a trusted
|
|
114
|
+
single-user machine; exact Host on every request and exact Origin plus
|
|
115
|
+
`X-Embassy-Request` on every POST constrain browser origins, not local
|
|
116
|
+
software. Preserve the direct root URL, multi-window/browser access, collision
|
|
117
|
+
failure with no fallback port, no CORS/`OPTIONS`, and only the reviewed pair,
|
|
118
|
+
unpair, refresh-discovery, and stale-registration-removal mutations—never a
|
|
119
|
+
provider or generic control method. Do not add a wildcard/remote listener,
|
|
120
|
+
external assets, service workers, telemetry, or additional mutation endpoints.
|
|
121
|
+
Keep the public v1 launcher foreground, macOS-only, and local-host-only.
|
|
102
122
|
|
|
103
123
|
## Live validation
|
|
104
124
|
|
|
@@ -120,3 +140,17 @@ macOS caps socket paths at ~104 bytes — keep `TMPDIR` short (CI pins
|
|
|
120
140
|
`TMPDIR=/tmp`; do the same locally if the transport tests hang). On Linux,
|
|
121
141
|
the darwin-only lease and peer-generation tests skip explicitly (the host
|
|
122
142
|
lease spawns macOS's `/usr/bin/lockf`); macOS runs the full suite.
|
|
143
|
+
|
|
144
|
+
## Design honesty rules
|
|
145
|
+
|
|
146
|
+
These outlive any visual era and bind every surface — dashboards, CLI copy,
|
|
147
|
+
site, docs, in both languages:
|
|
148
|
+
|
|
149
|
+
- Progress is never green. Only a terminal success state may look like one.
|
|
150
|
+
- `delivered` means the write completed; `released` is not read; nothing may
|
|
151
|
+
imply a model consumed, understood, or acted on a message.
|
|
152
|
+
- Refusals are not failures: a fail-closed refusal renders as policy, not as
|
|
153
|
+
breakage.
|
|
154
|
+
- The brand accent is never a state color, and state colors are never
|
|
155
|
+
decoration.
|
|
156
|
+
- Every alert pairs its state with the exact next command, copyable.
|
package/README.md
CHANGED
|
@@ -34,6 +34,8 @@ Embassy is built for one person, one macOS account, and agents you already trust
|
|
|
34
34
|
|
|
35
35
|
The first command starts the managed daemon if it is not already running (`restart` and `stop` also exist); the second launches the ChatGPT desktop app pointed at it. `CODEX_APP_SERVER_USE_LOCAL_DAEMON` is not documented by OpenAI; it is observed to work with this Desktop build and may change. Run the daemon command from a normal terminal, never from inside an agent session: Codex tasks inherit the daemon's environment, so a daemon started inside a Claude Code session leaks that session's identity into every task and registration fails closed with `CALLER_IDENTITY_CONFLICT` — fix it from a normal terminal with `codex app-server daemon restart`. The Claude session you select as a destination needs [`crossSessionInbound`](docs/CONFIGURATION.md) enabled — that is Claude Code's own setting, configured in Claude Code, not in Embassy.
|
|
36
36
|
|
|
37
|
+
Provider compatibility needs no separate operator step. `embassy serve` automatically validates the release's exact Claude and Codex version pins and fails closed on unknown versions or required protocol shapes.
|
|
38
|
+
|
|
37
39
|
> **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.
|
|
38
40
|
|
|
39
41
|
### 1. Start Embassy
|
|
@@ -51,7 +53,10 @@ embassy health
|
|
|
51
53
|
embassy status
|
|
52
54
|
```
|
|
53
55
|
|
|
54
|
-
`status` lists `availablePeers` — the live Claude sessions you can select.
|
|
56
|
+
`status` lists `availablePeers` — the live Claude sessions you can select. If
|
|
57
|
+
that list is empty, start a Claude Code session and run
|
|
58
|
+
`embassy refresh-dashboard`, which re-runs Claude discovery; the next `status`
|
|
59
|
+
should show it.
|
|
55
60
|
|
|
56
61
|
### 2. Register the Codex task
|
|
57
62
|
|
|
@@ -61,9 +66,9 @@ Ask your Codex agent to run this as a shell step in its current turn — the com
|
|
|
61
66
|
embassy register-codex --alias codex-reviewer@this-mac
|
|
62
67
|
```
|
|
63
68
|
|
|
64
|
-
You should see `"accepted":true`. The `codex-` prefix is required for Claude discovery. To retire the task later, run `unregister-codex
|
|
69
|
+
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.
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+
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.
|
|
67
72
|
|
|
68
73
|
### 3. Select a Claude destination
|
|
69
74
|
|
|
@@ -73,7 +78,11 @@ Pick one name from `availablePeers`:
|
|
|
73
78
|
embassy select-claude --alias advisor@this-mac
|
|
74
79
|
```
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
Run this from the operator terminal, or from inside the Codex task — either works, because `select-claude` uses an inherited Codex identity when one is present and resolves the sole registered task when one is not. `embassy select-claude --session <uuid>` selects the same session by its native UUID.
|
|
82
|
+
|
|
83
|
+
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.
|
|
84
|
+
|
|
85
|
+
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`.
|
|
77
86
|
|
|
78
87
|
### 4. Send a message
|
|
79
88
|
|
|
@@ -90,6 +99,17 @@ MSG
|
|
|
90
99
|
|
|
91
100
|
You should see a `conv_` conversation token and a `dlv_` delivery token. Because this send requested a reply, Claude's response is automatically routed back to the Codex task. In the other direction, a compatible Claude session uses its native `ListAgents` and `SendMessage` tools to contact `codex-reviewer` — no Embassy command needed.
|
|
92
101
|
|
|
102
|
+
`send-to-codex` is the CLI form of that same direction, for a Claude session that prefers an explicit command. It takes the same flags and reads the body from stdin, and it must run inside the Claude session so it inherits that session's reply identity:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
embassy send-to-codex \
|
|
106
|
+
--from advisor@this-mac \
|
|
107
|
+
--to codex-reviewer@this-mac \
|
|
108
|
+
--expects-reply <<'MSG'
|
|
109
|
+
Summarize the migration risks you found.
|
|
110
|
+
MSG
|
|
111
|
+
```
|
|
112
|
+
|
|
93
113
|
### 5. Follow up
|
|
94
114
|
|
|
95
115
|
Either participant can continue the conversation with `reply`. The initiating
|
|
@@ -110,23 +130,29 @@ alias and begins with an `<embassy-reply-hint>` containing the full conversation
|
|
|
110
130
|
token, the recipient's exact alias, and the corresponding `embassy reply`
|
|
111
131
|
command. Use only that delivered full token and alias; never guess one from a
|
|
112
132
|
suffix or substitute the sender's alias. The CLI still rechecks the caller,
|
|
113
|
-
conversation membership, current route policy,
|
|
133
|
+
conversation membership, and current route policy, so the hint is
|
|
114
134
|
not a permission bypass.
|
|
115
135
|
|
|
116
136
|
The frame is a clear provenance marker, not a cryptographic signature or a
|
|
117
137
|
claim that the body is trustworthy. Embassy neutralizes nested occurrences of
|
|
118
|
-
its
|
|
138
|
+
its reserved framing tags in the untrusted body before provider delivery;
|
|
119
139
|
arbitrary same-user code and all message text remain untrusted input.
|
|
120
140
|
|
|
121
|
-
`EMBASSY_MAX_HOPS` bounds each conversation against runaway reply loops. The initial send is hop 0 and each routed reply increments the count; the default `16` means a normal conversation never notices it. An attempt past the bound is rejected and recorded as `HOP_LIMIT_EXCEEDED`. Do not retry an exhausted conversation token; start a fresh conversation. The accepted range and other bounds are documented in [Configuration](docs/CONFIGURATION.md).
|
|
122
|
-
|
|
123
141
|
### See it live
|
|
124
142
|
|
|
125
|
-
`embassy dashboard --live` opens a five-tab streaming view in the browser
|
|
143
|
+
`embassy dashboard --live` opens a five-tab streaming view in the browser
|
|
144
|
+
(overview, deliveries, routes, activity, diagnostics) at
|
|
145
|
+
`http://127.0.0.1:41961/` by default. To choose another stable port for that
|
|
146
|
+
invocation, run `embassy dashboard --live --port <n>` with an integer from 1024
|
|
147
|
+
through 65535. Up to four concurrent live views — across windows, tabs, or
|
|
148
|
+
browsers — can use that URL while the foreground companion runs; a fifth stream
|
|
149
|
+
is refused until one closes. If the port is occupied, startup fails explicitly,
|
|
150
|
+
points to `--port`, and never falls back to another port. See
|
|
151
|
+
[Dashboard](docs/DASHBOARD.md) for details.
|
|
126
152
|
|
|
127
153
|
The live dashboard can also remove an orphaned Codex registration after an explicit confirmation, but only when the broker proves that the registration is stale and its owning endpoint generation is dead. A current, merely offline, or ambiguous generation is never removable through this recovery action.
|
|
128
154
|
|
|
129
|
-
The broker also publishes mode-0600 static snapshots as `gateway-dashboard.html` and `gateway-dashboard.zh-CN.html`.
|
|
155
|
+
The broker also publishes mode-0600 static snapshots as `gateway-dashboard.html` and `gateway-dashboard.zh-CN.html`. The live dashboard has no login, token, cookie, or per-browser session: it assumes a trusted single-user machine, and local software that can reach or spoof loopback can read it and invoke its bounded actions. The server still requires the exact Host header on every request and the exact Origin plus `X-Embassy-Request` on every POST; it sends no CORS headers and does not accept `OPTIONS`.
|
|
130
156
|
|
|
131
157
|
## How it works
|
|
132
158
|
|
|
@@ -137,7 +163,7 @@ The broker also publishes mode-0600 static snapshots as `gateway-dashboard.html`
|
|
|
137
163
|
│ │
|
|
138
164
|
▼ ▼
|
|
139
165
|
┌──────────────────── Embassy ─────────────────────────────┐
|
|
140
|
-
│ explicit routes │
|
|
166
|
+
│ explicit routes │ Codex busy queue │ receipts │ dashboard │
|
|
141
167
|
└───────────────────────────────────────────────────────────┘
|
|
142
168
|
```
|
|
143
169
|
|
|
@@ -145,7 +171,7 @@ Embassy publishes each registered Codex task into Claude Code's live-session reg
|
|
|
145
171
|
|
|
146
172
|
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.
|
|
147
173
|
|
|
148
|
-
|
|
174
|
+
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.
|
|
149
175
|
|
|
150
176
|
Immediately before the provider write, Embassy gives every routed body one
|
|
151
177
|
broker-owned cross-session marker containing the verified sender alias and a
|
|
@@ -153,7 +179,7 @@ recipient reply hint. The full conversation token travels only in the
|
|
|
153
179
|
initiator's accepted result and the recipient's transient message payload; it
|
|
154
180
|
never enters the dashboard, public snapshot, journal, receipt, or log.
|
|
155
181
|
|
|
156
|
-
Every settled message produces a receipt. `delivered` means terminal provider
|
|
182
|
+
Every settled message produces a receipt. `delivered` means the direction's terminal provider boundary was observed — toward Codex, the App Server accepted the turn; toward Claude, the native mailbox write completed. Neither means the model read or acted on it. `unconfirmed` and `ambiguous` mean the required evidence is missing; they are terminal states and never auto-retried. See [Delivery](docs/DELIVERY.md) for the full semantics.
|
|
157
183
|
|
|
158
184
|
## The vocabulary
|
|
159
185
|
|
|
@@ -183,21 +209,28 @@ Codex tasks can then be prompted with `$embassy-peer`; Claude Code discovers it
|
|
|
183
209
|
| --- | --- | --- |
|
|
184
210
|
| `serve` | operator | Start the foreground broker and dashboard |
|
|
185
211
|
| `health` / `status` | operator | Check liveness and inspect the sanitized snapshot |
|
|
186
|
-
| `refresh-dashboard` | operator |
|
|
187
|
-
| `dashboard --live [--lang en\|zh-CN]` | operator | Start the live dashboard companion with bounded route-consent actions; requires a running `embassy serve` |
|
|
212
|
+
| `refresh-dashboard` | operator | Re-run Claude session discovery and regenerate both static dashboard files |
|
|
213
|
+
| `dashboard --live [--lang en\|zh-CN] [--port <n>]` | operator | Start the live dashboard companion with bounded route-consent actions; requires a running `embassy serve` |
|
|
188
214
|
| `delivery-status` | either provider | Read one delivery tracker with `embassy delivery-status --token dlv_<token>` |
|
|
189
215
|
| `wait-delivery` | either provider | Wait for that tracker to settle, up to the delivery deadline |
|
|
190
|
-
| `
|
|
191
|
-
| `
|
|
192
|
-
| `
|
|
193
|
-
| `
|
|
194
|
-
| `send-to-
|
|
195
|
-
| `
|
|
216
|
+
| `untrack` | either provider | Close one active progress watch: `embassy untrack --conversation conv_<token>` |
|
|
217
|
+
| `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 |
|
|
218
|
+
| `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 |
|
|
219
|
+
| `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 |
|
|
220
|
+
| `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>]` |
|
|
221
|
+
| `send-to-codex` | Claude session | Same flags and stdin body, using the inherited native reply identity |
|
|
222
|
+
| `reply` | conversation-token holder | Continue an active conversation with the full token returned to the initiator or delivered in the recipient's broker-owned reply hint: `--conversation conv_<token> --alias <your-alias>`, body on stdin, optional `--track [--idle-minutes <n>]` |
|
|
223
|
+
|
|
224
|
+
`--track` opens a progress watch over the conversation; `--idle-minutes <n>`
|
|
225
|
+
sets how long the watched thread may idle before the watch reports a stall
|
|
226
|
+
(1–1440, default 5, rejected without `--track`). Close a watch with `untrack`,
|
|
227
|
+
or by replying with a leading `DONE:`. See [Delivery](docs/DELIVERY.md).
|
|
196
228
|
|
|
197
229
|
## Safety in one minute
|
|
198
230
|
|
|
199
|
-
- **Local
|
|
231
|
+
- **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.
|
|
200
232
|
- **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.
|
|
233
|
+
- **Compatibility is automatic and exact-pinned.** Broker/provider startup validates only the release's reviewed versions and protocol shapes. Every replacement App Server endpoint generation gets a fresh monitor-only check before route re-anchoring; unknown versions and malformed generations stay write-disabled.
|
|
201
234
|
- **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.
|
|
202
235
|
- **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.
|
|
203
236
|
- **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.
|
|
@@ -206,7 +239,7 @@ See [SECURITY.md](SECURITY.md) for the full boundary and vulnerability-reporting
|
|
|
206
239
|
|
|
207
240
|
## What Embassy is not
|
|
208
241
|
|
|
209
|
-
- **Not an orchestrator.** It does not spawn agents or manage their work.
|
|
242
|
+
- **Not an orchestrator.** It does not spawn agents or manage their work. Codex-bound ordinary messages start one turn apiece as the task becomes idle; Claude-bound messages enter Claude's mailbox without waiting for idle.
|
|
210
243
|
- **Not a hosted service.** Personal, same-machine, same-OS-account software.
|
|
211
244
|
- **Not a permission bypass — but it is a new path.** Neither agent gains a tool it did not already have, and Embassy grants, relaxes, and answers nothing. It does, however, connect two products that previously could not exchange text at all. That path is the product; treat it with the respect you would give any new input channel.
|
|
212
245
|
- **Not official.** Not affiliated with or endorsed by Anthropic or OpenAI.
|
|
@@ -215,11 +248,10 @@ See [SECURITY.md](SECURITY.md) for the full boundary and vulnerability-reporting
|
|
|
215
248
|
|
|
216
249
|
| Document | What it covers |
|
|
217
250
|
| --- | --- |
|
|
218
|
-
| [Architecture](docs/GATEWAY-ARCHITECTURE.md) | The full design: topology, adapters, control plane, threat model,
|
|
251
|
+
| [Architecture](docs/GATEWAY-ARCHITECTURE.md) | The full design: topology, adapters, control plane, threat model, and the paired-consent inbound model |
|
|
219
252
|
| [Delivery](docs/DELIVERY.md) | Delivery semantics, tokens, settlement states, and retry rules |
|
|
220
253
|
| [Configuration](docs/CONFIGURATION.md) | Environment variables, compatibility contract, and addressing rules |
|
|
221
254
|
| [Dashboard](docs/DASHBOARD.md) | Static and live dashboard setup, security model, and mutation actions |
|
|
222
|
-
| [Migration](docs/MIGRATION.md) | Migrating from the prototype gateway |
|
|
223
255
|
| [Security policy](SECURITY.md) | How to report a vulnerability, and the boundary in depth |
|
|
224
256
|
| [Contributing](CONTRIBUTING.md) | Where changes go, and how to run the deterministic suite |
|
|
225
257
|
| [Changelog](CHANGELOG.md) | What each release contains |
|
package/README.zh-CN.md
CHANGED
|
@@ -34,6 +34,8 @@ Embassy 专为单人、单一 macOS 账户以及你已信任以该用户身份
|
|
|
34
34
|
|
|
35
35
|
第一条命令在托管守护进程未运行时启动它(也提供 `restart` 与 `stop` 子命令);第二条以指向该守护进程的方式启动 ChatGPT 桌面应用。`CODEX_APP_SERVER_USE_LOCAL_DAEMON` 未见于 OpenAI 文档;它经验证适用于当前 Desktop 构建,未来可能变化。请在普通终端中运行守护进程命令,切勿在代理会话内运行:Codex 任务会继承守护进程的环境,因此在 Claude Code 会话内启动的守护进程会把该会话的身份泄漏到每个任务中,注册将以 `CALLER_IDENTITY_CONFLICT` 关闭失败——请在普通终端执行 `codex app-server daemon restart` 修复。你选择作为目的地的 Claude 会话需要启用 [`crossSessionInbound`](docs/CONFIGURATION.zh-CN.md)——这是 Claude Code 自身的设置,在 Claude Code 中配置,而非在 Embassy 中。
|
|
36
36
|
|
|
37
|
+
提供方兼容性无需操作员执行额外步骤。`embassy serve` 会自动验证本发布版精确固定的 Claude 与 Codex 版本,并在遇到未知版本或必需协议结构时关闭失败。
|
|
38
|
+
|
|
37
39
|
> **已知限制:** 仅当 Desktop 使用托管独立 App Server 时,Embassy 才能访问 Codex 任务。在该模式下,任务目前无法连接 Desktop 内置的应用内浏览器(`@Browser` 可加载但无法附着)。将 Desktop 切换回其默认的私有 App Server 会立即恢复内置浏览器——但会使这些任务对 Embassy 不可达。目前未发现其他能力回退,但这并非穷尽的能力对比测试。
|
|
38
40
|
|
|
39
41
|
### 1. 启动 Embassy
|
|
@@ -51,7 +53,7 @@ embassy health
|
|
|
51
53
|
embassy status
|
|
52
54
|
```
|
|
53
55
|
|
|
54
|
-
`status` 列出 `availablePeers`——你可以选择的在线 Claude
|
|
56
|
+
`status` 列出 `availablePeers`——你可以选择的在线 Claude 会话。如果该列表为空,请先启动一个 Claude Code 会话,然后运行 `embassy refresh-dashboard`——它会重新执行 Claude 发现;下一次 `status` 应该就能看到该会话。
|
|
55
57
|
|
|
56
58
|
### 2. 注册 Codex 任务
|
|
57
59
|
|
|
@@ -61,9 +63,9 @@ embassy status
|
|
|
61
63
|
embassy register-codex --alias codex-reviewer@this-mac
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
你应看到 `"accepted":true`。`codex-` 前缀是 Claude
|
|
66
|
+
你应看到 `"accepted":true`。`codex-` 前缀是 Claude 发现所必需的。之后若要注销该任务,请在同一个任务内运行 `embassy unregister-codex --alias codex-reviewer@this-mac`。
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
托管 App Server 端点代际变更与 `embassy serve` 重启都会使用精确任务重新激活。每个替代端点都从仅监控状态开始;只有重新初始化并通过 `thread/loaded/list` 恰好一次找到字节级一致的原任务时,才能重新锚定别名,而且在激活这个精确代际前写入始终保持封锁。因此,正常的代理重启不需要手动重新注册。端点不兼容,或精确任务缺失、重复,都会使路由以 `REOBSERVATION_REQUIRED` 保持陈旧;该任务恢复可观察后,请从精确任务内再次运行 `embassy register-codex --alias codex-reviewer@this-mac`,且不要先注销。Embassy 绝不会按别名改投其他任务,也不会重放写入结果不明确的正文。
|
|
67
69
|
|
|
68
70
|
### 3. 选择 Claude 目的地
|
|
69
71
|
|
|
@@ -73,7 +75,11 @@ embassy register-codex --alias codex-reviewer@this-mac
|
|
|
73
75
|
embassy select-claude --alias advisor@this-mac
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
这条命令可以在操作员终端中运行,也可以在 Codex 任务内运行——两者都可以,因为 `select-claude` 在存在继承的 Codex 身份时会使用它,不存在时则解析唯一一个已注册任务。`embassy select-claude --session <uuid>` 通过原生 UUID 选择同一个会话。
|
|
79
|
+
|
|
80
|
+
你应看到 `"accepted":true`。注册和选择共同构成一个配对——现在这个 Claude 会话和这个 Codex 任务可以通过 Embassy 交换消息。
|
|
81
|
+
|
|
82
|
+
当你注册了多个任务后,请用 `embassy pair --claude <name@host> --codex <codex-alias>` 显式指定两端;多个配对可以并存。与 `select-claude` 不同,`pair` 和 `unpair` 必须**在 Codex 任务内部**运行,就像 `register-codex` 一样。在普通终端中它们会以 `CODEX_IDENTITY_REQUIRED` 失败,在 Claude 会话内则以 `CALLER_IDENTITY_CONFLICT` 失败。
|
|
77
83
|
|
|
78
84
|
### 4. 发送消息
|
|
79
85
|
|
|
@@ -90,6 +96,17 @@ MSG
|
|
|
90
96
|
|
|
91
97
|
你应看到一个 `conv_` 对话令牌和一个 `dlv_` 投递令牌。因为此次发送请求了回复,Claude 的响应会被自动路由回 Codex 任务。反方向上,兼容的 Claude 会话使用其原生的 `ListAgents` 和 `SendMessage` 工具联系 `codex-reviewer`——无需 Embassy 命令。
|
|
92
98
|
|
|
99
|
+
`send-to-codex` 是同一方向的 CLI 形式,供偏好显式命令的 Claude 会话使用。它接受相同的标志并从标准输入读取正文,并且必须在该 Claude 会话内运行,才能继承该会话的回复标识:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
embassy send-to-codex \
|
|
103
|
+
--from advisor@this-mac \
|
|
104
|
+
--to codex-reviewer@this-mac \
|
|
105
|
+
--expects-reply <<'MSG'
|
|
106
|
+
Summarize the migration risks you found.
|
|
107
|
+
MSG
|
|
108
|
+
```
|
|
109
|
+
|
|
93
110
|
### 5. 后续跟进
|
|
94
111
|
|
|
95
112
|
任何持有完整 `conv_` 令牌的对话参与方都可以用 `reply` 继续仍然有效的对话。初始发送方从 Embassy 命令结果中获得令牌;接收方则从入站消息的来源封装中获得同一个完整令牌和回复提示:
|
|
@@ -102,17 +119,17 @@ Please expand on the migration risk.
|
|
|
102
119
|
MSG
|
|
103
120
|
```
|
|
104
121
|
|
|
105
|
-
Embassy 会在实际写入提供方之前,为双向路由消息添加一个由代理控制的 `<cross-session-message>` 来源封装。封装标出已经验证的发送方别名,其首个 `<embassy-reply-hint>` 元素包含完整对话令牌、接收方自己的精确别名和可直接使用的 `embassy reply` 命令。朝向 Codex 时,外层标记本身还带有 `conversation="conv_..."`;朝向 Claude 时,为符合 Claude Code
|
|
122
|
+
Embassy 会在实际写入提供方之前,为双向路由消息添加一个由代理控制的 `<cross-session-message>` 来源封装。封装标出已经验证的发送方别名,其首个 `<embassy-reply-hint>` 元素包含完整对话令牌、接收方自己的精确别名和可直接使用的 `embassy reply` 命令。朝向 Codex 时,外层标记本身还带有 `conversation="conv_..."`;朝向 Claude 时,为符合 Claude Code 的规范解析格式,完整令牌和回复提示位于封装正文中,而不作为外层属性。请使用收到的完整令牌,切勿猜测或重构它。令牌本身不授予路由权限:每次回复仍会重新检查调用方身份、对话参与关系和实时路由。
|
|
106
123
|
|
|
107
|
-
|
|
124
|
+
该封装是清晰的来源标记,既不是密码学签名,也不表示正文可信。在写入提供方之前,Embassy 会中和不可信正文中嵌套出现的自有保留封装标签;以你的 OS 用户身份运行的任意代码和所有消息文本,始终都是不可信输入。
|
|
108
125
|
|
|
109
126
|
### 实时查看
|
|
110
127
|
|
|
111
|
-
`embassy dashboard --live`
|
|
128
|
+
`embassy dashboard --live` 在浏览器中打开一个五选项卡流式视图(总览、投递、路由、活动、诊断),默认地址为 `http://127.0.0.1:41961/`。如需为本次启动选择另一个稳定端口,请运行 `embassy dashboard --live --port <n>`,其中整数范围为 1024 到 65535。当前台组件运行时,该 URL 最多支持四个并发实时视图(可分布在窗口、标签页或浏览器中);在其中一个关闭前,第五条流会被拒绝。若端口已被占用,启动会明确失败并提示使用 `--port`,不会回退到其他端口。详见[仪表盘](docs/DASHBOARD.zh-CN.md)。
|
|
112
129
|
|
|
113
130
|
实时仪表盘也可以在明确确认后移除孤立的 Codex 注册,但仅限代理已经证明该注册陈旧且其所属端点代际已失效的情况。当前、仅离线或代际状态不明确的注册绝不能通过此恢复操作移除。
|
|
114
131
|
|
|
115
|
-
代理还会以 mode 0600 发布静态快照 `gateway-dashboard.html` 与 `gateway-dashboard.zh-CN.html
|
|
132
|
+
代理还会以 mode 0600 发布静态快照 `gateway-dashboard.html` 与 `gateway-dashboard.zh-CN.html`。实时仪表盘没有登录、令牌、Cookie 或逐浏览器会话:它假定这是一台可信的单用户机器;能够访问或伪造 loopback 的本地软件可以读取仪表盘并调用其有限操作。服务器仍会对每个请求要求精确的 Host 头,并对每个 POST 要求精确的 Origin 与 `X-Embassy-Request`;它不发送 CORS 头,也不接受 `OPTIONS`。
|
|
116
133
|
|
|
117
134
|
## 工作原理
|
|
118
135
|
|
|
@@ -123,7 +140,7 @@ Embassy 会在实际写入提供方之前,为双向路由消息添加一个由
|
|
|
123
140
|
│ │
|
|
124
141
|
▼ ▼
|
|
125
142
|
┌──────────────────── Embassy ─────────────────────────────┐
|
|
126
|
-
│ 显式路由 │ 忙碌排队 │ 回执 │ 仪表盘
|
|
143
|
+
│ 显式路由 │ Codex 忙碌排队 │ 回执 │ 仪表盘 │
|
|
127
144
|
└───────────────────────────────────────────────────────────┘
|
|
128
145
|
```
|
|
129
146
|
|
|
@@ -131,11 +148,13 @@ Embassy 将每个已注册的 Codex 任务以各自的 `codex-*` 对等方身份
|
|
|
131
148
|
|
|
132
149
|
配对是一个 Claude 会话与一个 Codex 任务之间的单一显式权限边,而配对关系是多对多的:一个 Claude 会话可以与多个 Codex 任务建立边,一个 Codex 任务也可以与多个 Claude 会话建立边(默认上限 128 个配对)。每条边都通过 `pair` 或单任务简写 `select-claude` 显式创建;一切都不会被隐式推断。没有边时,发送方以 `SENDER_NOT_PAIRED` 终局结算。`embassy serve --inbound open` 是显式的退出选项,可恢复任意会话入站。
|
|
133
150
|
|
|
134
|
-
|
|
151
|
+
投递时机因方向而异。通过路由与写前检查后,所有朝向 Claude 的正文都会立即写入 Claude 的原生邮箱,无论观测到 Claude 正繁忙还是空闲。`transport_written` 记录这次邮箱写入,并且就是朝向 Claude 的终局 `delivered` 边界;它不表示 Claude 已读取或消费正文。朝向 Codex 的普通正文则在任务忙碌时排队,并在任务空闲后启动轮次。仅在 Claude→Codex 方向,正文以精确 `STEER:` 开头的消息可以在 App Server 的下一个工具调用边界进入当前轮次;若该边界不可用,消息会回到普通队列。
|
|
135
152
|
|
|
136
153
|
每条被路由的消息在接收方看到时都位于 Embassy 生成的跨会话来源封装中,其中包含已验证的发送方别名、完整 `conv_` 令牌和面向该接收方的回复提示。来源封装是模型可见的结构性提示,并非密码学身份认证;消息正文始终应被视为不可信输入。
|
|
137
154
|
|
|
138
|
-
|
|
155
|
+
完整对话令牌只出现在初始发送方收到的命令结果,以及接收方那次临时的消息载荷中;它绝不会进入仪表盘、公开快照、账簿、回执或日志。
|
|
156
|
+
|
|
157
|
+
每条已结算的消息都会产生回执。`delivered` 表示观测到了该方向的终端提供方边界——朝向 Codex,意味着 App Server 接受了该轮次;朝向 Claude,意味着原生邮箱写入完成。两者都不意味着模型已读取或执行。`unconfirmed` 和 `ambiguous` 表示所需证据缺失;它们是终态,从不自动重试。完整语义详见[投递](docs/DELIVERY.zh-CN.md)。
|
|
139
158
|
|
|
140
159
|
## 核心术语
|
|
141
160
|
|
|
@@ -165,21 +184,25 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
|
|
|
165
184
|
| --- | --- | --- |
|
|
166
185
|
| `serve` | 操作员 | 启动前台代理和仪表盘 |
|
|
167
186
|
| `health` / `status` | 操作员 | 检查存活状态并查看脱敏快照 |
|
|
168
|
-
| `refresh-dashboard` | 操作员 |
|
|
169
|
-
| `dashboard --live [--lang en\|zh-CN]` | 操作员 | 启动带有限路由同意操作的实时仪表盘组件;需要 `embassy serve` 正在运行 |
|
|
187
|
+
| `refresh-dashboard` | 操作员 | 重新执行 Claude 会话发现,并重新生成两个静态仪表盘文件 |
|
|
188
|
+
| `dashboard --live [--lang en\|zh-CN] [--port <n>]` | 操作员 | 启动带有限路由同意操作的实时仪表盘组件;需要 `embassy serve` 正在运行 |
|
|
170
189
|
| `delivery-status` | 任一提供方 | 使用 `embassy delivery-status --token dlv_<token>` 读取单条投递跟踪器 |
|
|
171
190
|
| `wait-delivery` | 任一提供方 | 等待该跟踪器结算,直至投递截止时间 |
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `send-to-
|
|
177
|
-
| `
|
|
191
|
+
| `untrack` | 任一提供方 | 关闭一个活跃的进度监视:`embassy untrack --conversation conv_<token>` |
|
|
192
|
+
| `register-codex` / `unregister-codex` | Codex 任务 | 通告或注销该任务;两者都需要 `--alias <codex-alias>`,而 `embassy register-codex --alias codex-successor@this-mac --succeeds codex-reviewer@this-mac` 会将注册转交给另一个任务 |
|
|
193
|
+
| `pair` / `unpair` | Codex 任务 | 显式指定两端来添加或移除一条 Claude↔Codex 边:`embassy pair --claude advisor@this-mac --codex codex-reviewer@this-mac`。与 `register-codex` 一样,它必须在 Codex 任务内部运行 |
|
|
194
|
+
| `select-claude` / `unselect-claude` | 操作员或 Codex 任务 | `pair`/`unpair` 的单任务简写,接受 `--alias <name@host>` 或 `--session <uuid>`:仅在 Codex 端无歧义(继承标识或唯一已注册任务)时解析,否则以关闭状态失败 |
|
|
195
|
+
| `send-to-claude` | 已注册的 Codex 任务 | 向已配对的 Claude 会话发送一条有界消息:`--from <codex-alias> --to <claude-alias>`,正文从标准输入读取,可选 `--expects-reply` 与 `--track [--idle-minutes <n>]` |
|
|
196
|
+
| `send-to-codex` | Claude 会话 | 标志与正文输入方式相同,使用继承的原生回复标识 |
|
|
197
|
+
| `reply` | 对话令牌持有方 | 使用初始发送时返回或随入站来源提示收到的完整令牌继续一个活跃对话:`--conversation conv_<token> --alias <你的别名>`,正文从标准输入读取,可选 `--track [--idle-minutes <n>]`;调用方、对话参与关系和路由会重新检查 |
|
|
198
|
+
|
|
199
|
+
`--track` 会为该对话开启一个进度监视;`--idle-minutes <n>` 设置被监视线程在监视报告停滞前可以空闲多久(1–1440,默认 5,未加 `--track` 时会被拒绝)。用 `untrack` 关闭监视,或在回复正文开头使用 `DONE:` 关闭。详见[投递](docs/DELIVERY.zh-CN.md)。
|
|
178
200
|
|
|
179
201
|
## 一分钟了解安全性
|
|
180
202
|
|
|
181
|
-
-
|
|
203
|
+
- **本地代理,稳定的 loopback 仪表盘。** `embassy serve` 仅监听私有 Unix 域套接字,不发起任何提供商 API 调用。可选启用的 `embassy dashboard --live` 组件是一个独立进程,也是 Embassy 能创建的唯一监听器;它精确绑定 `127.0.0.1`,默认使用稳定端口 `41961`(也可为本次启动传入 `--port <n>`)。它是在可信单用户机器上有意不设身份认证的本地 HTTP;Host、Origin 与哨兵检查约束浏览器来源的请求,但不认证本地进程或 OS 用户。
|
|
182
204
|
- **同 UID 隔离,而非身份认证。** 调用者身份继承自本地进程环境。路由所有权和生成号检查能减少误操作,但不是对已以你的 OS 用户身份运行的代码的防御。
|
|
205
|
+
- **兼容性检查自动执行并精确固定版本。** 代理/提供方启动只验证本发布版已审查的版本和协议结构。每个替代 App Server 端点代际都必须先通过新的仅监控检查才能重新锚定路由;未知版本与结构异常的代际保持禁止写入。
|
|
183
206
|
- **来源标记是提示,不是签名。** Embassy 在提供方写入边界生成跨会话来源封装,让接收模型能够区分代理路由消息及其已验证发送方别名;这不是密码学证明,也不会把不可信正文变成可信指令。
|
|
184
207
|
- **原生权限保持原生。** Embassy 不发送任何 Codex 审批或沙盒覆盖,也不应答任何审批请求。`crossSessionInbound` 仍是 Claude 自身的控制机制;Embassy 无法覆盖它。
|
|
185
208
|
- **消息体有界保存,属于你。** 消息体以有界保留策略持久化在 broker 的私有 mode-0600 状态中,让台账能够展示邮件本身;排队中的邮件在 broker 重启后幸存并恰好重发一次。原始提供方帧仍仅存于内存。静态仪表盘文件保持仅元数据;实时仪表盘展示保留的正文。
|
|
@@ -188,7 +211,7 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
|
|
|
188
211
|
|
|
189
212
|
## Embassy 不是什么
|
|
190
213
|
|
|
191
|
-
- **不是编排器。**
|
|
214
|
+
- **不是编排器。** 它不生成代理,也不管理它们的工作。朝向 Codex 的普通消息会在任务空闲时逐条启动轮次;朝向 Claude 的消息无需等待空闲,直接进入 Claude 的邮箱。
|
|
192
215
|
- **不是托管服务。** 面向个人的、同机同账户软件。
|
|
193
216
|
- **不是权限绕过——但它是一条新路径。** 两个代理都不会获得它原本没有的工具,Embassy 也不授予、放宽或应答任何权限。然而,它确实连接了两个此前无法交换文本的产品。这条路径就是产品本身;请以对待任何新输入通道应有的审慎来看待它。
|
|
194
217
|
- **不是官方产品。** 与 Anthropic 或 OpenAI 没有任何关联或背书关系。
|
|
@@ -197,11 +220,10 @@ cp -R "$(npm root -g)/agent-embassy/skills/embassy-peer" ~/.claude/skills/
|
|
|
197
220
|
|
|
198
221
|
| 文档 | 涵盖内容 |
|
|
199
222
|
| --- | --- |
|
|
200
|
-
| [架构](docs/GATEWAY-ARCHITECTURE.md) |
|
|
223
|
+
| [架构](docs/GATEWAY-ARCHITECTURE.md) | 完整设计:拓扑、适配器、控制平面、威胁模型,以及基于配对同意的入站模型 |
|
|
201
224
|
| [投递](docs/DELIVERY.zh-CN.md) | 投递语义、令牌、结算状态与重试规则 |
|
|
202
225
|
| [配置](docs/CONFIGURATION.zh-CN.md) | 环境变量、兼容性约定与寻址规则 |
|
|
203
226
|
| [仪表盘](docs/DASHBOARD.zh-CN.md) | 静态与实时仪表盘设置、安全模型与变更操作 |
|
|
204
|
-
| [迁移](docs/MIGRATION.zh-CN.md) | 从原型网关迁移 |
|
|
205
227
|
| [安全策略](SECURITY.md) | 如何报告漏洞,以及详细的安全边界 |
|
|
206
228
|
| [贡献指南](CONTRIBUTING.md) | 变更的归属位置,以及如何运行确定性测试套件 |
|
|
207
229
|
| [变更日志](CHANGELOG.md) | 每个版本包含的内容 |
|