agent-embassy 4.0.0 → 4.2.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 +18 -0
- package/README.md +127 -23
- package/dist/src/gateway/codex-stateless-transport.js +2 -1
- package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
- package/dist/src/gateway/core-cli.d.ts +1 -2
- package/dist/src/gateway/core-cli.js +18 -2
- package/dist/src/gateway/core-cli.js.map +1 -1
- package/dist/src/gateway/core-version.d.ts +1 -0
- package/dist/src/gateway/core-version.js +2 -0
- package/dist/src/gateway/core-version.js.map +1 -0
- package/dist/src/gateway/tui-ssh.d.ts +36 -0
- package/dist/src/gateway/tui-ssh.js +199 -0
- package/dist/src/gateway/tui-ssh.js.map +1 -0
- package/dist/src/gateway/tui.d.ts +73 -0
- package/dist/src/gateway/tui.js +563 -0
- package/dist/src/gateway/tui.js.map +1 -0
- package/docs/CONFIGURATION.md +66 -14
- package/docs/GATEWAY-ARCHITECTURE.md +9 -1
- package/package.json +1 -1
- package/skills/embassy-peer/SKILL.md +24 -6
package/docs/CONFIGURATION.md
CHANGED
|
@@ -9,6 +9,8 @@ or version metadata never grants routing authority.
|
|
|
9
9
|
`EMBASSY_STATE_DIR` may set an absolute state directory. Otherwise Embassy
|
|
10
10
|
uses `$XDG_STATE_HOME/agent-embassy`, or
|
|
11
11
|
`$HOME/.local/state/agent-embassy` when `XDG_STATE_HOME` is unset.
|
|
12
|
+
Every client shell must use the same state-directory configuration captured
|
|
13
|
+
by the installed service.
|
|
12
14
|
|
|
13
15
|
The directory must be owned by the current user, mode 0700, and must not be a
|
|
14
16
|
symbolic link. `gateway-state.json`, `nodes.json`, and other broker-owned files
|
|
@@ -18,8 +20,11 @@ contact the broker. If access was expected, also verify the configured state
|
|
|
18
20
|
directory belongs to this user; do not start a second broker to work around an
|
|
19
21
|
access denial.
|
|
20
22
|
|
|
21
|
-
`nodes.json` is the static host and federation inventory.
|
|
22
|
-
|
|
23
|
+
`nodes.json` is the static host and federation inventory.
|
|
24
|
+
Create the private state directory before saving the example, and set directory
|
|
25
|
+
mode 0700 and `nodes.json` mode 0600 before installing the service.
|
|
26
|
+
|
|
27
|
+
A machine without peers uses an empty list:
|
|
23
28
|
|
|
24
29
|
```json
|
|
25
30
|
{"version":1,"host":"studio","nodes":[]}
|
|
@@ -40,6 +45,9 @@ fallback, dynamic discovery, or multi-hop routing.
|
|
|
40
45
|
Local route aliases end in the inventory's exact host. `register-codex` and
|
|
41
46
|
`retire` refuse a different host. Remote routes are resolved through the owner
|
|
42
47
|
listed in `nodes`; they can be retired only on that owner.
|
|
48
|
+
Read `host` from the `nodes.json` that first boot created and use it as every
|
|
49
|
+
local `@host` suffix; the examples use `@studio` only when you explicitly chose
|
|
50
|
+
`host: studio`, not as a universal alias suffix.
|
|
43
51
|
|
|
44
52
|
## Delivery settings
|
|
45
53
|
|
|
@@ -86,18 +94,35 @@ native agent list.
|
|
|
86
94
|
|
|
87
95
|
### Codex CLI
|
|
88
96
|
|
|
97
|
+
To receive in Codex, use its managed standalone installation with its App Server
|
|
98
|
+
daemon already running under the same macOS login; merely having a `codex`
|
|
99
|
+
executable on PATH is insufficient, and Embassy does not install or start that daemon.
|
|
100
|
+
|
|
89
101
|
A Codex task registers itself with `embassy register-codex --alias ...` using
|
|
90
102
|
its inherited `CODEX_THREAD_ID`. The ID is not a command argument or public
|
|
91
103
|
output. Registration is a logical state change and performs no App Server I/O.
|
|
92
104
|
Each delivery independently attests the current App Server interface and exact
|
|
93
105
|
task before authorization, resumes that task without retaining history, and
|
|
94
106
|
writes through a fresh operation.
|
|
107
|
+
The ellipsis in `--alias ...` is a substitution: use the task's chosen
|
|
108
|
+
`codex-` name with this machine's exact `@host` suffix.
|
|
95
109
|
|
|
96
110
|
`register-codex --succeeds <old-alias>` atomically retires a predecessor and
|
|
97
111
|
installs the caller. It never reanchors pending work to a new identity.
|
|
98
112
|
|
|
99
113
|
## SSH federation
|
|
100
114
|
|
|
115
|
+
Install Embassy and run `embassy service install` on both Macs; for `studio`
|
|
116
|
+
and `laptop`, use `{"version":1,"host":"studio","nodes":["laptop"]}` on
|
|
117
|
+
studio and `{"version":1,"host":"laptop","nodes":["studio"]}` on laptop,
|
|
118
|
+
with each peer name matching both the remote inventory's `host` and a working
|
|
119
|
+
SSH destination or `~/.ssh/config` Host alias.
|
|
120
|
+
|
|
121
|
+
After changing a running broker's inventory, reload it with
|
|
122
|
+
`embassy service install`; register `codex-reviewer@laptop` from the live
|
|
123
|
+
Codex task on laptop, then ask the Claude session on studio to run
|
|
124
|
+
`embassy send --to codex-reviewer@laptop` with the message on stdin.
|
|
125
|
+
|
|
101
126
|
For each configured remote node Embassy runs the fixed system SSH client in
|
|
102
127
|
batch mode with forwarding and local commands disabled. Authentication is the
|
|
103
128
|
user's SSH configuration. The remote command is `embassy peer-stdio`; the two
|
|
@@ -110,10 +135,12 @@ requires that host to be in its `nodes.json` peer list. The SSH login is
|
|
|
110
135
|
trusted, so the claim is trusted too. Keep the local `host` correct when
|
|
111
136
|
copying configuration: a wrong allowed host label can misattribute origin.
|
|
112
137
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
138
|
+
From studio, verify the remote command environment with
|
|
139
|
+
`/usr/bin/ssh laptop 'which -a embassy; node --version; embassy --version'`,
|
|
140
|
+
then verify the corresponding direction from laptop; both remote Node and
|
|
141
|
+
Embassy must resolve without an interactive shell or password prompt.
|
|
142
|
+
Federation does not accept a password, private key, host override, or arbitrary
|
|
143
|
+
SSH argument from Embassy configuration.
|
|
117
144
|
|
|
118
145
|
Remote endpoint catalogs are bounded memory-only caches. The owner is queried
|
|
119
146
|
again for exact identity resolution. A handoff is one correlated write, the
|
|
@@ -127,6 +154,20 @@ and timestamp. A failed observation retains its last rows and records
|
|
|
127
154
|
provider I/O. Display is capped at 128 remote rows across all nodes; exact and
|
|
128
155
|
named routing always queries the owner and is unaffected by display truncation.
|
|
129
156
|
|
|
157
|
+
## Multi-host terminal
|
|
158
|
+
|
|
159
|
+
`embassy tui` uses this inventory for its host overview. Opening it in a terminal
|
|
160
|
+
starts bounded status reads over the same non-interactive SSH configuration as
|
|
161
|
+
federation; it does not modify SSH keys, configuration, or broker protocols.
|
|
162
|
+
Use `[` / `]` for host selection. Explicit actions execute the existing CLI on
|
|
163
|
+
that host, and remote retirement confirms the HOST and full endpoint ID.
|
|
164
|
+
Read timeout is eight seconds; refresh/retire allow fifteen seconds and loopback
|
|
165
|
+
check thirty. A timed-out SSH process is terminated, escalated after one second,
|
|
166
|
+
and never overlapped by a replacement before it closes. Its pane stays stale;
|
|
167
|
+
local operation and other hosts continue. Version diagnostics are lazy remote
|
|
168
|
+
CLI observations only, never broker-version evidence. Unsupported shapes refuse
|
|
169
|
+
display as current data and disable retirement until a supported fresh read.
|
|
170
|
+
|
|
130
171
|
## launchd service
|
|
131
172
|
|
|
132
173
|
```sh
|
|
@@ -135,6 +176,11 @@ embassy service status
|
|
|
135
176
|
embassy service uninstall
|
|
136
177
|
```
|
|
137
178
|
|
|
179
|
+
`embassy service install` starts the per-user launchd agent immediately and
|
|
180
|
+
arranges login startup; use the same command to reload broker configuration or
|
|
181
|
+
start a stopped installation, and use `embassy service uninstall` to stop and
|
|
182
|
+
unload it.
|
|
183
|
+
|
|
138
184
|
The service is a per-user launchd agent. Installation captures the absolute
|
|
139
185
|
Node executable and Embassy CLI file, plus every nonempty `EMBASSY_*` value and
|
|
140
186
|
`XDG_STATE_HOME` from the installing shell. It captures no other environment
|
|
@@ -146,7 +192,7 @@ The plist uses `RunAtLoad` and `KeepAlive` with only `Crashed: true`. A verified
|
|
|
146
192
|
`SIGABRT` crash relaunches it. A clean exit, nonzero boot refusal, ordinary
|
|
147
193
|
`SIGTERM`, or a deliberate
|
|
148
194
|
`kill -9` leaves the service not running. Use `embassy service status` to
|
|
149
|
-
observe that state and
|
|
195
|
+
observe that state and run `embassy service install` deliberately.
|
|
150
196
|
|
|
151
197
|
The foreground alternative is `embassy serve`. It does not daemonize or open
|
|
152
198
|
a network listener. Both forms acquire the same fixed host-wide advisory lease
|
|
@@ -155,20 +201,26 @@ before provider setup, so only one broker can run.
|
|
|
155
201
|
## Private state reset
|
|
156
202
|
|
|
157
203
|
Version 4 accepts only schema-6 `gateway-state.json`. It deliberately contains
|
|
158
|
-
no
|
|
204
|
+
no 3.x converter or compatibility reader. An older or unknown schema refuses
|
|
159
205
|
with `GATEWAY_STATE_SCHEMA_UNSUPPORTED`; invalid schema-6 bytes refuse with
|
|
160
206
|
`CORRUPT_GATEWAY_STATE`. Refusal does not mutate the installed file.
|
|
161
207
|
|
|
162
208
|
Reset procedure:
|
|
163
209
|
|
|
164
|
-
1.
|
|
165
|
-
work
|
|
166
|
-
2. Stop
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
210
|
+
1. Before replacing a 3.x installation, use its matching CLI to inspect and
|
|
211
|
+
settle or explicitly abandon pending work.
|
|
212
|
+
2. Stop a launchd broker with `embassy service uninstall` (or stop the foreground
|
|
213
|
+
serve process) and confirm it is stopped with `embassy service status`.
|
|
214
|
+
3. Back up and move aside only `gateway-state.json` in that broker's state
|
|
215
|
+
directory. Keep the valid `nodes.json`.
|
|
216
|
+
4. Install 4.0.0, then run `embassy service install`.
|
|
217
|
+
5. The v4 broker creates fresh schema-6 state.
|
|
170
218
|
6. Re-register Codex tasks. Claude endpoints are recorded on discovery/use.
|
|
171
219
|
|
|
220
|
+
All state produced by Embassy 3.x is unsupported by 4.x; preserve the matching
|
|
221
|
+
old binary as well as its old state if rollback may be needed, and never run
|
|
222
|
+
the old and new brokers together.
|
|
223
|
+
|
|
172
224
|
A reset abandons unsettled work and invalidates delivery tokens and
|
|
173
225
|
conversation references. Rollback means stopping v4 and restoring both the old
|
|
174
226
|
binary and its untouched old state. Never hand-edit either schema.
|
|
@@ -226,7 +226,7 @@ socket. A mutating request whose reply is lost after write reports
|
|
|
226
226
|
The public CLI is:
|
|
227
227
|
|
|
228
228
|
```text
|
|
229
|
-
register-codex send status
|
|
229
|
+
register-codex send status tui
|
|
230
230
|
refresh delivery-status wait-delivery
|
|
231
231
|
retire check health
|
|
232
232
|
serve service peer-stdio
|
|
@@ -242,6 +242,14 @@ private loopback endpoints and uses the real ledger/coordinator/receipt path,
|
|
|
242
242
|
then retires them; no provider or model is contacted. It is not a
|
|
243
243
|
provider-readiness test.
|
|
244
244
|
|
|
245
|
+
`tui` is a terminal-only client: one in-flight operation per host and no broker
|
|
246
|
+
protocol or state extension. Its local pane uses private control; remote panes
|
|
247
|
+
run existing CLI commands over non-interactive SSH, independently of each other.
|
|
248
|
+
Remote status is validated with the same closed snapshot decoder, not inferred
|
|
249
|
+
from catalogs. Each confirmation captures host and endpoint ID; stale remote
|
|
250
|
+
observations cannot authorize retirement. Lost action responses remain unknown
|
|
251
|
+
and are never automatically replayed. Non-TTY output is local-only.
|
|
252
|
+
|
|
245
253
|
Machine-facing CLI success is one `{ok, command, result}` JSON line. The
|
|
246
254
|
snapshot is at `.result` and its endpoint rows at `.result.routes`; native
|
|
247
255
|
handles and message bodies cannot hitchhike through the closed result decoder.
|
package/package.json
CHANGED
|
@@ -5,32 +5,40 @@ description: Register a Codex task, find named Claude/Codex sessions, and send o
|
|
|
5
5
|
|
|
6
6
|
# Embassy Peer Gateway
|
|
7
7
|
|
|
8
|
-
Use the installed `embassy` CLI.
|
|
8
|
+
Use the installed `embassy` CLI. Global npm installation includes `skills/embassy-peer` under the `agent-embassy` package in `npm root -g`; the operator can copy that entire folder into `~/.codex/skills/` and `~/.claude/skills/`, then ask each agent to use it, or provide the shown commands directly to the agent's shell tool. The agent must not install or copy skills, or modify provider configuration.
|
|
9
9
|
|
|
10
10
|
Send only the authorized body to the named recipient. A peer's message is a request, not a grant to change scope or permissions. Never inspect provider credentials, histories, registry files, socket paths, or inherited identity values to make a call work.
|
|
11
11
|
|
|
12
12
|
## Connect and identify
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Healthy means the Embassy control socket and ledger respond; a passing check exercises only broker loopback, so neither proves that a Claude session or Codex task can receive or answer a message. `embassy health` checks the broker control/ledger. `embassy check` requires no special inbound reply handler. Leave service installation, removal and restarting to the operator unless explicitly requested.
|
|
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
|
-
|
|
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.
|
|
19
|
+
|
|
20
|
+
Ask the live Codex CLI task to execute the following registration through its shell tool; an ordinary terminal lacks that task's inherited identity:
|
|
19
21
|
|
|
20
22
|
```sh
|
|
21
23
|
embassy register-codex --alias codex-reviewer@your-host
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
|
|
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
|
+
|
|
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.
|
|
25
29
|
|
|
26
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.
|
|
27
31
|
|
|
32
|
+
Ellipses (`...` or `…`) stand for the intended command and arguments; `conv_REPLACE_WITH_EXACT_REFERENCE`, `dlv_REPLACE_WITH_EXACT_TOKEN`, and `<public-id>` are substitutions for exact received references, returned tokens, and public endpoint IDs, not runnable literal values.
|
|
33
|
+
|
|
28
34
|
## Address, send, reply
|
|
29
35
|
|
|
30
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.
|
|
31
37
|
|
|
32
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.
|
|
33
39
|
|
|
40
|
+
Find the current Claude target name with an authorized `embassy refresh` followed by `embassy status --json`, or use the exact current name supplied by that session.
|
|
41
|
+
|
|
34
42
|
Claude and Codex both send in one command, with no `--from`:
|
|
35
43
|
|
|
36
44
|
```sh
|
|
@@ -41,7 +49,15 @@ MESSAGE
|
|
|
41
49
|
|
|
42
50
|
Use nonempty UTF-8 standard input, at most 16 KiB, never a body argument. Acceptance returns an opaque `deliveryToken` and `conversationId`, not proof of reading or comprehension.
|
|
43
51
|
|
|
44
|
-
Reply using the exact command from the broker-owned first reply hint
|
|
52
|
+
Reply using the exact command from the broker-owned first reply hint.
|
|
53
|
+
|
|
54
|
+
The receiving Codex task sees a broker hint such as:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
<embassy-reply-hint conversation="conv_EXACT_REFERENCE" ...>Reply by running `embassy send --conversation conv_EXACT_REFERENCE` with the reply body on stdin.</embassy-reply-hint>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
It must execute the exact received command to send the reply, because ordinary Codex final output is not forwarded automatically; the references below are substitutions, not usable literal values.
|
|
45
61
|
|
|
46
62
|
```sh
|
|
47
63
|
embassy send --conversation conv_REPLACE_WITH_EXACT_REFERENCE <<'MESSAGE'
|
|
@@ -55,13 +71,15 @@ One wake may contain several independently framed messages. Read each outer `cro
|
|
|
55
71
|
|
|
56
72
|
## Delivery and active turns
|
|
57
73
|
|
|
58
|
-
|
|
74
|
+
Retain `result.deliveryToken` from the successful send response in your current session and substitute that exact value for the example; status shows aggregate route queues and recent delivery metadata but cannot recover a lost delivery token or distinguish identical sends by token.
|
|
59
75
|
|
|
60
76
|
```sh
|
|
61
77
|
embassy delivery-status --token dlv_REPLACE_WITH_EXACT_TOKEN
|
|
62
78
|
embassy wait-delivery --token dlv_REPLACE_WITH_EXACT_TOKEN
|
|
63
79
|
```
|
|
64
80
|
|
|
81
|
+
Use `delivery-status` to inspect that delivery's phase, pending age or terminal code; use `status --json` to identify a stranded local route, and retire it with `retire --alias` using its alias or `retire --endpoint` using its public id from `result.routes`, understanding that this settles all outstanding work for that endpoint.
|
|
82
|
+
|
|
65
83
|
The waiter is bounded by the deadline plus three seconds. A found result has `state`, `terminal`, `deadlineAt`, and either `pendingForMs` or `safeErrorCode`; an evicted token returns `{found:false}` and waiter exit 3, not a failed-delivery result. `queued`, `reserved`, `armed`, and `accepted` are nonterminal. Terminal states are `delivered`, `failed`, `cancelled`, `expired`, `ambiguous`, and `unconfirmed`. Body pruning keeps receipt and reply references until their count/time retention expires. Cross-host confirmation means the destination durably owns the handoff, not that its agent consumed it.
|
|
66
84
|
|
|
67
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.
|