agent-embassy 3.1.0 → 4.1.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 (118) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/CONTRIBUTING.md +92 -202
  3. package/README.md +179 -162
  4. package/SECURITY.md +191 -348
  5. package/dist/src/gateway/broker-check.d.ts +26 -0
  6. package/dist/src/gateway/broker-check.js +89 -0
  7. package/dist/src/gateway/broker-check.js.map +1 -0
  8. package/dist/src/gateway/broker-control.d.ts +72 -0
  9. package/dist/src/gateway/broker-control.js +164 -0
  10. package/dist/src/gateway/broker-control.js.map +1 -0
  11. package/dist/src/gateway/broker.d.ts +117 -0
  12. package/dist/src/gateway/broker.js +186 -0
  13. package/dist/src/gateway/broker.js.map +1 -0
  14. package/dist/src/gateway/claude-peer.d.ts +1 -124
  15. package/dist/src/gateway/claude-peer.js +61 -1052
  16. package/dist/src/gateway/claude-peer.js.map +1 -1
  17. package/dist/src/gateway/codex-stateless-transport.d.ts +0 -12
  18. package/dist/src/gateway/codex-stateless-transport.js +9 -142
  19. package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
  20. package/dist/src/gateway/config.d.ts +2 -6
  21. package/dist/src/gateway/config.js +17 -27
  22. package/dist/src/gateway/config.js.map +1 -1
  23. package/dist/src/gateway/coordinator.d.ts +57 -0
  24. package/dist/src/gateway/coordinator.js +217 -0
  25. package/dist/src/gateway/coordinator.js.map +1 -0
  26. package/dist/src/gateway/core-cli.d.ts +14 -0
  27. package/dist/src/gateway/core-cli.js +293 -0
  28. package/dist/src/gateway/core-cli.js.map +1 -0
  29. package/dist/src/gateway/core-service-command.d.ts +16 -0
  30. package/dist/src/gateway/core-service-command.js +71 -0
  31. package/dist/src/gateway/core-service-command.js.map +1 -0
  32. package/dist/src/gateway/core-version.d.ts +1 -0
  33. package/dist/src/gateway/core-version.js +2 -0
  34. package/dist/src/gateway/core-version.js.map +1 -0
  35. package/dist/src/gateway/endpoint-directory.d.ts +33 -0
  36. package/dist/src/gateway/endpoint-directory.js +223 -0
  37. package/dist/src/gateway/endpoint-directory.js.map +1 -0
  38. package/dist/src/gateway/federation.d.ts +89 -0
  39. package/dist/src/gateway/federation.js +632 -0
  40. package/dist/src/gateway/federation.js.map +1 -0
  41. package/dist/src/gateway/ledger-codec.d.ts +3 -0
  42. package/dist/src/gateway/ledger-codec.js +159 -0
  43. package/dist/src/gateway/ledger-codec.js.map +1 -0
  44. package/dist/src/gateway/ledger.d.ts +138 -0
  45. package/dist/src/gateway/ledger.js +319 -0
  46. package/dist/src/gateway/ledger.js.map +1 -0
  47. package/dist/src/gateway/local-control.d.ts +23 -0
  48. package/dist/src/gateway/local-control.js +489 -0
  49. package/dist/src/gateway/local-control.js.map +1 -0
  50. package/dist/src/gateway/native-destinations.d.ts +34 -0
  51. package/dist/src/gateway/native-destinations.js +272 -0
  52. package/dist/src/gateway/native-destinations.js.map +1 -0
  53. package/dist/src/gateway/owned-state.d.ts +57 -0
  54. package/dist/src/gateway/owned-state.js +398 -0
  55. package/dist/src/gateway/owned-state.js.map +1 -0
  56. package/dist/src/gateway/provenance-envelope.d.ts +3 -3
  57. package/dist/src/gateway/provenance-envelope.js +3 -23
  58. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  59. package/dist/src/gateway/runtime.d.ts +41 -0
  60. package/dist/src/gateway/runtime.js +175 -0
  61. package/dist/src/gateway/runtime.js.map +1 -0
  62. package/dist/src/gateway/tui.d.ts +67 -0
  63. package/dist/src/gateway/tui.js +516 -0
  64. package/dist/src/gateway/tui.js.map +1 -0
  65. package/docs/CONFIGURATION.md +178 -266
  66. package/docs/DELIVERY.md +133 -82
  67. package/docs/GATEWAY-ARCHITECTURE.md +281 -949
  68. package/package.json +5 -5
  69. package/skills/embassy-peer/SKILL.md +38 -196
  70. package/skills/embassy-peer/agents/openai.yaml +2 -2
  71. package/dist/src/gateway/claude-helper-protocol.d.ts +0 -117
  72. package/dist/src/gateway/claude-helper-protocol.js +0 -122
  73. package/dist/src/gateway/claude-helper-protocol.js.map +0 -1
  74. package/dist/src/gateway/claude-helper-supervisor.d.ts +0 -87
  75. package/dist/src/gateway/claude-helper-supervisor.js +0 -374
  76. package/dist/src/gateway/claude-helper-supervisor.js.map +0 -1
  77. package/dist/src/gateway/claude-helper.d.ts +0 -1
  78. package/dist/src/gateway/claude-helper.js +0 -252
  79. package/dist/src/gateway/claude-helper.js.map +0 -1
  80. package/dist/src/gateway/cli.d.ts +0 -56
  81. package/dist/src/gateway/cli.js +0 -1532
  82. package/dist/src/gateway/cli.js.map +0 -1
  83. package/dist/src/gateway/codex-socket-holder.d.ts +0 -26
  84. package/dist/src/gateway/codex-socket-holder.js +0 -76
  85. package/dist/src/gateway/codex-socket-holder.js.map +0 -1
  86. package/dist/src/gateway/control.d.ts +0 -279
  87. package/dist/src/gateway/control.js +0 -933
  88. package/dist/src/gateway/control.js.map +0 -1
  89. package/dist/src/gateway/peer-client.d.ts +0 -58
  90. package/dist/src/gateway/peer-client.js +0 -217
  91. package/dist/src/gateway/peer-client.js.map +0 -1
  92. package/dist/src/gateway/peer-mailbox.d.ts +0 -78
  93. package/dist/src/gateway/peer-mailbox.js +0 -168
  94. package/dist/src/gateway/peer-mailbox.js.map +0 -1
  95. package/dist/src/gateway/peer-protocol.d.ts +0 -110
  96. package/dist/src/gateway/peer-protocol.js +0 -79
  97. package/dist/src/gateway/peer-protocol.js.map +0 -1
  98. package/dist/src/gateway/peer-stdio.d.ts +0 -23
  99. package/dist/src/gateway/peer-stdio.js +0 -100
  100. package/dist/src/gateway/peer-stdio.js.map +0 -1
  101. package/dist/src/gateway/providers.d.ts +0 -164
  102. package/dist/src/gateway/providers.js +0 -975
  103. package/dist/src/gateway/providers.js.map +0 -1
  104. package/dist/src/gateway/server.d.ts +0 -46
  105. package/dist/src/gateway/server.js +0 -216
  106. package/dist/src/gateway/server.js.map +0 -1
  107. package/dist/src/gateway/service.d.ts +0 -371
  108. package/dist/src/gateway/service.js +0 -2335
  109. package/dist/src/gateway/service.js.map +0 -1
  110. package/dist/src/gateway/status-view.d.ts +0 -119
  111. package/dist/src/gateway/status-view.js +0 -484
  112. package/dist/src/gateway/status-view.js.map +0 -1
  113. package/dist/src/gateway/store.d.ts +0 -188
  114. package/dist/src/gateway/store.js +0 -2360
  115. package/dist/src/gateway/store.js.map +0 -1
  116. package/dist/src/gateway/types.d.ts +0 -541
  117. package/dist/src/gateway/types.js +0 -332
  118. package/dist/src/gateway/types.js.map +0 -1
