agent-embassy 3.0.0 → 4.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.
- package/CHANGELOG.md +42 -0
- package/CONTRIBUTING.md +92 -200
- package/README.md +159 -138
- package/SECURITY.md +191 -335
- package/dist/src/gateway/broker-check.d.ts +26 -0
- package/dist/src/gateway/broker-check.js +89 -0
- package/dist/src/gateway/broker-check.js.map +1 -0
- package/dist/src/gateway/broker-control.d.ts +72 -0
- package/dist/src/gateway/broker-control.js +164 -0
- package/dist/src/gateway/broker-control.js.map +1 -0
- package/dist/src/gateway/broker.d.ts +117 -0
- package/dist/src/gateway/broker.js +186 -0
- package/dist/src/gateway/broker.js.map +1 -0
- package/dist/src/gateway/claude-peer.d.ts +1 -124
- package/dist/src/gateway/claude-peer.js +62 -1053
- package/dist/src/gateway/claude-peer.js.map +1 -1
- package/dist/src/gateway/codex-stateless-transport.d.ts +0 -12
- package/dist/src/gateway/codex-stateless-transport.js +8 -142
- package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
- package/dist/src/gateway/config.d.ts +2 -6
- package/dist/src/gateway/config.js +17 -27
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/coordinator.d.ts +57 -0
- package/dist/src/gateway/coordinator.js +217 -0
- package/dist/src/gateway/coordinator.js.map +1 -0
- package/dist/src/gateway/core-cli.d.ts +15 -0
- package/dist/src/gateway/core-cli.js +282 -0
- package/dist/src/gateway/core-cli.js.map +1 -0
- package/dist/src/gateway/core-service-command.d.ts +16 -0
- package/dist/src/gateway/core-service-command.js +71 -0
- package/dist/src/gateway/core-service-command.js.map +1 -0
- package/dist/src/gateway/endpoint-directory.d.ts +33 -0
- package/dist/src/gateway/endpoint-directory.js +223 -0
- package/dist/src/gateway/endpoint-directory.js.map +1 -0
- package/dist/src/gateway/federation.d.ts +89 -0
- package/dist/src/gateway/federation.js +632 -0
- package/dist/src/gateway/federation.js.map +1 -0
- package/dist/src/gateway/ledger-codec.d.ts +3 -0
- package/dist/src/gateway/ledger-codec.js +159 -0
- package/dist/src/gateway/ledger-codec.js.map +1 -0
- package/dist/src/gateway/ledger.d.ts +138 -0
- package/dist/src/gateway/ledger.js +319 -0
- package/dist/src/gateway/ledger.js.map +1 -0
- package/dist/src/gateway/local-control.d.ts +23 -0
- package/dist/src/gateway/local-control.js +489 -0
- package/dist/src/gateway/local-control.js.map +1 -0
- package/dist/src/gateway/native-destinations.d.ts +34 -0
- package/dist/src/gateway/native-destinations.js +272 -0
- package/dist/src/gateway/native-destinations.js.map +1 -0
- package/dist/src/gateway/owned-state.d.ts +57 -0
- package/dist/src/gateway/owned-state.js +398 -0
- package/dist/src/gateway/owned-state.js.map +1 -0
- package/dist/src/gateway/provenance-envelope.d.ts +3 -3
- package/dist/src/gateway/provenance-envelope.js +3 -23
- package/dist/src/gateway/provenance-envelope.js.map +1 -1
- package/dist/src/gateway/runtime.d.ts +41 -0
- package/dist/src/gateway/runtime.js +175 -0
- package/dist/src/gateway/runtime.js.map +1 -0
- package/docs/CONFIGURATION.md +178 -266
- package/docs/DELIVERY.md +133 -82
- package/docs/GATEWAY-ARCHITECTURE.md +276 -943
- package/package.json +5 -5
- package/skills/embassy-peer/SKILL.md +38 -194
- package/skills/embassy-peer/agents/openai.yaml +2 -2
- package/dist/src/gateway/claude-helper-client.d.ts +0 -2
- package/dist/src/gateway/claude-helper-client.js +0 -2
- package/dist/src/gateway/claude-helper-client.js.map +0 -1
- package/dist/src/gateway/claude-helper-protocol.d.ts +0 -117
- package/dist/src/gateway/claude-helper-protocol.js +0 -122
- package/dist/src/gateway/claude-helper-protocol.js.map +0 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +0 -87
- package/dist/src/gateway/claude-helper-supervisor.js +0 -347
- package/dist/src/gateway/claude-helper-supervisor.js.map +0 -1
- package/dist/src/gateway/claude-helper.d.ts +0 -1
- package/dist/src/gateway/claude-helper.js +0 -252
- package/dist/src/gateway/claude-helper.js.map +0 -1
- package/dist/src/gateway/cli.d.ts +0 -57
- package/dist/src/gateway/cli.js +0 -1503
- package/dist/src/gateway/cli.js.map +0 -1
- package/dist/src/gateway/codex-socket-holder.d.ts +0 -26
- package/dist/src/gateway/codex-socket-holder.js +0 -76
- package/dist/src/gateway/codex-socket-holder.js.map +0 -1
- package/dist/src/gateway/control.d.ts +0 -261
- package/dist/src/gateway/control.js +0 -903
- package/dist/src/gateway/control.js.map +0 -1
- package/dist/src/gateway/peer-client.d.ts +0 -58
- package/dist/src/gateway/peer-client.js +0 -217
- package/dist/src/gateway/peer-client.js.map +0 -1
- package/dist/src/gateway/peer-mailbox.d.ts +0 -78
- package/dist/src/gateway/peer-mailbox.js +0 -168
- package/dist/src/gateway/peer-mailbox.js.map +0 -1
- package/dist/src/gateway/peer-protocol.d.ts +0 -105
- package/dist/src/gateway/peer-protocol.js +0 -70
- package/dist/src/gateway/peer-protocol.js.map +0 -1
- package/dist/src/gateway/peer-stdio.d.ts +0 -23
- package/dist/src/gateway/peer-stdio.js +0 -100
- package/dist/src/gateway/peer-stdio.js.map +0 -1
- package/dist/src/gateway/providers.d.ts +0 -163
- package/dist/src/gateway/providers.js +0 -972
- package/dist/src/gateway/providers.js.map +0 -1
- package/dist/src/gateway/server.d.ts +0 -47
- package/dist/src/gateway/server.js +0 -219
- package/dist/src/gateway/server.js.map +0 -1
- package/dist/src/gateway/service.d.ts +0 -373
- package/dist/src/gateway/service.js +0 -2274
- package/dist/src/gateway/service.js.map +0 -1
- package/dist/src/gateway/status-view.d.ts +0 -167
- package/dist/src/gateway/status-view.js +0 -488
- package/dist/src/gateway/status-view.js.map +0 -1
- package/dist/src/gateway/store.d.ts +0 -185
- package/dist/src/gateway/store.js +0 -2359
- package/dist/src/gateway/store.js.map +0 -1
- package/dist/src/gateway/types.d.ts +0 -528
- package/dist/src/gateway/types.js +0 -341
- package/dist/src/gateway/types.js.map +0 -1
|
@@ -1,488 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Human rendering of the public snapshot. Pure and side-effect free: it takes
|
|
3
|
-
* a validated `GatewayPublicSnapshot` and returns text, so every judgement it
|
|
4
|
-
* makes — which connectors matter, what counts as stale, which alerts are
|
|
5
|
-
* actionable — is unit-testable against fixture snapshots without a broker.
|
|
6
|
-
*
|
|
7
|
-
* Nothing here reaches for state the snapshot does not already carry, and
|
|
8
|
-
* nothing here asks the broker for anything: `status` is read-only. The
|
|
9
|
-
* snapshot is the whole input; `StatusViewOptions` adds only what the client
|
|
10
|
-
* knows about itself (its own version, the state directory it resolved, the
|
|
11
|
-
* pid recorded in that directory's controller lock, and the clock).
|
|
12
|
-
*
|
|
13
|
-
* Caps: at most `STATUS_CAPS.sessions` discovered sessions, `.shellPeers`
|
|
14
|
-
* shell-peer lines, and `.alerts` alert rows are printed. Every cap says how
|
|
15
|
-
* many rows it hid, and the shell-peer list is ordered stale-first so a stuck
|
|
16
|
-
* peer is never the row that falls off the end.
|
|
17
|
-
*/
|
|
18
|
-
import { gatewayPublicSnapshotLimits } from "./types.js";
|
|
19
|
-
/**
|
|
20
|
-
* The backstop for a route the broker has not heard about in a long time.
|
|
21
|
-
*
|
|
22
|
-
* It is deliberately far above the broker's own 35-second connector window
|
|
23
|
-
* (`CONNECTOR_OBSERVATION_STALE_AFTER_MS`), because that window is crossed
|
|
24
|
-
* routinely and innocently: the Codex observer polls one route at a time
|
|
25
|
-
* every 15 s, and Claude routes are not polled at all — their evidence is
|
|
26
|
-
* edge-triggered, written when a discovery scan or a delivery observes the
|
|
27
|
-
* session, so a quiet Claude session's `lastSeenAt` simply stops advancing
|
|
28
|
-
* while the session is perfectly alive. A word that meant "gone" at 35 s
|
|
29
|
-
* would tell operators to retire live work; ten minutes plus a code that
|
|
30
|
-
* says the endpoint is gone is what earns that sentence.
|
|
31
|
-
*/
|
|
32
|
-
export const STATUS_ROUTE_STALE_AFTER_MS = 10 * 60_000;
|
|
33
|
-
/** Older than this, the header offers a rescan. `status` never rescans itself. */
|
|
34
|
-
export const STATUS_SCAN_STALE_AFTER_MS = 60_000;
|
|
35
|
-
/** The one safe code that means the Codex task behind a route is actually gone. */
|
|
36
|
-
export const CODEX_ENDPOINT_GONE_CODES = ["THREAD_NOT_OBSERVED"];
|
|
37
|
-
export const STATUS_RECENT = Object.freeze({ default: 10, minimum: 1, maximum: 100 });
|
|
38
|
-
export const STATUS_CAPS = Object.freeze({ sessions: 16, shellPeers: 8, alerts: 6 });
|
|
39
|
-
const PREVIEW_MAX_CHARS = 60;
|
|
40
|
-
/**
|
|
41
|
-
* One remedy per safe code, each one line. A connector with an unknown code
|
|
42
|
-
* still gets a bounded generic remedy — it is on the delivery path, so the
|
|
43
|
-
* operator must be told something — while an alert with an unknown code is
|
|
44
|
-
* counted rather than printed. That filter is what makes the alert section
|
|
45
|
-
* "actionable alerts" instead of an event log.
|
|
46
|
-
*
|
|
47
|
-
* `PEER_ALIAS_COLLISION` is deliberately the same sentence the CLI prints for
|
|
48
|
-
* a refused send (`CLI_HINT.aliasCollision`); `status-view.test.ts` pins the
|
|
49
|
-
* two strings together so they cannot drift apart.
|
|
50
|
-
*/
|
|
51
|
-
export const STATUS_REMEDY = {
|
|
52
|
-
MANAGED_CODEX_UNAVAILABLE: "Either a process outside Embassy holds the managed Codex control socket — quit it — or the managed App Server standalone layout is missing, which starting the daemon alone does not create: follow the Codex prerequisite in the README (the official installer, then the daemon).",
|
|
53
|
-
PEER_ALIAS_COLLISION: "the alias names more than one live session; rename one, or address the session by UUID with --to <session-uuid>.",
|
|
54
|
-
PEER_PROTOCOL_MISMATCH: "That node runs a different federation peer protocol; upgrade the lagging node's Embassy and it re-catalogs on the next refresh.",
|
|
55
|
-
PEER_TUNNEL_UNAVAILABLE: "The SSH tunnel to that node is down; check the node is reachable and its broker is running.",
|
|
56
|
-
PEER_DIAL_FAILED: "Embassy could not open the SSH tunnel to that node; check its entry in nodes.json and your SSH configuration.",
|
|
57
|
-
PEER_CATALOG_INCOMPLETE: "That node answered with an incomplete catalog; its mirrored routes are shown from the last complete one.",
|
|
58
|
-
PEER_ROUTE_STALE: "That mirrored route was missing from the node's latest catalog; it retires when the node stops publishing it.",
|
|
59
|
-
CLAUDE_PEER_NOT_OBSERVED: "That Claude session is no longer in the live registry; run `embassy refresh`, and its route retires on the next send if the session exited.",
|
|
60
|
-
ROUTE_UNOBSERVED: "The provider stopped reporting this route; retire it if the session or task ended.",
|
|
61
|
-
THREAD_NOT_OBSERVED: "That Codex task is gone. Run `embassy register-codex --alias <new-alias> --succeeds <this alias>` from the new task, or `embassy unregister-codex --alias <this alias>` from the old one.",
|
|
62
|
-
CODEX_OBSERVER_UNAVAILABLE: "Embassy cannot observe Codex tasks; start the managed daemon with `codex app-server daemon start`.",
|
|
63
|
-
DISPATCH_RUNNER_FAILED: "A delivery attempt failed inside the broker; the message keeps its own settled state — read it with `embassy delivery-status`, and restart the broker if this repeats.",
|
|
64
|
-
CLAUDE_INGRESS_REJECTED: "A Claude session refused an inbound message; check that session's `crossSessionInbound` setting.",
|
|
65
|
-
CLAUDE_REPLY_REJECTED: "A reply could not be written back to the originating Claude session; it may have exited — run `embassy refresh`.",
|
|
66
|
-
ROUTE_OBSERVATION_FAILED: "The provider's route observation failed once; the state words above may be out of date until the next poll.",
|
|
67
|
-
EPHEMERAL_ROUTE_EXPIRY_FAILED: "A throwaway `embassy check` registration could not be retired on time. The broker retries twice more, five seconds apart; if all three attempts fail the registration stays until the broker restarts, which clears it by construction.",
|
|
68
|
-
GATEWAY_WAKE_FAILED: "The broker's maintenance tick failed once; if it repeats, restart the broker.",
|
|
69
|
-
};
|
|
70
|
-
const ANSI = Object.freeze({
|
|
71
|
-
reset: "\u001b[0m", bold: "\u001b[1m", dim: "\u001b[2m",
|
|
72
|
-
red: "\u001b[31m", yellow: "\u001b[33m", green: "\u001b[32m",
|
|
73
|
-
});
|
|
74
|
-
/** The one place that emits an escape sequence; `color: false` emits none. */
|
|
75
|
-
export const terminalPainter = (color) => color ? (text, tone) => `${ANSI[tone]}${text}${ANSI.reset}` : (text) => text;
|
|
76
|
-
const wordColor = (word) => word === "ok" ? "green" : word === "degraded" || word === "offline" ? "red" : "yellow";
|
|
77
|
-
/**
|
|
78
|
-
* Bodies are the one snapshot field with no shape validation beyond "non-empty
|
|
79
|
-
* UTF-8 without NUL", so a preview strips C0/C1 controls and Unicode format
|
|
80
|
-
* characters — an escape sequence would repaint the operator's terminal, and a
|
|
81
|
-
* bidi override or zero-width joiner would let a body render as text it is
|
|
82
|
-
* not — collapses runs of whitespace, and is cut to one short line.
|
|
83
|
-
*/
|
|
84
|
-
function previewBody(body, maximum = PREVIEW_MAX_CHARS) {
|
|
85
|
-
const flattened = body
|
|
86
|
-
.replace(/[\u0000-\u001f\u007f-\u009f]/gu, " ")
|
|
87
|
-
.replace(/\p{Cf}/gu, "")
|
|
88
|
-
.replace(/\s+/gu, " ")
|
|
89
|
-
.trim();
|
|
90
|
-
const characters = [...flattened];
|
|
91
|
-
return characters.length <= maximum ? flattened : `${characters.slice(0, maximum - 1).join("")}…`;
|
|
92
|
-
}
|
|
93
|
-
/** Relative wall-clock age: deterministic, and free of the reader's timezone. */
|
|
94
|
-
function relativeAge(timestamp, now) {
|
|
95
|
-
if (timestamp === undefined)
|
|
96
|
-
return "never";
|
|
97
|
-
const observed = Date.parse(timestamp);
|
|
98
|
-
if (!Number.isFinite(observed))
|
|
99
|
-
return "unknown";
|
|
100
|
-
const seconds = Math.max(0, Math.round((now - observed) / 1_000));
|
|
101
|
-
if (seconds < 1)
|
|
102
|
-
return "just now";
|
|
103
|
-
if (seconds < 60)
|
|
104
|
-
return `${String(seconds)}s ago`;
|
|
105
|
-
const minutes = Math.round(seconds / 60);
|
|
106
|
-
if (minutes < 60)
|
|
107
|
-
return `${String(minutes)}m ago`;
|
|
108
|
-
const hours = Math.round(minutes / 60);
|
|
109
|
-
if (hours < 48)
|
|
110
|
-
return `${String(hours)}h ago`;
|
|
111
|
-
return `${String(Math.round(hours / 24))}d ago`;
|
|
112
|
-
}
|
|
113
|
-
/** The same age without "ago", for a phrase that supplies its own preposition. */
|
|
114
|
-
const spanFor = (timestamp, now) => relativeAge(timestamp, now).replace(/ ago$/, "");
|
|
115
|
-
const ageMs = (timestamp, now) => {
|
|
116
|
-
if (timestamp === undefined)
|
|
117
|
-
return undefined;
|
|
118
|
-
const observed = Date.parse(timestamp);
|
|
119
|
-
return Number.isFinite(observed) ? Math.max(0, now - observed) : undefined;
|
|
120
|
-
};
|
|
121
|
-
/**
|
|
122
|
-
* Connector words. A connector reporting `CONNECTOR_OBSERVATION_STALE` has
|
|
123
|
-
* nothing wrong with it: no route of that provider was observed inside the
|
|
124
|
-
* broker's window. That is `stale`, not `degraded`, and the difference is the
|
|
125
|
-
* point — an idle Mac with no registered Codex task must not read as broken.
|
|
126
|
-
*/
|
|
127
|
-
function connectorWord(connector) {
|
|
128
|
-
if (connector.health === "healthy" || connector.health === "connecting")
|
|
129
|
-
return "ok";
|
|
130
|
-
if (connector.health === "offline")
|
|
131
|
-
return "offline";
|
|
132
|
-
return connector.safeErrorCode === "CONNECTOR_OBSERVATION_STALE" ? "stale" : "degraded";
|
|
133
|
-
}
|
|
134
|
-
function routeView(route, discovered, now) {
|
|
135
|
-
if (!route.enabled)
|
|
136
|
-
return { word: "disabled", lastSeen: relativeAge(route.lastSeenAt, now) };
|
|
137
|
-
if (discovered !== undefined) {
|
|
138
|
-
return {
|
|
139
|
-
word: discovered.state === "awaiting_approval" ? "awaiting" : discovered.state,
|
|
140
|
-
lastSeen: `discovered ${spanFor(discovered.lastSeenAt, now)}`,
|
|
141
|
-
...(discovered.state === "awaiting_approval"
|
|
142
|
-
? { remedy: "waiting on an approval prompt in that session's own terminal" } : {}),
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
const observed = ageMs(route.lastSeenAt, now);
|
|
146
|
-
const beyondBackstop = observed !== undefined && observed > STATUS_ROUTE_STALE_AFTER_MS;
|
|
147
|
-
const word = beyondBackstop ? "stale"
|
|
148
|
-
: route.state === "awaiting_approval" ? "awaiting" : route.state;
|
|
149
|
-
const lastSeen = relativeAge(route.lastSeenAt, now);
|
|
150
|
-
if (word === "awaiting") {
|
|
151
|
-
return { word, lastSeen,
|
|
152
|
-
remedy: `waiting on an approval prompt in that ${route.provider === "codex" ? "Codex task" : "session"}'s own terminal` };
|
|
153
|
-
}
|
|
154
|
-
if (word !== "stale")
|
|
155
|
-
return { word, lastSeen };
|
|
156
|
-
// Stale, and now the only question that matters: gone, or merely quiet?
|
|
157
|
-
if (route.provider === "codex") {
|
|
158
|
-
// A bare silence is not evidence the task is gone, and neither is the
|
|
159
|
-
// broker's own 35-second word: the succession remedy needs BOTH the
|
|
160
|
-
// ten-minute backstop and a code that says the endpoint itself is gone.
|
|
161
|
-
// Anything less tells operators to retire tasks that are merely busy.
|
|
162
|
-
const gone = beyondBackstop && route.safeErrorCode !== undefined &&
|
|
163
|
-
CODEX_ENDPOINT_GONE_CODES.includes(route.safeErrorCode);
|
|
164
|
-
return { word, lastSeen, remedy: gone
|
|
165
|
-
? STATUS_REMEDY.THREAD_NOT_OBSERVED ?? ""
|
|
166
|
-
: `not observed for ${spanFor(route.lastSeenAt, now)}; the task may be busy or the app-server slow — run \`embassy check --to ${route.alias}\` to settle it` };
|
|
167
|
-
}
|
|
168
|
-
if (route.provider === "claude") {
|
|
169
|
-
return { word, lastSeen,
|
|
170
|
-
remedy: "that session has exited or renamed; run `embassy refresh`" };
|
|
171
|
-
}
|
|
172
|
-
return { word, lastSeen };
|
|
173
|
-
}
|
|
174
|
-
const severityRank = (word) => word === "degraded" || word === "offline" ? 0 : word === "stale" ? 1 : 2;
|
|
175
|
-
/**
|
|
176
|
-
* The overall word is informational and derived from the two connectors a
|
|
177
|
-
* message actually travels through. A shell peer never contributes: its
|
|
178
|
-
* mailbox is pull-only, so "nobody is awaiting it" is a fact about the
|
|
179
|
-
* operator's other terminal, not about the broker.
|
|
180
|
-
*/
|
|
181
|
-
function overallWord(snapshot) {
|
|
182
|
-
const routed = snapshot.connectors.filter((connector) => connector.provider === "claude" || connector.provider === "codex");
|
|
183
|
-
if (routed.length === 0)
|
|
184
|
-
return "offline";
|
|
185
|
-
return routed.map(connectorWord).reduce((worst, word) => severityRank(word) < severityRank(worst) ? word : worst, "ok");
|
|
186
|
-
}
|
|
187
|
-
/** The remedy for one connector's condition; never empty when the word is not ok. */
|
|
188
|
-
function connectorRemedy(connector, snapshot) {
|
|
189
|
-
const code = connector.safeErrorCode;
|
|
190
|
-
if (code === "CONNECTOR_OBSERVATION_STALE" && connector.provider === "codex") {
|
|
191
|
-
return snapshot.routes.some((route) => route.provider === "codex")
|
|
192
|
-
? "A registered Codex task has not been observed recently; run `embassy check` to test the round trip."
|
|
193
|
-
: "No Codex task is registered. Run `embassy register-codex --alias codex-<name>@<host>` from inside the task.";
|
|
194
|
-
}
|
|
195
|
-
if (code === "CONNECTOR_OBSERVATION_STALE" && connector.provider === "claude") {
|
|
196
|
-
return "No Claude session has been observed recently; start one, then run `embassy refresh`.";
|
|
197
|
-
}
|
|
198
|
-
const known = code === undefined ? undefined : STATUS_REMEDY[code];
|
|
199
|
-
if (known !== undefined)
|
|
200
|
-
return known;
|
|
201
|
-
return `The ${connector.provider} connector is not answering. Read \`embassy status --json\` for the full snapshot, and restart the broker if it does not clear.`;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Colliding Claude names are filtered out of `availablePeers` by the broker,
|
|
205
|
-
* and the only public trace left is a rejection count on the Claude
|
|
206
|
-
* connector's registry observation. The count is therefore what can honestly
|
|
207
|
-
* be reported: which name collided is not in the snapshot.
|
|
208
|
-
*/
|
|
209
|
-
const claudeConnector = (snapshot) => snapshot.connectors.find((connector) => connector.provider === "claude");
|
|
210
|
-
function collisionCount(snapshot) {
|
|
211
|
-
return claudeConnector(snapshot)?.registry?.rejected.find((row) => row.safeErrorCode === "PEER_ALIAS_COLLISION")?.count ?? 0;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* The registry-drift signal: the scan saw records and could not parse a single
|
|
215
|
-
* one into the fields Embassy consumes, and has not since this broker started.
|
|
216
|
-
* That is what a changed Claude Code registry layout looks like from here.
|
|
217
|
-
*/
|
|
218
|
-
function registryDrifted(snapshot) {
|
|
219
|
-
const registry = claudeConnector(snapshot)?.registry;
|
|
220
|
-
return registry !== undefined && registry.entriesScanned > 0 &&
|
|
221
|
-
!registry.parseableRecordSeenSinceBoot;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Columns padded to content width; the last column is never padded. Padding is
|
|
225
|
-
* measured and applied on the plain value and colour is put on afterwards —
|
|
226
|
-
* padding a string that already carries escape bytes counts them as width and
|
|
227
|
-
* shears the table apart the moment colour is on.
|
|
228
|
-
*/
|
|
229
|
-
function table(headers, rows, paint) {
|
|
230
|
-
const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => (row[index]?.value ?? "").length)));
|
|
231
|
-
const render = (cells) => cells.map((cell, index) => {
|
|
232
|
-
const padded = index === headers.length - 1 ? cell.value : cell.value.padEnd(widths[index] ?? 0);
|
|
233
|
-
return cell.tone === undefined ? padded : paint(padded, cell.tone);
|
|
234
|
-
}).join(" ").trimEnd();
|
|
235
|
-
return [render(headers.map((value) => ({ value }))), ...rows.map(render)];
|
|
236
|
-
}
|
|
237
|
-
/** The most recent alert per (code, host, alias), newest first, remedied ones only. */
|
|
238
|
-
function actionableAlerts(alerts) {
|
|
239
|
-
const latest = new Map();
|
|
240
|
-
for (const alert of alerts) {
|
|
241
|
-
latest.set(`${alert.code} ${alert.host ?? ""} ${alert.alias ?? ""}`, alert);
|
|
242
|
-
}
|
|
243
|
-
const rows = [...latest.values()].sort((left, right) => right.timestamp.localeCompare(left.timestamp));
|
|
244
|
-
const explained = rows.filter((alert) => STATUS_REMEDY[alert.code] !== undefined);
|
|
245
|
-
return {
|
|
246
|
-
shown: explained.slice(0, STATUS_CAPS.alerts),
|
|
247
|
-
hidden: Math.max(0, explained.length - STATUS_CAPS.alerts),
|
|
248
|
-
unexplained: rows.length - explained.length,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
const messageArrow = (event) => `${event.sourceAlias} → ${event.targetAlias}`;
|
|
252
|
-
export function renderStatus(snapshot, options) {
|
|
253
|
-
const now = options.now;
|
|
254
|
-
const paint = terminalPainter(options.color);
|
|
255
|
-
const lines = [];
|
|
256
|
-
const overall = overallWord(snapshot);
|
|
257
|
-
const discoveredByAlias = new Map(snapshot.availablePeers.map((peer) => [peer.alias, peer]));
|
|
258
|
-
const brokerFacts = [
|
|
259
|
-
paint(overall, wordColor(overall)),
|
|
260
|
-
...(options.pid === undefined ? [] : [`pid ${String(options.pid)}`]),
|
|
261
|
-
`snapshot ${relativeAge(snapshot.generatedAt, now)}`,
|
|
262
|
-
];
|
|
263
|
-
lines.push(`${paint(`embassy ${options.version}`, "bold")} broker ${brokerFacts.join(" · ")}`);
|
|
264
|
-
lines.push(paint(`state dir ${options.stateDir}`, "dim"));
|
|
265
|
-
// `status` never rescans — a rescan journals an activity row and performs a
|
|
266
|
-
// passive discovery scan, both of which need the operator to ask. So the
|
|
267
|
-
// header says how old the scan is and offers the command. The scan's own
|
|
268
|
-
// stamp is the newest `availablePeers[].lastSeenAt`: every discovered
|
|
269
|
-
// session is stamped by the scan that found it, whereas the claude
|
|
270
|
-
// connector's `lastSeenAt` also moves on a delivery. With nothing
|
|
271
|
-
// discovered there is no stamp to read, so the line says that rather than
|
|
272
|
-
// inventing an age.
|
|
273
|
-
const scannedAt = snapshot.availablePeers
|
|
274
|
-
.map((peer) => peer.lastSeenAt)
|
|
275
|
-
.filter((stamp) => stamp !== undefined)
|
|
276
|
-
.sort().at(-1);
|
|
277
|
-
const scanAge = ageMs(scannedAt, now);
|
|
278
|
-
lines.push(paint(scannedAt === undefined ? "sessions: none discovered"
|
|
279
|
-
: `sessions scanned ${relativeAge(scannedAt, now)}`, "dim") +
|
|
280
|
-
(scanAge === undefined || scanAge > STATUS_SCAN_STALE_AFTER_MS
|
|
281
|
-
? paint(" — run `embassy refresh` to rescan", "yellow") : ""));
|
|
282
|
-
lines.push("", paint("connectors", "bold"));
|
|
283
|
-
const routedConnectors = snapshot.connectors.filter((connector) => connector.provider === "claude" || connector.provider === "codex");
|
|
284
|
-
if (routedConnectors.length === 0)
|
|
285
|
-
lines.push(" none — the broker has no provider connectors");
|
|
286
|
-
for (const connector of routedConnectors) {
|
|
287
|
-
const word = connectorWord(connector);
|
|
288
|
-
const suffix = word === "ok" ? "" : ` ${connector.safeErrorCode ?? "no safe code"}`;
|
|
289
|
-
lines.push(` ${connector.provider.padEnd(7)} ${paint(word, wordColor(word))}${suffix}`);
|
|
290
|
-
if (word !== "ok")
|
|
291
|
-
lines.push(paint(` ${connectorRemedy(connector, snapshot)}`, "dim"));
|
|
292
|
-
if (connector.provider === "claude" && registryDrifted(snapshot)) {
|
|
293
|
-
lines.push(paint(" no parseable session record since broker start — Claude Code's registry layout may have changed; run `embassy check`", "yellow"));
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// A registered shell peer is a connector from the operator's side: the route
|
|
297
|
-
// exists, but whether anything is awaiting it lives in another terminal.
|
|
298
|
-
// Queued mail with no waiter is the one observable proof, and it never
|
|
299
|
-
// touches the overall word. Stale first, so the cap can only hide quiet ones.
|
|
300
|
-
const shellPeers = snapshot.routes
|
|
301
|
-
.filter((route) => route.provider === "peer")
|
|
302
|
-
.sort((left, right) => Number(right.queueDepth > 0) - Number(left.queueDepth > 0));
|
|
303
|
-
for (const peer of shellPeers.slice(0, STATUS_CAPS.shellPeers)) {
|
|
304
|
-
const waiting = peer.queueDepth > 0;
|
|
305
|
-
lines.push(` ${peer.alias} ${waiting
|
|
306
|
-
? paint("stale (token or await loop gone)", "yellow") : paint("ok", "green")}`);
|
|
307
|
-
if (waiting) {
|
|
308
|
-
lines.push(paint(` ${String(peer.queueDepth)} message(s) waiting: run \`embassy await --alias ${peer.alias} --token-stdin\` in the shell holding its token, or \`embassy unregister-peer --alias ${peer.alias} --token-stdin\`.`, "dim"));
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
if (shellPeers.length > STATUS_CAPS.shellPeers) {
|
|
312
|
-
lines.push(paint(` ${String(shellPeers.length - STATUS_CAPS.shellPeers)} more shell peer(s) with empty mailboxes`, "dim"));
|
|
313
|
-
}
|
|
314
|
-
lines.push("", paint("sessions", "bold"));
|
|
315
|
-
if (snapshot.availablePeers.length === 0) {
|
|
316
|
-
lines.push(" none discovered — start a Claude Code session, then run `embassy refresh`");
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
const rows = snapshot.availablePeers.slice(0, STATUS_CAPS.sessions).map((peer) => {
|
|
320
|
-
const word = peer.state === "awaiting_approval" ? "awaiting" : peer.state;
|
|
321
|
-
return [{ value: peer.alias }, { value: word, tone: wordColor(word === "offline" ? "offline" : "ok") },
|
|
322
|
-
{ value: peer.routed ? "routed" : "no route yet" },
|
|
323
|
-
{ value: relativeAge(peer.lastSeenAt, now) }];
|
|
324
|
-
});
|
|
325
|
-
for (const line of table(["session", "state", "route", "last seen"], rows, paint)) {
|
|
326
|
-
lines.push(` ${line}`);
|
|
327
|
-
}
|
|
328
|
-
if (snapshot.availablePeers.length > STATUS_CAPS.sessions) {
|
|
329
|
-
lines.push(paint(` ${String(snapshot.availablePeers.length - STATUS_CAPS.sessions)} more discovered session(s) — read \`embassy status --json\``, "dim"));
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
const collisions = collisionCount(snapshot);
|
|
333
|
-
if (collisions > 0) {
|
|
334
|
-
lines.push(paint(` ${String(collisions)} discovered Claude name(s) are shared by more than one live session and are hidden from this list; ${STATUS_REMEDY.PEER_ALIAS_COLLISION ?? ""}`, "yellow"));
|
|
335
|
-
}
|
|
336
|
-
lines.push("", paint("routes", "bold"));
|
|
337
|
-
if (snapshot.routes.length === 0) {
|
|
338
|
-
lines.push(" none — a Claude session's route installs on its first send; a Codex task is registered explicitly");
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
const views = snapshot.routes.map((route) => ({
|
|
342
|
-
route, view: routeView(route, route.provider === "claude" ? discoveredByAlias.get(route.alias) : undefined, now),
|
|
343
|
-
}));
|
|
344
|
-
const rows = views.map(({ route, view }) => [
|
|
345
|
-
{ value: route.alias }, { value: route.provider },
|
|
346
|
-
{ value: view.word, tone: wordColor(view.word === "idle" || view.word === "busy" ? "ok" : view.word) },
|
|
347
|
-
{ value: String(route.queueDepth) }, { value: view.lastSeen },
|
|
348
|
-
]);
|
|
349
|
-
for (const line of table(["alias", "provider", "state", "queue", "last seen"], rows, paint)) {
|
|
350
|
-
lines.push(` ${line}`);
|
|
351
|
-
}
|
|
352
|
-
for (const { route, view } of views) {
|
|
353
|
-
if (view.remedy === undefined)
|
|
354
|
-
continue;
|
|
355
|
-
lines.push(paint(` ${route.alias}: ${view.remedy}`, "dim"));
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
const recent = snapshot.messages.slice(-options.recent);
|
|
359
|
-
lines.push("", paint(`recent (${String(recent.length)} of ${String(snapshot.messages.length)})`, "bold"));
|
|
360
|
-
if (recent.length === 0)
|
|
361
|
-
lines.push(" no messages retained");
|
|
362
|
-
for (const event of [...recent].reverse()) {
|
|
363
|
-
const latency = event.latencyMs === undefined ? "" : ` ${String(event.latencyMs)} ms`;
|
|
364
|
-
const code = event.safeErrorCode === undefined ? "" : ` ${event.safeErrorCode}`;
|
|
365
|
-
lines.push(` ${relativeAge(event.timestamp, now).padEnd(9)} ${messageArrow(event)} ${event.state}${latency}${code}`);
|
|
366
|
-
if (event.body !== undefined)
|
|
367
|
-
lines.push(paint(` ${previewBody(event.body)}`, "dim"));
|
|
368
|
-
}
|
|
369
|
-
const { shown, hidden, unexplained } = actionableAlerts(snapshot.alerts);
|
|
370
|
-
if (shown.length > 0) {
|
|
371
|
-
lines.push("", paint("alerts", "bold"));
|
|
372
|
-
for (const alert of shown) {
|
|
373
|
-
const subject = alert.alias ?? alert.host ?? alert.provider ?? "";
|
|
374
|
-
lines.push(` ${alert.code}${subject === "" ? "" : ` ${subject}`} ${relativeAge(alert.timestamp, now)}`);
|
|
375
|
-
lines.push(paint(` ${STATUS_REMEDY[alert.code] ?? ""}`, "dim"));
|
|
376
|
-
}
|
|
377
|
-
if (hidden > 0)
|
|
378
|
-
lines.push(paint(` ${String(hidden)} more alert(s) not shown`, "dim"));
|
|
379
|
-
if (unexplained > 0) {
|
|
380
|
-
lines.push(paint(` ${String(unexplained)} alert(s) with no known remedy — read \`embassy status --json\``, "dim"));
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
const omitted = Object.entries(snapshot.truncation)
|
|
384
|
-
.filter((entry) => typeof entry[1] === "number" && entry[1] > 0)
|
|
385
|
-
.map(([name, count]) => `${String(count)} ${name}`);
|
|
386
|
-
if (omitted.length > 0) {
|
|
387
|
-
lines.push("", paint(`omitted from this snapshot: ${omitted.join(", ")}`, "dim"));
|
|
388
|
-
}
|
|
389
|
-
return `${lines.join("\n")}\n`;
|
|
390
|
-
}
|
|
391
|
-
export const emptyWatchState = Object.freeze({
|
|
392
|
-
messageStates: new Map(), lastSequence: -1,
|
|
393
|
-
lastActivitySequence: -1, truncatedMessages: 0,
|
|
394
|
-
});
|
|
395
|
-
/**
|
|
396
|
-
* Pure diff of one poll against the last, in stable emit order.
|
|
397
|
-
*
|
|
398
|
-
* A snapshot can carry the same message twice — once as a journaled activity
|
|
399
|
-
* event and once as the live row — so the last occurrence in sequence order is
|
|
400
|
-
* the current state. What this can promise is "at most once per observed
|
|
401
|
-
* change": a transition the broker passed through entirely between two polls
|
|
402
|
-
* is never seen, and rows evicted from the retained window before this tail
|
|
403
|
-
* reached them are reported as a notice rather than silently skipped.
|
|
404
|
-
*/
|
|
405
|
-
export function diffWatch(previous, snapshot) {
|
|
406
|
-
const events = [];
|
|
407
|
-
const ordered = [...snapshot.messages].sort((left, right) => left.sequence - right.sequence);
|
|
408
|
-
const messageStates = new Map();
|
|
409
|
-
const sequences = [...ordered.map((event) => event.sequence),
|
|
410
|
-
...(snapshot.activityEvents ?? []).map((event) => event.sequence)];
|
|
411
|
-
const lastSequence = sequences.length === 0 ? previous.lastSequence
|
|
412
|
-
: Math.max(previous.lastSequence, ...sequences);
|
|
413
|
-
// Message and activity events share one counter, and settling a message
|
|
414
|
-
// re-stamps it, so an ordinary gap in the numbers proves nothing. Only a
|
|
415
|
-
// jump wider than the whole retained window proves rows were evicted before
|
|
416
|
-
// this tail could read them — that, and truncation, are the honest signals.
|
|
417
|
-
const lowest = sequences.length === 0 ? undefined : Math.min(...sequences);
|
|
418
|
-
const missed = lowest === undefined ? 0 : lowest - previous.lastSequence - 1;
|
|
419
|
-
if (previous.lastSequence >= 0 && missed > gatewayPublicSnapshotLimits.messages) {
|
|
420
|
-
events.push({ type: "notice", text: `the retained window advanced past ${String(missed)} event(s) before this tail saw them` });
|
|
421
|
-
}
|
|
422
|
-
if (snapshot.truncation.messages > previous.truncatedMessages) {
|
|
423
|
-
events.push({ type: "notice", text: `${String(snapshot.truncation.messages)} message row(s) omitted from this snapshot by the size budget` });
|
|
424
|
-
}
|
|
425
|
-
for (const event of ordered) {
|
|
426
|
-
const before = previous.messageStates.get(event.messageIdSuffix);
|
|
427
|
-
const already = messageStates.get(event.messageIdSuffix);
|
|
428
|
-
messageStates.set(event.messageIdSuffix, event.state);
|
|
429
|
-
if (already === event.state)
|
|
430
|
-
continue;
|
|
431
|
-
if (before === undefined && already === undefined) {
|
|
432
|
-
events.push({ type: "message", event });
|
|
433
|
-
continue;
|
|
434
|
-
}
|
|
435
|
-
const from = already ?? before;
|
|
436
|
-
if (from === event.state)
|
|
437
|
-
continue;
|
|
438
|
-
events.push({
|
|
439
|
-
type: "transition", message: event.messageIdSuffix, timestamp: event.timestamp,
|
|
440
|
-
from, to: event.state, sourceAlias: event.sourceAlias, targetAlias: event.targetAlias,
|
|
441
|
-
...(event.latencyMs === undefined ? {} : { latencyMs: event.latencyMs }),
|
|
442
|
-
...(event.safeErrorCode === undefined ? {} : { safeErrorCode: event.safeErrorCode }),
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
let lastActivitySequence = previous.lastActivitySequence;
|
|
446
|
-
for (const event of [...(snapshot.activityEvents ?? [])].sort((left, right) => left.sequence - right.sequence)) {
|
|
447
|
-
if (event.sequence <= previous.lastActivitySequence)
|
|
448
|
-
continue;
|
|
449
|
-
events.push({ type: "activity", event });
|
|
450
|
-
lastActivitySequence = Math.max(lastActivitySequence, event.sequence);
|
|
451
|
-
}
|
|
452
|
-
return {
|
|
453
|
-
state: { messageStates, lastSequence, lastActivitySequence,
|
|
454
|
-
truncatedMessages: snapshot.truncation.messages },
|
|
455
|
-
events,
|
|
456
|
-
};
|
|
457
|
-
}
|
|
458
|
-
const SETTLED_BADLY = ["failed", "ambiguous", "unconfirmed", "expired", "cancelled", "abandoned", "rejected"];
|
|
459
|
-
/** Local wall-clock time, because a tail is read beside other live logs. */
|
|
460
|
-
const clockOf = (timestamp) => {
|
|
461
|
-
const parsed = Date.parse(timestamp);
|
|
462
|
-
return Number.isFinite(parsed) ? new Date(parsed).toTimeString().slice(0, 8) : "--:--:--";
|
|
463
|
-
};
|
|
464
|
-
/** One terminal line per watch event; the activity line is deliberately secondary. */
|
|
465
|
-
export function renderWatchEvent(event, color) {
|
|
466
|
-
const paint = terminalPainter(color);
|
|
467
|
-
if (event.type === "notice")
|
|
468
|
-
return paint(` note ${event.text}`, "yellow");
|
|
469
|
-
if (event.type === "message") {
|
|
470
|
-
const preview = event.event.body === undefined
|
|
471
|
-
? "" : ` ${paint(previewBody(event.event.body, 40), "dim")}`;
|
|
472
|
-
return `${clockOf(event.event.timestamp)} ${event.event.messageIdSuffix} ${messageArrow(event.event)} ${event.event.state} ${String(event.event.bytes)} B${preview}`;
|
|
473
|
-
}
|
|
474
|
-
if (event.type === "transition") {
|
|
475
|
-
const latency = event.latencyMs === undefined ? "" : ` (${String(event.latencyMs)} ms)`;
|
|
476
|
-
const code = event.safeErrorCode === undefined ? "" : ` ${event.safeErrorCode}`;
|
|
477
|
-
const word = event.to === "delivered" ? paint(event.to, "green")
|
|
478
|
-
: SETTLED_BADLY.includes(event.to) ? paint(event.to, "red") : event.to;
|
|
479
|
-
return `${clockOf(event.timestamp)} ${event.message} ${event.from} → ${word}${latency}${code}`;
|
|
480
|
-
}
|
|
481
|
-
const detail = event.event.safeErrorCode === undefined ? "" : ` ${event.event.safeErrorCode}`;
|
|
482
|
-
return paint(`${clockOf(event.event.timestamp)} ${event.event.action} ${event.event.aliases.join(", ")} ${event.event.outcome}${detail}`, "dim");
|
|
483
|
-
}
|
|
484
|
-
/** Pure helpers the renderer's own tests drive directly; not part of the CLI surface. */
|
|
485
|
-
export const __test = Object.freeze({
|
|
486
|
-
connectorWord, overallWord, previewBody, relativeAge, routeView,
|
|
487
|
-
});
|
|
488
|
-
//# sourceMappingURL=status-view.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"status-view.js","sourceRoot":"","sources":["../../../src/gateway/status-view.ts"],"names":[],"mappings":"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"}
|