agent-embassy 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/CONTRIBUTING.md +122 -0
  3. package/LICENSE +21 -0
  4. package/README.md +185 -0
  5. package/README.zh-CN.md +185 -0
  6. package/SECURITY.md +224 -0
  7. package/assets/live-dashboard/app.css +1610 -0
  8. package/assets/mark-seal.svg +7 -0
  9. package/assets/mark.svg +7 -0
  10. package/assets/social-preview.png +0 -0
  11. package/assets/vendor/react/LICENSE +21 -0
  12. package/assets/vendor/react/react-dom.production.min.js +267 -0
  13. package/assets/vendor/react/react.production.min.js +31 -0
  14. package/dist/src/errors.d.ts +5 -0
  15. package/dist/src/errors.js +11 -0
  16. package/dist/src/errors.js.map +1 -0
  17. package/dist/src/gateway/claude-compatibility-scratch.d.ts +18 -0
  18. package/dist/src/gateway/claude-compatibility-scratch.js +158 -0
  19. package/dist/src/gateway/claude-compatibility-scratch.js.map +1 -0
  20. package/dist/src/gateway/claude-helper-client.d.ts +43 -0
  21. package/dist/src/gateway/claude-helper-client.js +212 -0
  22. package/dist/src/gateway/claude-helper-client.js.map +1 -0
  23. package/dist/src/gateway/claude-helper-protocol.d.ts +172 -0
  24. package/dist/src/gateway/claude-helper-protocol.js +373 -0
  25. package/dist/src/gateway/claude-helper-protocol.js.map +1 -0
  26. package/dist/src/gateway/claude-helper-supervisor.d.ts +74 -0
  27. package/dist/src/gateway/claude-helper-supervisor.js +497 -0
  28. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -0
  29. package/dist/src/gateway/claude-helper.d.ts +1 -0
  30. package/dist/src/gateway/claude-helper.js +269 -0
  31. package/dist/src/gateway/claude-helper.js.map +1 -0
  32. package/dist/src/gateway/claude-peer.d.ts +273 -0
  33. package/dist/src/gateway/claude-peer.js +2359 -0
  34. package/dist/src/gateway/claude-peer.js.map +1 -0
  35. package/dist/src/gateway/claude-runtime.d.ts +40 -0
  36. package/dist/src/gateway/claude-runtime.js +302 -0
  37. package/dist/src/gateway/claude-runtime.js.map +1 -0
  38. package/dist/src/gateway/cli-copy.d.ts +8 -0
  39. package/dist/src/gateway/cli-copy.en.d.ts +13 -0
  40. package/dist/src/gateway/cli-copy.en.js +43 -0
  41. package/dist/src/gateway/cli-copy.en.js.map +1 -0
  42. package/dist/src/gateway/cli-copy.js +19 -0
  43. package/dist/src/gateway/cli-copy.js.map +1 -0
  44. package/dist/src/gateway/cli-copy.zh-CN.d.ts +13 -0
  45. package/dist/src/gateway/cli-copy.zh-CN.js +43 -0
  46. package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -0
  47. package/dist/src/gateway/cli.d.ts +44 -0
  48. package/dist/src/gateway/cli.js +969 -0
  49. package/dist/src/gateway/cli.js.map +1 -0
  50. package/dist/src/gateway/codex-app-server.d.ts +310 -0
  51. package/dist/src/gateway/codex-app-server.js +1746 -0
  52. package/dist/src/gateway/codex-app-server.js.map +1 -0
  53. package/dist/src/gateway/codex-local-transport.d.ts +81 -0
  54. package/dist/src/gateway/codex-local-transport.js +617 -0
  55. package/dist/src/gateway/codex-local-transport.js.map +1 -0
  56. package/dist/src/gateway/codex-registration-generation.d.ts +5 -0
  57. package/dist/src/gateway/codex-registration-generation.js +19 -0
  58. package/dist/src/gateway/codex-registration-generation.js.map +1 -0
  59. package/dist/src/gateway/codex-registration-succession.d.ts +209 -0
  60. package/dist/src/gateway/codex-registration-succession.js +588 -0
  61. package/dist/src/gateway/codex-registration-succession.js.map +1 -0
  62. package/dist/src/gateway/compatibility.d.ts +70 -0
  63. package/dist/src/gateway/compatibility.js +252 -0
  64. package/dist/src/gateway/compatibility.js.map +1 -0
  65. package/dist/src/gateway/config.d.ts +24 -0
  66. package/dist/src/gateway/config.js +130 -0
  67. package/dist/src/gateway/config.js.map +1 -0
  68. package/dist/src/gateway/control.d.ts +308 -0
  69. package/dist/src/gateway/control.js +1573 -0
  70. package/dist/src/gateway/control.js.map +1 -0
  71. package/dist/src/gateway/dashboard-copy.d.ts +7 -0
  72. package/dist/src/gateway/dashboard-copy.en.d.ts +506 -0
  73. package/dist/src/gateway/dashboard-copy.en.js +507 -0
  74. package/dist/src/gateway/dashboard-copy.en.js.map +1 -0
  75. package/dist/src/gateway/dashboard-copy.js +516 -0
  76. package/dist/src/gateway/dashboard-copy.js.map +1 -0
  77. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +506 -0
  78. package/dist/src/gateway/dashboard-copy.zh-CN.js +507 -0
  79. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -0
  80. package/dist/src/gateway/dashboard-model.d.ts +207 -0
  81. package/dist/src/gateway/dashboard-model.js +720 -0
  82. package/dist/src/gateway/dashboard-model.js.map +1 -0
  83. package/dist/src/gateway/dashboard.d.ts +26 -0
  84. package/dist/src/gateway/dashboard.js +941 -0
  85. package/dist/src/gateway/dashboard.js.map +1 -0
  86. package/dist/src/gateway/delivery-machine.d.ts +235 -0
  87. package/dist/src/gateway/delivery-machine.js +540 -0
  88. package/dist/src/gateway/delivery-machine.js.map +1 -0
  89. package/dist/src/gateway/instance-lease.d.ts +21 -0
  90. package/dist/src/gateway/instance-lease.js +549 -0
  91. package/dist/src/gateway/instance-lease.js.map +1 -0
  92. package/dist/src/gateway/live-dashboard-app/app.js +2914 -0
  93. package/dist/src/gateway/live-dashboard-assets.d.ts +10 -0
  94. package/dist/src/gateway/live-dashboard-assets.js +73 -0
  95. package/dist/src/gateway/live-dashboard-assets.js.map +1 -0
  96. package/dist/src/gateway/live-dashboard-bootstrap.d.ts +36 -0
  97. package/dist/src/gateway/live-dashboard-bootstrap.js +176 -0
  98. package/dist/src/gateway/live-dashboard-bootstrap.js.map +1 -0
  99. package/dist/src/gateway/live-dashboard-command.d.ts +54 -0
  100. package/dist/src/gateway/live-dashboard-command.js +324 -0
  101. package/dist/src/gateway/live-dashboard-command.js.map +1 -0
  102. package/dist/src/gateway/live-dashboard-http.d.ts +41 -0
  103. package/dist/src/gateway/live-dashboard-http.js +445 -0
  104. package/dist/src/gateway/live-dashboard-http.js.map +1 -0
  105. package/dist/src/gateway/live-dashboard-protocol.d.ts +38 -0
  106. package/dist/src/gateway/live-dashboard-protocol.js +156 -0
  107. package/dist/src/gateway/live-dashboard-protocol.js.map +1 -0
  108. package/dist/src/gateway/live-dashboard-server.d.ts +33 -0
  109. package/dist/src/gateway/live-dashboard-server.js +130 -0
  110. package/dist/src/gateway/live-dashboard-server.js.map +1 -0
  111. package/dist/src/gateway/live-dashboard-stream.d.ts +46 -0
  112. package/dist/src/gateway/live-dashboard-stream.js +233 -0
  113. package/dist/src/gateway/live-dashboard-stream.js.map +1 -0
  114. package/dist/src/gateway/live-dashboard.d.ts +31 -0
  115. package/dist/src/gateway/live-dashboard.js +190 -0
  116. package/dist/src/gateway/live-dashboard.js.map +1 -0
  117. package/dist/src/gateway/locale.d.ts +4 -0
  118. package/dist/src/gateway/locale.js +10 -0
  119. package/dist/src/gateway/locale.js.map +1 -0
  120. package/dist/src/gateway/progress-watch-machine.d.ts +97 -0
  121. package/dist/src/gateway/progress-watch-machine.js +172 -0
  122. package/dist/src/gateway/progress-watch-machine.js.map +1 -0
  123. package/dist/src/gateway/providers.d.ts +287 -0
  124. package/dist/src/gateway/providers.js +2451 -0
  125. package/dist/src/gateway/providers.js.map +1 -0
  126. package/dist/src/gateway/server.d.ts +57 -0
  127. package/dist/src/gateway/server.js +264 -0
  128. package/dist/src/gateway/server.js.map +1 -0
  129. package/dist/src/gateway/service.d.ts +449 -0
  130. package/dist/src/gateway/service.js +4831 -0
  131. package/dist/src/gateway/service.js.map +1 -0
  132. package/dist/src/gateway/store.d.ts +340 -0
  133. package/dist/src/gateway/store.js +4047 -0
  134. package/dist/src/gateway/store.js.map +1 -0
  135. package/dist/src/gateway/types.d.ts +514 -0
  136. package/dist/src/gateway/types.js +414 -0
  137. package/dist/src/gateway/types.js.map +1 -0
  138. package/dist/src/mutex.d.ts +4 -0
  139. package/dist/src/mutex.js +23 -0
  140. package/dist/src/mutex.js.map +1 -0
  141. package/docs/DESIGN.md +134 -0
  142. package/docs/GATEWAY-ARCHITECTURE.md +858 -0
  143. package/package.json +80 -0
  144. package/skills/embassy-peer/SKILL.md +198 -0
  145. package/skills/embassy-peer/agents/openai.yaml +4 -0