@@ -0,0 +1,175 @@
1
+ import { userInfo } from "node:os";
2
+ import path from "node:path";
3
+ import { BridgeError } from "../errors.js";
4
+ import { LoopbackDestination } from "./broker-check.js";
5
+ import { handleBrokerCommand } from "./broker-control.js";
6
+ import { MessagingBroker } from "./broker.js";
7
+ import { ClaudePeerAdapter } from "./claude-peer.js";
8
+ import { attestClaudePeerRuntime } from "./claude-runtime.js";
9
+ import { createStatelessCodexOperationTransport } from "./codex-stateless-transport.js";
10
+ import { loadGatewayConfig, defaultGatewayStateDir } from "./config.js";
11
+ import { Coordinator } from "./coordinator.js";
12
+ import { EndpointDirectory } from "./endpoint-directory.js";
13
+ import { ensureGatewayNodeInventoryFile, loadGatewayNodeInventory } from "./federation-nodes.js";
14
+ import { Federation, isFederatedHandoff } from "./federation.js";
15
+ import { acquireGatewayInstanceLease } from "./instance-lease.js";
16
+ import { createLedgerCodec } from "./ledger-codec.js";
17
+ import { serveLocalControl } from "./local-control.js";
18
+ import { ClaudeDestination, CodexDestination } from "./native-destinations.js";
19
+ import { OwnedStateFile } from "./owned-state.js";
20
+ const leaseLost = () => new BridgeError("GATEWAY_INSTANCE_LEASE_LOST", "Embassy lost its host-wide gateway lease and shut down.", true);
21
+ const cancelled = () => new BridgeError("GATEWAY_START_CANCELLED", "Gateway startup was cancelled before it became ready.", true);
22
+ const codexEnvironment = (env) => Object.fromEntries(["HOME", "USER", "LOGNAME"].flatMap((key) => env[key] === undefined ? [] : [[key, env[key]]]));
23
+ /** Assemble the schema-6 broker. Construction is inert: provider and SSH I/O starts
24
+ * only when an addressed operation reaches its destination. */
25
+ export async function runCoreRuntime(options, dependencies = {}) {
26
+ const env = options.env ?? process.env;
27
+ const d = {
28
+ loginHome: dependencies.loginHome ?? (() => userInfo().homedir),
29
+ loadInventory: dependencies.loadInventory ?? loadGatewayNodeInventory,
30
+ ensureInventory: dependencies.ensureInventory ?? ensureGatewayNodeInventoryFile,
31
+ loadConfig: dependencies.loadConfig ?? loadGatewayConfig,
32
+ acquireLease: dependencies.acquireLease ?? acquireGatewayInstanceLease,
33
+ attestClaudeRuntime: dependencies.attestClaudeRuntime ?? attestClaudePeerRuntime,
34
+ createClaudePeer: dependencies.createClaudePeer ?? ((runtime, config) => new ClaudePeerAdapter({ ...runtime })),
35
+ createCodexOperation: dependencies.createCodexOperation ?? ((source) => createStatelessCodexOperationTransport({ local: { environment: codexEnvironment(source) } })),
36
+ createFederation: dependencies.createFederation ?? ((host, nodes) => new Federation({ host, nodes })),
37
+ serveControl: dependencies.serveControl ?? serveLocalControl,
38
+ add: dependencies.addSignalListener ?? ((signal, listener) => process.on(signal, listener)),
39
+ remove: dependencies.removeSignalListener ?? ((signal, listener) => process.off(signal, listener)),
40
+ };
41
+ const controller = new AbortController();
42
+ let ready = false;
43
+ const stop = () => { ready = false; controller.abort(); };
44
+ const stopped = new Promise((resolve) => controller.signal.addEventListener("abort", () => resolve(), { once: true }));
45
+ d.add("SIGINT", stop);
46
+ try {
47
+ d.add("SIGTERM", stop);
48
+ }
49
+ catch (error) {
50
+ d.remove("SIGINT", stop);
51
+ throw error;
52
+ }
53
+ options.signal?.addEventListener("abort", stop, { once: true });
54
+ if (options.signal?.aborted)
55
+ stop();
56
+ let lease, store;
57
+ let control, broker;
58
+ let claude, loopback;
59
+ let federation;
60
+ let primary;
61
+ try {
62
+ if (controller.signal.aborted)
63
+ throw cancelled();
64
+ let inventory = await d.loadInventory(path.resolve(defaultGatewayStateDir(env)));
65
+ if (controller.signal.aborted)
66
+ throw cancelled();
67
+ const config = d.loadConfig(env, inventory), ledgerLimits = config.limits;
68
+ const acquiring = d.acquireLease(d.loginHome()).then((value) => ({ kind: "lease", value }), (error) => ({ kind: "error", error }));
69
+ const acquired = await Promise.race([acquiring, stopped.then(() => ({ kind: "stopped" }))]);
70
+ if (acquired.kind === "stopped") {
71
+ void acquiring.then((late) => late.kind === "lease" ? late.value.close().catch(() => undefined) : undefined);
72
+ throw cancelled();
73
+ }
74
+ if (acquired.kind === "error")
75
+ throw acquired.error;
76
+ lease = acquired.value;
77
+ const assertLease = () => { if (lease.isLost())
78
+ throw leaseLost(); };
79
+ const assertStarting = () => { assertLease(); if (controller.signal.aborted)
80
+ throw cancelled(); };
81
+ const assertWrite = () => {
82
+ assertLease();
83
+ if (controller.signal.aborted)
84
+ throw new BridgeError("GATEWAY_SHUTDOWN", "The gateway is stopping.");
85
+ };
86
+ const awaitInertStartup = async (operation) => {
87
+ const outcome = await Promise.race([
88
+ operation.then((value) => ({ kind: "result", value }), (error) => ({ kind: "error", error })),
89
+ stopped.then(() => ({ kind: "stopped" })),
90
+ lease.lost.then(() => ({ kind: "lost" })),
91
+ ]);
92
+ if (outcome.kind === "result")
93
+ return outcome.value;
94
+ if (outcome.kind === "error")
95
+ throw outcome.error;
96
+ throw outcome.kind === "lost" ? leaseLost() : cancelled();
97
+ };
98
+ assertStarting();
99
+ // Validate the installed ledger before any first-boot inventory write. An
100
+ // unsupported or corrupt state refusal must leave every directory byte intact.
101
+ store = new OwnedStateFile(config.stateDir, createLedgerCodec(config.hostId, ledgerLimits), { assertWritable: assertLease });
102
+ await store.initialize();
103
+ assertStarting();
104
+ inventory = await d.ensureInventory(config.stateDir, inventory.host);
105
+ assertStarting();
106
+ if (inventory.host !== config.hostId || inventory.nodes.length !== config.peerNodes.length ||
107
+ inventory.nodes.some((node, index) => node !== config.peerNodes[index])) {
108
+ throw new BridgeError("GATEWAY_NODE_INVENTORY_CHANGED", "nodes.json changed while the broker was starting.");
109
+ }
110
+ assertStarting();
111
+ // Attestation owns no resource and performs no writes, so shutdown may stop
112
+ // waiting for a stuck filesystem read without leaving a late cleanup burden.
113
+ const runtime = await awaitInertStartup(Promise.resolve().then(() => d.attestClaudeRuntime()));
114
+ assertStarting();
115
+ const peer = d.createClaudePeer(runtime, config);
116
+ claude = new ClaudeDestination({ host: config.hostId, stateRoot: config.stateDir, peer });
117
+ const codex = new CodexDestination({ host: config.hostId, operation: d.createCodexOperation(env) });
118
+ loopback = new LoopbackDestination(codex);
119
+ federation = d.createFederation(config.hostId, config.peerNodes);
120
+ const directory = new EndpointDirectory({ host: config.hostId, limits: ledgerLimits, store, claude: peer, remote: federation });
121
+ const coordinator = new Coordinator({ host: config.hostId, limits: ledgerLimits, store, claude,
122
+ codex: loopback, ssh: federation, resolve: (identity) => directory.exact(identity), assertWritable: assertWrite });
123
+ broker = new MessagingBroker({ host: config.hostId, limits: ledgerLimits, store, directory, coordinator,
124
+ nodes: config.peerNodes, steeringEnabled: config.steeringEnabled, federation });
125
+ control = await d.serveControl({ stateDir: config.stateDir, socketPath: config.controlSocketPath,
126
+ handle: (input) => {
127
+ if (!ready || controller.signal.aborted)
128
+ throw new Error("CONTROL_NOT_READY");
129
+ assertLease();
130
+ return handleBrokerCommand(input, { broker: broker, validateHandoff: isFederatedHandoff,
131
+ check: () => loopback.check({ host: config.hostId, limits: ledgerLimits, store: store, coordinator }) });
132
+ } });
133
+ assertStarting();
134
+ await loopback.cleanup({ host: config.hostId, limits: ledgerLimits, store });
135
+ assertStarting();
136
+ await broker.start();
137
+ assertStarting();
138
+ ready = true;
139
+ const announced = Promise.resolve(options.onReady({ status: "ready", hostId: config.hostId,
140
+ codexMode: "native_messaging" })).then(() => ({ kind: "ready" }), (error) => ({ kind: "error", error }));
141
+ const publication = await Promise.race([announced, stopped.then(() => ({ kind: "stopped" })),
142
+ lease.lost.then(() => ({ kind: "lost" }))]);
143
+ if (publication.kind === "error")
144
+ throw publication.error;
145
+ if (publication.kind === "lost" || lease.isLost())
146
+ throw leaseLost();
147
+ if (publication.kind === "ready" && !controller.signal.aborted)
148
+ await Promise.race([stopped, lease.lost]);
149
+ if (lease.isLost())
150
+ throw leaseLost();
151
+ }
152
+ catch (error) {
153
+ primary = error;
154
+ }
155
+ options.signal?.removeEventListener("abort", stop);
156
+ d.remove("SIGINT", stop);
157
+ d.remove("SIGTERM", stop);
158
+ const failures = [];
159
+ for (const resource of [control, broker, ...(broker === undefined ? [loopback, claude, federation] : []), store]) {
160
+ if (resource !== undefined)
161
+ await resource.close().catch((error) => failures.push(error));
162
+ }
163
+ // If any owned resource did not confirm cleanup, retain a still-held host-wide lease.
164
+ // Releasing it could admit a second broker while the first still owns a socket,
165
+ // provider operation, or state handle. A lease already lost cannot fence anything;
166
+ // close its helper so that failure does not leak another process.
167
+ if (lease !== undefined && (failures.length === 0 || lease.isLost())) {
168
+ await lease.close().catch((error) => failures.push(error));
169
+ }
170
+ if (failures.length)
171
+ throw new AggregateError(primary === undefined ? failures : [primary, ...failures], "Gateway execution and cleanup failures are preserved independently.");
172
+ if (primary !== undefined)
173
+ throw primary;
174
+ }
175
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/gateway/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { type Readable, type Writable } from "node:stream";
2
+ import type { BrokerCommand } from "./broker-control.js";
3
+ type Input = Pick<Readable, "on" | "off"> & {
4
+ isTTY?: boolean;
5
+ isRaw?: boolean;
6
+ readableFlowing?: boolean | null;
7
+ pause?: Readable["pause"];
8
+ resume?: Readable["resume"];
9
+ setRawMode?: (enabled: boolean) => unknown;
10
+ };
11
+ type Output = Pick<Writable, "write"> & {
12
+ isTTY?: boolean;
13
+ columns?: number;
14
+ rows?: number;
15
+ on?: Writable["on"];
16
+ off?: Writable["off"];
17
+ };
18
+ export type TuiDependencies = Readonly<{
19
+ input: Input;
20
+ output: Output;
21
+ call: (command: BrokerCommand) => Promise<unknown>;
22
+ renderStatus: (snapshot: unknown) => string;
23
+ host?: string;
24
+ hint?: (code: string) => string;
25
+ signal?: AbortSignal;
26
+ }>;
27
+ type Obj = Record<string, unknown>;
28
+ type Section = "endpoints" | "deliveries" | "retirements" | "result";
29
+ type Mode = "browse" | "token" | "confirm";
30
+ type EndpointRow = Readonly<{
31
+ id: string;
32
+ alias: string;
33
+ provider: string;
34
+ host: string;
35
+ local: boolean;
36
+ queueDepth?: number;
37
+ lastOperation?: Obj;
38
+ observedAt?: string;
39
+ safeErrorCode?: string;
40
+ placeholder?: boolean;
41
+ }>;
42
+ export type TuiModel = {
43
+ snapshot?: Obj;
44
+ snapshotAt?: number;
45
+ staleSince?: number;
46
+ error?: string;
47
+ action?: string;
48
+ actionRunning?: boolean;
49
+ host?: string;
50
+ restarted?: boolean;
51
+ section: Section;
52
+ previousSection?: Exclude<Section, "result">;
53
+ selected: Record<Exclude<Section, "result">, number> & Partial<Record<"result", number>>;
54
+ selectedEndpoint?: string;
55
+ mode: Mode;
56
+ token: string;
57
+ retiring?: EndpointRow;
58
+ result?: Readonly<{
59
+ label: string;
60
+ value: string;
61
+ }>;
62
+ };
63
+ /** Pure screen renderer. It emits no ANSI so all dynamic values remain inert. */
64
+ export declare function renderTui(model: Readonly<TuiModel>, columns?: number, rows?: number, now?: number): string;
65
+ /** Interactive, dependency-free client over the existing broker commands. */
66
+ export declare function runTui(dependencies: TuiDependencies): Promise<void>;
67
+ export {};