@cortexkit/aft-bridge 0.57.2 → 0.58.1
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/dist/bash-format.d.ts +7 -0
- package/dist/bash-format.d.ts.map +1 -1
- package/dist/bash-format.js +9 -0
- package/dist/bash-format.js.map +1 -1
- package/dist/bash-hints.d.ts +31 -3
- package/dist/bash-hints.d.ts.map +1 -1
- package/dist/bash-hints.js +40 -9
- package/dist/bash-hints.js.map +1 -1
- package/dist/bash-host-fallback.js +1 -1
- package/dist/bash-host-fallback.js.map +1 -1
- package/dist/binary-identity.d.ts +109 -0
- package/dist/binary-identity.d.ts.map +1 -0
- package/dist/binary-identity.js +295 -0
- package/dist/binary-identity.js.map +1 -0
- package/dist/bridge.d.ts +10 -1
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +74 -24
- package/dist/bridge.js.map +1 -1
- package/dist/child-process.d.ts +39 -0
- package/dist/child-process.d.ts.map +1 -0
- package/dist/child-process.js +64 -0
- package/dist/child-process.js.map +1 -0
- package/dist/coerce.d.ts +2 -0
- package/dist/coerce.d.ts.map +1 -1
- package/dist/coerce.js +29 -0
- package/dist/coerce.js.map +1 -1
- package/dist/config-error.d.ts +71 -0
- package/dist/config-error.d.ts.map +1 -0
- package/dist/config-error.js +112 -0
- package/dist/config-error.js.map +1 -0
- package/dist/config-watch.d.ts +170 -0
- package/dist/config-watch.d.ts.map +1 -0
- package/dist/config-watch.js +479 -0
- package/dist/config-watch.js.map +1 -0
- package/dist/downloader.d.ts +4 -2
- package/dist/downloader.d.ts.map +1 -1
- package/dist/downloader.js +41 -20
- package/dist/downloader.js.map +1 -1
- package/dist/durable-log.d.ts +11 -0
- package/dist/durable-log.d.ts.map +1 -1
- package/dist/durable-log.js +81 -5
- package/dist/durable-log.js.map +1 -1
- package/dist/edit-summary.d.ts +8 -0
- package/dist/edit-summary.d.ts.map +1 -1
- package/dist/edit-summary.js +7 -0
- package/dist/edit-summary.js.map +1 -1
- package/dist/feature-config.d.ts +192 -0
- package/dist/feature-config.d.ts.map +1 -0
- package/dist/feature-config.js +657 -0
- package/dist/feature-config.js.map +1 -0
- package/dist/index.d.ts +19 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/message-detach.d.ts +25 -0
- package/dist/message-detach.d.ts.map +1 -0
- package/dist/message-detach.js +34 -0
- package/dist/message-detach.js.map +1 -0
- package/dist/migration-notices.d.ts +29 -0
- package/dist/migration-notices.d.ts.map +1 -0
- package/dist/migration-notices.js +114 -0
- package/dist/migration-notices.js.map +1 -0
- package/dist/migration.d.ts +1 -1
- package/dist/migration.d.ts.map +1 -1
- package/dist/migration.js +1 -1
- package/dist/migration.js.map +1 -1
- package/dist/npm-resolver.d.ts +1 -1
- package/dist/npm-resolver.d.ts.map +1 -1
- package/dist/npm-resolver.js +1 -1
- package/dist/npm-resolver.js.map +1 -1
- package/dist/onnx-probe.d.ts +44 -0
- package/dist/onnx-probe.d.ts.map +1 -0
- package/dist/onnx-probe.js +167 -0
- package/dist/onnx-probe.js.map +1 -0
- package/dist/onnx-runtime.d.ts +19 -4
- package/dist/onnx-runtime.d.ts.map +1 -1
- package/dist/onnx-runtime.js +146 -34
- package/dist/onnx-runtime.js.map +1 -1
- package/dist/path-lookup.d.ts +22 -0
- package/dist/path-lookup.d.ts.map +1 -0
- package/dist/path-lookup.js +51 -0
- package/dist/path-lookup.js.map +1 -0
- package/dist/resolver.d.ts +47 -21
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +254 -159
- package/dist/resolver.js.map +1 -1
- package/dist/revivable-transport.d.ts.map +1 -1
- package/dist/revivable-transport.js +12 -0
- package/dist/revivable-transport.js.map +1 -1
- package/dist/semantic-status.d.ts +10 -1
- package/dist/semantic-status.d.ts.map +1 -1
- package/dist/semantic-status.js +50 -2
- package/dist/semantic-status.js.map +1 -1
- package/dist/storage-paths.d.ts +9 -0
- package/dist/storage-paths.d.ts.map +1 -1
- package/dist/storage-paths.js +18 -1
- package/dist/storage-paths.js.map +1 -1
- package/dist/subc-transport.d.ts +58 -1
- package/dist/subc-transport.d.ts.map +1 -1
- package/dist/subc-transport.js +378 -50
- package/dist/subc-transport.js.map +1 -1
- package/dist/tar-executable.js +1 -1
- package/dist/tar-executable.js.map +1 -1
- package/dist/transport-factory.d.ts +14 -2
- package/dist/transport-factory.d.ts.map +1 -1
- package/dist/transport-factory.js +24 -16
- package/dist/transport-factory.js.map +1 -1
- package/dist/version-probe.d.ts +33 -0
- package/dist/version-probe.d.ts.map +1 -0
- package/dist/version-probe.js +108 -0
- package/dist/version-probe.js.map +1 -0
- package/package.json +2 -2
- package/dist/bash-timeout.d.ts +0 -19
- package/dist/bash-timeout.d.ts.map +0 -1
- package/dist/bash-timeout.js +0 -26
- package/dist/bash-timeout.js.map +0 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity sidecars for binaries in AFT's versioned cache.
|
|
3
|
+
*
|
|
4
|
+
* Plugin hosts (OpenCode, Pi) run every plugin on one JavaScript thread. Asking
|
|
5
|
+
* a cached `aft` binary for its version means executing it, and on macOS the
|
|
6
|
+
* host thread stays inside `posix_spawn` until the child image is paged in and
|
|
7
|
+
* assessed. For an 85 MB binary under memory pressure that has been measured
|
|
8
|
+
* at close to a minute, and the same file goes cold again during the day, so
|
|
9
|
+
* the cost is not paid only once. The host froze for that long on every
|
|
10
|
+
* instance boot.
|
|
11
|
+
*
|
|
12
|
+
* Instead of executing the binary, every writer of the versioned cache records
|
|
13
|
+
* what it installed in a small JSON file next to the binary
|
|
14
|
+
* (`<binary>.identity.json`): the version, byte size, modification time, inode
|
|
15
|
+
* and a SHA-256 of the bytes. Resolution then trusts a cached binary when its
|
|
16
|
+
* sidecar exists and the file's size, mtime and inode still match — a `stat`
|
|
17
|
+
* and a tiny read, never an exec and never a hash. Any mismatch (the file was
|
|
18
|
+
* replaced, touched, or copied over) makes the entry untrusted again.
|
|
19
|
+
*
|
|
20
|
+
* The SHA-256 is never computed on the resolve path, because hashing 85 MB
|
|
21
|
+
* synchronously would block the host thread just like the exec did. It is
|
|
22
|
+
* what a running bridge compares against later to notice that the binary on
|
|
23
|
+
* disk was replaced (see {@link peekBinaryContentHash}).
|
|
24
|
+
*/
|
|
25
|
+
import { createHash } from "node:crypto";
|
|
26
|
+
import { createReadStream, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
27
|
+
import { warn } from "./active-logger.js";
|
|
28
|
+
const SIDECAR_SCHEMA = 1;
|
|
29
|
+
function bareVersion(version) {
|
|
30
|
+
return version.startsWith("v") ? version.slice(1) : version;
|
|
31
|
+
}
|
|
32
|
+
/** Path of the identity sidecar for `binaryPath`. */
|
|
33
|
+
export function identitySidecarPath(binaryPath) {
|
|
34
|
+
return `${binaryPath}.identity.json`;
|
|
35
|
+
}
|
|
36
|
+
function stampOf(binaryPath) {
|
|
37
|
+
const stat = statSync(binaryPath, { bigint: true });
|
|
38
|
+
// Some filesystems (notably FAT volumes on Windows) report inode 0; treat it
|
|
39
|
+
// as unknown rather than as a value every file shares.
|
|
40
|
+
const ino = stat.ino > 0n ? stat.ino.toString() : null;
|
|
41
|
+
return { size: stat.size.toString(), mtimeNs: stat.mtimeNs.toString(), ino };
|
|
42
|
+
}
|
|
43
|
+
function sameStamp(a, b) {
|
|
44
|
+
return a.size === b.size && a.mtimeNs === b.mtimeNs && a.ino === b.ino;
|
|
45
|
+
}
|
|
46
|
+
function parseIdentity(raw) {
|
|
47
|
+
try {
|
|
48
|
+
const value = JSON.parse(raw);
|
|
49
|
+
if (value.schema !== SIDECAR_SCHEMA ||
|
|
50
|
+
typeof value.version !== "string" ||
|
|
51
|
+
typeof value.size !== "string" ||
|
|
52
|
+
typeof value.mtimeNs !== "string" ||
|
|
53
|
+
!(value.ino === null || typeof value.ino === "string") ||
|
|
54
|
+
typeof value.sha256 !== "string") {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** Read and validate the sidecar for `binaryPath`; null when absent or malformed. */
|
|
64
|
+
export function readBinaryIdentity(binaryPath) {
|
|
65
|
+
let raw;
|
|
66
|
+
try {
|
|
67
|
+
raw = readFileSync(identitySidecarPath(binaryPath), "utf8");
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return parseIdentity(raw);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Decide whether the binary at `binaryPath` is still the file its sidecar
|
|
76
|
+
* describes. Uses `stat` only: no exec and no hash, so it is safe on a host's
|
|
77
|
+
* main thread.
|
|
78
|
+
*/
|
|
79
|
+
export function checkBinaryIdentity(binaryPath) {
|
|
80
|
+
const identity = readBinaryIdentity(binaryPath);
|
|
81
|
+
if (!identity)
|
|
82
|
+
return { status: "missing" };
|
|
83
|
+
let stamp;
|
|
84
|
+
try {
|
|
85
|
+
stamp = stampOf(binaryPath);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return { status: "mismatch", reason: "binary is missing or unreadable" };
|
|
89
|
+
}
|
|
90
|
+
if (stamp.size !== identity.size) {
|
|
91
|
+
return { status: "mismatch", reason: `size ${stamp.size} != recorded ${identity.size}` };
|
|
92
|
+
}
|
|
93
|
+
if (stamp.mtimeNs !== identity.mtimeNs) {
|
|
94
|
+
return { status: "mismatch", reason: `mtime ${stamp.mtimeNs} != recorded ${identity.mtimeNs}` };
|
|
95
|
+
}
|
|
96
|
+
// A sidecar written where the inode was unknown cannot vouch for it either
|
|
97
|
+
// way; size and mtime still have to match.
|
|
98
|
+
if (identity.ino !== null && stamp.ino !== identity.ino) {
|
|
99
|
+
return { status: "mismatch", reason: `inode ${stamp.ino} != recorded ${identity.ino}` };
|
|
100
|
+
}
|
|
101
|
+
return { status: "trusted", version: identity.version };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* True when `binaryPath` has a matching sidecar that records `expectedVersion`
|
|
105
|
+
* (with or without a leading `v`). Stat-only; see {@link checkBinaryIdentity}.
|
|
106
|
+
*/
|
|
107
|
+
export function isTrustedCachedBinary(binaryPath, expectedVersion) {
|
|
108
|
+
const check = checkBinaryIdentity(binaryPath);
|
|
109
|
+
return check.status === "trusted" && bareVersion(check.version) === bareVersion(expectedVersion);
|
|
110
|
+
}
|
|
111
|
+
function writeSidecarAtomically(binaryPath, identity) {
|
|
112
|
+
const sidecar = identitySidecarPath(binaryPath);
|
|
113
|
+
const tmp = `${sidecar}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
114
|
+
try {
|
|
115
|
+
writeFileSync(tmp, `${JSON.stringify(identity)}\n`, "utf8");
|
|
116
|
+
if (process.platform === "win32") {
|
|
117
|
+
// renameSync cannot replace an existing file on Windows.
|
|
118
|
+
try {
|
|
119
|
+
unlinkSync(sidecar);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Absent is fine; a real failure surfaces from renameSync below.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
renameSync(tmp, sidecar);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
try {
|
|
129
|
+
unlinkSync(tmp);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// The temp file may never have been created.
|
|
133
|
+
}
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Record the identity of a binary that is already in its final place, with a
|
|
139
|
+
* SHA-256 the caller has already computed (for example while verifying a
|
|
140
|
+
* download against the release checksum). Writes the sidecar atomically
|
|
141
|
+
* (temp file + rename). Synchronous and cheap: one stat and one small write.
|
|
142
|
+
*/
|
|
143
|
+
export function writeBinaryIdentitySidecar(binaryPath, version, sha256) {
|
|
144
|
+
const identity = {
|
|
145
|
+
schema: SIDECAR_SCHEMA,
|
|
146
|
+
version: bareVersion(version),
|
|
147
|
+
...stampOf(binaryPath),
|
|
148
|
+
sha256,
|
|
149
|
+
};
|
|
150
|
+
writeSidecarAtomically(binaryPath, identity);
|
|
151
|
+
return identity;
|
|
152
|
+
}
|
|
153
|
+
/** Remove the sidecar of `binaryPath`, if any, before that binary is replaced. */
|
|
154
|
+
export function removeBinaryIdentitySidecar(binaryPath) {
|
|
155
|
+
try {
|
|
156
|
+
unlinkSync(identitySidecarPath(binaryPath));
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Absent sidecars are the common case.
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* SHA-256 of a file, streamed. The reads run on libuv's thread pool and the
|
|
164
|
+
* digest is fed in small chunks, so the event loop keeps turning while an
|
|
165
|
+
* 85 MB binary is hashed.
|
|
166
|
+
*/
|
|
167
|
+
export function sha256File(path) {
|
|
168
|
+
return new Promise((resolve, reject) => {
|
|
169
|
+
const hash = createHash("sha256");
|
|
170
|
+
const stream = createReadStream(path);
|
|
171
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
172
|
+
stream.on("error", reject);
|
|
173
|
+
stream.on("end", () => resolve(hash.digest("hex")));
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const pendingIdentityWrites = new Set();
|
|
177
|
+
/**
|
|
178
|
+
* Hash `binaryPath` without blocking the event loop and write its sidecar.
|
|
179
|
+
* The file is stat-ed before and after hashing; if it changed in between, no
|
|
180
|
+
* sidecar is written (the hash would describe a file that no longer exists).
|
|
181
|
+
* Never throws; resolves to whether a sidecar was written.
|
|
182
|
+
*/
|
|
183
|
+
export function recordBinaryIdentity(binaryPath, version) {
|
|
184
|
+
const task = (async () => {
|
|
185
|
+
try {
|
|
186
|
+
const before = stampOf(binaryPath);
|
|
187
|
+
const sha256 = await sha256File(binaryPath);
|
|
188
|
+
const after = stampOf(binaryPath);
|
|
189
|
+
if (!sameStamp(before, after)) {
|
|
190
|
+
warn(`Binary at ${binaryPath} changed while it was being hashed; identity not recorded`);
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
writeSidecarAtomically(binaryPath, {
|
|
194
|
+
schema: SIDECAR_SCHEMA,
|
|
195
|
+
version: bareVersion(version),
|
|
196
|
+
...after,
|
|
197
|
+
sha256,
|
|
198
|
+
});
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
warn(`Could not record identity for ${binaryPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
})();
|
|
206
|
+
pendingIdentityWrites.add(task);
|
|
207
|
+
void task.finally(() => pendingIdentityWrites.delete(task));
|
|
208
|
+
return task;
|
|
209
|
+
}
|
|
210
|
+
/** Test helper: wait for every identity write started by {@link recordBinaryIdentity}. */
|
|
211
|
+
export async function __waitForIdentityWritesForTests() {
|
|
212
|
+
while (pendingIdentityWrites.size > 0) {
|
|
213
|
+
await Promise.all([...pendingIdentityWrites]);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* A key for the file's current size, mtime and inode, or null when the file
|
|
218
|
+
* cannot be stat-ed. Two equal keys mean the file has not been replaced or
|
|
219
|
+
* rewritten in between (as far as stat can tell).
|
|
220
|
+
*/
|
|
221
|
+
export function binaryStampKey(binaryPath) {
|
|
222
|
+
try {
|
|
223
|
+
const stamp = stampOf(binaryPath);
|
|
224
|
+
return `${stamp.size}:${stamp.mtimeNs}:${stamp.ino ?? "-"}`;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/** Content hashes already computed, keyed by path, valid while the stamp key is unchanged. */
|
|
231
|
+
const contentHashCache = new Map();
|
|
232
|
+
/** Content hashes being computed, keyed by path and stamp key. */
|
|
233
|
+
const contentHashInFlight = new Map();
|
|
234
|
+
/**
|
|
235
|
+
* SHA-256 of `binaryPath`'s bytes, computed by streaming the file so the event
|
|
236
|
+
* loop keeps running. Resolves to null when the file is unreadable, or when it
|
|
237
|
+
* changes while being hashed. With `expectedStampKey`, also resolves to null
|
|
238
|
+
* unless the file still has that stamp, so the hash can only describe that
|
|
239
|
+
* exact file. Results are cached until the file's stamp changes.
|
|
240
|
+
*/
|
|
241
|
+
export function binaryContentHash(binaryPath, expectedStampKey) {
|
|
242
|
+
const stampKey = binaryStampKey(binaryPath);
|
|
243
|
+
if (stampKey === null)
|
|
244
|
+
return Promise.resolve(null);
|
|
245
|
+
if (expectedStampKey !== undefined && stampKey !== expectedStampKey) {
|
|
246
|
+
return Promise.resolve(null);
|
|
247
|
+
}
|
|
248
|
+
const cached = contentHashCache.get(binaryPath);
|
|
249
|
+
if (cached && cached.stampKey === stampKey)
|
|
250
|
+
return Promise.resolve(cached.sha256);
|
|
251
|
+
const flightKey = `${binaryPath}\0${stampKey}`;
|
|
252
|
+
const existing = contentHashInFlight.get(flightKey);
|
|
253
|
+
if (existing)
|
|
254
|
+
return existing;
|
|
255
|
+
const task = (async () => {
|
|
256
|
+
try {
|
|
257
|
+
const sha256 = await sha256File(binaryPath);
|
|
258
|
+
if (binaryStampKey(binaryPath) !== stampKey)
|
|
259
|
+
return null;
|
|
260
|
+
contentHashCache.set(binaryPath, { stampKey, sha256 });
|
|
261
|
+
return sha256;
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
finally {
|
|
267
|
+
contentHashInFlight.delete(flightKey);
|
|
268
|
+
}
|
|
269
|
+
})();
|
|
270
|
+
contentHashInFlight.set(flightKey, task);
|
|
271
|
+
return task;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* The content hash of `binaryPath` if it is known without reading the file,
|
|
275
|
+
* else null. Known means: a matching identity sidecar (stat check only) or a
|
|
276
|
+
* hash computed earlier for the file's current stamp. On a miss, a streamed
|
|
277
|
+
* hash starts in the background so a later call can answer. Never reads or
|
|
278
|
+
* hashes the file synchronously, so it is safe on a host's main thread.
|
|
279
|
+
*/
|
|
280
|
+
export function peekBinaryContentHash(binaryPath) {
|
|
281
|
+
if (checkBinaryIdentity(binaryPath).status === "trusted") {
|
|
282
|
+
const sha256 = readBinaryIdentity(binaryPath)?.sha256;
|
|
283
|
+
if (sha256)
|
|
284
|
+
return sha256;
|
|
285
|
+
}
|
|
286
|
+
const stampKey = binaryStampKey(binaryPath);
|
|
287
|
+
if (stampKey === null)
|
|
288
|
+
return null;
|
|
289
|
+
const cached = contentHashCache.get(binaryPath);
|
|
290
|
+
if (cached && cached.stampKey === stampKey)
|
|
291
|
+
return cached.sha256;
|
|
292
|
+
void binaryContentHash(binaryPath);
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=binary-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-identity.js","sourceRoot":"","sources":["../src/binary-identity.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge.d.ts
CHANGED
|
@@ -274,10 +274,19 @@ export declare class BinaryBridge implements AftProjectTransport {
|
|
|
274
274
|
private invalidateTransportProcess;
|
|
275
275
|
hasPendingRequests(): boolean;
|
|
276
276
|
hasOutstandingBackgroundTasks(): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Fingerprint the binary this child was spawned from, without reading it on
|
|
279
|
+
* the host thread. When the fingerprint is not known yet, it is hashed in the
|
|
280
|
+
* background and adopted only if the file still has the stamp it had at
|
|
281
|
+
* spawn and this is still the same child, so the fingerprint always
|
|
282
|
+
* describes the bytes the running child came from.
|
|
283
|
+
*/
|
|
284
|
+
private recordSpawnedBinaryFingerprint;
|
|
277
285
|
/**
|
|
278
286
|
* Idle-window maintenance hook: when the on-disk binary changed since this
|
|
279
287
|
* child spawned, stop routing new work to this bridge so the pool can let it
|
|
280
|
-
* drain and retire it.
|
|
288
|
+
* drain and retire it. A fingerprint that is still being computed counts as
|
|
289
|
+
* unchanged; the next check sees the result.
|
|
281
290
|
*/
|
|
282
291
|
maybeScheduleRespawnForUpdatedBinary(checkIntervalMs: number, now?: number): boolean;
|
|
283
292
|
/** Project root this bridge was spawned/configured for. */
|
package/dist/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { createHash } from "node:crypto";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
1
|
import { homedir } from "node:os";
|
|
5
2
|
import { join } from "node:path";
|
|
6
3
|
import { StringDecoder } from "node:string_decoder";
|
|
7
4
|
import { error, getActiveLogger, getLogFilePath, log, warn } from "./active-logger.js";
|
|
5
|
+
import { binaryContentHash, binaryStampKey, peekBinaryContentHash } from "./binary-identity.js";
|
|
6
|
+
import { spawn } from "./child-process.js";
|
|
8
7
|
import { isPassiveCommand, PASSIVE_COMMAND_TIMEOUT_MS } from "./command-timeouts.js";
|
|
9
8
|
import { withPathPrepended } from "./path-env.js";
|
|
10
9
|
const DEFAULT_BRIDGE_TIMEOUT_MS = 30_000;
|
|
@@ -35,15 +34,22 @@ function bashTaskIdFrom(response) {
|
|
|
35
34
|
return camelCase;
|
|
36
35
|
return undefined;
|
|
37
36
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
/**
|
|
38
|
+
* The bridge fingerprints its binary's bytes at spawn and compares that with
|
|
39
|
+
* the file on disk during idle maintenance, so a bridge whose binary was
|
|
40
|
+
* replaced (an upgrade or a local rebuild) retires and the next call respawns
|
|
41
|
+
* onto the new binary. Hashing the ~85 MB binary synchronously stalled the
|
|
42
|
+
* host thread on every spawn and every check, so the default reader never
|
|
43
|
+
* reads the file itself: it answers from the identity sidecar or an earlier
|
|
44
|
+
* hash of the same stamp, and otherwise starts a streamed hash and reports
|
|
45
|
+
* "unknown for now".
|
|
46
|
+
*/
|
|
47
|
+
function peekBinaryFingerprint(binaryPath) {
|
|
48
|
+
return peekBinaryContentHash(binaryPath);
|
|
45
49
|
}
|
|
46
|
-
let binaryFingerprintReader =
|
|
50
|
+
let binaryFingerprintReader = peekBinaryFingerprint;
|
|
51
|
+
/** Off-thread fingerprint used when the spawn-time peek had no answer yet. */
|
|
52
|
+
let binaryFingerprintAsyncReader = binaryContentHash;
|
|
47
53
|
function readBinaryFingerprint(binaryPath) {
|
|
48
54
|
try {
|
|
49
55
|
const fingerprint = binaryFingerprintReader(binaryPath);
|
|
@@ -55,7 +61,13 @@ function readBinaryFingerprint(binaryPath) {
|
|
|
55
61
|
}
|
|
56
62
|
/** Test seam: replace the on-disk binary fingerprint reader without fs module mocks. */
|
|
57
63
|
export function __setBinaryFingerprintForTests(impl) {
|
|
58
|
-
binaryFingerprintReader = impl ??
|
|
64
|
+
binaryFingerprintReader = impl ?? peekBinaryFingerprint;
|
|
65
|
+
binaryFingerprintAsyncReader = impl
|
|
66
|
+
? async (binaryPath) => {
|
|
67
|
+
const fingerprint = impl(binaryPath);
|
|
68
|
+
return typeof fingerprint === "string" && fingerprint.length > 0 ? fingerprint : null;
|
|
69
|
+
}
|
|
70
|
+
: binaryContentHash;
|
|
59
71
|
}
|
|
60
72
|
// ## Note on TypeScript `as` type assertions
|
|
61
73
|
//
|
|
@@ -399,10 +411,34 @@ export class BinaryBridge {
|
|
|
399
411
|
hasOutstandingBackgroundTasks() {
|
|
400
412
|
return this.outstandingBackgroundTaskIds.size > 0;
|
|
401
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Fingerprint the binary this child was spawned from, without reading it on
|
|
416
|
+
* the host thread. When the fingerprint is not known yet, it is hashed in the
|
|
417
|
+
* background and adopted only if the file still has the stamp it had at
|
|
418
|
+
* spawn and this is still the same child, so the fingerprint always
|
|
419
|
+
* describes the bytes the running child came from.
|
|
420
|
+
*/
|
|
421
|
+
recordSpawnedBinaryFingerprint() {
|
|
422
|
+
this.spawnedBinaryFingerprint = readBinaryFingerprint(this.binaryPath);
|
|
423
|
+
if (this.spawnedBinaryFingerprint)
|
|
424
|
+
return;
|
|
425
|
+
const spawnStampKey = binaryStampKey(this.binaryPath);
|
|
426
|
+
if (spawnStampKey === null)
|
|
427
|
+
return;
|
|
428
|
+
const generation = this.processGeneration;
|
|
429
|
+
void binaryFingerprintAsyncReader(this.binaryPath, spawnStampKey).then((fingerprint) => {
|
|
430
|
+
if (fingerprint &&
|
|
431
|
+
this.processGeneration === generation &&
|
|
432
|
+
this.spawnedBinaryFingerprint === null) {
|
|
433
|
+
this.spawnedBinaryFingerprint = fingerprint;
|
|
434
|
+
}
|
|
435
|
+
}, () => { });
|
|
436
|
+
}
|
|
402
437
|
/**
|
|
403
438
|
* Idle-window maintenance hook: when the on-disk binary changed since this
|
|
404
439
|
* child spawned, stop routing new work to this bridge so the pool can let it
|
|
405
|
-
* drain and retire it.
|
|
440
|
+
* drain and retire it. A fingerprint that is still being computed counts as
|
|
441
|
+
* unchanged; the next check sees the result.
|
|
406
442
|
*/
|
|
407
443
|
maybeScheduleRespawnForUpdatedBinary(checkIntervalMs, now = Date.now()) {
|
|
408
444
|
if (this._shuttingDown || this._retiringDueToBinaryChange || !this.isAlive())
|
|
@@ -1092,7 +1128,7 @@ export class BinaryBridge {
|
|
|
1092
1128
|
});
|
|
1093
1129
|
this.process = child;
|
|
1094
1130
|
this.processGeneration += 1;
|
|
1095
|
-
this.
|
|
1131
|
+
this.recordSpawnedBinaryFingerprint();
|
|
1096
1132
|
this.lastBinaryFingerprintCheckAt = Date.now();
|
|
1097
1133
|
this.stdoutBuffer = "";
|
|
1098
1134
|
this.stdoutReadOffset = 0;
|
|
@@ -1110,16 +1146,30 @@ export class BinaryBridge {
|
|
|
1110
1146
|
}
|
|
1111
1147
|
}
|
|
1112
1148
|
onStderrData(data) {
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1149
|
+
// Search each incoming segment once; never concatenate an unbounded partial record.
|
|
1150
|
+
const partialLimit = 64 * 1024;
|
|
1151
|
+
let offset = 0;
|
|
1152
|
+
while (offset < data.length) {
|
|
1153
|
+
const newline = data.indexOf("\n", offset);
|
|
1154
|
+
const end = newline < 0 ? data.length : newline;
|
|
1155
|
+
while (offset < end) {
|
|
1156
|
+
const count = Math.min(partialLimit - this.stderrBuffer.length, end - offset);
|
|
1157
|
+
this.stderrBuffer += data.slice(offset, offset + count);
|
|
1158
|
+
offset += count;
|
|
1159
|
+
if (this.stderrBuffer.length === partialLimit) {
|
|
1160
|
+
const last = this.stderrBuffer.charCodeAt(this.stderrBuffer.length - 1);
|
|
1161
|
+
const carry = last >= 0xd800 && last <= 0xdbff ? this.stderrBuffer.slice(-1) : "";
|
|
1162
|
+
const fragment = carry ? this.stderrBuffer.slice(0, -1) : this.stderrBuffer;
|
|
1163
|
+
const tagged = tagStderrLine(`${fragment} [stderr record truncated into bounded fragments; ${Buffer.byteLength(fragment)} bytes shown, continuation follows]`);
|
|
1164
|
+
this.stderrBuffer = carry;
|
|
1165
|
+
this.logVia(tagged);
|
|
1166
|
+
this.pushStderrLine(tagged);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
if (newline < 0)
|
|
1170
|
+
break;
|
|
1171
|
+
this.flushStderrBuffer();
|
|
1172
|
+
offset = newline + 1;
|
|
1123
1173
|
}
|
|
1124
1174
|
}
|
|
1125
1175
|
flushStderrBuffer() {
|