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.
- package/CHANGELOG.md +61 -0
- package/CONTRIBUTING.md +122 -0
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/README.zh-CN.md +185 -0
- package/SECURITY.md +224 -0
- package/assets/live-dashboard/app.css +1610 -0
- package/assets/mark-seal.svg +7 -0
- package/assets/mark.svg +7 -0
- package/assets/social-preview.png +0 -0
- package/assets/vendor/react/LICENSE +21 -0
- package/assets/vendor/react/react-dom.production.min.js +267 -0
- package/assets/vendor/react/react.production.min.js +31 -0
- package/dist/src/errors.d.ts +5 -0
- package/dist/src/errors.js +11 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/gateway/claude-compatibility-scratch.d.ts +18 -0
- package/dist/src/gateway/claude-compatibility-scratch.js +158 -0
- package/dist/src/gateway/claude-compatibility-scratch.js.map +1 -0
- package/dist/src/gateway/claude-helper-client.d.ts +43 -0
- package/dist/src/gateway/claude-helper-client.js +212 -0
- package/dist/src/gateway/claude-helper-client.js.map +1 -0
- package/dist/src/gateway/claude-helper-protocol.d.ts +172 -0
- package/dist/src/gateway/claude-helper-protocol.js +373 -0
- package/dist/src/gateway/claude-helper-protocol.js.map +1 -0
- package/dist/src/gateway/claude-helper-supervisor.d.ts +74 -0
- package/dist/src/gateway/claude-helper-supervisor.js +497 -0
- package/dist/src/gateway/claude-helper-supervisor.js.map +1 -0
- package/dist/src/gateway/claude-helper.d.ts +1 -0
- package/dist/src/gateway/claude-helper.js +269 -0
- package/dist/src/gateway/claude-helper.js.map +1 -0
- package/dist/src/gateway/claude-peer.d.ts +273 -0
- package/dist/src/gateway/claude-peer.js +2359 -0
- package/dist/src/gateway/claude-peer.js.map +1 -0
- package/dist/src/gateway/claude-runtime.d.ts +40 -0
- package/dist/src/gateway/claude-runtime.js +302 -0
- package/dist/src/gateway/claude-runtime.js.map +1 -0
- package/dist/src/gateway/cli-copy.d.ts +8 -0
- package/dist/src/gateway/cli-copy.en.d.ts +13 -0
- package/dist/src/gateway/cli-copy.en.js +43 -0
- package/dist/src/gateway/cli-copy.en.js.map +1 -0
- package/dist/src/gateway/cli-copy.js +19 -0
- package/dist/src/gateway/cli-copy.js.map +1 -0
- package/dist/src/gateway/cli-copy.zh-CN.d.ts +13 -0
- package/dist/src/gateway/cli-copy.zh-CN.js +43 -0
- package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -0
- package/dist/src/gateway/cli.d.ts +44 -0
- package/dist/src/gateway/cli.js +969 -0
- package/dist/src/gateway/cli.js.map +1 -0
- package/dist/src/gateway/codex-app-server.d.ts +310 -0
- package/dist/src/gateway/codex-app-server.js +1746 -0
- package/dist/src/gateway/codex-app-server.js.map +1 -0
- package/dist/src/gateway/codex-local-transport.d.ts +81 -0
- package/dist/src/gateway/codex-local-transport.js +617 -0
- package/dist/src/gateway/codex-local-transport.js.map +1 -0
- package/dist/src/gateway/codex-registration-generation.d.ts +5 -0
- package/dist/src/gateway/codex-registration-generation.js +19 -0
- package/dist/src/gateway/codex-registration-generation.js.map +1 -0
- package/dist/src/gateway/codex-registration-succession.d.ts +209 -0
- package/dist/src/gateway/codex-registration-succession.js +588 -0
- package/dist/src/gateway/codex-registration-succession.js.map +1 -0
- package/dist/src/gateway/compatibility.d.ts +70 -0
- package/dist/src/gateway/compatibility.js +252 -0
- package/dist/src/gateway/compatibility.js.map +1 -0
- package/dist/src/gateway/config.d.ts +24 -0
- package/dist/src/gateway/config.js +130 -0
- package/dist/src/gateway/config.js.map +1 -0
- package/dist/src/gateway/control.d.ts +308 -0
- package/dist/src/gateway/control.js +1573 -0
- package/dist/src/gateway/control.js.map +1 -0
- package/dist/src/gateway/dashboard-copy.d.ts +7 -0
- package/dist/src/gateway/dashboard-copy.en.d.ts +506 -0
- package/dist/src/gateway/dashboard-copy.en.js +507 -0
- package/dist/src/gateway/dashboard-copy.en.js.map +1 -0
- package/dist/src/gateway/dashboard-copy.js +516 -0
- package/dist/src/gateway/dashboard-copy.js.map +1 -0
- package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +506 -0
- package/dist/src/gateway/dashboard-copy.zh-CN.js +507 -0
- package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -0
- package/dist/src/gateway/dashboard-model.d.ts +207 -0
- package/dist/src/gateway/dashboard-model.js +720 -0
- package/dist/src/gateway/dashboard-model.js.map +1 -0
- package/dist/src/gateway/dashboard.d.ts +26 -0
- package/dist/src/gateway/dashboard.js +941 -0
- package/dist/src/gateway/dashboard.js.map +1 -0
- package/dist/src/gateway/delivery-machine.d.ts +235 -0
- package/dist/src/gateway/delivery-machine.js +540 -0
- package/dist/src/gateway/delivery-machine.js.map +1 -0
- package/dist/src/gateway/instance-lease.d.ts +21 -0
- package/dist/src/gateway/instance-lease.js +549 -0
- package/dist/src/gateway/instance-lease.js.map +1 -0
- package/dist/src/gateway/live-dashboard-app/app.js +2914 -0
- package/dist/src/gateway/live-dashboard-assets.d.ts +10 -0
- package/dist/src/gateway/live-dashboard-assets.js +73 -0
- package/dist/src/gateway/live-dashboard-assets.js.map +1 -0
- package/dist/src/gateway/live-dashboard-bootstrap.d.ts +36 -0
- package/dist/src/gateway/live-dashboard-bootstrap.js +176 -0
- package/dist/src/gateway/live-dashboard-bootstrap.js.map +1 -0
- package/dist/src/gateway/live-dashboard-command.d.ts +54 -0
- package/dist/src/gateway/live-dashboard-command.js +324 -0
- package/dist/src/gateway/live-dashboard-command.js.map +1 -0
- package/dist/src/gateway/live-dashboard-http.d.ts +41 -0
- package/dist/src/gateway/live-dashboard-http.js +445 -0
- package/dist/src/gateway/live-dashboard-http.js.map +1 -0
- package/dist/src/gateway/live-dashboard-protocol.d.ts +38 -0
- package/dist/src/gateway/live-dashboard-protocol.js +156 -0
- package/dist/src/gateway/live-dashboard-protocol.js.map +1 -0
- package/dist/src/gateway/live-dashboard-server.d.ts +33 -0
- package/dist/src/gateway/live-dashboard-server.js +130 -0
- package/dist/src/gateway/live-dashboard-server.js.map +1 -0
- package/dist/src/gateway/live-dashboard-stream.d.ts +46 -0
- package/dist/src/gateway/live-dashboard-stream.js +233 -0
- package/dist/src/gateway/live-dashboard-stream.js.map +1 -0
- package/dist/src/gateway/live-dashboard.d.ts +31 -0
- package/dist/src/gateway/live-dashboard.js +190 -0
- package/dist/src/gateway/live-dashboard.js.map +1 -0
- package/dist/src/gateway/locale.d.ts +4 -0
- package/dist/src/gateway/locale.js +10 -0
- package/dist/src/gateway/locale.js.map +1 -0
- package/dist/src/gateway/progress-watch-machine.d.ts +97 -0
- package/dist/src/gateway/progress-watch-machine.js +172 -0
- package/dist/src/gateway/progress-watch-machine.js.map +1 -0
- package/dist/src/gateway/providers.d.ts +287 -0
- package/dist/src/gateway/providers.js +2451 -0
- package/dist/src/gateway/providers.js.map +1 -0
- package/dist/src/gateway/server.d.ts +57 -0
- package/dist/src/gateway/server.js +264 -0
- package/dist/src/gateway/server.js.map +1 -0
- package/dist/src/gateway/service.d.ts +449 -0
- package/dist/src/gateway/service.js +4831 -0
- package/dist/src/gateway/service.js.map +1 -0
- package/dist/src/gateway/store.d.ts +340 -0
- package/dist/src/gateway/store.js +4047 -0
- package/dist/src/gateway/store.js.map +1 -0
- package/dist/src/gateway/types.d.ts +514 -0
- package/dist/src/gateway/types.js +414 -0
- package/dist/src/gateway/types.js.map +1 -0
- package/dist/src/mutex.d.ts +4 -0
- package/dist/src/mutex.js +23 -0
- package/dist/src/mutex.js.map +1 -0
- package/docs/DESIGN.md +134 -0
- package/docs/GATEWAY-ARCHITECTURE.md +858 -0
- package/package.json +80 -0
- package/skills/embassy-peer/SKILL.md +198 -0
- package/skills/embassy-peer/agents/openai.yaml +4 -0
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { spawn, } from "node:child_process";
|
|
3
|
+
import { constants } from "node:fs";
|
|
4
|
+
import { chmod, lstat, mkdir, open, readdir, realpath, unlink, } from "node:fs/promises";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { BridgeError } from "../errors.js";
|
|
8
|
+
const HOST_STATE_DIRECTORY = path.join(".local", "state", "agent-embassy");
|
|
9
|
+
const HOST_STATE_MARKER_FILE = ".agent-embassy-state";
|
|
10
|
+
const HOST_STATE_MARKER_CONTENT = "agent-embassy-state-v1\n";
|
|
11
|
+
const HOST_LOCK_FILE = ".gateway-host.lock";
|
|
12
|
+
const LEGACY_STATE_DIRECTORY = path.join(".local", "state", "claude-agent-bridge", "gateway");
|
|
13
|
+
const LEGACY_MARKER_FILE = ".claude-codex-gateway-state";
|
|
14
|
+
const LEGACY_MARKER_CONTENT = "claude-codex-local-gateway-state-v1\n";
|
|
15
|
+
const LEGACY_LOCK_FILE = ".gateway-controller.lock";
|
|
16
|
+
const MAX_MARKER_BYTES = 128;
|
|
17
|
+
const MAX_LOCK_BYTES = 4 * 1024;
|
|
18
|
+
const LOCKF_PATH = "/usr/bin/lockf";
|
|
19
|
+
const CAT_PATH = "/bin/cat";
|
|
20
|
+
const HOST_LEASE_READY_TIMEOUT_MS = 5_000;
|
|
21
|
+
const HOST_LEASE_EXIT_TIMEOUT_MS = 5_000;
|
|
22
|
+
function isObject(value) {
|
|
23
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
function isPositiveInteger(value) {
|
|
26
|
+
return Number.isSafeInteger(value) && value > 0;
|
|
27
|
+
}
|
|
28
|
+
function isLockRecord(value) {
|
|
29
|
+
if (!isObject(value))
|
|
30
|
+
return false;
|
|
31
|
+
const keys = Object.keys(value);
|
|
32
|
+
return (keys.length === 4 &&
|
|
33
|
+
keys.every((key) => ["schemaVersion", "pid", "hostname", "token"].includes(key)) &&
|
|
34
|
+
value.schemaVersion === 1 &&
|
|
35
|
+
isPositiveInteger(value.pid) &&
|
|
36
|
+
typeof value.hostname === "string" &&
|
|
37
|
+
value.hostname.length > 0 &&
|
|
38
|
+
value.hostname.length <= 255 &&
|
|
39
|
+
typeof value.token === "string" &&
|
|
40
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value.token));
|
|
41
|
+
}
|
|
42
|
+
function assertPrivateOwned(uid, mode, description) {
|
|
43
|
+
if (typeof process.getuid === "function" && uid !== process.getuid()) {
|
|
44
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", `${description} is not owned by the current process user.`, true);
|
|
45
|
+
}
|
|
46
|
+
if ((mode & 0o077) !== 0) {
|
|
47
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", `${description} is not private to the current process user.`, true);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function readPrivateFile(filePath, maximumBytes) {
|
|
51
|
+
const info = await lstat(filePath);
|
|
52
|
+
if (info.isSymbolicLink() || !info.isFile() || info.size > maximumBytes) {
|
|
53
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "An Embassy instance-control file cannot be safely verified.", true);
|
|
54
|
+
}
|
|
55
|
+
assertPrivateOwned(info.uid, info.mode, "An Embassy instance-control file");
|
|
56
|
+
const handle = await open(filePath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
57
|
+
try {
|
|
58
|
+
const opened = await handle.stat();
|
|
59
|
+
if (!opened.isFile() ||
|
|
60
|
+
opened.dev !== info.dev ||
|
|
61
|
+
opened.ino !== info.ino ||
|
|
62
|
+
opened.size > maximumBytes) {
|
|
63
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "An Embassy instance-control file changed during verification.", true);
|
|
64
|
+
}
|
|
65
|
+
assertPrivateOwned(opened.uid, opened.mode, "An Embassy instance-control file");
|
|
66
|
+
const buffer = Buffer.alloc(maximumBytes + 1);
|
|
67
|
+
let offset = 0;
|
|
68
|
+
while (offset < buffer.length) {
|
|
69
|
+
const { bytesRead } = await handle.read(buffer, offset, buffer.length - offset, offset);
|
|
70
|
+
if (bytesRead === 0)
|
|
71
|
+
break;
|
|
72
|
+
offset += bytesRead;
|
|
73
|
+
}
|
|
74
|
+
if (offset > maximumBytes) {
|
|
75
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "An Embassy instance-control file exceeds its bounded size.", true);
|
|
76
|
+
}
|
|
77
|
+
return buffer.subarray(0, offset).toString("utf8");
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
await handle.close();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function waitForChildExit(child, timeoutMs) {
|
|
84
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
85
|
+
return Promise.resolve();
|
|
86
|
+
}
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
const timer = setTimeout(() => {
|
|
89
|
+
cleanup();
|
|
90
|
+
reject(new BridgeError("GATEWAY_CLEANUP_FAILED", "Embassy could not confirm host-wide lease cleanup."));
|
|
91
|
+
}, timeoutMs);
|
|
92
|
+
const onExit = () => {
|
|
93
|
+
cleanup();
|
|
94
|
+
resolve();
|
|
95
|
+
};
|
|
96
|
+
const cleanup = () => {
|
|
97
|
+
clearTimeout(timer);
|
|
98
|
+
child.removeListener("exit", onExit);
|
|
99
|
+
};
|
|
100
|
+
child.once("exit", onExit);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function waitForHostLeaseReady(child, challenge) {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
let output = "";
|
|
106
|
+
let settled = false;
|
|
107
|
+
const timer = setTimeout(() => {
|
|
108
|
+
finish(new BridgeError("GATEWAY_INSTANCE_IN_USE", "Another or unverifiable Embassy gateway owns this machine.", true));
|
|
109
|
+
}, HOST_LEASE_READY_TIMEOUT_MS);
|
|
110
|
+
const cleanup = () => {
|
|
111
|
+
clearTimeout(timer);
|
|
112
|
+
child.stdout.removeListener("data", onData);
|
|
113
|
+
child.removeListener("error", onError);
|
|
114
|
+
child.removeListener("exit", onExit);
|
|
115
|
+
};
|
|
116
|
+
const finish = (error) => {
|
|
117
|
+
if (settled)
|
|
118
|
+
return;
|
|
119
|
+
settled = true;
|
|
120
|
+
cleanup();
|
|
121
|
+
if (error === undefined)
|
|
122
|
+
resolve();
|
|
123
|
+
else
|
|
124
|
+
reject(error);
|
|
125
|
+
};
|
|
126
|
+
const unavailable = () => new BridgeError("GATEWAY_INSTANCE_IN_USE", "Another or unverifiable Embassy gateway owns this machine.", true);
|
|
127
|
+
const onData = (chunk) => {
|
|
128
|
+
output += chunk.toString();
|
|
129
|
+
if (Buffer.byteLength(output, "utf8") > MAX_LOCK_BYTES) {
|
|
130
|
+
finish(unavailable());
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (output === challenge)
|
|
134
|
+
finish();
|
|
135
|
+
else if (output.includes("\n"))
|
|
136
|
+
finish(unavailable());
|
|
137
|
+
};
|
|
138
|
+
const onError = () => finish(unavailable());
|
|
139
|
+
const onExit = () => finish(unavailable());
|
|
140
|
+
const onStdinError = () => finish(unavailable());
|
|
141
|
+
child.stdout.on("data", onData);
|
|
142
|
+
child.once("error", onError);
|
|
143
|
+
child.once("exit", onExit);
|
|
144
|
+
// A contending lockf helper may exit before the challenge write reaches
|
|
145
|
+
// its pipe. Its stdin then emits EPIPE/ERR_STREAM_DESTROYED in addition to
|
|
146
|
+
// invoking the write callback. Treat that as the same bounded contention
|
|
147
|
+
// outcome instead of allowing an unhandled stream error to escape.
|
|
148
|
+
child.stdin.on("error", onStdinError);
|
|
149
|
+
child.stdin.write(challenge, "utf8", (error) => {
|
|
150
|
+
if (error !== null && error !== undefined)
|
|
151
|
+
finish(unavailable());
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function monitorHostLeaseLoss(child) {
|
|
156
|
+
let resolveLost;
|
|
157
|
+
let expectedClose = false;
|
|
158
|
+
let lost = false;
|
|
159
|
+
let disposed = false;
|
|
160
|
+
const loss = new Promise((resolve) => {
|
|
161
|
+
resolveLost = resolve;
|
|
162
|
+
});
|
|
163
|
+
const markLost = () => {
|
|
164
|
+
if (expectedClose || lost)
|
|
165
|
+
return;
|
|
166
|
+
lost = true;
|
|
167
|
+
resolveLost?.();
|
|
168
|
+
};
|
|
169
|
+
const onError = () => markLost();
|
|
170
|
+
const onExit = () => markLost();
|
|
171
|
+
// Attach this monitor before the READY handshake. The handshake removes its
|
|
172
|
+
// own temporary listeners when it resolves, so this permanent listener
|
|
173
|
+
// closes the otherwise possible READY-to-monitor event gap.
|
|
174
|
+
child.on("error", onError);
|
|
175
|
+
child.on("exit", onExit);
|
|
176
|
+
return {
|
|
177
|
+
lost: loss,
|
|
178
|
+
isLost: () => lost,
|
|
179
|
+
assertHeld: () => {
|
|
180
|
+
if (lost) {
|
|
181
|
+
throw new BridgeError("GATEWAY_INSTANCE_LEASE_LOST", "Embassy lost its host-wide gateway lease.", true);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
expectClose: () => {
|
|
185
|
+
expectedClose = true;
|
|
186
|
+
},
|
|
187
|
+
dispose: () => {
|
|
188
|
+
if (disposed)
|
|
189
|
+
return;
|
|
190
|
+
disposed = true;
|
|
191
|
+
child.removeListener("error", onError);
|
|
192
|
+
child.removeListener("exit", onExit);
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
async function acquireHostAdvisoryLease(directory, spawnLeaseHelper, exitTimeoutMs) {
|
|
197
|
+
const lockPath = path.join(directory, HOST_LOCK_FILE);
|
|
198
|
+
const seed = await open(lockPath, constants.O_CREAT |
|
|
199
|
+
constants.O_RDWR |
|
|
200
|
+
(constants.O_NOFOLLOW ?? 0), 0o600);
|
|
201
|
+
let seededDevice;
|
|
202
|
+
let seededInode;
|
|
203
|
+
try {
|
|
204
|
+
const info = await seed.stat();
|
|
205
|
+
if (!info.isFile()) {
|
|
206
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The Embassy host lease is not a regular file.", true);
|
|
207
|
+
}
|
|
208
|
+
assertPrivateOwned(info.uid, info.mode, "The Embassy host lease");
|
|
209
|
+
seededDevice = info.dev;
|
|
210
|
+
seededInode = info.ino;
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
await seed.close();
|
|
214
|
+
}
|
|
215
|
+
const child = spawnLeaseHelper(LOCKF_PATH, ["-k", "-t", "0", lockPath, CAT_PATH], {
|
|
216
|
+
env: {},
|
|
217
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
218
|
+
});
|
|
219
|
+
const monitor = monitorHostLeaseLoss(child);
|
|
220
|
+
const token = randomUUID();
|
|
221
|
+
const challenge = `embassy-host-lease:${token}\n`;
|
|
222
|
+
try {
|
|
223
|
+
await waitForHostLeaseReady(child, challenge);
|
|
224
|
+
monitor.assertHeld();
|
|
225
|
+
const lockedInfo = await lstat(lockPath);
|
|
226
|
+
if (lockedInfo.isSymbolicLink() ||
|
|
227
|
+
!lockedInfo.isFile() ||
|
|
228
|
+
lockedInfo.dev !== seededDevice ||
|
|
229
|
+
lockedInfo.ino !== seededInode) {
|
|
230
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The Embassy host lease changed during acquisition.", true);
|
|
231
|
+
}
|
|
232
|
+
assertPrivateOwned(lockedInfo.uid, lockedInfo.mode, "The Embassy host lease");
|
|
233
|
+
const record = {
|
|
234
|
+
schemaVersion: 1,
|
|
235
|
+
pid: process.pid,
|
|
236
|
+
hostname: os.hostname(),
|
|
237
|
+
token,
|
|
238
|
+
};
|
|
239
|
+
const recordHandle = await open(lockPath, constants.O_RDWR | (constants.O_NOFOLLOW ?? 0));
|
|
240
|
+
try {
|
|
241
|
+
const opened = await recordHandle.stat();
|
|
242
|
+
if (opened.dev !== seededDevice || opened.ino !== seededInode) {
|
|
243
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The Embassy host lease changed during acquisition.", true);
|
|
244
|
+
}
|
|
245
|
+
await recordHandle.truncate(0);
|
|
246
|
+
await recordHandle.writeFile(`${JSON.stringify(record)}\n`, "utf8");
|
|
247
|
+
await recordHandle.sync();
|
|
248
|
+
}
|
|
249
|
+
finally {
|
|
250
|
+
await recordHandle.close();
|
|
251
|
+
}
|
|
252
|
+
monitor.assertHeld();
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
monitor.expectClose();
|
|
256
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
257
|
+
child.stdin.end();
|
|
258
|
+
child.kill("SIGTERM");
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
await waitForChildExit(child, exitTimeoutMs);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
265
|
+
child.kill("SIGKILL");
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
await waitForChildExit(child, exitTimeoutMs);
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
throw new BridgeError("GATEWAY_CLEANUP_FAILED", "Embassy could not confirm failed host-lease acquisition cleanup.");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
finally {
|
|
275
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
276
|
+
monitor.dispose();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (error instanceof BridgeError)
|
|
280
|
+
throw error;
|
|
281
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "Embassy could not acquire its host-wide gateway lease.", true);
|
|
282
|
+
}
|
|
283
|
+
let closed = false;
|
|
284
|
+
return {
|
|
285
|
+
lost: monitor.lost,
|
|
286
|
+
isLost: monitor.isLost,
|
|
287
|
+
close: async () => {
|
|
288
|
+
if (closed)
|
|
289
|
+
return;
|
|
290
|
+
closed = true;
|
|
291
|
+
monitor.expectClose();
|
|
292
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
293
|
+
child.stdin.end();
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
await waitForChildExit(child, exitTimeoutMs);
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
300
|
+
child.kill("SIGKILL");
|
|
301
|
+
await waitForChildExit(child, exitTimeoutMs).catch(() => undefined);
|
|
302
|
+
}
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
finally {
|
|
306
|
+
monitor.dispose();
|
|
307
|
+
}
|
|
308
|
+
// Deliberately keep the fixed lock file. Removing it after releasing the
|
|
309
|
+
// kernel lock creates an unlink/recreate race in which a successor can
|
|
310
|
+
// be locked on the old inode while a third process locks a new one.
|
|
311
|
+
// Reusing one private inode preserves lock ordering across generations.
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
async function acquireProcessLease(directory, lockFileName) {
|
|
316
|
+
const lockPath = path.join(directory, lockFileName);
|
|
317
|
+
const ownedToken = randomUUID();
|
|
318
|
+
let handle;
|
|
319
|
+
try {
|
|
320
|
+
handle = await open(lockPath, constants.O_CREAT |
|
|
321
|
+
constants.O_EXCL |
|
|
322
|
+
constants.O_RDWR |
|
|
323
|
+
(constants.O_NOFOLLOW ?? 0), 0o600);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
if (error instanceof Error &&
|
|
327
|
+
"code" in error &&
|
|
328
|
+
error.code === "EEXIST") {
|
|
329
|
+
// The legacy controller did not participate in Embassy's kernel-held
|
|
330
|
+
// host lease. Preserve any pre-existing legacy lock—live, stale, or
|
|
331
|
+
// unverifiable—rather than path-reclaiming across that protocol boundary.
|
|
332
|
+
await readPrivateFile(lockPath, MAX_LOCK_BYTES).catch(() => undefined);
|
|
333
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "A legacy or unverifiable gateway lock already exists.", true);
|
|
334
|
+
}
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
const record = {
|
|
339
|
+
schemaVersion: 1,
|
|
340
|
+
pid: process.pid,
|
|
341
|
+
hostname: os.hostname(),
|
|
342
|
+
token: ownedToken,
|
|
343
|
+
};
|
|
344
|
+
await handle.writeFile(`${JSON.stringify(record)}\n`, "utf8");
|
|
345
|
+
await handle.sync();
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
await handle.close().catch(() => undefined);
|
|
349
|
+
await unlink(lockPath).catch(() => undefined);
|
|
350
|
+
throw error;
|
|
351
|
+
}
|
|
352
|
+
let closed = false;
|
|
353
|
+
return {
|
|
354
|
+
close: async () => {
|
|
355
|
+
if (closed)
|
|
356
|
+
return;
|
|
357
|
+
closed = true;
|
|
358
|
+
try {
|
|
359
|
+
await handle.close();
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
throw new BridgeError("GATEWAY_CLEANUP_FAILED", "Embassy could not confirm legacy instance-lease cleanup.");
|
|
363
|
+
}
|
|
364
|
+
try {
|
|
365
|
+
const current = JSON.parse(await readPrivateFile(lockPath, MAX_LOCK_BYTES));
|
|
366
|
+
if (isLockRecord(current) && current.token === ownedToken) {
|
|
367
|
+
await unlink(lockPath);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
if (error instanceof Error &&
|
|
372
|
+
"code" in error &&
|
|
373
|
+
error.code === "ENOENT") {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
throw new BridgeError("GATEWAY_CLEANUP_FAILED", "Embassy could not confirm legacy instance-lease cleanup.");
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
async function ensureHostStateMarker(directory) {
|
|
382
|
+
const markerPath = path.join(directory, HOST_STATE_MARKER_FILE);
|
|
383
|
+
try {
|
|
384
|
+
const marker = await readPrivateFile(markerPath, MAX_MARKER_BYTES);
|
|
385
|
+
if (marker !== HOST_STATE_MARKER_CONTENT) {
|
|
386
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The Embassy host-lease root has an unrecognized ownership marker.", true);
|
|
387
|
+
}
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
catch (error) {
|
|
391
|
+
if (!(error instanceof Error) ||
|
|
392
|
+
!("code" in error) ||
|
|
393
|
+
error.code !== "ENOENT") {
|
|
394
|
+
throw error;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// Claim only a genuinely empty root. In particular, do not make a
|
|
398
|
+
// pre-existing non-empty directory look Embassy-owned merely because it is
|
|
399
|
+
// at the default path.
|
|
400
|
+
if ((await readdir(directory)).length > 0) {
|
|
401
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The Embassy host-lease root is non-empty and has no ownership marker.", true);
|
|
402
|
+
}
|
|
403
|
+
let marker;
|
|
404
|
+
try {
|
|
405
|
+
marker = await open(markerPath, constants.O_CREAT |
|
|
406
|
+
constants.O_EXCL |
|
|
407
|
+
constants.O_WRONLY |
|
|
408
|
+
(constants.O_NOFOLLOW ?? 0), 0o600);
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
if (error instanceof Error &&
|
|
412
|
+
"code" in error &&
|
|
413
|
+
error.code === "EEXIST") {
|
|
414
|
+
const racedMarker = await readPrivateFile(markerPath, MAX_MARKER_BYTES);
|
|
415
|
+
if (racedMarker === HOST_STATE_MARKER_CONTENT)
|
|
416
|
+
return;
|
|
417
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The Embassy host-lease root has an unrecognized ownership marker.", true);
|
|
418
|
+
}
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
421
|
+
try {
|
|
422
|
+
await marker.writeFile(HOST_STATE_MARKER_CONTENT, "utf8");
|
|
423
|
+
await marker.chmod(0o600);
|
|
424
|
+
await marker.sync();
|
|
425
|
+
}
|
|
426
|
+
finally {
|
|
427
|
+
await marker.close();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
function validateLoginHome(loginHome) {
|
|
431
|
+
if (!path.isAbsolute(loginHome) ||
|
|
432
|
+
path.resolve(loginHome) !== loginHome ||
|
|
433
|
+
loginHome.includes("\0")) {
|
|
434
|
+
throw new BridgeError("INVALID_GATEWAY_LOGIN_HOME", "Embassy requires the verified absolute login home.");
|
|
435
|
+
}
|
|
436
|
+
return loginHome;
|
|
437
|
+
}
|
|
438
|
+
async function prepareHostLeaseDirectory(loginHome) {
|
|
439
|
+
const homeInfo = await lstat(loginHome);
|
|
440
|
+
if (homeInfo.isSymbolicLink() ||
|
|
441
|
+
!homeInfo.isDirectory() ||
|
|
442
|
+
(await realpath(loginHome)) !== loginHome ||
|
|
443
|
+
(typeof process.getuid === "function" &&
|
|
444
|
+
homeInfo.uid !== process.getuid())) {
|
|
445
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The verified login home is not a current-user real directory.", true);
|
|
446
|
+
}
|
|
447
|
+
let current = loginHome;
|
|
448
|
+
let leafCreated = false;
|
|
449
|
+
const components = HOST_STATE_DIRECTORY.split(path.sep);
|
|
450
|
+
for (const [index, component] of components.entries()) {
|
|
451
|
+
current = path.join(current, component);
|
|
452
|
+
try {
|
|
453
|
+
await mkdir(current, { mode: 0o700 });
|
|
454
|
+
if (index === components.length - 1)
|
|
455
|
+
leafCreated = true;
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
if (!(error instanceof Error) ||
|
|
459
|
+
!("code" in error) ||
|
|
460
|
+
error.code !== "EEXIST") {
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
const info = await lstat(current);
|
|
465
|
+
if (info.isSymbolicLink() ||
|
|
466
|
+
!info.isDirectory() ||
|
|
467
|
+
(typeof process.getuid === "function" && info.uid !== process.getuid()) ||
|
|
468
|
+
(await realpath(current)) !== current) {
|
|
469
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "An Embassy host-lease path component is not a current-user real directory.", true);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (leafCreated)
|
|
473
|
+
await chmod(current, 0o700);
|
|
474
|
+
const leaf = await lstat(current);
|
|
475
|
+
assertPrivateOwned(leaf.uid, leaf.mode, "The Embassy host lease root");
|
|
476
|
+
await ensureHostStateMarker(current);
|
|
477
|
+
return current;
|
|
478
|
+
}
|
|
479
|
+
async function recognizedLegacyRoot(loginHome) {
|
|
480
|
+
const directory = path.join(loginHome, LEGACY_STATE_DIRECTORY);
|
|
481
|
+
try {
|
|
482
|
+
const info = await lstat(directory);
|
|
483
|
+
if (info.isSymbolicLink() || !info.isDirectory())
|
|
484
|
+
return undefined;
|
|
485
|
+
assertPrivateOwned(info.uid, info.mode, "The legacy gateway root");
|
|
486
|
+
if ((await realpath(directory)) !== directory)
|
|
487
|
+
return undefined;
|
|
488
|
+
const marker = await readPrivateFile(path.join(directory, LEGACY_MARKER_FILE), MAX_MARKER_BYTES);
|
|
489
|
+
return marker === LEGACY_MARKER_CONTENT ? directory : undefined;
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
// An absent, unsafe, or unrecognized legacy tree is never mutated.
|
|
493
|
+
return undefined;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Acquire the one per-login-user Embassy controller lease. The fixed lease is
|
|
498
|
+
* deliberately independent of EMBASSY_STATE_DIR. For one release, a genuine
|
|
499
|
+
* legacy default state root is also leased so a still-running pre-rename
|
|
500
|
+
* gateway cannot advertise a second Codex peer.
|
|
501
|
+
*/
|
|
502
|
+
export async function acquireGatewayInstanceLease(suppliedLoginHome, dependencies = {}) {
|
|
503
|
+
const loginHome = validateLoginHome(suppliedLoginHome);
|
|
504
|
+
const hostDirectory = await prepareHostLeaseDirectory(loginHome);
|
|
505
|
+
const leases = [];
|
|
506
|
+
let hostLease;
|
|
507
|
+
try {
|
|
508
|
+
// A kernel-held macOS lease makes state-directory overrides irrelevant and
|
|
509
|
+
// disappears automatically if the gateway crashes. The PID/token record
|
|
510
|
+
// is metadata for exact cleanup; it is never used for path-only reclaim.
|
|
511
|
+
const spawnLeaseHelper = dependencies.spawnLeaseHelper ??
|
|
512
|
+
((command, args, options) => spawn(command, args, options));
|
|
513
|
+
const exitTimeoutMs = dependencies.hostLeaseExitTimeoutMs ?? HOST_LEASE_EXIT_TIMEOUT_MS;
|
|
514
|
+
if (!Number.isSafeInteger(exitTimeoutMs) ||
|
|
515
|
+
exitTimeoutMs < 10 ||
|
|
516
|
+
exitTimeoutMs > HOST_LEASE_EXIT_TIMEOUT_MS) {
|
|
517
|
+
throw new BridgeError("GATEWAY_INSTANCE_IN_USE", "The Embassy host-lease cleanup bound is invalid.", true);
|
|
518
|
+
}
|
|
519
|
+
hostLease = await acquireHostAdvisoryLease(hostDirectory, spawnLeaseHelper, exitTimeoutMs);
|
|
520
|
+
leases.push(hostLease);
|
|
521
|
+
const legacyDirectory = await recognizedLegacyRoot(loginHome);
|
|
522
|
+
if (legacyDirectory !== undefined) {
|
|
523
|
+
leases.push(await acquireProcessLease(legacyDirectory, LEGACY_LOCK_FILE));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
catch (error) {
|
|
527
|
+
for (const lease of leases.reverse())
|
|
528
|
+
await lease.close();
|
|
529
|
+
throw error;
|
|
530
|
+
}
|
|
531
|
+
let closed = false;
|
|
532
|
+
return {
|
|
533
|
+
lost: hostLease.lost,
|
|
534
|
+
isLost: hostLease.isLost,
|
|
535
|
+
close: async () => {
|
|
536
|
+
if (closed)
|
|
537
|
+
return;
|
|
538
|
+
closed = true;
|
|
539
|
+
const failures = [];
|
|
540
|
+
for (const lease of leases.reverse()) {
|
|
541
|
+
await lease.close().catch((error) => failures.push(error));
|
|
542
|
+
}
|
|
543
|
+
if (failures.length > 0) {
|
|
544
|
+
throw new BridgeError("GATEWAY_CLEANUP_FAILED", "Embassy could not confirm exact instance-lease cleanup.");
|
|
545
|
+
}
|
|
546
|
+
},
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=instance-lease.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-lease.js","sourceRoot":"","sources":["../../../src/gateway/instance-lease.ts"],"names":[],"mappings":"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"}
|