package/SECURITY.md ADDED
@@ -0,0 +1,224 @@
1
+ # Security policy
2
+
3
+ ## Supported versions
4
+
5
+ Security fixes are applied to the latest Embassy release and the `main`
6
+ branch. Pre-release prototype versions are not supported.
7
+
8
+ ## Reporting a vulnerability
9
+
10
+ Please use this repository's private GitHub Security Advisory interface. Do
11
+ not open a public issue for a suspected vulnerability.
12
+
13
+ Reports should contain the smallest synthetic reproduction possible. Do not
14
+ include credentials, OAuth material, Keychain data, message bodies, raw model
15
+ output, provider histories, local Embassy state, socket addresses, native
16
+ session or thread identifiers, or unredacted personal paths.
17
+
18
+ ## Deployment boundary
19
+
20
+ Embassy is personal, same-machine software for one macOS user. Run it only
21
+ under an OS account that is yours alone and where you trust every process
22
+ already running as that user. Do not expose its sockets or state directory on a
23
+ network, host it as a service, or use it to share a Claude or Codex subscription
24
+ between users.
25
+
26
+ The broker is local; the agents are not. Embassy does not call a provider API,
27
+ but a delivered body becomes model input in the receiving product and may be
28
+ sent to and retained by Anthropic or OpenAI under that product's normal terms
29
+ and settings.
30
+
31
+ ## Trust model
32
+
33
+ Embassy provides same-UID containment and route attribution, not authentication
34
+ against other processes running as the same OS user.
35
+
36
+ - A Codex route is attributed to the exact inherited `CODEX_THREAD_ID` of the
37
+ task that self-registers it.
38
+ - A Claude route is attributed to a validated live peer generation and native
39
+ session UUID. An inherited `CLAUDE_CODE_MESSAGING_SOCKET` is a transient
40
+ reply capability, not a credential.
41
+ - Aliases are labels. They do not grant authority and are re-resolved against
42
+ the exact private route binding before delivery.
43
+ - Any process already running as the same OS user may be able to present local
44
+ environment or socket capabilities. Embassy is not a sandbox for untrusted
45
+ same-user code.
46
+
47
+ ## Routing and consent
48
+
49
+ - A Codex task must explicitly self-register with a `codex-*` alias before it
50
+ can participate.
51
+ - Codex-to-Claude delivery requires an explicit operator-created pair with a
52
+ compatible live Claude session. Discovery alone is never permission to send.
53
+ - Every registered `codex-*` peer is visible to every compatible live Claude
54
+ session running as the same OS user, but paired mode accepts only sessions
55
+ holding an explicit pair edge with that exact task. Other senders settle
56
+ terminally with `SENDER_NOT_PAIRED`. `embassy serve --inbound open` is the
57
+ explicit opt-out from pairing.
58
+ - Pairs are additive, bounded, and per-edge: adding an edge never retires
59
+ another, and removing one invalidates its active conversation capabilities
60
+ before the change is published. Explicitly requested endpoint replacement
61
+ (registration succession) atomically settles the outgoing endpoint's
62
+ accepted work before the replacement is exposed; a half-replaced
63
+ intermediate state is never published.
64
+ - Embassy never mutates a Codex task's approval or sandbox policy and never
65
+ answers an approval request. An inbound turn uses the task's existing native
66
+ policy. With `approvalPolicy: never`, no human confirmation occurs on that
67
+ path; with an approval-requiring policy, the turn may wait for the user.
68
+ - Claude's native `crossSessionInbound` setting controls messages entering a
69
+ Claude session. Embassy cannot override an accept, hold, or refuse decision.
70
+
71
+ Every routed message is untrusted input capable of steering the receiving
72
+ agent. Registration and selection control reachability; they do not make the
73
+ message content trustworthy.
74
+
75
+ The literal leading `STEER:` prefix is a protocol instruction, not proof of a
76
+ trusted author or safe intent. Any exact same-UID Claude sender already allowed
77
+ to reach the registered Codex task can use it. The receiver's existing Codex
78
+ policy still governs tools and approvals, and an operator who does not want
79
+ this timing behavior must set `EMBASSY_STEERING_ENABLED=0` before starting the
80
+ broker.
81
+
82
+ ## Process and protocol boundary
83
+
84
+ - The v1 launcher is foreground, macOS-only, same-machine, and local-host-only.
85
+ - Before provider setup, the launcher acquires one host-wide macOS advisory
86
+ lease. If its lease helper exits or the lease is otherwise lost
87
+ unexpectedly, Embassy shuts down rather than continuing without singleton
88
+ ownership.
89
+ - The control plane is a private Unix-domain socket in a controller-owned
90
+ mode-0700 state directory. `embassy serve` has no TCP or HTTP listener; its
91
+ only listeners are private Unix-domain sockets. The opt-in
92
+ `embassy dashboard --live` companion is a separate process with its own
93
+ loopback HTTP listener — see "Live companion boundary" below.
94
+ - Provider protocols are version-pinned. Unknown Claude Code peer or Codex App
95
+ Server versions, schemas, and endpoint generations fail closed.
96
+ - Embassy publishes at most one visibly prefixed, process-owned `codex-*`
97
+ record in Claude's registry. It creates one callback socket and removes only
98
+ exact-owned artifacts whose generation still matches during graceful
99
+ shutdown.
100
+ - App Server methods are allowlisted. Embassy exposes no archive, deletion,
101
+ shell, configuration, authentication, plugin, history, approval-response, or
102
+ generic RPC method.
103
+ - `turn/steer` is reachable only for an exact leading `STEER:` body in the
104
+ Claude-to-Codex direction, with an exact observed active-turn ID. App Server
105
+ admits it at the next tool-call boundary; Embassy never interrupts or injects
106
+ mid-generation. Clean boundary refusal falls back to the normal queue, which
107
+ retains at most three steers per route. The environment kill switch defaults
108
+ on and can disable this classification globally. Interrupt remains limited to
109
+ an exact turn started and positively observed by the same connector.
110
+ - Exact App Server 0.147.0 initialization enables `experimentalApi: true`
111
+ solely for `thread/resume.excludeTurns: true`. It adds no general
112
+ experimental method or authority. Missing, malformed, or nonempty returned
113
+ turns fail closed and are never retained.
114
+ - Queues, frames, bodies, callbacks, deadlines, hop counts, deduplication,
115
+ rate limits, and transient conversations are bounded. Ambiguous writes are
116
+ never retried automatically.
117
+ - The only network listener Embassy can create belongs to the opt-in
118
+ `embassy dashboard --live` companion, described under "Live companion
119
+ boundary". Everything enumerated above concerns `embassy serve`.
120
+
121
+ ## Filesystem boundary
122
+
123
+ Controller-owned state is a dedicated mode-0700 directory. Its files and
124
+ control socket are mode 0600 and validated against replacement, symlinks, and
125
+ unexpected ownership or permissions.
126
+
127
+ The host-wide singleton has one fixed surface under the verified login home:
128
+ the private mode-0700 `~/.local/state/agent-embassy` directory and its mode-0600
129
+ `.gateway-host.lock`. Neither `EMBASSY_STATE_DIR` nor `XDG_STATE_HOME` relocates
130
+ that lease. Embassy executes the exact `/usr/bin/lockf` and `/bin/cat` helpers,
131
+ without a shell, to hold the kernel lease for the foreground process lifetime.
132
+ The lock file is retained and reused across restarts; process exit releases the
133
+ kernel lock.
134
+
135
+ Embassy's provider-facing access is intentionally enumerable:
136
+
137
+ - read and execute the configured Claude launcher only for bounded exact-version
138
+ attestation;
139
+ - read the live Claude session registry and connect validated peer sockets;
140
+ - for an explicit `compat-certify`, start one bounded no-stdin Claude print
141
+ session in a scrubbed environment, route one marked diagnostic frame only to
142
+ that scratch session, and terminate it after the receipt deadline;
143
+ - create and later remove its one callback socket and one registry record;
144
+ - resolve the managed Codex installation and attach to the already-running
145
+ local App Server; and
146
+ - inspect canonical filesystem metadata needed to validate provider-advertised
147
+ endpoints and generations.
148
+
149
+ Claude-owned registry files and peer sockets are accepted according to actual
150
+ filesystem accessibility plus bounded schema, type, PID/path correlation,
151
+ liveness, and generation checks. Embassy does not treat provider-owned Unix
152
+ owner or mode bits as an additional routing policy.
153
+
154
+ Embassy does not need or intentionally read credentials, Keychain items,
155
+ Claude project history, Codex or Claude transcripts, shell history, or provider
156
+ configuration contents. Report a bug if any normal code path attempts to do so.
157
+
158
+ ## Persistence and disclosure
159
+
160
+ Message bodies, prompts, replies, raw provider frames, tool data, stderr,
161
+ callback addresses, and socket paths remain memory-only. They are discarded on
162
+ restart and never replayed.
163
+
164
+ The closed private binding store may retain the exact Codex thread ID and Claude
165
+ session UUID required for ownership and endpoint re-observation. Native IDs are
166
+ forbidden from public snapshots, normalized events, the dashboard, aliases,
167
+ logs, errors, and CLI output. A Claude UUID may enter only as a user-supplied
168
+ explicit CLI selector; Embassy never discovers or prints it publicly.
169
+
170
+ The static dashboard is two atomically rewritten mode-0600 files, not a web
171
+ application: `gateway-dashboard.html` and `gateway-dashboard.zh-CN.html`, both
172
+ written on every publish and cross-linked in the page. They contain allowlisted
173
+ metadata only and have no JavaScript, external assets, storage, telemetry,
174
+ mutation endpoint, or self-refresh. Any process already running as the same OS
175
+ user can read them.
176
+
177
+ ### Live companion boundary
178
+
179
+ `embassy dashboard --live` binds an authenticated HTTP listener on `127.0.0.1` with
180
+ an ephemeral port. It is a separate foreground process from `embassy serve`.
181
+ Access requires a one-use 256-bit URL-fragment token exchanged for a
182
+ path-scoped `HttpOnly` `SameSite=Strict` session cookie. The exact Host header
183
+ is checked on every request; navigation GETs permit a missing Origin and carry
184
+ no sentinel, while non-navigation POSTs require the exact Origin plus the
185
+ `X-Embassy-Request` sentinel. There are no CORS headers, generic control or
186
+ provider routes, storage, telemetry, or external assets. The sole mutation
187
+ route accepts only select-Claude, unselect-Claude, and refresh-discovery JSON
188
+ bodies, capped at 1 KiB and six confirmed actions per minute. The browser
189
+ cannot register tasks, send, reply, approve, interrupt, change settings, or
190
+ invoke arbitrary broker/provider methods. Any process
191
+ running as your OS user — including root and browser extensions with local
192
+ filesystem access — can read what the browser can read.
193
+
194
+ The bootstrap URL, including its one-use capability, is written to a mode-0600
195
+ `bootstrap.html` inside a fresh mode-0700 run directory under the private state
196
+ root and removed when the companion exits; treat that directory with the same
197
+ care as the rest of the state root.
198
+
199
+ Reports involving the live companion are in scope if they demonstrate a path by
200
+ which a remote origin, a cross-site request, or a process running as a
201
+ different OS user can read the authenticated stream or bypass the token-to-cookie
202
+ exchange. Same-UID local reads are within the documented containment model and
203
+ are not treated as vulnerabilities unless they bypass an explicit control such
204
+ as accessing a session without presenting the cookie.
205
+
206
+
207
+ ## Validation boundary
208
+
209
+ Routine tests use temporary directories, fake peers, and fake App Server
210
+ transports. They do not inspect live provider state or contact a model.
211
+
212
+ The default `observed` compatibility policy may admit an unknown same-major
213
+ provider version only after the bounded schema probe passes. That evidence
214
+ cannot detect a semantic change that preserves every validated shape. Runtime
215
+ record, frame, response, identity, and deadline checks remain mandatory, and
216
+ operators can use `compat-certify` for explicit on-machine wire evidence after
217
+ an upstream update. `compat-check` creates no message or turn;
218
+ `compat-certify --with-turn` is the only certification form that explicitly
219
+ starts a Codex model turn.
220
+
221
+ Passive live discovery, a live provider connection, a native message, and an
222
+ App Server turn are distinct authorization gates. Each requires an explicit
223
+ user request for that operation. Never infer permission for a live send from a
224
+ previous smoke test, and never enable live provider traffic in CI.