agent-embassy 4.2.0 → 4.3.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 +9 -0
- package/README.md +27 -16
- package/SECURITY.md +25 -11
- package/dist/src/gateway/broker-control.js +9 -2
- package/dist/src/gateway/broker-control.js.map +1 -1
- package/dist/src/gateway/broker.d.ts +14 -0
- package/dist/src/gateway/broker.js +6 -2
- package/dist/src/gateway/broker.js.map +1 -1
- package/dist/src/gateway/codex-discovery.d.ts +42 -0
- package/dist/src/gateway/codex-discovery.js +604 -0
- package/dist/src/gateway/codex-discovery.js.map +1 -0
- package/dist/src/gateway/codex-stateless-transport.d.ts +1 -1
- package/dist/src/gateway/codex-stateless-transport.js +126 -18
- package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
- package/dist/src/gateway/core-cli.js +8 -5
- package/dist/src/gateway/core-cli.js.map +1 -1
- package/dist/src/gateway/core-version.d.ts +1 -1
- package/dist/src/gateway/core-version.js +1 -1
- package/dist/src/gateway/endpoint-directory.d.ts +12 -0
- package/dist/src/gateway/endpoint-directory.js +94 -4
- package/dist/src/gateway/endpoint-directory.js.map +1 -1
- package/dist/src/gateway/ledger-codec.js +11 -6
- package/dist/src/gateway/ledger-codec.js.map +1 -1
- package/dist/src/gateway/ledger.d.ts +2 -1
- package/dist/src/gateway/ledger.js +5 -2
- package/dist/src/gateway/ledger.js.map +1 -1
- package/dist/src/gateway/local-control.d.ts +1 -1
- package/dist/src/gateway/local-control.js +1 -1
- package/dist/src/gateway/owned-state.d.ts +1 -0
- package/dist/src/gateway/owned-state.js +1 -1
- package/dist/src/gateway/owned-state.js.map +1 -1
- package/dist/src/gateway/runtime.d.ts +4 -2
- package/dist/src/gateway/runtime.js +18 -5
- package/dist/src/gateway/runtime.js.map +1 -1
- package/dist/src/gateway/tui.d.ts +1 -0
- package/dist/src/gateway/tui.js +6 -3
- package/dist/src/gateway/tui.js.map +1 -1
- package/docs/CONFIGURATION.md +57 -17
- package/docs/DELIVERY.md +18 -6
- package/docs/GATEWAY-ARCHITECTURE.md +43 -21
- package/package.json +2 -2
- package/skills/embassy-peer/SKILL.md +6 -6
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Product contract
|
|
4
4
|
|
|
5
|
-
Embassy connects live Claude Code sessions and
|
|
5
|
+
Embassy connects live Claude Code sessions and Codex CLI agents by
|
|
6
6
|
name, locally or across directly configured SSH gateways. All four provider
|
|
7
7
|
pairs are supported. Sending is one `embassy send` command; receiving wakes the
|
|
8
8
|
target through its native interface. A receipt proves delivery machinery, not
|
|
@@ -31,7 +31,7 @@ Claude/Codex CLI
|
|
|
31
31
|
remote broker ledger
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
There is one broker per login user and host. The broker owns one schema-
|
|
34
|
+
There is one broker per login user and host. The broker owns one schema-7 JSON
|
|
35
35
|
document and one private control socket. It does not listen on a network port.
|
|
36
36
|
launchd may supervise the same foreground `serve` entry point.
|
|
37
37
|
|
|
@@ -52,13 +52,18 @@ and restart. Retirement retains a bounded private hash of the native binding
|
|
|
52
52
|
to fence immediate re-enrollment. After that evidence is evicted, a later
|
|
53
53
|
registration gets a new ID; old replies and remote references cannot revive.
|
|
54
54
|
|
|
55
|
-
Codex endpoints are
|
|
56
|
-
|
|
55
|
+
Codex endpoints are discovered as bounded metadata from the same-user App
|
|
56
|
+
Server daemon. The immutable native thread UUID is their private identity;
|
|
57
|
+
native names are mutable lookup aliases for automatic rows; explicitly registered
|
|
58
|
+
rows keep the operator's alias. Only the 20 most recent roots are
|
|
59
|
+
automatically listed, without publishing native IDs. Explicit registration by a
|
|
60
|
+
task that inherits the exact UUID remains a fallback and reconciles with the
|
|
61
|
+
same endpoint row. Claude endpoints are discovered by exact session UUID and recorded
|
|
57
62
|
when a Claude caller or target is resolved. A same-UUID rename updates one
|
|
58
|
-
endpoint; a different identity never inherits work.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
endpoint; a different identity never inherits work. Live endpoints may share
|
|
64
|
+
a display name, but name resolution then refuses with `PEER_ALIAS_COLLISION`.
|
|
65
|
+
An exact user-supplied Claude UUID can disambiguate Claude selection without
|
|
66
|
+
making UUIDs public output.
|
|
62
67
|
Partial discovery cannot clear an observed collision. The bounded collision
|
|
63
68
|
proof sets fail closed on overflow until a complete scan; exact UUID lookup
|
|
64
69
|
remains available. Operator retirement can use `--endpoint <public-id>` when
|
|
@@ -69,8 +74,10 @@ and any local cache are bounded and memory-only; neither grants lookup or write
|
|
|
69
74
|
authority. Remote endpoint rows contain opaque IDs and aliases, not native
|
|
70
75
|
handles.
|
|
71
76
|
|
|
72
|
-
`refresh` runs local Claude discovery and all configured catalog
|
|
73
|
-
in parallel.
|
|
77
|
+
`refresh` runs local Claude and Codex discovery and all configured catalog
|
|
78
|
+
observations in parallel. Codex discovery also follows bounded daemon metadata
|
|
79
|
+
events and reconnects with a fresh bounded enumeration after daemon loss. Each
|
|
80
|
+
successful node observation replaces its rows and timestamp.
|
|
74
81
|
A failure retains the last timestamped rows with `PEER_TUNNEL_UNAVAILABLE`.
|
|
75
82
|
The status projection reads this cache without network I/O and caps the combined
|
|
76
83
|
remote display at 128 rows, reporting truncation. Routing still uses the owner
|
|
@@ -132,8 +139,8 @@ guessing. The live host lease is checked before a transaction, before
|
|
|
132
139
|
persistence, and immediately before rename.
|
|
133
140
|
|
|
134
141
|
No-op transactions write nothing. Unsupported or corrupt state refuses before
|
|
135
|
-
mutation.
|
|
136
|
-
the
|
|
142
|
+
mutation. Valid schema 6 reads forward with all existing rows retained; writes use 7.
|
|
143
|
+
The only added field is the private retention marker. Schema ≤5 still needs a reset.
|
|
137
144
|
|
|
138
145
|
## Coordinator
|
|
139
146
|
|
|
@@ -172,10 +179,24 @@ native socket is still used for receive and reply wake-up.
|
|
|
172
179
|
|
|
173
180
|
### Codex operation
|
|
174
181
|
|
|
182
|
+
One bounded App Server observer enumerates the recency top 20 unarchived root threads,
|
|
183
|
+
combines loaded-state and lifecycle/name events, and retains only the metadata
|
|
184
|
+
used by the endpoint directory. It drains unwanted notifications and
|
|
185
|
+
unsubscribes from threads it is not actively brokering so observation does not
|
|
186
|
+
pin them in memory. Window aging preserves pending identities and drops unused
|
|
187
|
+
automatic rows without settlement or retirement. Explicit registrations remain
|
|
188
|
+
retained across restart. `thread/closed` marks a root dormant, not retired.
|
|
189
|
+
Archive/delete evidence and explicit retirement use existing settlement; operator
|
|
190
|
+
retirement evidence suppresses rediscovery. Identity storage stays bounded.
|
|
191
|
+
|
|
175
192
|
The Codex adapter creates a fresh App Server connection per operation, checks
|
|
176
|
-
the current interface, resumes the exact
|
|
177
|
-
excluded, and starts one turn carrying the
|
|
178
|
-
|
|
193
|
+
the current interface, resumes the exact known
|
|
194
|
+
thread with history excluded when needed, and starts one turn carrying the
|
|
195
|
+
bounded batch only after an immediate idle-status check. Returned history and
|
|
196
|
+
model output are not retained or forwarded. While active, ordinary messages
|
|
197
|
+
remain in Embassy's ledger. A competing client can start a turn between the
|
|
198
|
+
idle check and write; the indistinguishable App Server response means the
|
|
199
|
+
receipt proves acceptance and lifetime, not that Embassy started a fresh turn.
|
|
179
200
|
|
|
180
201
|
An accepted operation remains tracked until its terminal lifetime notification.
|
|
181
202
|
An exact leading Claude-to-Codex `STEER:` may use that same accepted
|
|
@@ -218,7 +239,7 @@ reset.
|
|
|
218
239
|
|
|
219
240
|
## Local control and CLI
|
|
220
241
|
|
|
221
|
-
The private control protocol is version
|
|
242
|
+
The private control protocol is version 6. Each connection carries one bounded
|
|
222
243
|
JSON request and one closed JSON response over the expected private Unix
|
|
223
244
|
socket. A mutating request whose reply is lost after write reports
|
|
224
245
|
`CONTROL_WRITE_OUTCOME_AMBIGUOUS`; the CLI does not retry it.
|
|
@@ -236,8 +257,9 @@ serve service peer-stdio
|
|
|
236
257
|
`send` accepts exactly one of `--to` and `--conversation`; it has no `--from`.
|
|
237
258
|
Human `status` is a rendering of the same closed body-free JSON shape. Its
|
|
238
259
|
health word describes control/ledger health, local route rows expose their last
|
|
239
|
-
native operation, and
|
|
240
|
-
|
|
260
|
+
native operation, and Codex rows expose busy, waiting, idle, dormant or unknown
|
|
261
|
+
status, without parent references or registration-origin labels. The federation section
|
|
262
|
+
exposes only the last bounded catalog observation. `health` is a control-path probe. `check` creates temporary
|
|
241
263
|
private loopback endpoints and uses the real ledger/coordinator/receipt path,
|
|
242
264
|
then retires them; no provider or model is contacted. It is not a
|
|
243
265
|
provider-readiness test.
|
|
@@ -261,7 +283,7 @@ Startup order is ownership-sensitive:
|
|
|
261
283
|
1. load the private node inventory, or derive a transient first-boot default,
|
|
262
284
|
and load configuration;
|
|
263
285
|
2. acquire the fixed host-wide kernel lease;
|
|
264
|
-
3. open and validate schema-
|
|
286
|
+
3. open and validate schema-7 state without changing the inventory;
|
|
265
287
|
4. atomically install and reload the default inventory when first boot needs
|
|
266
288
|
one;
|
|
267
289
|
5. construct native and SSH adapters;
|
|
@@ -282,8 +304,8 @@ model interrupt.
|
|
|
282
304
|
|
|
283
305
|
| Surface | Version | Compatibility policy |
|
|
284
306
|
|---|---:|---|
|
|
285
|
-
| Private state (`gateway-state.json`) |
|
|
286
|
-
| Private control (CLI ↔ broker) |
|
|
307
|
+
| Private state (`gateway-state.json`) | 7 | Reset only; older and unknown schemas refuse without mutation |
|
|
308
|
+
| Private control (CLI ↔ broker) | 6 | CLI and broker must come from one installation |
|
|
287
309
|
| Federation (`peer-stdio`) | 3 | Exact version and host handshake; no compatibility mode |
|
|
288
310
|
| Consumed Claude peer protocol | 1 | Incompatible records are rejected in isolation |
|
|
289
311
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-embassy",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "A local gateway for bidirectional messaging between Claude Code sessions and Codex tasks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"probe:codex-remote": "tsx scripts/probe-codex-remote.ts",
|
|
58
58
|
"pretest": "npm run build",
|
|
59
59
|
"start": "node dist/src/gateway/core-cli.js serve",
|
|
60
|
-
"test": "tsx --test test/*.test.ts",
|
|
60
|
+
"test": "tsx --test --test-timeout=120000 test/*.test.ts",
|
|
61
61
|
"typecheck": "tsc -p tsconfig.json",
|
|
62
62
|
"soak": "tsx --test test/soak/core-soak.test.ts"
|
|
63
63
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: embassy-peer
|
|
3
|
-
description:
|
|
3
|
+
description: Find named Claude/Codex sessions, use fallback Codex registration when needed, and send or reply through an installed Embassy gateway. Use for agent-to-agent messaging and receipts, not provider configuration or direct socket access.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Embassy Peer Gateway
|
|
@@ -15,9 +15,9 @@ Healthy means the Embassy control socket and ledger respond; a passing check exe
|
|
|
15
15
|
|
|
16
16
|
A client reads the private state directory and optional `nodes.json`, then connects to its private Unix socket. A sandboxed task needs read/write access to that directory. Follow denied-access guidance; do not relocate state or start a second broker to bypass it. If access was expected, verify `EMBASSY_STATE_DIR` names this user's own directory.
|
|
17
17
|
|
|
18
|
-
To receive in Codex, use its managed standalone installation with its App Server daemon already running under the same macOS login; merely having a `codex` executable on PATH is insufficient, and Embassy does not install or start that daemon.
|
|
18
|
+
To receive in Codex, use its managed standalone installation with its App Server daemon already running under the same macOS login; merely having a `codex` executable on PATH is insufficient, and Embassy does not install or start that daemon. The 20 most recent unarchived Codex roots appear automatically in `embassy status`, including dormant roots that resume on delivery. Sub-agents are excluded; explicit fallback registrations remain retained outside that window, including after a broker restart.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
For a harness without native daemon integration, ask the live Codex CLI task to execute this fallback registration through its shell tool; an ordinary terminal lacks that task's inherited identity:
|
|
21
21
|
|
|
22
22
|
```sh
|
|
23
23
|
embassy register-codex --alias codex-reviewer@your-host
|
|
@@ -25,7 +25,7 @@ embassy register-codex --alias codex-reviewer@your-host
|
|
|
25
25
|
|
|
26
26
|
Read `host` from the `nodes.json` that first boot created and use it as every local `@host` suffix; replace `your-host` with that exact value, not the example `studio` unless you explicitly chose it. `nodes.json` lives inside `EMBASSY_STATE_DIR` when set; otherwise it lives in `$XDG_STATE_HOME/agent-embassy`, or `~/.local/state/agent-embassy` when `XDG_STATE_HOME` is unset; every client shell must use the same state-directory configuration captured by the installed service.
|
|
27
27
|
|
|
28
|
-
The CLI reads inherited `CODEX_THREAD_ID`; never supply, print, or guess it. Registration performs no provider I/O. Claude callers are identified from inherited `CLAUDE_CODE_MESSAGING_SOCKET` and live registry evidence on first use; there is no separate Claude registration command.
|
|
28
|
+
The CLI reads inherited `CODEX_THREAD_ID`; never supply, print, or guess it. Discovery and fallback registration produce the same endpoint kind and identity. Registration performs no provider I/O. Claude callers are identified from inherited `CLAUDE_CODE_MESSAGING_SOCKET` and live registry evidence on first use; there is no separate Claude registration command.
|
|
29
29
|
|
|
30
30
|
For `CALLER_IDENTITY_CONFLICT`, strip only the unwanted identity at the call site: `env -u CLAUDE_CODE_MESSAGING_SOCKET embassy …` for Codex, or `env -u CODEX_THREAD_ID embassy …` for Claude. Do not read either value or restart the broker to repair the caller's environment.
|
|
31
31
|
|
|
@@ -33,7 +33,7 @@ Ellipses (`...` or `…`) stand for the intended command and arguments; `conv_RE
|
|
|
33
33
|
|
|
34
34
|
## Address, send, reply
|
|
35
35
|
|
|
36
|
-
`embassy status --json` returns metadata under `.result`: owned routes, recent delivery states, retirements and last operation outcomes. It includes no bodies or native IDs. Human terminal rendering is not a parser contract. `embassy refresh` performs live Claude discovery; run it only when authorized. Named sends resolve directly, including over configured SSH, without requiring prior catalog polling at the destination.
|
|
36
|
+
`embassy status --json` returns metadata under `.result`: owned routes, recent delivery states, retirements and last operation outcomes. It includes no bodies or native IDs. Human terminal rendering is not a parser contract. `embassy refresh` performs live Claude and Codex discovery; run it only when authorized. Named sends resolve directly, including over configured SSH, without requiring prior catalog polling at the destination.
|
|
37
37
|
|
|
38
38
|
Names are lookup indexes, not identities. Stop on `PEER_ALIAS_COLLISION` rather than choosing a session. A Claude UUID may be used as `--to` only when user-supplied; do not discover or echo native IDs. A renamed or replaced endpoint never inherits work addressed to another identity.
|
|
39
39
|
|
|
@@ -84,7 +84,7 @@ The waiter is bounded by the deadline plus three seconds. A found result has `st
|
|
|
84
84
|
|
|
85
85
|
Do not resend an ambiguous or unconfirmed delivery. `CONTROL_WRITE_OUTCOME_AMBIGUOUS` also means the operation may have applied: inspect status, do not repeat it. Explicit replies are new messages, not automatic forwarding of Codex output.
|
|
86
86
|
|
|
87
|
-
Receiving is native: Claude's socket mailbox or Codex's accepted turn. Agents do not poll inbound mail. Ordinary Codex work queues while the task is busy; a bounded backlog is packed into one wake with separate identities, provenance, and receipts. Capacity and deadlines still apply.
|
|
87
|
+
Receiving is native: Claude's socket mailbox or Codex's accepted turn. Agents do not poll inbound mail. Ordinary Codex work queues while the task is observed busy; a bounded backlog is packed into one wake with separate identities, provenance, and receipts. A competing client can start a turn after Embassy's idle check, causing an ordinary message to enter that turn as steer text; the provider response cannot distinguish the race, so the receipt proves acceptance and lifetime, not fresh-turn creation. Capacity and deadlines still apply.
|
|
88
88
|
|
|
89
89
|
Only when explicitly asked to steer, a Claude sender may start the body with exact `STEER:` for an active Codex recipient. Embassy uses that exact turn's same-session capability at the next tool-call boundary, never interrupts, and keeps the three-steer cap and global kill switch. A cleanly unavailable boundary leaves the message queued. Never synthesize STEER, answer approvals, or change a sandbox to force delivery.
|
|
90
90
|
|