usebeeline 0.1.180 → 0.1.181
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/usebeeline.mjs +739 -613
- package/package.json +1 -1
package/dist/usebeeline.mjs
CHANGED
|
@@ -173,6 +173,116 @@ var init_lifecycle_test_guard = __esm({
|
|
|
173
173
|
}
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
+
// apps/body/dist/self-update-manifest.js
|
|
177
|
+
function resolveManifestUrl(env = process.env) {
|
|
178
|
+
const override = env.BEELINE_UPDATE_MANIFEST_URL?.trim();
|
|
179
|
+
return override && override.length > 0 ? override : DEFAULT_UPDATE_MANIFEST_URL;
|
|
180
|
+
}
|
|
181
|
+
function parseUpdateManifest(raw, platform) {
|
|
182
|
+
let parsed;
|
|
183
|
+
try {
|
|
184
|
+
parsed = JSON.parse(raw);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
throw new Error(`update manifest is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
187
|
+
}
|
|
188
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
189
|
+
throw new Error("update manifest is not an object");
|
|
190
|
+
}
|
|
191
|
+
const manifest = parsed;
|
|
192
|
+
const bundles = manifest.bundles;
|
|
193
|
+
if (typeof bundles !== "object" || bundles === null) {
|
|
194
|
+
throw new Error("update manifest has no bundles table");
|
|
195
|
+
}
|
|
196
|
+
const entry = bundles[platform];
|
|
197
|
+
if (typeof entry !== "object" || entry === null) {
|
|
198
|
+
throw new Error(`update manifest has no bundle for platform ${platform}`);
|
|
199
|
+
}
|
|
200
|
+
const bundle = entry;
|
|
201
|
+
const file = typeof bundle.file === "string" ? bundle.file : "";
|
|
202
|
+
const sha256 = typeof bundle.sha256 === "string" ? bundle.sha256.toLowerCase() : "";
|
|
203
|
+
if (!file || !/^[a-z0-9][a-z0-9._-]*$/i.test(file)) {
|
|
204
|
+
throw new Error(`update manifest names an unusable bundle file: ${JSON.stringify(bundle.file)}`);
|
|
205
|
+
}
|
|
206
|
+
if (!/^[0-9a-f]{64}$/.test(sha256)) {
|
|
207
|
+
throw new Error(`update manifest carries no usable sha256 for ${platform}`);
|
|
208
|
+
}
|
|
209
|
+
const sourceCommit = typeof bundle.commit === "string" && bundle.commit ? bundle.commit : typeof manifest.sourceCommit === "string" ? manifest.sourceCommit : void 0;
|
|
210
|
+
const version = typeof bundle.version === "string" && bundle.version ? bundle.version : typeof manifest.version === "string" ? manifest.version : void 0;
|
|
211
|
+
return {
|
|
212
|
+
schemaVersion: typeof manifest.schemaVersion === "number" ? manifest.schemaVersion : 1,
|
|
213
|
+
...sourceCommit ? { sourceCommit } : {},
|
|
214
|
+
...version ? { version } : {},
|
|
215
|
+
bundles,
|
|
216
|
+
bundle: {
|
|
217
|
+
file,
|
|
218
|
+
sha256,
|
|
219
|
+
...typeof bundle.bytes === "number" ? { bytes: bundle.bytes } : {},
|
|
220
|
+
...sourceCommit ? { commit: sourceCommit } : {},
|
|
221
|
+
...version ? { version } : {},
|
|
222
|
+
...typeof bundle.node === "string" ? { node: bundle.node } : {}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function compareBundleIdentity(installed, published) {
|
|
227
|
+
if (installed?.commit && published.commit) {
|
|
228
|
+
if (installed.commit === published.commit)
|
|
229
|
+
return { kind: "current" };
|
|
230
|
+
return { kind: "update-available", published };
|
|
231
|
+
}
|
|
232
|
+
if (installed?.version && published.version) {
|
|
233
|
+
const ordering = compareVersions(installed.version, published.version);
|
|
234
|
+
if (ordering > 0)
|
|
235
|
+
return { kind: "current" };
|
|
236
|
+
if (ordering < 0)
|
|
237
|
+
return { kind: "update-available", published };
|
|
238
|
+
if (installed.commit && published.commit)
|
|
239
|
+
return { kind: "current" };
|
|
240
|
+
return { kind: "current" };
|
|
241
|
+
}
|
|
242
|
+
const missing = [
|
|
243
|
+
...installed?.commit || installed?.version ? [] : ["installed identity"],
|
|
244
|
+
...published.commit || published.version ? [] : ["published identity"]
|
|
245
|
+
];
|
|
246
|
+
return {
|
|
247
|
+
kind: "indeterminate",
|
|
248
|
+
reason: `cannot compare: ${missing.join(" and ")} unknown`
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function compareVersions(a, b) {
|
|
252
|
+
const parse = (value) => {
|
|
253
|
+
const parts = value.split(/[.+-]/).filter(Boolean);
|
|
254
|
+
if (parts.length === 0)
|
|
255
|
+
return void 0;
|
|
256
|
+
return parts.map((part) => /^\d+$/.test(part) ? Number(part) : part);
|
|
257
|
+
};
|
|
258
|
+
const left = parse(a);
|
|
259
|
+
const right = parse(b);
|
|
260
|
+
if (!left || !right)
|
|
261
|
+
return a === b ? 0 : a > b ? 1 : -1;
|
|
262
|
+
const length = Math.max(left.length, right.length);
|
|
263
|
+
for (let index = 0; index < length; index += 1) {
|
|
264
|
+
const l = left[index];
|
|
265
|
+
const r = right[index];
|
|
266
|
+
if (l === void 0)
|
|
267
|
+
return -1;
|
|
268
|
+
if (r === void 0)
|
|
269
|
+
return 1;
|
|
270
|
+
if (l === r)
|
|
271
|
+
continue;
|
|
272
|
+
if (typeof l === "number" && typeof r === "number")
|
|
273
|
+
return l > r ? 1 : -1;
|
|
274
|
+
return String(l) > String(r) ? 1 : -1;
|
|
275
|
+
}
|
|
276
|
+
return 0;
|
|
277
|
+
}
|
|
278
|
+
var DEFAULT_UPDATE_MANIFEST_URL;
|
|
279
|
+
var init_self_update_manifest = __esm({
|
|
280
|
+
"apps/body/dist/self-update-manifest.js"() {
|
|
281
|
+
"use strict";
|
|
282
|
+
DEFAULT_UPDATE_MANIFEST_URL = "https://usebeeline.app/dl/manifest.json";
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
|
|
176
286
|
// apps/body/dist/trusty-squire-storage.js
|
|
177
287
|
import { homedir as homedir2 } from "node:os";
|
|
178
288
|
import { isAbsolute, resolve as resolve4 } from "node:path";
|
|
@@ -328,151 +438,250 @@ visit(root)
|
|
|
328
438
|
}
|
|
329
439
|
});
|
|
330
440
|
|
|
331
|
-
// apps/body/dist/self-update-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
let
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
if (
|
|
344
|
-
|
|
441
|
+
// apps/body/dist/self-update-activate-release.js
|
|
442
|
+
import { join, dirname as dirname4, resolve as resolve6 } from "node:path";
|
|
443
|
+
import { access, mkdir as mkdir3, rename as rename2, rm as rm3, symlink, copyFile, readFile as readFile2, readdir as readdir3, lstat as lstat3 } from "node:fs/promises";
|
|
444
|
+
import { constants as fsConstants } from "node:fs";
|
|
445
|
+
async function activateRelease(layout, releaseId, options = {}) {
|
|
446
|
+
assertInstallTestIsolation(layout);
|
|
447
|
+
let releaseDir = join(layout.releasesRoot, releaseId);
|
|
448
|
+
let previousReleaseId = await activeReleaseId(layout);
|
|
449
|
+
await access(join(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
|
|
450
|
+
await mkdir3(layout.releasesRoot, { recursive: true });
|
|
451
|
+
await mkdir3(layout.binDir, { recursive: true });
|
|
452
|
+
const kind = await pathKind(layout.libDir);
|
|
453
|
+
if (kind === "directory") {
|
|
454
|
+
const legacyIdentity = await readBundleJson(layout.libDir);
|
|
455
|
+
const legacyId = sanitizeReleaseId(legacyIdentity?.commit ?? legacyIdentity?.version ?? `legacy-${Date.now()}`);
|
|
456
|
+
const legacyDir = join(layout.releasesRoot, legacyId);
|
|
457
|
+
try {
|
|
458
|
+
await access(legacyDir, fsConstants.F_OK);
|
|
459
|
+
const preservedId = `${legacyId}-${Date.now()}`;
|
|
460
|
+
await rename2(layout.libDir, join(layout.releasesRoot, preservedId));
|
|
461
|
+
await normalizeLegacyBundleShape(join(layout.releasesRoot, preservedId));
|
|
462
|
+
previousReleaseId = preservedId;
|
|
463
|
+
} catch {
|
|
464
|
+
await rename2(layout.libDir, legacyDir);
|
|
465
|
+
await normalizeLegacyBundleShape(legacyDir);
|
|
466
|
+
previousReleaseId = legacyId;
|
|
467
|
+
}
|
|
345
468
|
}
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
469
|
+
const tempLink = `${layout.libDir}.new-${process.pid}`;
|
|
470
|
+
await rm3(tempLink, { force: true });
|
|
471
|
+
await symlink(join("beeline-releases", releaseId), tempLink);
|
|
472
|
+
await rename2(tempLink, layout.libDir);
|
|
473
|
+
await fsyncDir(dirname4(layout.libDir));
|
|
474
|
+
await installRecoveryLauncher(layout, releaseDir);
|
|
475
|
+
await writeBinForwarders(layout, releaseDir);
|
|
476
|
+
const state = await readUpdateState(layout);
|
|
477
|
+
await writeUpdateState(layout, {
|
|
478
|
+
...state,
|
|
479
|
+
stagedReleaseId: void 0,
|
|
480
|
+
previousReleaseId: previousReleaseId && previousReleaseId !== releaseId ? previousReleaseId : state.previousReleaseId
|
|
481
|
+
});
|
|
482
|
+
if (!options.deferPruning)
|
|
483
|
+
await pruneHelperReleases(layout);
|
|
484
|
+
}
|
|
485
|
+
async function installRecoveryLauncher(layout, releaseDir) {
|
|
486
|
+
const bootstrap = join(releaseDir, "lib/beeline/recovery-cli.mjs");
|
|
487
|
+
if (await access(bootstrap).then(() => true, () => false)) {
|
|
488
|
+
const stable = resolve6(layout.libDir, "../beeline-bootstrap.mjs");
|
|
489
|
+
const temporary = `${stable}.${process.pid}.tmp`;
|
|
490
|
+
await copyFile(bootstrap, temporary);
|
|
491
|
+
await rename2(temporary, stable);
|
|
492
|
+
await replaceFile(resolve6(layout.libDir, "../beeline-node-path"), `${process.execPath}
|
|
493
|
+
`, 384);
|
|
350
494
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
495
|
+
}
|
|
496
|
+
async function normalizeLegacyBundleShape(bundleDir) {
|
|
497
|
+
const innerLib = join(bundleDir, "lib", "beeline");
|
|
498
|
+
let anyFlat = false;
|
|
499
|
+
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
500
|
+
try {
|
|
501
|
+
await access(join(bundleDir, name), fsConstants.F_OK);
|
|
502
|
+
anyFlat = true;
|
|
503
|
+
break;
|
|
504
|
+
} catch {
|
|
505
|
+
}
|
|
354
506
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
507
|
+
if (!anyFlat)
|
|
508
|
+
return;
|
|
509
|
+
await mkdir3(innerLib, { recursive: true });
|
|
510
|
+
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
511
|
+
try {
|
|
512
|
+
await access(join(innerLib, name), fsConstants.F_OK);
|
|
513
|
+
continue;
|
|
514
|
+
} catch {
|
|
515
|
+
}
|
|
516
|
+
await rename2(join(bundleDir, name), join(innerLib, name)).catch(() => void 0);
|
|
360
517
|
}
|
|
361
|
-
|
|
362
|
-
|
|
518
|
+
}
|
|
519
|
+
async function writeBinForwarders(layout, activeBundleRoot) {
|
|
520
|
+
const entries = [
|
|
521
|
+
...FORWARDER_TOOLS.map((tool) => [tool, tool]),
|
|
522
|
+
...Object.entries(FORWARDER_ALIASES).map(([alias, tool]) => [alias, tool])
|
|
523
|
+
];
|
|
524
|
+
for (const [name, tool] of entries) {
|
|
525
|
+
const target = join(activeBundleRoot, "bin", tool);
|
|
526
|
+
try {
|
|
527
|
+
await access(target, fsConstants.X_OK);
|
|
528
|
+
} catch {
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
const independent = await access(resolve6(layout.libDir, "../beeline-bootstrap.mjs")).then(() => true, () => false);
|
|
532
|
+
await replaceFile(join(layout.binDir, name), independent || tool !== "beeline" ? forwarderScript(tool) : forwarderScript("legacy-beeline").replace("/bin/legacy-beeline", "/bin/beeline"), 493);
|
|
363
533
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
...version ? { version } : {},
|
|
377
|
-
...typeof bundle.node === "string" ? { node: bundle.node } : {}
|
|
534
|
+
}
|
|
535
|
+
async function repairInstallForwarders(layout, opts = {}) {
|
|
536
|
+
assertInstallTestIsolation(layout);
|
|
537
|
+
if (await pathKind(layout.libDir) !== "symlink")
|
|
538
|
+
return false;
|
|
539
|
+
await installRecoveryLauncher(layout, layout.libDir);
|
|
540
|
+
const forwarderHealthy = async (name, tool) => {
|
|
541
|
+
let current;
|
|
542
|
+
try {
|
|
543
|
+
current = await readFile2(join(layout.binDir, name), "utf8");
|
|
544
|
+
} catch {
|
|
545
|
+
current = void 0;
|
|
378
546
|
}
|
|
547
|
+
const independent = await access(resolve6(layout.libDir, "../beeline-bootstrap.mjs")).then(() => true, () => false);
|
|
548
|
+
const expected = independent || tool !== "beeline" ? forwarderScript(tool) : forwarderScript("legacy-beeline").replace("/bin/legacy-beeline", "/bin/beeline");
|
|
549
|
+
return current === expected;
|
|
379
550
|
};
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
return { kind: "current" };
|
|
385
|
-
return { kind: "update-available", published };
|
|
551
|
+
let healthy = await forwarderHealthy("beeline", "beeline");
|
|
552
|
+
for (const [alias, tool] of Object.entries(FORWARDER_ALIASES)) {
|
|
553
|
+
if (!await forwarderHealthy(alias, tool))
|
|
554
|
+
healthy = false;
|
|
386
555
|
}
|
|
387
|
-
if (
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
556
|
+
if (healthy)
|
|
557
|
+
return false;
|
|
558
|
+
await mkdir3(layout.binDir, { recursive: true });
|
|
559
|
+
await writeBinForwarders(layout, layout.libDir);
|
|
560
|
+
opts.logger?.(`[body] self-update: repaired <prefix>/bin forwarders to follow the active-bundle anchor (${layout.libDir})`);
|
|
561
|
+
return true;
|
|
562
|
+
}
|
|
563
|
+
function describeIdentity(identity) {
|
|
564
|
+
if (!identity)
|
|
565
|
+
return "unknown";
|
|
566
|
+
const parts = [];
|
|
567
|
+
if (identity.version)
|
|
568
|
+
parts.push(identity.version);
|
|
569
|
+
if (identity.commit)
|
|
570
|
+
parts.push(identity.commit.slice(0, 12));
|
|
571
|
+
return parts.join(" ") || "unknown";
|
|
572
|
+
}
|
|
573
|
+
async function pruneHelperReleases(layout, loadedRelease) {
|
|
574
|
+
assertInstallTestIsolation(layout);
|
|
575
|
+
if (!await ordinaryDirectory(layout.releasesRoot))
|
|
576
|
+
return [];
|
|
577
|
+
const active = await activeReleaseId(layout);
|
|
578
|
+
if (!active)
|
|
579
|
+
return [];
|
|
580
|
+
const state = await readUpdateState(layout);
|
|
581
|
+
const candidates = [];
|
|
582
|
+
for (const entry of await readdir3(layout.releasesRoot, { withFileTypes: true })) {
|
|
583
|
+
if (entry.name.startsWith("."))
|
|
584
|
+
continue;
|
|
585
|
+
if (entry.isSymbolicLink()) {
|
|
586
|
+
if (![active, state.previousReleaseId, state.stagedReleaseId, loadedRelease].includes(entry.name))
|
|
587
|
+
await rm3(join(layout.releasesRoot, entry.name), { force: true });
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
if (!entry.isDirectory())
|
|
591
|
+
continue;
|
|
592
|
+
const path = join(layout.releasesRoot, entry.name);
|
|
593
|
+
if (!await ordinaryDirectory(path))
|
|
594
|
+
continue;
|
|
595
|
+
candidates.push({
|
|
596
|
+
id: entry.name,
|
|
597
|
+
modified: (await lstat3(path)).mtimeMs,
|
|
598
|
+
bootable: await access(join(path, BUNDLE_ENTRYPOINT)).then(() => true, () => false)
|
|
599
|
+
});
|
|
396
600
|
}
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
];
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
reason: `cannot compare: ${missing.join(" and ")} unknown`
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
function compareVersions(a, b) {
|
|
407
|
-
const parse = (value) => {
|
|
408
|
-
const parts = value.split(/[.+-]/).filter(Boolean);
|
|
409
|
-
if (parts.length === 0)
|
|
410
|
-
return void 0;
|
|
411
|
-
return parts.map((part) => /^\d+$/.test(part) ? Number(part) : part);
|
|
412
|
-
};
|
|
413
|
-
const left = parse(a);
|
|
414
|
-
const right = parse(b);
|
|
415
|
-
if (!left || !right)
|
|
416
|
-
return a === b ? 0 : a > b ? 1 : -1;
|
|
417
|
-
const length = Math.max(left.length, right.length);
|
|
418
|
-
for (let index = 0; index < length; index += 1) {
|
|
419
|
-
const l = left[index];
|
|
420
|
-
const r = right[index];
|
|
421
|
-
if (l === void 0)
|
|
422
|
-
return -1;
|
|
423
|
-
if (r === void 0)
|
|
424
|
-
return 1;
|
|
425
|
-
if (l === r)
|
|
601
|
+
const recordedPrevious = candidates.find((entry) => entry.id === state.previousReleaseId && entry.id !== active && entry.bootable)?.id;
|
|
602
|
+
const previous = recordedPrevious ?? candidates.filter((entry) => entry.bootable && entry.id !== active && entry.id !== state.stagedReleaseId).sort((a, b) => b.modified - a.modified)[0]?.id;
|
|
603
|
+
const keep = /* @__PURE__ */ new Set([active, previous, loadedRelease, state.stagedReleaseId]);
|
|
604
|
+
const removed = [];
|
|
605
|
+
for (const entry of candidates) {
|
|
606
|
+
if (keep.has(entry.id))
|
|
426
607
|
continue;
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
return String(l) > String(r) ? 1 : -1;
|
|
608
|
+
await removeStoragePath(join(layout.releasesRoot, entry.id));
|
|
609
|
+
removed.push(entry.id);
|
|
430
610
|
}
|
|
431
|
-
|
|
611
|
+
if (previous !== state.previousReleaseId)
|
|
612
|
+
await writeUpdateState(layout, { ...state, previousReleaseId: previous });
|
|
613
|
+
return removed;
|
|
432
614
|
}
|
|
433
|
-
var
|
|
434
|
-
var
|
|
435
|
-
"apps/body/dist/self-update-
|
|
615
|
+
var LEGACY_FLAT_BUNDLE_FILES;
|
|
616
|
+
var init_self_update_activate_release = __esm({
|
|
617
|
+
"apps/body/dist/self-update-activate-release.js"() {
|
|
436
618
|
"use strict";
|
|
437
|
-
|
|
619
|
+
init_lifecycle_test_guard();
|
|
620
|
+
init_storage_filesystem();
|
|
621
|
+
init_self_update();
|
|
622
|
+
LEGACY_FLAT_BUNDLE_FILES = [
|
|
623
|
+
"beeline-cli.mjs",
|
|
624
|
+
"beeline-readonly-mcp.mjs",
|
|
625
|
+
"pi-mcp-adapter.mjs",
|
|
626
|
+
"bundle.json"
|
|
627
|
+
];
|
|
438
628
|
}
|
|
439
629
|
});
|
|
440
630
|
|
|
441
631
|
// apps/body/dist/self-update.js
|
|
442
632
|
var self_update_exports = {};
|
|
443
633
|
__export(self_update_exports, {
|
|
634
|
+
BUNDLE_ENTRYPOINT: () => BUNDLE_ENTRYPOINT,
|
|
635
|
+
CODEGRAPH_ENTRYPOINT: () => CODEGRAPH_ENTRYPOINT,
|
|
636
|
+
FORWARDER_ALIASES: () => FORWARDER_ALIASES,
|
|
637
|
+
FORWARDER_TOOLS: () => FORWARDER_TOOLS,
|
|
638
|
+
PI_MCP_ADAPTER_ENTRYPOINT: () => PI_MCP_ADAPTER_ENTRYPOINT,
|
|
639
|
+
RELEASES_SEGMENT: () => RELEASES_SEGMENT,
|
|
444
640
|
STAGED_NODE_PATH_FILE: () => STAGED_NODE_PATH_FILE,
|
|
445
641
|
SelfUpdateManager: () => SelfUpdateManager,
|
|
446
642
|
activateRelease: () => activateRelease,
|
|
447
643
|
activeReleaseId: () => activeReleaseId,
|
|
644
|
+
anchorLayout: () => anchorLayout,
|
|
448
645
|
archiveUrlFor: () => archiveUrlFor,
|
|
449
646
|
beelineInstallLayout: () => beelineInstallLayout,
|
|
647
|
+
bundleJsonCandidates: () => bundleJsonCandidates,
|
|
450
648
|
defaultBeelineInstallLayout: () => defaultBeelineInstallLayout,
|
|
451
649
|
describeIdentity: () => describeIdentity,
|
|
452
650
|
discoveredBeelineInstallLayout: () => discoveredBeelineInstallLayout,
|
|
651
|
+
entrypointCandidates: () => entrypointCandidates,
|
|
652
|
+
fetchText: () => fetchText,
|
|
653
|
+
forwarderScript: () => forwarderScript,
|
|
654
|
+
fsyncDir: () => fsyncDir,
|
|
453
655
|
hostPlatformKey: () => hostPlatformKey,
|
|
454
656
|
nodeVersionAtLeast: () => nodeVersionAtLeast,
|
|
455
657
|
normalizeLegacyBundleShape: () => normalizeLegacyBundleShape,
|
|
658
|
+
pathKind: () => pathKind,
|
|
456
659
|
prepareLatestRelease: () => prepareLatestRelease,
|
|
457
660
|
pruneHelperReleases: () => pruneHelperReleases,
|
|
458
661
|
readBundleEngineMinimum: () => readBundleEngineMinimum,
|
|
662
|
+
readBundleJson: () => readBundleJson,
|
|
459
663
|
readInstalledBundleIdentity: () => readInstalledBundleIdentity,
|
|
460
664
|
readUpdateState: () => readUpdateState,
|
|
461
665
|
releaseIdFromPath: () => releaseIdFromPath,
|
|
462
666
|
repairInstallForwarders: () => repairInstallForwarders,
|
|
667
|
+
replaceFile: () => replaceFile,
|
|
668
|
+
requiredBundlePaths: () => requiredBundlePaths,
|
|
463
669
|
resolveBundleEntrypoint: () => resolveBundleEntrypoint,
|
|
670
|
+
run: () => run,
|
|
464
671
|
runningReleaseId: () => runningReleaseId,
|
|
672
|
+
sanitizeReleaseId: () => sanitizeReleaseId,
|
|
465
673
|
stageRelease: () => stageRelease,
|
|
674
|
+
updateStatePath: () => updateStatePath,
|
|
466
675
|
writeUpdateState: () => writeUpdateState
|
|
467
676
|
});
|
|
468
|
-
import {
|
|
469
|
-
import {
|
|
470
|
-
import { access, chmod as chmod2, copyFile, lstat as lstat3, mkdir as mkdir3, open, readFile as readFile2, readdir as readdir3, rename as rename2, rm as rm3, symlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
471
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
677
|
+
import { readFile as readFile3, mkdir as mkdir4, open, rename as rename3, lstat as lstat4, access as access2, writeFile as writeFile2, rm as rm4, chmod as chmod2 } from "node:fs/promises";
|
|
678
|
+
import { join as join2, resolve as resolve7, dirname as dirname5 } from "node:path";
|
|
472
679
|
import { homedir as homedir3 } from "node:os";
|
|
473
|
-
import {
|
|
680
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
681
|
+
import { constants as fsConstants2 } from "node:fs";
|
|
682
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
474
683
|
function anchorLayout(rawLibDir) {
|
|
475
|
-
const libDir =
|
|
684
|
+
const libDir = resolve7(rawLibDir);
|
|
476
685
|
const segments = libDir.split(/[/\\]/);
|
|
477
686
|
const idx = segments.lastIndexOf(RELEASES_SEGMENT);
|
|
478
687
|
if (idx >= 2 && segments[idx - 1] === "lib") {
|
|
@@ -488,9 +697,9 @@ function anchorLayout(rawLibDir) {
|
|
|
488
697
|
// prefix's bin, NOT <prefix>/lib/bin — deriving it one level up was the
|
|
489
698
|
// defect that made activateRelease write its stable forwarders where
|
|
490
699
|
// nothing executed them, leaving stale raw wrappers in <prefix>/bin.
|
|
491
|
-
binDir:
|
|
700
|
+
binDir: resolve7(libDir, "../../bin"),
|
|
492
701
|
libDir,
|
|
493
|
-
releasesRoot:
|
|
702
|
+
releasesRoot: resolve7(libDir, `../${RELEASES_SEGMENT}`)
|
|
494
703
|
};
|
|
495
704
|
}
|
|
496
705
|
function beelineInstallLayout(env = process.env) {
|
|
@@ -502,18 +711,18 @@ function beelineInstallLayout(env = process.env) {
|
|
|
502
711
|
function releaseIdFromPath(path) {
|
|
503
712
|
if (!path?.trim())
|
|
504
713
|
return void 0;
|
|
505
|
-
const segments =
|
|
714
|
+
const segments = resolve7(path.trim()).split(/[/\\]/);
|
|
506
715
|
const idx = segments.lastIndexOf(RELEASES_SEGMENT);
|
|
507
716
|
const id = idx >= 0 ? segments[idx + 1] : void 0;
|
|
508
717
|
return id ? sanitizeReleaseId(id) : void 0;
|
|
509
718
|
}
|
|
510
719
|
function runningReleaseId(layout, env = process.env, invocationPath = process.argv[1]) {
|
|
511
|
-
const releasesRoot =
|
|
512
|
-
const anchor =
|
|
720
|
+
const releasesRoot = resolve7(layout.releasesRoot);
|
|
721
|
+
const anchor = resolve7(layout.libDir);
|
|
513
722
|
for (const raw of [env.BEELINE_LIB_DIR, invocationPath]) {
|
|
514
723
|
if (!raw?.trim())
|
|
515
724
|
continue;
|
|
516
|
-
const resolved =
|
|
725
|
+
const resolved = resolve7(raw.trim());
|
|
517
726
|
if (resolved !== anchor && !resolved.startsWith(`${releasesRoot}/`))
|
|
518
727
|
continue;
|
|
519
728
|
const id = releaseIdFromPath(resolved);
|
|
@@ -524,7 +733,7 @@ function runningReleaseId(layout, env = process.env, invocationPath = process.ar
|
|
|
524
733
|
}
|
|
525
734
|
function defaultBeelineInstallLayout(env = process.env) {
|
|
526
735
|
const home2 = env.HOME?.trim() || homedir3();
|
|
527
|
-
return anchorLayout(
|
|
736
|
+
return anchorLayout(resolve7(home2, ".local", "lib", "beeline"));
|
|
528
737
|
}
|
|
529
738
|
function discoveredBeelineInstallLayout(env = process.env) {
|
|
530
739
|
const explicitAnchor = env.BEELINE_INSTALL_LIB_DIR?.trim();
|
|
@@ -532,7 +741,7 @@ function discoveredBeelineInstallLayout(env = process.env) {
|
|
|
532
741
|
return anchorLayout(explicitAnchor);
|
|
533
742
|
const explicitBinDir = env.BEELINE_INSTALL_DIR?.trim();
|
|
534
743
|
if (explicitBinDir)
|
|
535
|
-
return anchorLayout(
|
|
744
|
+
return anchorLayout(resolve7(dirname5(resolve7(explicitBinDir)), "lib", "beeline"));
|
|
536
745
|
return defaultBeelineInstallLayout(env);
|
|
537
746
|
}
|
|
538
747
|
function hostPlatformKey() {
|
|
@@ -543,13 +752,13 @@ function hostPlatformKey() {
|
|
|
543
752
|
return `${os}-${arch}`;
|
|
544
753
|
}
|
|
545
754
|
function bundleJsonCandidates(bundleDir) {
|
|
546
|
-
return [
|
|
755
|
+
return [join2(bundleDir, "lib", "beeline", "bundle.json"), join2(bundleDir, "bundle.json")];
|
|
547
756
|
}
|
|
548
757
|
async function readBundleJson(bundleDir) {
|
|
549
758
|
let raw;
|
|
550
759
|
for (const candidate of bundleJsonCandidates(bundleDir)) {
|
|
551
760
|
try {
|
|
552
|
-
raw = await
|
|
761
|
+
raw = await readFile3(candidate, "utf8");
|
|
553
762
|
break;
|
|
554
763
|
} catch {
|
|
555
764
|
}
|
|
@@ -569,7 +778,7 @@ async function readBundleJson(bundleDir) {
|
|
|
569
778
|
async function readBundleEngineMinimum(bundleDir) {
|
|
570
779
|
for (const candidate of bundleJsonCandidates(bundleDir)) {
|
|
571
780
|
try {
|
|
572
|
-
const parsed = JSON.parse(await
|
|
781
|
+
const parsed = JSON.parse(await readFile3(candidate, "utf8"));
|
|
573
782
|
const match = /^>=(\d+)\.(\d+)\.(\d+)$/.exec(parsed.node ?? "");
|
|
574
783
|
if (match)
|
|
575
784
|
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
@@ -589,17 +798,17 @@ function nodeVersionAtLeast(version, minimum) {
|
|
|
589
798
|
return true;
|
|
590
799
|
}
|
|
591
800
|
function updateStatePath(layout) {
|
|
592
|
-
return
|
|
801
|
+
return join2(layout.releasesRoot, ".state", "update-state.json");
|
|
593
802
|
}
|
|
594
803
|
async function readUpdateState(layout) {
|
|
595
804
|
try {
|
|
596
|
-
return JSON.parse(await
|
|
805
|
+
return JSON.parse(await readFile3(updateStatePath(layout), "utf8"));
|
|
597
806
|
} catch {
|
|
598
807
|
return {};
|
|
599
808
|
}
|
|
600
809
|
}
|
|
601
810
|
async function writeUpdateState(layout, state) {
|
|
602
|
-
await
|
|
811
|
+
await mkdir4(join2(layout.releasesRoot, ".state"), { recursive: true });
|
|
603
812
|
const path = updateStatePath(layout);
|
|
604
813
|
const temporary = `${path}.${process.pid}.tmp`;
|
|
605
814
|
const handle = await open(temporary, "w", 384);
|
|
@@ -610,8 +819,8 @@ async function writeUpdateState(layout, state) {
|
|
|
610
819
|
} finally {
|
|
611
820
|
await handle.close();
|
|
612
821
|
}
|
|
613
|
-
await
|
|
614
|
-
await fsyncDir(
|
|
822
|
+
await rename3(temporary, path);
|
|
823
|
+
await fsyncDir(dirname5(path));
|
|
615
824
|
}
|
|
616
825
|
async function readInstalledBundleIdentity(layout, _state = {}) {
|
|
617
826
|
const fromDisk = await readBundleJson(layout.libDir);
|
|
@@ -625,7 +834,7 @@ function sanitizeReleaseId(id) {
|
|
|
625
834
|
}
|
|
626
835
|
async function pathKind(path) {
|
|
627
836
|
try {
|
|
628
|
-
const info = await
|
|
837
|
+
const info = await lstat4(path);
|
|
629
838
|
if (info.isSymbolicLink())
|
|
630
839
|
return "symlink";
|
|
631
840
|
return info.isDirectory() ? "directory" : "missing";
|
|
@@ -688,12 +897,12 @@ function run(command2, args, _timeoutMs) {
|
|
|
688
897
|
});
|
|
689
898
|
}
|
|
690
899
|
function entrypointCandidates(bundleDir) {
|
|
691
|
-
return [
|
|
900
|
+
return [join2(bundleDir, BUNDLE_ENTRYPOINT), join2(bundleDir, "beeline-cli.mjs")];
|
|
692
901
|
}
|
|
693
902
|
async function resolveBundleEntrypoint(bundleDir) {
|
|
694
903
|
for (const candidate of entrypointCandidates(bundleDir)) {
|
|
695
904
|
try {
|
|
696
|
-
await
|
|
905
|
+
await access2(candidate, fsConstants2.F_OK);
|
|
697
906
|
return candidate;
|
|
698
907
|
} catch {
|
|
699
908
|
}
|
|
@@ -717,17 +926,17 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
717
926
|
});
|
|
718
927
|
const log2 = opts.logger ?? ((line) => console.log(`[body] self-update: ${line}`));
|
|
719
928
|
let releaseId = sanitizeReleaseId((published.commit ?? published.version ?? `release-${Date.now()}`) + (opts.force ? `-repair-${Date.now()}` : ""));
|
|
720
|
-
let releaseDir =
|
|
721
|
-
let okMarker =
|
|
929
|
+
let releaseDir = join2(layout.releasesRoot, releaseId);
|
|
930
|
+
let okMarker = join2(releaseDir, ".stage-ok");
|
|
722
931
|
let previouslyVerified = false;
|
|
723
932
|
try {
|
|
724
|
-
const recorded = await
|
|
933
|
+
const recorded = await readFile3(okMarker, "utf8");
|
|
725
934
|
if (recorded.trim() === published.sha256 && !opts.force)
|
|
726
935
|
return releaseId;
|
|
727
936
|
releaseId = sanitizeReleaseId(`${releaseId}-${published.sha256.slice(0, 12)}`);
|
|
728
|
-
releaseDir =
|
|
729
|
-
okMarker =
|
|
730
|
-
const matching = await
|
|
937
|
+
releaseDir = join2(layout.releasesRoot, releaseId);
|
|
938
|
+
okMarker = join2(releaseDir, ".stage-ok");
|
|
939
|
+
const matching = await readFile3(okMarker, "utf8").catch(() => "");
|
|
731
940
|
if (matching.trim() === published.sha256 && !opts.force)
|
|
732
941
|
return releaseId;
|
|
733
942
|
previouslyVerified = Boolean(matching);
|
|
@@ -735,12 +944,12 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
735
944
|
}
|
|
736
945
|
if (await activeReleaseId(layout) === releaseId) {
|
|
737
946
|
releaseId = sanitizeReleaseId(`${releaseId}-repair-${Date.now()}`);
|
|
738
|
-
releaseDir =
|
|
739
|
-
okMarker =
|
|
947
|
+
releaseDir = join2(layout.releasesRoot, releaseId);
|
|
948
|
+
okMarker = join2(releaseDir, ".stage-ok");
|
|
740
949
|
previouslyVerified = false;
|
|
741
950
|
}
|
|
742
|
-
await
|
|
743
|
-
const tempArchive =
|
|
951
|
+
await mkdir4(releaseDir, { recursive: true });
|
|
952
|
+
const tempArchive = join2(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
|
|
744
953
|
try {
|
|
745
954
|
log2(`downloading ${published.file}`);
|
|
746
955
|
const response = await fetchImpl(archiveUrlFor(manifestUrl, published.file), {
|
|
@@ -784,7 +993,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
784
993
|
throw new Error(`extracting bundle failed: ${extract.stderr}`);
|
|
785
994
|
for (const relative of requiredBundlePaths()) {
|
|
786
995
|
try {
|
|
787
|
-
await
|
|
996
|
+
await access2(join2(releaseDir, relative), fsConstants2.F_OK);
|
|
788
997
|
} catch {
|
|
789
998
|
throw new Error(`staged bundle is missing ${relative}`);
|
|
790
999
|
}
|
|
@@ -797,11 +1006,11 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
797
1006
|
if (!nodeVersionAtLeast(process.versions.node, engineMinimum)) {
|
|
798
1007
|
throw new Error(`staged bundle requires Node.js >=${engineMinimum.join(".")}, but this process is running Node.js ${process.versions.node} \u2014 install a satisfying Node runtime and retry`);
|
|
799
1008
|
}
|
|
800
|
-
await writeFile2(
|
|
1009
|
+
await writeFile2(join2(releaseDir, STAGED_NODE_PATH_FILE), `${process.execPath}
|
|
801
1010
|
`, "utf8");
|
|
802
1011
|
}
|
|
803
1012
|
if (opts.smokeTestCli !== false) {
|
|
804
|
-
const probe = await run(process.execPath, [
|
|
1013
|
+
const probe = await run(process.execPath, [join2(releaseDir, BUNDLE_ENTRYPOINT), "--version"], Math.min(6e4, remaining()));
|
|
805
1014
|
if (probe.status !== 0) {
|
|
806
1015
|
throw new Error(`staged bundle failed its startup smoke test (--version exited ${probe.status})${probe.stderr ? `: ${probe.stderr.trim()}` : ""}`);
|
|
807
1016
|
}
|
|
@@ -812,10 +1021,10 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
812
1021
|
return releaseId;
|
|
813
1022
|
} catch (error) {
|
|
814
1023
|
if (!previouslyVerified)
|
|
815
|
-
await
|
|
1024
|
+
await rm4(releaseDir, { recursive: true, force: true });
|
|
816
1025
|
throw error;
|
|
817
1026
|
} finally {
|
|
818
|
-
await
|
|
1027
|
+
await rm4(tempArchive, { force: true });
|
|
819
1028
|
}
|
|
820
1029
|
}
|
|
821
1030
|
function forwarderScript(tool) {
|
|
@@ -850,142 +1059,14 @@ async function replaceFile(path, contents, mode) {
|
|
|
850
1059
|
const temp = `${path}.new-${process.pid}`;
|
|
851
1060
|
await writeFile2(temp, contents, { mode });
|
|
852
1061
|
await chmod2(temp, mode);
|
|
853
|
-
await
|
|
854
|
-
}
|
|
855
|
-
async function activateRelease(layout, releaseId, options = {}) {
|
|
856
|
-
assertInstallTestIsolation(layout);
|
|
857
|
-
let releaseDir = join(layout.releasesRoot, releaseId);
|
|
858
|
-
let previousReleaseId = await activeReleaseId(layout);
|
|
859
|
-
await access(join(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
|
|
860
|
-
await mkdir3(layout.releasesRoot, { recursive: true });
|
|
861
|
-
await mkdir3(layout.binDir, { recursive: true });
|
|
862
|
-
const kind = await pathKind(layout.libDir);
|
|
863
|
-
if (kind === "directory") {
|
|
864
|
-
const legacyIdentity = await readBundleJson(layout.libDir);
|
|
865
|
-
const legacyId = sanitizeReleaseId(legacyIdentity?.commit ?? legacyIdentity?.version ?? `legacy-${Date.now()}`);
|
|
866
|
-
const legacyDir = join(layout.releasesRoot, legacyId);
|
|
867
|
-
try {
|
|
868
|
-
await access(legacyDir, fsConstants.F_OK);
|
|
869
|
-
const preservedId = `${legacyId}-${Date.now()}`;
|
|
870
|
-
await rename2(layout.libDir, join(layout.releasesRoot, preservedId));
|
|
871
|
-
await normalizeLegacyBundleShape(join(layout.releasesRoot, preservedId));
|
|
872
|
-
previousReleaseId = preservedId;
|
|
873
|
-
} catch {
|
|
874
|
-
await rename2(layout.libDir, legacyDir);
|
|
875
|
-
await normalizeLegacyBundleShape(legacyDir);
|
|
876
|
-
previousReleaseId = legacyId;
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
const tempLink = `${layout.libDir}.new-${process.pid}`;
|
|
880
|
-
await rm3(tempLink, { force: true });
|
|
881
|
-
await symlink(join("beeline-releases", releaseId), tempLink);
|
|
882
|
-
await rename2(tempLink, layout.libDir);
|
|
883
|
-
await fsyncDir(dirname4(layout.libDir));
|
|
884
|
-
await installRecoveryLauncher(layout, releaseDir);
|
|
885
|
-
await writeBinForwarders(layout, releaseDir);
|
|
886
|
-
const state = await readUpdateState(layout);
|
|
887
|
-
await writeUpdateState(layout, {
|
|
888
|
-
...state,
|
|
889
|
-
stagedReleaseId: void 0,
|
|
890
|
-
previousReleaseId: previousReleaseId && previousReleaseId !== releaseId ? previousReleaseId : state.previousReleaseId
|
|
891
|
-
});
|
|
892
|
-
if (!options.deferPruning)
|
|
893
|
-
await pruneHelperReleases(layout);
|
|
894
|
-
}
|
|
895
|
-
async function installRecoveryLauncher(layout, releaseDir) {
|
|
896
|
-
const bootstrap = join(releaseDir, "lib/beeline/recovery-cli.mjs");
|
|
897
|
-
if (await access(bootstrap).then(() => true, () => false)) {
|
|
898
|
-
const stable = resolve6(layout.libDir, "../beeline-bootstrap.mjs");
|
|
899
|
-
const temporary = `${stable}.${process.pid}.tmp`;
|
|
900
|
-
await copyFile(bootstrap, temporary);
|
|
901
|
-
await rename2(temporary, stable);
|
|
902
|
-
await replaceFile(resolve6(layout.libDir, "../beeline-node-path"), `${process.execPath}
|
|
903
|
-
`, 384);
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
async function normalizeLegacyBundleShape(bundleDir) {
|
|
907
|
-
const innerLib = join(bundleDir, "lib", "beeline");
|
|
908
|
-
let anyFlat = false;
|
|
909
|
-
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
910
|
-
try {
|
|
911
|
-
await access(join(bundleDir, name), fsConstants.F_OK);
|
|
912
|
-
anyFlat = true;
|
|
913
|
-
break;
|
|
914
|
-
} catch {
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
if (!anyFlat)
|
|
918
|
-
return;
|
|
919
|
-
await mkdir3(innerLib, { recursive: true });
|
|
920
|
-
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
921
|
-
try {
|
|
922
|
-
await access(join(innerLib, name), fsConstants.F_OK);
|
|
923
|
-
continue;
|
|
924
|
-
} catch {
|
|
925
|
-
}
|
|
926
|
-
await rename2(join(bundleDir, name), join(innerLib, name)).catch(() => void 0);
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
async function writeBinForwarders(layout, activeBundleRoot) {
|
|
930
|
-
const entries = [
|
|
931
|
-
...FORWARDER_TOOLS.map((tool) => [tool, tool]),
|
|
932
|
-
...Object.entries(FORWARDER_ALIASES).map(([alias, tool]) => [alias, tool])
|
|
933
|
-
];
|
|
934
|
-
for (const [name, tool] of entries) {
|
|
935
|
-
const target = join(activeBundleRoot, "bin", tool);
|
|
936
|
-
try {
|
|
937
|
-
await access(target, fsConstants.X_OK);
|
|
938
|
-
} catch {
|
|
939
|
-
continue;
|
|
940
|
-
}
|
|
941
|
-
const independent = await access(resolve6(layout.libDir, "../beeline-bootstrap.mjs")).then(() => true, () => false);
|
|
942
|
-
await replaceFile(join(layout.binDir, name), independent || tool !== "beeline" ? forwarderScript(tool) : forwarderScript("legacy-beeline").replace("/bin/legacy-beeline", "/bin/beeline"), 493);
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
async function repairInstallForwarders(layout, opts = {}) {
|
|
946
|
-
assertInstallTestIsolation(layout);
|
|
947
|
-
if (await pathKind(layout.libDir) !== "symlink")
|
|
948
|
-
return false;
|
|
949
|
-
await installRecoveryLauncher(layout, layout.libDir);
|
|
950
|
-
const forwarderHealthy = async (name, tool) => {
|
|
951
|
-
let current;
|
|
952
|
-
try {
|
|
953
|
-
current = await readFile2(join(layout.binDir, name), "utf8");
|
|
954
|
-
} catch {
|
|
955
|
-
current = void 0;
|
|
956
|
-
}
|
|
957
|
-
const independent = await access(resolve6(layout.libDir, "../beeline-bootstrap.mjs")).then(() => true, () => false);
|
|
958
|
-
const expected = independent || tool !== "beeline" ? forwarderScript(tool) : forwarderScript("legacy-beeline").replace("/bin/legacy-beeline", "/bin/beeline");
|
|
959
|
-
return current === expected;
|
|
960
|
-
};
|
|
961
|
-
let healthy = await forwarderHealthy("beeline", "beeline");
|
|
962
|
-
for (const [alias, tool] of Object.entries(FORWARDER_ALIASES)) {
|
|
963
|
-
if (!await forwarderHealthy(alias, tool))
|
|
964
|
-
healthy = false;
|
|
965
|
-
}
|
|
966
|
-
if (healthy)
|
|
967
|
-
return false;
|
|
968
|
-
await mkdir3(layout.binDir, { recursive: true });
|
|
969
|
-
await writeBinForwarders(layout, layout.libDir);
|
|
970
|
-
opts.logger?.(`[body] self-update: repaired <prefix>/bin forwarders to follow the active-bundle anchor (${layout.libDir})`);
|
|
971
|
-
return true;
|
|
972
|
-
}
|
|
973
|
-
function describeIdentity(identity) {
|
|
974
|
-
if (!identity)
|
|
975
|
-
return "unknown";
|
|
976
|
-
const parts = [];
|
|
977
|
-
if (identity.version)
|
|
978
|
-
parts.push(identity.version);
|
|
979
|
-
if (identity.commit)
|
|
980
|
-
parts.push(identity.commit.slice(0, 12));
|
|
981
|
-
return parts.join(" ") || "unknown";
|
|
1062
|
+
await rename3(temp, path);
|
|
982
1063
|
}
|
|
983
1064
|
async function prepareLatestRelease(layout, options = {}) {
|
|
984
1065
|
try {
|
|
985
1066
|
const manifestUrl = options.manifest?.url ?? resolveManifestUrl(options.env ?? process.env);
|
|
986
1067
|
const bundle = options.manifest?.bundle ?? parseUpdateManifest(await fetchText(manifestUrl, options.fetchImpl ?? fetch), hostPlatformKey()).bundle;
|
|
987
1068
|
const pending = (await readUpdateState(layout)).stagedReleaseId;
|
|
988
|
-
const pendingDigest = pending ? await
|
|
1069
|
+
const pendingDigest = pending ? await readFile3(join2(layout.releasesRoot, pending, ".stage-ok"), "utf8").catch(() => "") : "";
|
|
989
1070
|
const releaseId = !options.force && pending && pendingDigest.trim() === bundle.sha256 ? pending : await stageRelease(layout, manifestUrl, bundle, {
|
|
990
1071
|
fetchImpl: options.fetchImpl,
|
|
991
1072
|
logger: options.logger,
|
|
@@ -995,69 +1076,32 @@ async function prepareLatestRelease(layout, options = {}) {
|
|
|
995
1076
|
await writeUpdateState(layout, {
|
|
996
1077
|
...await readUpdateState(layout),
|
|
997
1078
|
lastCheckAt: Date.now(),
|
|
998
|
-
lastCheckResult: "verified",
|
|
999
|
-
stagedReleaseId: releaseId
|
|
1000
|
-
});
|
|
1001
|
-
return { releaseId, identity: { version: bundle.version, commit: bundle.commit } };
|
|
1002
|
-
} catch (error) {
|
|
1003
|
-
await writeUpdateState(layout, {
|
|
1004
|
-
...await readUpdateState(layout),
|
|
1005
|
-
lastCheckAt: Date.now(),
|
|
1006
|
-
lastCheckResult: "unconfirmed",
|
|
1007
|
-
lastCheckError: String(error)
|
|
1008
|
-
}).catch(() => void 0);
|
|
1009
|
-
throw error;
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
async function pruneHelperReleases(layout, loadedRelease) {
|
|
1013
|
-
assertInstallTestIsolation(layout);
|
|
1014
|
-
if (!await ordinaryDirectory(layout.releasesRoot))
|
|
1015
|
-
return [];
|
|
1016
|
-
const active = await activeReleaseId(layout);
|
|
1017
|
-
if (!active)
|
|
1018
|
-
return [];
|
|
1019
|
-
const state = await readUpdateState(layout);
|
|
1020
|
-
const candidates = [];
|
|
1021
|
-
for (const entry of await readdir3(layout.releasesRoot, { withFileTypes: true })) {
|
|
1022
|
-
if (entry.name.startsWith("."))
|
|
1023
|
-
continue;
|
|
1024
|
-
if (entry.isSymbolicLink()) {
|
|
1025
|
-
if (![active, state.previousReleaseId, state.stagedReleaseId, loadedRelease].includes(entry.name))
|
|
1026
|
-
await rm3(join(layout.releasesRoot, entry.name), { force: true });
|
|
1027
|
-
continue;
|
|
1028
|
-
}
|
|
1029
|
-
if (!entry.isDirectory())
|
|
1030
|
-
continue;
|
|
1031
|
-
const path = join(layout.releasesRoot, entry.name);
|
|
1032
|
-
if (!await ordinaryDirectory(path))
|
|
1033
|
-
continue;
|
|
1034
|
-
candidates.push({
|
|
1035
|
-
id: entry.name,
|
|
1036
|
-
modified: (await lstat3(path)).mtimeMs,
|
|
1037
|
-
bootable: await access(join(path, BUNDLE_ENTRYPOINT)).then(() => true, () => false)
|
|
1038
|
-
});
|
|
1039
|
-
}
|
|
1040
|
-
const recordedPrevious = candidates.find((entry) => entry.id === state.previousReleaseId && entry.id !== active && entry.bootable)?.id;
|
|
1041
|
-
const previous = recordedPrevious ?? candidates.filter((entry) => entry.bootable && entry.id !== active && entry.id !== state.stagedReleaseId).sort((a, b) => b.modified - a.modified)[0]?.id;
|
|
1042
|
-
const keep = /* @__PURE__ */ new Set([active, previous, loadedRelease, state.stagedReleaseId]);
|
|
1043
|
-
const removed = [];
|
|
1044
|
-
for (const entry of candidates) {
|
|
1045
|
-
if (keep.has(entry.id))
|
|
1046
|
-
continue;
|
|
1047
|
-
await removeStoragePath(join(layout.releasesRoot, entry.id));
|
|
1048
|
-
removed.push(entry.id);
|
|
1079
|
+
lastCheckResult: "verified",
|
|
1080
|
+
stagedReleaseId: releaseId
|
|
1081
|
+
});
|
|
1082
|
+
return { releaseId, identity: { version: bundle.version, commit: bundle.commit } };
|
|
1083
|
+
} catch (error) {
|
|
1084
|
+
await writeUpdateState(layout, {
|
|
1085
|
+
...await readUpdateState(layout),
|
|
1086
|
+
lastCheckAt: Date.now(),
|
|
1087
|
+
lastCheckResult: "unconfirmed",
|
|
1088
|
+
lastCheckError: String(error)
|
|
1089
|
+
}).catch(() => void 0);
|
|
1090
|
+
throw error;
|
|
1049
1091
|
}
|
|
1050
|
-
if (previous !== state.previousReleaseId)
|
|
1051
|
-
await writeUpdateState(layout, { ...state, previousReleaseId: previous });
|
|
1052
|
-
return removed;
|
|
1053
1092
|
}
|
|
1054
|
-
var RELEASES_SEGMENT, STAGED_NODE_PATH_FILE, BUNDLE_ENTRYPOINT, PI_MCP_ADAPTER_ENTRYPOINT, CODEGRAPH_ENTRYPOINT, FORWARDER_TOOLS, FORWARDER_ALIASES,
|
|
1093
|
+
var RELEASES_SEGMENT, STAGED_NODE_PATH_FILE, BUNDLE_ENTRYPOINT, PI_MCP_ADAPTER_ENTRYPOINT, CODEGRAPH_ENTRYPOINT, FORWARDER_TOOLS, FORWARDER_ALIASES, SelfUpdateManager;
|
|
1055
1094
|
var init_self_update = __esm({
|
|
1056
1095
|
"apps/body/dist/self-update.js"() {
|
|
1057
1096
|
"use strict";
|
|
1058
|
-
init_storage_filesystem();
|
|
1059
1097
|
init_lifecycle_test_guard();
|
|
1060
1098
|
init_self_update_manifest();
|
|
1099
|
+
init_self_update_activate_release();
|
|
1100
|
+
init_self_update_activate_release();
|
|
1101
|
+
init_self_update_activate_release();
|
|
1102
|
+
init_self_update_activate_release();
|
|
1103
|
+
init_self_update_activate_release();
|
|
1104
|
+
init_self_update_activate_release();
|
|
1061
1105
|
RELEASES_SEGMENT = "beeline-releases";
|
|
1062
1106
|
STAGED_NODE_PATH_FILE = ".node-path";
|
|
1063
1107
|
BUNDLE_ENTRYPOINT = "lib/beeline/beeline-cli.mjs";
|
|
@@ -1073,12 +1117,6 @@ var init_self_update = __esm({
|
|
|
1073
1117
|
FORWARDER_ALIASES = {
|
|
1074
1118
|
usebeeline: "beeline"
|
|
1075
1119
|
};
|
|
1076
|
-
LEGACY_FLAT_BUNDLE_FILES = [
|
|
1077
|
-
"beeline-cli.mjs",
|
|
1078
|
-
"beeline-readonly-mcp.mjs",
|
|
1079
|
-
"pi-mcp-adapter.mjs",
|
|
1080
|
-
"bundle.json"
|
|
1081
|
-
];
|
|
1082
1120
|
SelfUpdateManager = class {
|
|
1083
1121
|
options;
|
|
1084
1122
|
constructor(options) {
|
|
@@ -1108,9 +1146,9 @@ __export(managed_update_exports, {
|
|
|
1108
1146
|
withInstallLock: () => withInstallLock
|
|
1109
1147
|
});
|
|
1110
1148
|
import { spawn as spawn3 } from "node:child_process";
|
|
1111
|
-
import { resolve as
|
|
1149
|
+
import { resolve as resolve8 } from "node:path";
|
|
1112
1150
|
function withInstallLock(layout, work, options = {}) {
|
|
1113
|
-
return withKernelLock(`beeline-install:${
|
|
1151
|
+
return withKernelLock(`beeline-install:${resolve8(layout.libDir)}`, work, options.waitMs);
|
|
1114
1152
|
}
|
|
1115
1153
|
function versionAtLeast(actual, minimum) {
|
|
1116
1154
|
const parse = (value) => /^v?(\d+)\.(\d+)\.(\d+)$/.exec(value)?.slice(1).map(Number);
|
|
@@ -1135,7 +1173,7 @@ async function runManagedUpdateWorker() {
|
|
|
1135
1173
|
}
|
|
1136
1174
|
async function prepareReleaseInWorker(env, deadlineAt, entrypoint) {
|
|
1137
1175
|
const layout = beelineInstallLayout(env);
|
|
1138
|
-
const bootstrap = entrypoint ??
|
|
1176
|
+
const bootstrap = entrypoint ?? resolve8(layout.libDir, "../beeline-bootstrap.mjs");
|
|
1139
1177
|
return new Promise((done, reject) => {
|
|
1140
1178
|
const child = spawn3(process.execPath, [bootstrap, "managed-update-worker"], {
|
|
1141
1179
|
detached: true,
|
|
@@ -1227,7 +1265,7 @@ var init_managed_update = __esm({
|
|
|
1227
1265
|
if (this.#minimum) {
|
|
1228
1266
|
const identity = await readInstalledBundleIdentity({
|
|
1229
1267
|
...this.options.layout,
|
|
1230
|
-
libDir:
|
|
1268
|
+
libDir: resolve8(this.options.layout.releasesRoot, releaseId)
|
|
1231
1269
|
});
|
|
1232
1270
|
if (!identity?.version || !versionAtLeast(identity.version, this.#minimum)) {
|
|
1233
1271
|
this.#prepared = void 0;
|
|
@@ -3407,9 +3445,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
3407
3445
|
}
|
|
3408
3446
|
close(callback) {
|
|
3409
3447
|
if (callback === void 0) {
|
|
3410
|
-
return new Promise((
|
|
3448
|
+
return new Promise((resolve12, reject) => {
|
|
3411
3449
|
this.close((err, data) => {
|
|
3412
|
-
return err ? reject(err) :
|
|
3450
|
+
return err ? reject(err) : resolve12(data);
|
|
3413
3451
|
});
|
|
3414
3452
|
});
|
|
3415
3453
|
}
|
|
@@ -3447,12 +3485,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
3447
3485
|
err = null;
|
|
3448
3486
|
}
|
|
3449
3487
|
if (callback === void 0) {
|
|
3450
|
-
return new Promise((
|
|
3488
|
+
return new Promise((resolve12, reject) => {
|
|
3451
3489
|
this.destroy(err, (err2, data) => {
|
|
3452
3490
|
return err2 ? (
|
|
3453
3491
|
/* istanbul ignore next: should never error */
|
|
3454
3492
|
reject(err2)
|
|
3455
|
-
) :
|
|
3493
|
+
) : resolve12(data);
|
|
3456
3494
|
});
|
|
3457
3495
|
});
|
|
3458
3496
|
}
|
|
@@ -5719,8 +5757,8 @@ var require_util2 = __commonJS({
|
|
|
5719
5757
|
function createDeferredPromise() {
|
|
5720
5758
|
let res;
|
|
5721
5759
|
let rej;
|
|
5722
|
-
const promise = new Promise((
|
|
5723
|
-
res =
|
|
5760
|
+
const promise = new Promise((resolve12, reject) => {
|
|
5761
|
+
res = resolve12;
|
|
5724
5762
|
rej = reject;
|
|
5725
5763
|
});
|
|
5726
5764
|
return { promise, resolve: res, reject: rej };
|
|
@@ -7966,12 +8004,12 @@ upgrade: ${upgrade}\r
|
|
|
7966
8004
|
cb();
|
|
7967
8005
|
}
|
|
7968
8006
|
}
|
|
7969
|
-
const waitForDrain = () => new Promise((
|
|
8007
|
+
const waitForDrain = () => new Promise((resolve12, reject) => {
|
|
7970
8008
|
assert(callback === null);
|
|
7971
8009
|
if (socket[kError]) {
|
|
7972
8010
|
reject(socket[kError]);
|
|
7973
8011
|
} else {
|
|
7974
|
-
callback =
|
|
8012
|
+
callback = resolve12;
|
|
7975
8013
|
}
|
|
7976
8014
|
});
|
|
7977
8015
|
socket.on("close", onDrain).on("drain", onDrain);
|
|
@@ -8608,12 +8646,12 @@ var require_client_h2 = __commonJS({
|
|
|
8608
8646
|
cb();
|
|
8609
8647
|
}
|
|
8610
8648
|
}
|
|
8611
|
-
const waitForDrain = () => new Promise((
|
|
8649
|
+
const waitForDrain = () => new Promise((resolve12, reject) => {
|
|
8612
8650
|
assert(callback === null);
|
|
8613
8651
|
if (socket[kError]) {
|
|
8614
8652
|
reject(socket[kError]);
|
|
8615
8653
|
} else {
|
|
8616
|
-
callback =
|
|
8654
|
+
callback = resolve12;
|
|
8617
8655
|
}
|
|
8618
8656
|
});
|
|
8619
8657
|
h2stream.on("close", onDrain).on("drain", onDrain);
|
|
@@ -9091,16 +9129,16 @@ var require_client = __commonJS({
|
|
|
9091
9129
|
return this[kNeedDrain] < 2;
|
|
9092
9130
|
}
|
|
9093
9131
|
async [kClose]() {
|
|
9094
|
-
return new Promise((
|
|
9132
|
+
return new Promise((resolve12) => {
|
|
9095
9133
|
if (this[kSize]) {
|
|
9096
|
-
this[kClosedResolve] =
|
|
9134
|
+
this[kClosedResolve] = resolve12;
|
|
9097
9135
|
} else {
|
|
9098
|
-
|
|
9136
|
+
resolve12(null);
|
|
9099
9137
|
}
|
|
9100
9138
|
});
|
|
9101
9139
|
}
|
|
9102
9140
|
async [kDestroy](err) {
|
|
9103
|
-
return new Promise((
|
|
9141
|
+
return new Promise((resolve12) => {
|
|
9104
9142
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
9105
9143
|
for (let i = 0; i < requests.length; i++) {
|
|
9106
9144
|
const request2 = requests[i];
|
|
@@ -9111,7 +9149,7 @@ var require_client = __commonJS({
|
|
|
9111
9149
|
this[kClosedResolve]();
|
|
9112
9150
|
this[kClosedResolve] = null;
|
|
9113
9151
|
}
|
|
9114
|
-
|
|
9152
|
+
resolve12(null);
|
|
9115
9153
|
};
|
|
9116
9154
|
if (this[kHTTPContext]) {
|
|
9117
9155
|
this[kHTTPContext].destroy(err, callback);
|
|
@@ -9162,7 +9200,7 @@ var require_client = __commonJS({
|
|
|
9162
9200
|
});
|
|
9163
9201
|
}
|
|
9164
9202
|
try {
|
|
9165
|
-
const socket = await new Promise((
|
|
9203
|
+
const socket = await new Promise((resolve12, reject) => {
|
|
9166
9204
|
client[kConnector]({
|
|
9167
9205
|
host,
|
|
9168
9206
|
hostname,
|
|
@@ -9174,7 +9212,7 @@ var require_client = __commonJS({
|
|
|
9174
9212
|
if (err) {
|
|
9175
9213
|
reject(err);
|
|
9176
9214
|
} else {
|
|
9177
|
-
|
|
9215
|
+
resolve12(socket2);
|
|
9178
9216
|
}
|
|
9179
9217
|
});
|
|
9180
9218
|
});
|
|
@@ -9510,8 +9548,8 @@ var require_pool_base = __commonJS({
|
|
|
9510
9548
|
if (this[kQueue].isEmpty()) {
|
|
9511
9549
|
await Promise.all(this[kClients].map((c) => c.close()));
|
|
9512
9550
|
} else {
|
|
9513
|
-
await new Promise((
|
|
9514
|
-
this[kClosedResolve] =
|
|
9551
|
+
await new Promise((resolve12) => {
|
|
9552
|
+
this[kClosedResolve] = resolve12;
|
|
9515
9553
|
});
|
|
9516
9554
|
}
|
|
9517
9555
|
}
|
|
@@ -10754,7 +10792,7 @@ var require_readable = __commonJS({
|
|
|
10754
10792
|
if (this._readableState.closeEmitted) {
|
|
10755
10793
|
return null;
|
|
10756
10794
|
}
|
|
10757
|
-
return await new Promise((
|
|
10795
|
+
return await new Promise((resolve12, reject) => {
|
|
10758
10796
|
if (this[kContentLength] > limit) {
|
|
10759
10797
|
this.destroy(new AbortError());
|
|
10760
10798
|
}
|
|
@@ -10767,7 +10805,7 @@ var require_readable = __commonJS({
|
|
|
10767
10805
|
if (signal?.aborted) {
|
|
10768
10806
|
reject(signal.reason ?? new AbortError());
|
|
10769
10807
|
} else {
|
|
10770
|
-
|
|
10808
|
+
resolve12(null);
|
|
10771
10809
|
}
|
|
10772
10810
|
}).on("error", noop).on("data", function(chunk) {
|
|
10773
10811
|
limit -= chunk.length;
|
|
@@ -10786,7 +10824,7 @@ var require_readable = __commonJS({
|
|
|
10786
10824
|
}
|
|
10787
10825
|
async function consume(stream, type) {
|
|
10788
10826
|
assert(!stream[kConsume]);
|
|
10789
|
-
return new Promise((
|
|
10827
|
+
return new Promise((resolve12, reject) => {
|
|
10790
10828
|
if (isUnusable(stream)) {
|
|
10791
10829
|
const rState = stream._readableState;
|
|
10792
10830
|
if (rState.destroyed && rState.closeEmitted === false) {
|
|
@@ -10803,7 +10841,7 @@ var require_readable = __commonJS({
|
|
|
10803
10841
|
stream[kConsume] = {
|
|
10804
10842
|
type,
|
|
10805
10843
|
stream,
|
|
10806
|
-
resolve:
|
|
10844
|
+
resolve: resolve12,
|
|
10807
10845
|
reject,
|
|
10808
10846
|
length: 0,
|
|
10809
10847
|
body: []
|
|
@@ -10873,18 +10911,18 @@ var require_readable = __commonJS({
|
|
|
10873
10911
|
return buffer;
|
|
10874
10912
|
}
|
|
10875
10913
|
function consumeEnd(consume2) {
|
|
10876
|
-
const { type, body, resolve:
|
|
10914
|
+
const { type, body, resolve: resolve12, stream, length } = consume2;
|
|
10877
10915
|
try {
|
|
10878
10916
|
if (type === "text") {
|
|
10879
|
-
|
|
10917
|
+
resolve12(chunksDecode(body, length));
|
|
10880
10918
|
} else if (type === "json") {
|
|
10881
|
-
|
|
10919
|
+
resolve12(JSON.parse(chunksDecode(body, length)));
|
|
10882
10920
|
} else if (type === "arrayBuffer") {
|
|
10883
|
-
|
|
10921
|
+
resolve12(chunksConcat(body, length).buffer);
|
|
10884
10922
|
} else if (type === "blob") {
|
|
10885
|
-
|
|
10923
|
+
resolve12(new Blob(body, { type: stream[kContentType] }));
|
|
10886
10924
|
} else if (type === "bytes") {
|
|
10887
|
-
|
|
10925
|
+
resolve12(chunksConcat(body, length));
|
|
10888
10926
|
}
|
|
10889
10927
|
consumeFinish(consume2);
|
|
10890
10928
|
} catch (err) {
|
|
@@ -11141,9 +11179,9 @@ var require_api_request = __commonJS({
|
|
|
11141
11179
|
};
|
|
11142
11180
|
function request2(opts, callback) {
|
|
11143
11181
|
if (callback === void 0) {
|
|
11144
|
-
return new Promise((
|
|
11182
|
+
return new Promise((resolve12, reject) => {
|
|
11145
11183
|
request2.call(this, opts, (err, data) => {
|
|
11146
|
-
return err ? reject(err) :
|
|
11184
|
+
return err ? reject(err) : resolve12(data);
|
|
11147
11185
|
});
|
|
11148
11186
|
});
|
|
11149
11187
|
}
|
|
@@ -11366,9 +11404,9 @@ var require_api_stream = __commonJS({
|
|
|
11366
11404
|
};
|
|
11367
11405
|
function stream(opts, factory, callback) {
|
|
11368
11406
|
if (callback === void 0) {
|
|
11369
|
-
return new Promise((
|
|
11407
|
+
return new Promise((resolve12, reject) => {
|
|
11370
11408
|
stream.call(this, opts, factory, (err, data) => {
|
|
11371
|
-
return err ? reject(err) :
|
|
11409
|
+
return err ? reject(err) : resolve12(data);
|
|
11372
11410
|
});
|
|
11373
11411
|
});
|
|
11374
11412
|
}
|
|
@@ -11653,9 +11691,9 @@ var require_api_upgrade = __commonJS({
|
|
|
11653
11691
|
};
|
|
11654
11692
|
function upgrade(opts, callback) {
|
|
11655
11693
|
if (callback === void 0) {
|
|
11656
|
-
return new Promise((
|
|
11694
|
+
return new Promise((resolve12, reject) => {
|
|
11657
11695
|
upgrade.call(this, opts, (err, data) => {
|
|
11658
|
-
return err ? reject(err) :
|
|
11696
|
+
return err ? reject(err) : resolve12(data);
|
|
11659
11697
|
});
|
|
11660
11698
|
});
|
|
11661
11699
|
}
|
|
@@ -11747,9 +11785,9 @@ var require_api_connect = __commonJS({
|
|
|
11747
11785
|
};
|
|
11748
11786
|
function connect(opts, callback) {
|
|
11749
11787
|
if (callback === void 0) {
|
|
11750
|
-
return new Promise((
|
|
11788
|
+
return new Promise((resolve12, reject) => {
|
|
11751
11789
|
connect.call(this, opts, (err, data) => {
|
|
11752
|
-
return err ? reject(err) :
|
|
11790
|
+
return err ? reject(err) : resolve12(data);
|
|
11753
11791
|
});
|
|
11754
11792
|
});
|
|
11755
11793
|
}
|
|
@@ -12976,16 +13014,16 @@ var require_dns = __commonJS({
|
|
|
12976
13014
|
setRecords(origin, addresses) {
|
|
12977
13015
|
const timestamp = Date.now();
|
|
12978
13016
|
const records = { records: { 4: null, 6: null } };
|
|
12979
|
-
for (const
|
|
12980
|
-
|
|
12981
|
-
if (typeof
|
|
12982
|
-
|
|
13017
|
+
for (const record2 of addresses) {
|
|
13018
|
+
record2.timestamp = timestamp;
|
|
13019
|
+
if (typeof record2.ttl === "number") {
|
|
13020
|
+
record2.ttl = Math.min(record2.ttl, this.#maxTTL);
|
|
12983
13021
|
} else {
|
|
12984
|
-
|
|
13022
|
+
record2.ttl = this.#maxTTL;
|
|
12985
13023
|
}
|
|
12986
|
-
const familyRecords = records.records[
|
|
12987
|
-
familyRecords.ips.push(
|
|
12988
|
-
records.records[
|
|
13024
|
+
const familyRecords = records.records[record2.family] ?? { ips: [] };
|
|
13025
|
+
familyRecords.ips.push(record2);
|
|
13026
|
+
records.records[record2.family] = familyRecords;
|
|
12989
13027
|
}
|
|
12990
13028
|
this.#records.set(origin.hostname, records);
|
|
12991
13029
|
}
|
|
@@ -15611,7 +15649,7 @@ var require_fetch = __commonJS({
|
|
|
15611
15649
|
function dispatch({ body }) {
|
|
15612
15650
|
const url = requestCurrentURL(request2);
|
|
15613
15651
|
const agent = fetchParams.controller.dispatcher;
|
|
15614
|
-
return new Promise((
|
|
15652
|
+
return new Promise((resolve12, reject) => agent.dispatch(
|
|
15615
15653
|
{
|
|
15616
15654
|
path: url.pathname + url.search,
|
|
15617
15655
|
origin: url.origin,
|
|
@@ -15687,7 +15725,7 @@ var require_fetch = __commonJS({
|
|
|
15687
15725
|
}
|
|
15688
15726
|
}
|
|
15689
15727
|
const onError = this.onError.bind(this);
|
|
15690
|
-
|
|
15728
|
+
resolve12({
|
|
15691
15729
|
status,
|
|
15692
15730
|
statusText,
|
|
15693
15731
|
headersList,
|
|
@@ -15733,7 +15771,7 @@ var require_fetch = __commonJS({
|
|
|
15733
15771
|
for (let i = 0; i < rawHeaders.length; i += 2) {
|
|
15734
15772
|
headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true);
|
|
15735
15773
|
}
|
|
15736
|
-
|
|
15774
|
+
resolve12({
|
|
15737
15775
|
status,
|
|
15738
15776
|
statusText: STATUS_CODES[status],
|
|
15739
15777
|
headersList,
|
|
@@ -19463,8 +19501,8 @@ var require_util8 = __commonJS({
|
|
|
19463
19501
|
return true;
|
|
19464
19502
|
}
|
|
19465
19503
|
function delay(ms) {
|
|
19466
|
-
return new Promise((
|
|
19467
|
-
setTimeout(
|
|
19504
|
+
return new Promise((resolve12) => {
|
|
19505
|
+
setTimeout(resolve12, ms).unref();
|
|
19468
19506
|
});
|
|
19469
19507
|
}
|
|
19470
19508
|
module.exports = {
|
|
@@ -19630,41 +19668,41 @@ var require_eventsource_stream = __commonJS({
|
|
|
19630
19668
|
if (colonPosition === 0) {
|
|
19631
19669
|
return;
|
|
19632
19670
|
}
|
|
19633
|
-
let
|
|
19671
|
+
let field2 = "";
|
|
19634
19672
|
let value = "";
|
|
19635
19673
|
if (colonPosition !== -1) {
|
|
19636
|
-
|
|
19674
|
+
field2 = line.subarray(0, colonPosition).toString("utf8");
|
|
19637
19675
|
let valueStart = colonPosition + 1;
|
|
19638
19676
|
if (line[valueStart] === SPACE) {
|
|
19639
19677
|
++valueStart;
|
|
19640
19678
|
}
|
|
19641
19679
|
value = line.subarray(valueStart).toString("utf8");
|
|
19642
19680
|
} else {
|
|
19643
|
-
|
|
19681
|
+
field2 = line.toString("utf8");
|
|
19644
19682
|
value = "";
|
|
19645
19683
|
}
|
|
19646
|
-
switch (
|
|
19684
|
+
switch (field2) {
|
|
19647
19685
|
case "data":
|
|
19648
|
-
if (event[
|
|
19649
|
-
event[
|
|
19686
|
+
if (event[field2] === void 0) {
|
|
19687
|
+
event[field2] = value;
|
|
19650
19688
|
} else {
|
|
19651
|
-
event[
|
|
19689
|
+
event[field2] += `
|
|
19652
19690
|
${value}`;
|
|
19653
19691
|
}
|
|
19654
19692
|
break;
|
|
19655
19693
|
case "retry":
|
|
19656
19694
|
if (isASCIINumber(value)) {
|
|
19657
|
-
event[
|
|
19695
|
+
event[field2] = value;
|
|
19658
19696
|
}
|
|
19659
19697
|
break;
|
|
19660
19698
|
case "id":
|
|
19661
19699
|
if (isValidLastEventId(value)) {
|
|
19662
|
-
event[
|
|
19700
|
+
event[field2] = value;
|
|
19663
19701
|
}
|
|
19664
19702
|
break;
|
|
19665
19703
|
case "event":
|
|
19666
19704
|
if (value.length > 0) {
|
|
19667
|
-
event[
|
|
19705
|
+
event[field2] = value;
|
|
19668
19706
|
}
|
|
19669
19707
|
break;
|
|
19670
19708
|
}
|
|
@@ -20147,9 +20185,9 @@ var require_undici = __commonJS({
|
|
|
20147
20185
|
// apps/body/dist/filesystem-change.js
|
|
20148
20186
|
import { watch as watch2 } from "node:fs";
|
|
20149
20187
|
import { stat as stat2 } from "node:fs/promises";
|
|
20150
|
-
import { dirname as
|
|
20188
|
+
import { dirname as dirname6 } from "node:path";
|
|
20151
20189
|
function waitForPathRemoval(path) {
|
|
20152
|
-
return new Promise((
|
|
20190
|
+
return new Promise((resolve12, reject) => {
|
|
20153
20191
|
let reading = false, dirty = false, ended = false;
|
|
20154
20192
|
const finish = (error) => {
|
|
20155
20193
|
if (ended)
|
|
@@ -20159,7 +20197,7 @@ function waitForPathRemoval(path) {
|
|
|
20159
20197
|
if (error)
|
|
20160
20198
|
reject(error);
|
|
20161
20199
|
else
|
|
20162
|
-
|
|
20200
|
+
resolve12();
|
|
20163
20201
|
};
|
|
20164
20202
|
const inspect = async () => {
|
|
20165
20203
|
dirty = true;
|
|
@@ -20185,7 +20223,7 @@ function waitForPathRemoval(path) {
|
|
|
20185
20223
|
reading = false;
|
|
20186
20224
|
}
|
|
20187
20225
|
};
|
|
20188
|
-
const watcher = watch2(
|
|
20226
|
+
const watcher = watch2(dirname6(path), () => {
|
|
20189
20227
|
void inspect();
|
|
20190
20228
|
});
|
|
20191
20229
|
watcher.once("error", finish);
|
|
@@ -20219,9 +20257,9 @@ __export(store_exports, {
|
|
|
20219
20257
|
import { createHash as createHash4, randomUUID } from "node:crypto";
|
|
20220
20258
|
import { chmodSync, mkdirSync, readFileSync as readFileSync3, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
20221
20259
|
import { homedir as homedir4 } from "node:os";
|
|
20222
|
-
import { join as
|
|
20260
|
+
import { join as join3 } from "node:path";
|
|
20223
20261
|
function stateDir(env = process.env) {
|
|
20224
|
-
return
|
|
20262
|
+
return join3(env.XDG_STATE_HOME || join3(env.HOME || homedir4(), ".local/state"), "beeline-sessions");
|
|
20225
20263
|
}
|
|
20226
20264
|
function pidAlive(pid) {
|
|
20227
20265
|
try {
|
|
@@ -20243,17 +20281,17 @@ function writePrivate(path, text) {
|
|
|
20243
20281
|
}
|
|
20244
20282
|
function readState(dir = stateDir()) {
|
|
20245
20283
|
try {
|
|
20246
|
-
const value = JSON.parse(readFileSync3(
|
|
20284
|
+
const value = JSON.parse(readFileSync3(join3(dir, "state.json"), "utf8"));
|
|
20247
20285
|
return Array.isArray(value.sessions) ? value : { sessions: [] };
|
|
20248
20286
|
} catch {
|
|
20249
20287
|
return { sessions: [] };
|
|
20250
20288
|
}
|
|
20251
20289
|
}
|
|
20252
20290
|
function writeState(dir, state) {
|
|
20253
|
-
writePrivate(
|
|
20291
|
+
writePrivate(join3(ensureDir(dir), "state.json"), JSON.stringify(state, null, 2) + "\n");
|
|
20254
20292
|
}
|
|
20255
20293
|
async function withLock(dir, run2) {
|
|
20256
|
-
const lock =
|
|
20294
|
+
const lock = join3(ensureDir(dir), "state.lock");
|
|
20257
20295
|
for (let attempt = 0; ; attempt++) {
|
|
20258
20296
|
try {
|
|
20259
20297
|
mkdirSync(lock);
|
|
@@ -20292,16 +20330,16 @@ function safe(value) {
|
|
|
20292
20330
|
return value.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 120);
|
|
20293
20331
|
}
|
|
20294
20332
|
function inboxPath(dir, key) {
|
|
20295
|
-
return
|
|
20333
|
+
return join3(dir, "inbox", `${createHash4("sha256").update(key).digest("hex").slice(0, 24)}.txt`);
|
|
20296
20334
|
}
|
|
20297
20335
|
function queueInbox(dir, key, text) {
|
|
20298
20336
|
adoptInboxText(dir, key);
|
|
20299
20337
|
queueInboxOnce(dir, key, `local:${randomUUID()}`, text);
|
|
20300
20338
|
}
|
|
20301
20339
|
function adoptInboxText(dir, key) {
|
|
20302
|
-
const folder = ensureDir(
|
|
20340
|
+
const folder = ensureDir(join3(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24)));
|
|
20303
20341
|
try {
|
|
20304
|
-
renameSync(inboxPath(dir, key),
|
|
20342
|
+
renameSync(inboxPath(dir, key), join3(folder, `${randomUUID()}.text.pending`));
|
|
20305
20343
|
} catch (error) {
|
|
20306
20344
|
if (error.code !== "ENOENT")
|
|
20307
20345
|
throw error;
|
|
@@ -20312,8 +20350,8 @@ function queueInboxOnce(dir, key, deliveryId, text) {
|
|
|
20312
20350
|
const queuedAt = lastInboxOrder;
|
|
20313
20351
|
if (!deliveryId || deliveryId.length > 256)
|
|
20314
20352
|
throw new Error("Invalid inbox delivery identity");
|
|
20315
|
-
const folder = ensureDir(
|
|
20316
|
-
const stem =
|
|
20353
|
+
const folder = ensureDir(join3(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24)));
|
|
20354
|
+
const stem = join3(folder, createHash4("sha256").update(deliveryId).digest("hex"));
|
|
20317
20355
|
if (existsDelivery(stem + ".pending") || existsDelivery(stem + ".done"))
|
|
20318
20356
|
return false;
|
|
20319
20357
|
writePrivate(stem + ".pending", JSON.stringify({ id: deliveryId, text, queuedAt }));
|
|
@@ -20328,7 +20366,7 @@ function existsDelivery(path) {
|
|
|
20328
20366
|
}
|
|
20329
20367
|
}
|
|
20330
20368
|
function takeDeliveries(dir, key) {
|
|
20331
|
-
const folder =
|
|
20369
|
+
const folder = join3(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24));
|
|
20332
20370
|
let names;
|
|
20333
20371
|
try {
|
|
20334
20372
|
names = readdirSync(folder);
|
|
@@ -20337,7 +20375,7 @@ function takeDeliveries(dir, key) {
|
|
|
20337
20375
|
}
|
|
20338
20376
|
const pending = names.filter((name) => name.endsWith(".pending")).flatMap((name) => {
|
|
20339
20377
|
try {
|
|
20340
|
-
const contents = readFileSync3(
|
|
20378
|
+
const contents = readFileSync3(join3(folder, name), "utf8");
|
|
20341
20379
|
const item = name.endsWith(".text.pending") ? { text: contents, queuedAt: 0 } : JSON.parse(contents);
|
|
20342
20380
|
return typeof item.text === "string" ? [{ name, ...item }] : [];
|
|
20343
20381
|
} catch {
|
|
@@ -20346,7 +20384,7 @@ function takeDeliveries(dir, key) {
|
|
|
20346
20384
|
}).sort((a, b) => a.queuedAt - b.queuedAt || a.name.localeCompare(b.name));
|
|
20347
20385
|
const text = [];
|
|
20348
20386
|
for (const item of pending) {
|
|
20349
|
-
const path =
|
|
20387
|
+
const path = join3(folder, item.name), done = path.replace(/\.pending$/, ".done");
|
|
20350
20388
|
try {
|
|
20351
20389
|
renameSync(path, done);
|
|
20352
20390
|
} catch {
|
|
@@ -20362,15 +20400,15 @@ function takeInbox(dir, key) {
|
|
|
20362
20400
|
return takeDeliveries(dir, key).join("\n\n");
|
|
20363
20401
|
}
|
|
20364
20402
|
function recordHookSession(dir, session2) {
|
|
20365
|
-
writePrivate(
|
|
20403
|
+
writePrivate(join3(ensureDir(join3(dir, "hooks")), `${safe(session2.agent)}-${safe(session2.sessionId)}.json`), JSON.stringify(session2));
|
|
20366
20404
|
}
|
|
20367
20405
|
function forgetHookSession(dir, agent, sessionId) {
|
|
20368
|
-
rmSync(
|
|
20406
|
+
rmSync(join3(dir, "hooks", `${safe(agent)}-${safe(sessionId)}.json`), { force: true });
|
|
20369
20407
|
}
|
|
20370
20408
|
function hookSessions(dir, now = Date.now(), alive = pidAlive) {
|
|
20371
20409
|
let names;
|
|
20372
20410
|
try {
|
|
20373
|
-
names = readdirSync(
|
|
20411
|
+
names = readdirSync(join3(dir, "hooks"));
|
|
20374
20412
|
} catch {
|
|
20375
20413
|
return [];
|
|
20376
20414
|
}
|
|
@@ -20379,7 +20417,7 @@ function hookSessions(dir, now = Date.now(), alive = pidAlive) {
|
|
|
20379
20417
|
if (!name.endsWith(".json"))
|
|
20380
20418
|
continue;
|
|
20381
20419
|
try {
|
|
20382
|
-
const session2 = JSON.parse(readFileSync3(
|
|
20420
|
+
const session2 = JSON.parse(readFileSync3(join3(dir, "hooks", name), "utf8"));
|
|
20383
20421
|
if (now - session2.seenAt <= HOOK_TTL_MS && (session2.pid === void 0 || alive(session2.pid)))
|
|
20384
20422
|
found.push(session2);
|
|
20385
20423
|
} catch {
|
|
@@ -20404,7 +20442,7 @@ function admitHeldMcpCompletion(url, body) {
|
|
|
20404
20442
|
if (!["https:", "http:"].includes(target.protocol) || target.username || target.password || target.hash || target.search || target.pathname !== "/mcp/oauth/handoff" || !body || typeof body !== "object" || Object.getPrototypeOf(body) !== Object.prototype)
|
|
20405
20443
|
throw new Error("Held MCP completion route unavailable");
|
|
20406
20444
|
const fields = Object.getOwnPropertyDescriptors(body);
|
|
20407
|
-
if (Object.getOwnPropertySymbols(body).length || Object.keys(fields).some((key) => !["state", "completionV1", "waitMs"].includes(key)) || Object.values(fields).some((
|
|
20445
|
+
if (Object.getOwnPropertySymbols(body).length || Object.keys(fields).some((key) => !["state", "completionV1", "waitMs"].includes(key)) || Object.values(fields).some((field2) => !("value" in field2)) || fields.completionV1?.value !== true || typeof fields.state?.value !== "string" || !/^[A-Za-z0-9_-]{32,128}$/.test(fields.state.value) || !Number.isSafeInteger(fields.waitMs?.value) || fields.waitMs.value < 1 || fields.waitMs.value > 6e5)
|
|
20408
20446
|
throw new Error("Held MCP completion admission invalid");
|
|
20409
20447
|
}
|
|
20410
20448
|
async function request(url, body, headers, stream, cancellation, held = false) {
|
|
@@ -20636,10 +20674,18 @@ var init_beeline_api = __esm({
|
|
|
20636
20674
|
}
|
|
20637
20675
|
});
|
|
20638
20676
|
|
|
20677
|
+
// packages/api-contract/dist/phone-types-room-live-delta.js
|
|
20678
|
+
var init_phone_types_room_live_delta = __esm({
|
|
20679
|
+
"packages/api-contract/dist/phone-types-room-live-delta.js"() {
|
|
20680
|
+
"use strict";
|
|
20681
|
+
}
|
|
20682
|
+
});
|
|
20683
|
+
|
|
20639
20684
|
// packages/api-contract/dist/phone-types.js
|
|
20640
20685
|
var init_phone_types = __esm({
|
|
20641
20686
|
"packages/api-contract/dist/phone-types.js"() {
|
|
20642
20687
|
"use strict";
|
|
20688
|
+
init_phone_types_room_live_delta();
|
|
20643
20689
|
}
|
|
20644
20690
|
});
|
|
20645
20691
|
|
|
@@ -20650,21 +20696,12 @@ var init_model_choice = __esm({
|
|
|
20650
20696
|
}
|
|
20651
20697
|
});
|
|
20652
20698
|
|
|
20653
|
-
// packages/api-contract/dist/system-message-catalog.js
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
throw new Error(`System message ${key} needs ${entry.variables.length} variables`);
|
|
20658
|
-
let text = entry.parts[0];
|
|
20659
|
-
for (let index = 0; index < values.length; index++)
|
|
20660
|
-
text += `${values[index]}${entry.parts[index + 1]}`;
|
|
20661
|
-
return text;
|
|
20662
|
-
}
|
|
20663
|
-
var SYSTEM_MESSAGE_CATALOG;
|
|
20664
|
-
var init_system_message_catalog = __esm({
|
|
20665
|
-
"packages/api-contract/dist/system-message-catalog.js"() {
|
|
20699
|
+
// packages/api-contract/dist/system-message-catalog-away-auto-pause.js
|
|
20700
|
+
var SYSTEM_MESSAGE_AWAY_AUTO_PAUSE;
|
|
20701
|
+
var init_system_message_catalog_away_auto_pause = __esm({
|
|
20702
|
+
"packages/api-contract/dist/system-message-catalog-away-auto-pause.js"() {
|
|
20666
20703
|
"use strict";
|
|
20667
|
-
|
|
20704
|
+
SYSTEM_MESSAGE_AWAY_AUTO_PAUSE = {
|
|
20668
20705
|
"away-auto-pause.warning": { parts: ["will pause schedules and subscriptions for"], variables: [] },
|
|
20669
20706
|
"away-auto-pause.come-back": { parts: ["You have been away for 3 days. Come back within 1 day to keep them running. After they pause, ask your agent to resume."], variables: [] },
|
|
20670
20707
|
"agent-command.agent-mention": {
|
|
@@ -21312,7 +21349,17 @@ var init_system_message_catalog = __esm({
|
|
|
21312
21349
|
"daemon-service.instead-of": {
|
|
21313
21350
|
parts: ["instead of ", ""],
|
|
21314
21351
|
variables: ["input_from"]
|
|
21315
|
-
}
|
|
21352
|
+
}
|
|
21353
|
+
};
|
|
21354
|
+
}
|
|
21355
|
+
});
|
|
21356
|
+
|
|
21357
|
+
// packages/api-contract/dist/system-message-catalog-daemon-service.js
|
|
21358
|
+
var SYSTEM_MESSAGE_DAEMON_SERVICE;
|
|
21359
|
+
var init_system_message_catalog_daemon_service = __esm({
|
|
21360
|
+
"packages/api-contract/dist/system-message-catalog-daemon-service.js"() {
|
|
21361
|
+
"use strict";
|
|
21362
|
+
SYSTEM_MESSAGE_DAEMON_SERVICE = {
|
|
21316
21363
|
"daemon-service.needs-a-connection-to": {
|
|
21317
21364
|
parts: ["needs a connection to"],
|
|
21318
21365
|
variables: []
|
|
@@ -21960,7 +22007,17 @@ var init_system_message_catalog = __esm({
|
|
|
21960
22007
|
"vault-save-http.list-separator": {
|
|
21961
22008
|
parts: [", "],
|
|
21962
22009
|
variables: []
|
|
21963
|
-
}
|
|
22010
|
+
}
|
|
22011
|
+
};
|
|
22012
|
+
}
|
|
22013
|
+
});
|
|
22014
|
+
|
|
22015
|
+
// packages/api-contract/dist/system-message-catalog-voice-service.js
|
|
22016
|
+
var SYSTEM_MESSAGE_VOICE_SERVICE;
|
|
22017
|
+
var init_system_message_catalog_voice_service = __esm({
|
|
22018
|
+
"packages/api-contract/dist/system-message-catalog-voice-service.js"() {
|
|
22019
|
+
"use strict";
|
|
22020
|
+
SYSTEM_MESSAGE_VOICE_SERVICE = {
|
|
21964
22021
|
"voice-service.voice-call": {
|
|
21965
22022
|
parts: ["Voice call"],
|
|
21966
22023
|
variables: []
|
|
@@ -22605,7 +22662,17 @@ var init_system_message_catalog = __esm({
|
|
|
22605
22662
|
"turn-silence.the-helper-couldn-t-get-a-working-copy-of-check-the-repository-is": {
|
|
22606
22663
|
parts: ["the helper couldn't get a working copy of ", ". Check the repository is reachable."],
|
|
22607
22664
|
variables: ["classified_repo_the_repository"]
|
|
22608
|
-
}
|
|
22665
|
+
}
|
|
22666
|
+
};
|
|
22667
|
+
}
|
|
22668
|
+
});
|
|
22669
|
+
|
|
22670
|
+
// packages/api-contract/dist/system-message-catalog-turn-silence.js
|
|
22671
|
+
var SYSTEM_MESSAGE_TURN_SILENCE;
|
|
22672
|
+
var init_system_message_catalog_turn_silence = __esm({
|
|
22673
|
+
"packages/api-contract/dist/system-message-catalog-turn-silence.js"() {
|
|
22674
|
+
"use strict";
|
|
22675
|
+
SYSTEM_MESSAGE_TURN_SILENCE = {
|
|
22609
22676
|
"turn-silence.the-helper-is-out-of-date-run-beeline-start-on-the-helper-s-machi": {
|
|
22610
22677
|
parts: ["the helper is out of date. Run `beeline start` on the helper's machine."],
|
|
22611
22678
|
variables: []
|
|
@@ -22812,6 +22879,33 @@ var init_system_message_catalog = __esm({
|
|
|
22812
22879
|
}
|
|
22813
22880
|
});
|
|
22814
22881
|
|
|
22882
|
+
// packages/api-contract/dist/system-message-catalog.js
|
|
22883
|
+
function systemMessage(key, ...values) {
|
|
22884
|
+
const entry = SYSTEM_MESSAGE_CATALOG[key];
|
|
22885
|
+
if (values.length !== entry.variables.length)
|
|
22886
|
+
throw new Error(`System message ${key} needs ${entry.variables.length} variables`);
|
|
22887
|
+
let text = entry.parts[0];
|
|
22888
|
+
for (let index = 0; index < values.length; index++)
|
|
22889
|
+
text += `${values[index]}${entry.parts[index + 1]}`;
|
|
22890
|
+
return text;
|
|
22891
|
+
}
|
|
22892
|
+
var SYSTEM_MESSAGE_CATALOG;
|
|
22893
|
+
var init_system_message_catalog = __esm({
|
|
22894
|
+
"packages/api-contract/dist/system-message-catalog.js"() {
|
|
22895
|
+
"use strict";
|
|
22896
|
+
init_system_message_catalog_away_auto_pause();
|
|
22897
|
+
init_system_message_catalog_daemon_service();
|
|
22898
|
+
init_system_message_catalog_voice_service();
|
|
22899
|
+
init_system_message_catalog_turn_silence();
|
|
22900
|
+
SYSTEM_MESSAGE_CATALOG = {
|
|
22901
|
+
...SYSTEM_MESSAGE_AWAY_AUTO_PAUSE,
|
|
22902
|
+
...SYSTEM_MESSAGE_DAEMON_SERVICE,
|
|
22903
|
+
...SYSTEM_MESSAGE_VOICE_SERVICE,
|
|
22904
|
+
...SYSTEM_MESSAGE_TURN_SILENCE
|
|
22905
|
+
};
|
|
22906
|
+
}
|
|
22907
|
+
});
|
|
22908
|
+
|
|
22815
22909
|
// packages/api-contract/dist/voice.js
|
|
22816
22910
|
var init_voice = __esm({
|
|
22817
22911
|
"packages/api-contract/dist/voice.js"() {
|
|
@@ -22852,20 +22946,6 @@ var init_artifacts = __esm({
|
|
|
22852
22946
|
}
|
|
22853
22947
|
});
|
|
22854
22948
|
|
|
22855
|
-
// packages/api-contract/dist/repository-onboarding.js
|
|
22856
|
-
var init_repository_onboarding = __esm({
|
|
22857
|
-
"packages/api-contract/dist/repository-onboarding.js"() {
|
|
22858
|
-
"use strict";
|
|
22859
|
-
}
|
|
22860
|
-
});
|
|
22861
|
-
|
|
22862
|
-
// packages/api-contract/dist/vault-save.js
|
|
22863
|
-
var init_vault_save = __esm({
|
|
22864
|
-
"packages/api-contract/dist/vault-save.js"() {
|
|
22865
|
-
"use strict";
|
|
22866
|
-
}
|
|
22867
|
-
});
|
|
22868
|
-
|
|
22869
22949
|
// packages/api-contract/dist/agent-usage.js
|
|
22870
22950
|
var USAGE_OLD_SECONDS, USAGE_WINDOW_LABELS;
|
|
22871
22951
|
var init_agent_usage = __esm({
|
|
@@ -22885,52 +22965,6 @@ var init_agent_usage = __esm({
|
|
|
22885
22965
|
}
|
|
22886
22966
|
});
|
|
22887
22967
|
|
|
22888
|
-
// packages/api-contract/dist/system-events.js
|
|
22889
|
-
function isPerItemEventKind(value) {
|
|
22890
|
-
return PER_ITEM_EVENT_KINDS.includes(value);
|
|
22891
|
-
}
|
|
22892
|
-
var SYSTEM_LINE_SEPARATOR, SERVER_EVENT_KINDS, PER_ITEM_EVENT_KINDS, SUBSCRIBABLE_EVENT_KINDS, AGENT_EVENT_SLUG_MAX_LENGTH, AGENT_KIND;
|
|
22893
|
-
var init_system_events = __esm({
|
|
22894
|
-
"packages/api-contract/dist/system-events.js"() {
|
|
22895
|
-
"use strict";
|
|
22896
|
-
init_system_message_catalog();
|
|
22897
|
-
SYSTEM_LINE_SEPARATOR = systemMessage("system-events.separator");
|
|
22898
|
-
SERVER_EVENT_KINDS = [
|
|
22899
|
-
"joined",
|
|
22900
|
-
"left",
|
|
22901
|
-
"schedule-ran",
|
|
22902
|
-
"corner-opened",
|
|
22903
|
-
"check-passed",
|
|
22904
|
-
"check-failed",
|
|
22905
|
-
"merged",
|
|
22906
|
-
"grant-decided",
|
|
22907
|
-
"squire-approval-decided",
|
|
22908
|
-
"connector-offer-decided",
|
|
22909
|
-
"turn-cancelled",
|
|
22910
|
-
"choice-answered",
|
|
22911
|
-
"choice-skipped",
|
|
22912
|
-
"poll-closed",
|
|
22913
|
-
"workflow-handoff",
|
|
22914
|
-
"subscription-fired",
|
|
22915
|
-
"computer-session-activity"
|
|
22916
|
-
];
|
|
22917
|
-
PER_ITEM_EVENT_KINDS = [
|
|
22918
|
-
"grant-decided",
|
|
22919
|
-
"squire-approval-decided",
|
|
22920
|
-
"connector-offer-decided",
|
|
22921
|
-
"turn-cancelled",
|
|
22922
|
-
"choice-answered",
|
|
22923
|
-
"choice-skipped",
|
|
22924
|
-
"poll-closed",
|
|
22925
|
-
"subscription-fired",
|
|
22926
|
-
"computer-session-activity"
|
|
22927
|
-
];
|
|
22928
|
-
SUBSCRIBABLE_EVENT_KINDS = SERVER_EVENT_KINDS.filter((kind) => !isPerItemEventKind(kind) && kind !== "merged");
|
|
22929
|
-
AGENT_EVENT_SLUG_MAX_LENGTH = 40;
|
|
22930
|
-
AGENT_KIND = new RegExp(`^agent:[a-z0-9-]{1,${AGENT_EVENT_SLUG_MAX_LENGTH}}$`);
|
|
22931
|
-
}
|
|
22932
|
-
});
|
|
22933
|
-
|
|
22934
22968
|
// packages/api-contract/dist/agent-sign-in.js
|
|
22935
22969
|
var AGENT_SIGN_IN_ATTEMPT_TTL_MS, AGENT_SIGN_IN_SERVICE_LABELS;
|
|
22936
22970
|
var init_agent_sign_in = __esm({
|
|
@@ -22950,15 +22984,6 @@ var init_agent_sign_in = __esm({
|
|
|
22950
22984
|
}
|
|
22951
22985
|
});
|
|
22952
22986
|
|
|
22953
|
-
// packages/api-contract/dist/agent-access.js
|
|
22954
|
-
var ACCESS_NOTICE_WINDOW_MS;
|
|
22955
|
-
var init_agent_access = __esm({
|
|
22956
|
-
"packages/api-contract/dist/agent-access.js"() {
|
|
22957
|
-
"use strict";
|
|
22958
|
-
ACCESS_NOTICE_WINDOW_MS = 10 * 6e4;
|
|
22959
|
-
}
|
|
22960
|
-
});
|
|
22961
|
-
|
|
22962
22987
|
// packages/api-contract/dist/agent-grants.js
|
|
22963
22988
|
var AGENT_GRANT_KINDS, REQUESTABLE_AGENT_GRANT_KINDS, DECISION_LINE;
|
|
22964
22989
|
var init_agent_grants = __esm({
|
|
@@ -23049,23 +23074,124 @@ var init_room_choices = __esm({
|
|
|
23049
23074
|
}
|
|
23050
23075
|
});
|
|
23051
23076
|
|
|
23077
|
+
// packages/api-contract/dist/repository-onboarding.js
|
|
23078
|
+
var init_repository_onboarding = __esm({
|
|
23079
|
+
"packages/api-contract/dist/repository-onboarding.js"() {
|
|
23080
|
+
"use strict";
|
|
23081
|
+
}
|
|
23082
|
+
});
|
|
23083
|
+
|
|
23084
|
+
// packages/api-contract/dist/vault-save.js
|
|
23085
|
+
var init_vault_save = __esm({
|
|
23086
|
+
"packages/api-contract/dist/vault-save.js"() {
|
|
23087
|
+
"use strict";
|
|
23088
|
+
}
|
|
23089
|
+
});
|
|
23090
|
+
|
|
23091
|
+
// packages/api-contract/dist/system-events.js
|
|
23092
|
+
function isPerItemEventKind(value) {
|
|
23093
|
+
return PER_ITEM_EVENT_KINDS.includes(value);
|
|
23094
|
+
}
|
|
23095
|
+
var SYSTEM_LINE_SEPARATOR, SERVER_EVENT_KINDS, PER_ITEM_EVENT_KINDS, SUBSCRIBABLE_EVENT_KINDS, AGENT_EVENT_SLUG_MAX_LENGTH, AGENT_KIND;
|
|
23096
|
+
var init_system_events = __esm({
|
|
23097
|
+
"packages/api-contract/dist/system-events.js"() {
|
|
23098
|
+
"use strict";
|
|
23099
|
+
init_system_message_catalog();
|
|
23100
|
+
SYSTEM_LINE_SEPARATOR = systemMessage("system-events.separator");
|
|
23101
|
+
SERVER_EVENT_KINDS = [
|
|
23102
|
+
"joined",
|
|
23103
|
+
"left",
|
|
23104
|
+
"schedule-ran",
|
|
23105
|
+
"corner-opened",
|
|
23106
|
+
"check-passed",
|
|
23107
|
+
"check-failed",
|
|
23108
|
+
"merged",
|
|
23109
|
+
"grant-decided",
|
|
23110
|
+
"squire-approval-decided",
|
|
23111
|
+
"connector-offer-decided",
|
|
23112
|
+
"turn-cancelled",
|
|
23113
|
+
"choice-answered",
|
|
23114
|
+
"choice-skipped",
|
|
23115
|
+
"poll-closed",
|
|
23116
|
+
"workflow-handoff",
|
|
23117
|
+
"subscription-fired",
|
|
23118
|
+
"computer-session-activity"
|
|
23119
|
+
];
|
|
23120
|
+
PER_ITEM_EVENT_KINDS = [
|
|
23121
|
+
"grant-decided",
|
|
23122
|
+
"squire-approval-decided",
|
|
23123
|
+
"connector-offer-decided",
|
|
23124
|
+
"turn-cancelled",
|
|
23125
|
+
"choice-answered",
|
|
23126
|
+
"choice-skipped",
|
|
23127
|
+
"poll-closed",
|
|
23128
|
+
"subscription-fired",
|
|
23129
|
+
"computer-session-activity"
|
|
23130
|
+
];
|
|
23131
|
+
SUBSCRIBABLE_EVENT_KINDS = SERVER_EVENT_KINDS.filter((kind) => !isPerItemEventKind(kind) && kind !== "merged");
|
|
23132
|
+
AGENT_EVENT_SLUG_MAX_LENGTH = 40;
|
|
23133
|
+
AGENT_KIND = new RegExp(`^agent:[a-z0-9-]{1,${AGENT_EVENT_SLUG_MAX_LENGTH}}$`);
|
|
23134
|
+
}
|
|
23135
|
+
});
|
|
23136
|
+
|
|
23137
|
+
// packages/api-contract/dist/phone-guards-read-choice-card.js
|
|
23138
|
+
var init_phone_guards_read_choice_card = __esm({
|
|
23139
|
+
"packages/api-contract/dist/phone-guards-read-choice-card.js"() {
|
|
23140
|
+
"use strict";
|
|
23141
|
+
init_repository_onboarding();
|
|
23142
|
+
init_vault_save();
|
|
23143
|
+
init_system_events();
|
|
23144
|
+
init_voice();
|
|
23145
|
+
init_phone_types();
|
|
23146
|
+
init_room_choices();
|
|
23147
|
+
init_phone_guards();
|
|
23148
|
+
}
|
|
23149
|
+
});
|
|
23150
|
+
|
|
23151
|
+
// packages/api-contract/dist/agent-access.js
|
|
23152
|
+
var ACCESS_NOTICE_WINDOW_MS;
|
|
23153
|
+
var init_agent_access = __esm({
|
|
23154
|
+
"packages/api-contract/dist/agent-access.js"() {
|
|
23155
|
+
"use strict";
|
|
23156
|
+
ACCESS_NOTICE_WINDOW_MS = 10 * 6e4;
|
|
23157
|
+
}
|
|
23158
|
+
});
|
|
23159
|
+
|
|
23160
|
+
// packages/api-contract/dist/phone-guards-read-corner-lifecycle.js
|
|
23161
|
+
var init_phone_guards_read_corner_lifecycle = __esm({
|
|
23162
|
+
"packages/api-contract/dist/phone-guards-read-corner-lifecycle.js"() {
|
|
23163
|
+
"use strict";
|
|
23164
|
+
init_agent_access();
|
|
23165
|
+
init_phone_types();
|
|
23166
|
+
init_phone_guards();
|
|
23167
|
+
init_phone_guards_read_choice_card();
|
|
23168
|
+
}
|
|
23169
|
+
});
|
|
23170
|
+
|
|
23171
|
+
// packages/api-contract/dist/phone-guards-read-agent-detail-view.js
|
|
23172
|
+
var init_phone_guards_read_agent_detail_view = __esm({
|
|
23173
|
+
"packages/api-contract/dist/phone-guards-read-agent-detail-view.js"() {
|
|
23174
|
+
"use strict";
|
|
23175
|
+
init_agent_usage();
|
|
23176
|
+
init_phone_guards();
|
|
23177
|
+
init_phone_guards_read_corner_lifecycle();
|
|
23178
|
+
}
|
|
23179
|
+
});
|
|
23180
|
+
|
|
23052
23181
|
// packages/api-contract/dist/phone-guards.js
|
|
23053
23182
|
var CLOSED_VIEWER;
|
|
23054
23183
|
var init_phone_guards = __esm({
|
|
23055
23184
|
"packages/api-contract/dist/phone-guards.js"() {
|
|
23056
23185
|
"use strict";
|
|
23057
|
-
init_repository_onboarding();
|
|
23058
|
-
init_vault_save();
|
|
23059
23186
|
init_agent_usage();
|
|
23060
|
-
init_system_events();
|
|
23061
23187
|
init_agent_sign_in();
|
|
23062
|
-
init_agent_access();
|
|
23063
|
-
init_voice();
|
|
23064
|
-
init_phone_types();
|
|
23065
23188
|
init_agent_grants();
|
|
23066
23189
|
init_connector_offers();
|
|
23067
23190
|
init_workbench();
|
|
23068
23191
|
init_room_choices();
|
|
23192
|
+
init_phone_guards_read_choice_card();
|
|
23193
|
+
init_phone_guards_read_corner_lifecycle();
|
|
23194
|
+
init_phone_guards_read_agent_detail_view();
|
|
23069
23195
|
CLOSED_VIEWER = {
|
|
23070
23196
|
identity: { pubkey: "0".repeat(64), kind: "human", name: "" },
|
|
23071
23197
|
role: "member",
|
|
@@ -23697,9 +23823,9 @@ var init_stream_frame = __esm({
|
|
|
23697
23823
|
import { execFile as execFile3 } from "node:child_process";
|
|
23698
23824
|
import { closeSync, fstatSync, openSync, readSync, readdirSync as readdirSync2, readlinkSync, statSync as statSync2 } from "node:fs";
|
|
23699
23825
|
import { homedir as homedir5 } from "node:os";
|
|
23700
|
-
import { basename as basename3, join as
|
|
23826
|
+
import { basename as basename3, join as join4 } from "node:path";
|
|
23701
23827
|
function codexHome(env = process.env) {
|
|
23702
|
-
return env.CODEX_HOME ||
|
|
23828
|
+
return env.CODEX_HOME || join4(env.HOME || homedir5(), ".codex");
|
|
23703
23829
|
}
|
|
23704
23830
|
function turnEvent(line) {
|
|
23705
23831
|
if (!line.includes("event_msg") || !(line.includes("task_") || line.includes("turn_")))
|
|
@@ -23763,14 +23889,14 @@ function scanCodex(proc = "/proc") {
|
|
|
23763
23889
|
continue;
|
|
23764
23890
|
let fds;
|
|
23765
23891
|
try {
|
|
23766
|
-
fds = readdirSync2(
|
|
23892
|
+
fds = readdirSync2(join4(proc, name, "fd"));
|
|
23767
23893
|
} catch {
|
|
23768
23894
|
continue;
|
|
23769
23895
|
}
|
|
23770
23896
|
for (const fd of fds) {
|
|
23771
23897
|
let target;
|
|
23772
23898
|
try {
|
|
23773
|
-
target = readlinkSync(
|
|
23899
|
+
target = readlinkSync(join4(proc, name, "fd", fd));
|
|
23774
23900
|
} catch {
|
|
23775
23901
|
continue;
|
|
23776
23902
|
}
|
|
@@ -23779,7 +23905,7 @@ function scanCodex(proc = "/proc") {
|
|
|
23779
23905
|
continue;
|
|
23780
23906
|
let cwd;
|
|
23781
23907
|
try {
|
|
23782
|
-
cwd = readlinkSync(
|
|
23908
|
+
cwd = readlinkSync(join4(proc, name, "cwd"));
|
|
23783
23909
|
} catch {
|
|
23784
23910
|
}
|
|
23785
23911
|
if (!found.some((s) => s.threadId === threadId))
|
|
@@ -23789,12 +23915,12 @@ function scanCodex(proc = "/proc") {
|
|
|
23789
23915
|
return found;
|
|
23790
23916
|
}
|
|
23791
23917
|
function codexQueue(threadId, text, bin = "codex", timeoutMs = 3e4) {
|
|
23792
|
-
return new Promise((
|
|
23918
|
+
return new Promise((resolve12, reject) => {
|
|
23793
23919
|
execFile3(bin, ["queue", "--thread", threadId, "--message", text], { timeout: timeoutMs }, (error, _stdout, stderr) => {
|
|
23794
23920
|
if (error)
|
|
23795
23921
|
reject(new Error(String(stderr).trim() || error.message));
|
|
23796
23922
|
else
|
|
23797
|
-
|
|
23923
|
+
resolve12();
|
|
23798
23924
|
});
|
|
23799
23925
|
});
|
|
23800
23926
|
}
|
|
@@ -23812,12 +23938,12 @@ var init_codex = __esm({
|
|
|
23812
23938
|
import { closeSync as closeSync2, fstatSync as fstatSync2, openSync as openSync2, readFileSync as readFileSync4, readSync as readSync2, readdirSync as readdirSync3, statSync as statSync3 } from "node:fs";
|
|
23813
23939
|
import { createConnection as createConnection3 } from "node:net";
|
|
23814
23940
|
import { homedir as homedir6 } from "node:os";
|
|
23815
|
-
import { join as
|
|
23941
|
+
import { join as join5 } from "node:path";
|
|
23816
23942
|
function claudeConfigDir(env = process.env) {
|
|
23817
|
-
return env.CLAUDE_CONFIG_DIR ||
|
|
23943
|
+
return env.CLAUDE_CONFIG_DIR || join5(env.HOME || homedir6(), ".claude");
|
|
23818
23944
|
}
|
|
23819
23945
|
function scanClaude(env = process.env, alive = pidAlive) {
|
|
23820
|
-
const dir =
|
|
23946
|
+
const dir = join5(claudeConfigDir(env), "sessions");
|
|
23821
23947
|
let names;
|
|
23822
23948
|
try {
|
|
23823
23949
|
names = readdirSync3(dir);
|
|
@@ -23829,7 +23955,7 @@ function scanClaude(env = process.env, alive = pidAlive) {
|
|
|
23829
23955
|
if (!/^\d+\.json$/.test(name))
|
|
23830
23956
|
continue;
|
|
23831
23957
|
try {
|
|
23832
|
-
const value = JSON.parse(readFileSync4(
|
|
23958
|
+
const value = JSON.parse(readFileSync4(join5(dir, name), "utf8"));
|
|
23833
23959
|
if (Number.isInteger(value.pid) && alive(value.pid))
|
|
23834
23960
|
sessions.push(value);
|
|
23835
23961
|
} catch {
|
|
@@ -23841,7 +23967,7 @@ function chosenName(session2) {
|
|
|
23841
23967
|
return ["user", "peer", "hook"].includes(session2.nameSource ?? "") ? session2.name : void 0;
|
|
23842
23968
|
}
|
|
23843
23969
|
function postToClaude(socket, text, _timeoutMs = 5e3) {
|
|
23844
|
-
return new Promise((
|
|
23970
|
+
return new Promise((resolve12, reject) => {
|
|
23845
23971
|
const connection = createConnection3(socket.path);
|
|
23846
23972
|
connection.once("error", (error) => {
|
|
23847
23973
|
reject(error);
|
|
@@ -23850,13 +23976,13 @@ function postToClaude(socket, text, _timeoutMs = 5e3) {
|
|
|
23850
23976
|
if (socket.token)
|
|
23851
23977
|
connection.write(JSON.stringify({ type: "auth", token: socket.token }) + "\n");
|
|
23852
23978
|
connection.end(JSON.stringify({ type: "user", message: { role: "user", content: text } }) + "\n", () => {
|
|
23853
|
-
|
|
23979
|
+
resolve12();
|
|
23854
23980
|
});
|
|
23855
23981
|
});
|
|
23856
23982
|
});
|
|
23857
23983
|
}
|
|
23858
23984
|
function claudeTranscript(sessionId, env = process.env) {
|
|
23859
|
-
const root =
|
|
23985
|
+
const root = join5(claudeConfigDir(env), "projects");
|
|
23860
23986
|
let projects;
|
|
23861
23987
|
try {
|
|
23862
23988
|
projects = readdirSync3(root);
|
|
@@ -23864,7 +23990,7 @@ function claudeTranscript(sessionId, env = process.env) {
|
|
|
23864
23990
|
return void 0;
|
|
23865
23991
|
}
|
|
23866
23992
|
for (const project of projects) {
|
|
23867
|
-
const path =
|
|
23993
|
+
const path = join5(root, project, `${sessionId}.jsonl`);
|
|
23868
23994
|
try {
|
|
23869
23995
|
if (statSync3(path).isFile())
|
|
23870
23996
|
return path;
|
|
@@ -23903,7 +24029,7 @@ function heldBy(mode, setting) {
|
|
|
23903
24029
|
}
|
|
23904
24030
|
function inboundSetting(env = process.env) {
|
|
23905
24031
|
try {
|
|
23906
|
-
const value = JSON.parse(readFileSync4(
|
|
24032
|
+
const value = JSON.parse(readFileSync4(join5(claudeConfigDir(env), "settings.json"), "utf8"));
|
|
23907
24033
|
return typeof value.crossSessionInbound === "string" ? value.crossSessionInbound : void 0;
|
|
23908
24034
|
} catch {
|
|
23909
24035
|
return void 0;
|
|
@@ -23918,20 +24044,20 @@ var init_claude = __esm({
|
|
|
23918
24044
|
|
|
23919
24045
|
// apps/body/dist/session-join/claude-mcp.js
|
|
23920
24046
|
import { watch as watch3, mkdirSync as mkdirSync2, readFileSync as readFileSync5, readdirSync as readdirSync4, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
23921
|
-
import { join as
|
|
24047
|
+
import { join as join6 } from "node:path";
|
|
23922
24048
|
import { createInterface } from "node:readline";
|
|
23923
24049
|
function hasClaudeMcp(dir, claudePid) {
|
|
23924
24050
|
if (!claudePid)
|
|
23925
24051
|
return false;
|
|
23926
24052
|
let files;
|
|
23927
24053
|
try {
|
|
23928
|
-
files = readdirSync4(
|
|
24054
|
+
files = readdirSync4(join6(dir, "claude-mcp"));
|
|
23929
24055
|
} catch {
|
|
23930
24056
|
return false;
|
|
23931
24057
|
}
|
|
23932
24058
|
return files.some((file) => {
|
|
23933
24059
|
try {
|
|
23934
|
-
const entry = JSON.parse(readFileSync5(
|
|
24060
|
+
const entry = JSON.parse(readFileSync5(join6(dir, "claude-mcp", file), "utf8"));
|
|
23935
24061
|
return entry.claudePid === claudePid && pidAlive(entry.pid);
|
|
23936
24062
|
} catch {
|
|
23937
24063
|
return false;
|
|
@@ -23974,9 +24100,9 @@ async function runClaudeMcp(dir, env, rulesFor) {
|
|
|
23974
24100
|
if (!session2)
|
|
23975
24101
|
return;
|
|
23976
24102
|
if (!registration) {
|
|
23977
|
-
const folder =
|
|
24103
|
+
const folder = join6(dir, "claude-mcp");
|
|
23978
24104
|
mkdirSync2(folder, { recursive: true, mode: 448 });
|
|
23979
|
-
registration =
|
|
24105
|
+
registration = join6(folder, `${process.pid}.json`);
|
|
23980
24106
|
writeFileSync2(registration, JSON.stringify({ pid: process.pid, claudePid: session2.pid }), { mode: 384 });
|
|
23981
24107
|
}
|
|
23982
24108
|
await flushClaudeMcp(dir, session2, env.CLAUDE_CODE_MESSAGING_TOKEN);
|
|
@@ -24077,7 +24203,7 @@ var init_sessions = __esm({
|
|
|
24077
24203
|
import { spawn as spawn5 } from "node:child_process";
|
|
24078
24204
|
import { chmodSync as chmodSync2, closeSync as closeSync3, existsSync as existsSync2, mkdirSync as mkdirSync3, openSync as openSync3, readFileSync as readFileSync6, readdirSync as readdirSync5, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync3, watch as watch4 } from "node:fs";
|
|
24079
24205
|
import { createConnection as createConnection4, createServer as createServer3 } from "node:net";
|
|
24080
|
-
import { join as
|
|
24206
|
+
import { join as join7 } from "node:path";
|
|
24081
24207
|
import { createHash as createHash6 } from "node:crypto";
|
|
24082
24208
|
function command(runner2, joined2, args) {
|
|
24083
24209
|
const q = (v) => /^[A-Za-z0-9_./:@=-]+$/.test(v) ? v : `"${v.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
@@ -24179,7 +24305,7 @@ async function acceptMemberDelivery(dir, key, runner2, raw) {
|
|
|
24179
24305
|
}
|
|
24180
24306
|
function log(dir, line) {
|
|
24181
24307
|
try {
|
|
24182
|
-
writeFileSync3(
|
|
24308
|
+
writeFileSync3(join7(dir, "bridge.log"), `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
24183
24309
|
`, { flag: "a", mode: 384 });
|
|
24184
24310
|
} catch {
|
|
24185
24311
|
}
|
|
@@ -24205,7 +24331,7 @@ async function flush(dir, sources, deps = realDeps) {
|
|
|
24205
24331
|
}
|
|
24206
24332
|
}
|
|
24207
24333
|
function serveTools(dir) {
|
|
24208
|
-
const path =
|
|
24334
|
+
const path = join7(dir, "bridge.sock");
|
|
24209
24335
|
rmSync3(path, { force: true });
|
|
24210
24336
|
const server = createServer3((connection) => {
|
|
24211
24337
|
let buffer = "", taken = false;
|
|
@@ -24233,7 +24359,7 @@ function serveTools(dir) {
|
|
|
24233
24359
|
server.unref();
|
|
24234
24360
|
}
|
|
24235
24361
|
function outboxDir(cwd) {
|
|
24236
|
-
return
|
|
24362
|
+
return join7(cwd, ".beeline", "outbox");
|
|
24237
24363
|
}
|
|
24238
24364
|
async function serveOutboxes(dir) {
|
|
24239
24365
|
let served = 0;
|
|
@@ -24245,7 +24371,7 @@ async function serveOutboxes(dir) {
|
|
|
24245
24371
|
continue;
|
|
24246
24372
|
}
|
|
24247
24373
|
for (const name of names.filter((n) => n.endsWith(".request.json"))) {
|
|
24248
|
-
const path =
|
|
24374
|
+
const path = join7(outboxDir(joined2.cwd), name);
|
|
24249
24375
|
const taking = `${path}.taking`;
|
|
24250
24376
|
try {
|
|
24251
24377
|
renameSync2(path, taking);
|
|
@@ -24271,19 +24397,19 @@ async function serveOutboxes(dir) {
|
|
|
24271
24397
|
async function toolViaOutbox(cwd, name, args) {
|
|
24272
24398
|
const dirPath = outboxDir(cwd);
|
|
24273
24399
|
mkdirSync3(dirPath, { recursive: true });
|
|
24274
|
-
writeFileSync3(
|
|
24400
|
+
writeFileSync3(join7(cwd, ".beeline", ".gitignore"), "*\n");
|
|
24275
24401
|
const id = `${Date.now()}-${process.pid}`;
|
|
24276
|
-
const request2 =
|
|
24402
|
+
const request2 = join7(dirPath, `${id}.request.json`), result = join7(dirPath, `${id}.result.json`);
|
|
24277
24403
|
writeFileSync3(`${request2}.tmp`, JSON.stringify({ name, args }));
|
|
24278
24404
|
renameSync2(`${request2}.tmp`, request2);
|
|
24279
|
-
return new Promise((
|
|
24405
|
+
return new Promise((resolve12) => {
|
|
24280
24406
|
let settled = false;
|
|
24281
24407
|
const finish = (answer) => {
|
|
24282
24408
|
if (settled)
|
|
24283
24409
|
return;
|
|
24284
24410
|
settled = true;
|
|
24285
24411
|
watcher.close();
|
|
24286
|
-
|
|
24412
|
+
resolve12(answer);
|
|
24287
24413
|
};
|
|
24288
24414
|
const inspect = () => {
|
|
24289
24415
|
try {
|
|
@@ -24301,15 +24427,15 @@ async function toolViaOutbox(cwd, name, args) {
|
|
|
24301
24427
|
});
|
|
24302
24428
|
}
|
|
24303
24429
|
function toolViaBridge(dir, key, name, args) {
|
|
24304
|
-
return new Promise((
|
|
24305
|
-
const connection = createConnection4(
|
|
24430
|
+
return new Promise((resolve12) => {
|
|
24431
|
+
const connection = createConnection4(join7(dir, "bridge.sock"));
|
|
24306
24432
|
let text = "", sent = false, settled = false;
|
|
24307
24433
|
const unknown = { ok: false, error: "Beeline tool result is awaiting confirmation" };
|
|
24308
24434
|
const finish = (answer) => {
|
|
24309
24435
|
if (settled)
|
|
24310
24436
|
return;
|
|
24311
24437
|
settled = true;
|
|
24312
|
-
|
|
24438
|
+
resolve12(answer);
|
|
24313
24439
|
connection.destroy();
|
|
24314
24440
|
};
|
|
24315
24441
|
connection.setEncoding("utf8");
|
|
@@ -24331,7 +24457,7 @@ function toolViaBridge(dir, key, name, args) {
|
|
|
24331
24457
|
});
|
|
24332
24458
|
}
|
|
24333
24459
|
async function runBridge(dir, runner2) {
|
|
24334
|
-
const pidFile =
|
|
24460
|
+
const pidFile = join7(dir, "bridge.pid");
|
|
24335
24461
|
try {
|
|
24336
24462
|
const fd = openSync3(pidFile, "wx", 384);
|
|
24337
24463
|
writeFileSync3(fd, String(process.pid));
|
|
@@ -24364,7 +24490,7 @@ async function runBridge(dir, runner2) {
|
|
|
24364
24490
|
for (const watcher of outboxWatches.values())
|
|
24365
24491
|
watcher.close();
|
|
24366
24492
|
rmSync3(pidFile, { force: true });
|
|
24367
|
-
rmSync3(
|
|
24493
|
+
rmSync3(join7(dir, "bridge.sock"), { force: true });
|
|
24368
24494
|
process.exit(0);
|
|
24369
24495
|
};
|
|
24370
24496
|
process.once("SIGTERM", stop);
|
|
@@ -24435,7 +24561,7 @@ async function runBridge(dir, runner2) {
|
|
|
24435
24561
|
const path = outboxDir(joined2.cwd);
|
|
24436
24562
|
if (!outboxWatches.has(path)) {
|
|
24437
24563
|
mkdirSync3(path, { recursive: true, mode: 448 });
|
|
24438
|
-
const ignore =
|
|
24564
|
+
const ignore = join7(joined2.cwd, ".beeline", ".gitignore");
|
|
24439
24565
|
if (!existsSync2(ignore))
|
|
24440
24566
|
writeFileSync3(ignore, "*\n", { mode: 384 });
|
|
24441
24567
|
outboxWatches.set(path, watch4(path, (_event, name) => {
|
|
@@ -24447,8 +24573,8 @@ async function runBridge(dir, runner2) {
|
|
|
24447
24573
|
await serveOutboxes(dir).catch((error) => log(dir, `outbox: ${String(error)}`));
|
|
24448
24574
|
await flush(dir, sources).catch((error) => log(dir, `flush: ${String(error)}`));
|
|
24449
24575
|
if (!localDirty)
|
|
24450
|
-
await new Promise((
|
|
24451
|
-
wake =
|
|
24576
|
+
await new Promise((resolve12) => {
|
|
24577
|
+
wake = resolve12;
|
|
24452
24578
|
});
|
|
24453
24579
|
wake = void 0;
|
|
24454
24580
|
}
|
|
@@ -24462,12 +24588,12 @@ async function runBridge(dir, runner2) {
|
|
|
24462
24588
|
}
|
|
24463
24589
|
log(dir, `bridge ${process.pid} stopped: no joined sessions`);
|
|
24464
24590
|
rmSync3(pidFile, { force: true });
|
|
24465
|
-
rmSync3(
|
|
24591
|
+
rmSync3(join7(dir, "bridge.sock"), { force: true });
|
|
24466
24592
|
process.exit(0);
|
|
24467
24593
|
}
|
|
24468
24594
|
function bridgeRunning(dir) {
|
|
24469
24595
|
try {
|
|
24470
|
-
const holder = Number(readFileSync6(
|
|
24596
|
+
const holder = Number(readFileSync6(join7(dir, "bridge.pid"), "utf8"));
|
|
24471
24597
|
return Boolean(holder) && pidAlive(holder);
|
|
24472
24598
|
} catch {
|
|
24473
24599
|
return false;
|
|
@@ -24476,7 +24602,7 @@ function bridgeRunning(dir) {
|
|
|
24476
24602
|
function ensureBridge(dir, runner2, env = process.env) {
|
|
24477
24603
|
if (bridgeRunning(dir))
|
|
24478
24604
|
return;
|
|
24479
|
-
const out = openSync3(
|
|
24605
|
+
const out = openSync3(join7(dir, "bridge.log"), "a", 384);
|
|
24480
24606
|
const child = spawn5(runner2.node, [runner2.bundle, "session", "bridge"], { detached: true, stdio: ["ignore", out, out], env });
|
|
24481
24607
|
child.unref();
|
|
24482
24608
|
closeSync3(out);
|
|
@@ -24735,7 +24861,7 @@ def register(ctx):
|
|
|
24735
24861
|
import { spawnSync } from "node:child_process";
|
|
24736
24862
|
import { copyFileSync, existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync3, rmSync as rmSync4, statSync as statSync4, writeFileSync as writeFileSync4, chmodSync as chmodSync3 } from "node:fs";
|
|
24737
24863
|
import { homedir as homedir7 } from "node:os";
|
|
24738
|
-
import { dirname as
|
|
24864
|
+
import { dirname as dirname7, join as join8 } from "node:path";
|
|
24739
24865
|
function home(env) {
|
|
24740
24866
|
return env.HOME || homedir7();
|
|
24741
24867
|
}
|
|
@@ -24771,7 +24897,7 @@ function writeFile3(path, content, expected) {
|
|
|
24771
24897
|
}
|
|
24772
24898
|
if (before === content)
|
|
24773
24899
|
return false;
|
|
24774
|
-
mkdirSync4(
|
|
24900
|
+
mkdirSync4(dirname7(path), { recursive: true });
|
|
24775
24901
|
const backup = `${path}.bak-${NAME}`;
|
|
24776
24902
|
if (before !== void 0 && !existsSync3(backup) && !before.includes(" session hook "))
|
|
24777
24903
|
copyFileSync(path, backup);
|
|
@@ -24881,18 +25007,18 @@ function saveJson(path, value, remove) {
|
|
|
24881
25007
|
function claudeCode(context) {
|
|
24882
25008
|
const command2 = (event) => ({ hooks: [{ type: "command", command: hookCommand(context, "claude-code", event), timeout: 10 }] });
|
|
24883
25009
|
const remove = Boolean(context.remove);
|
|
24884
|
-
const path = context.env.CLAUDE_CONFIG_DIR ?
|
|
24885
|
-
return [...mergeClaudeMcp(path, context), ...hooksFile(
|
|
25010
|
+
const path = context.env.CLAUDE_CONFIG_DIR ? join8(context.env.CLAUDE_CONFIG_DIR, ".claude.json") : join8(home(context.env), ".claude.json");
|
|
25011
|
+
return [...mergeClaudeMcp(path, context), ...hooksFile(join8(claudeConfigDir(context.env), "settings.json"), "claude-code", [["SessionStart", command2("session-start")]], remove)];
|
|
24886
25012
|
}
|
|
24887
25013
|
function codex(context) {
|
|
24888
25014
|
const group = (event) => ({ matcher: "*", hooks: [{ type: "command", command: hookCommand(context, "codex", event), timeout: 10 }] });
|
|
24889
|
-
const lines = hooksFile(
|
|
25015
|
+
const lines = hooksFile(join8(codexHome(context.env), "hooks.json"), "codex", [["SessionStart", group("session-start")]], Boolean(context.remove));
|
|
24890
25016
|
if (lines.length && !context.remove)
|
|
24891
25017
|
lines.push("Codex asks once to trust Beeline\u2019s SessionStart hook if automatic trust is unavailable: open /hooks and trust only Beeline.");
|
|
24892
25018
|
return lines;
|
|
24893
25019
|
}
|
|
24894
25020
|
function geminiHome(env) {
|
|
24895
|
-
return env.GEMINI_CLI_HOME ||
|
|
25021
|
+
return env.GEMINI_CLI_HOME || join8(home(env), ".gemini");
|
|
24896
25022
|
}
|
|
24897
25023
|
function gemini(context) {
|
|
24898
25024
|
const group = (event, timeout) => ({ matcher: "*", hooks: [{
|
|
@@ -24901,7 +25027,7 @@ function gemini(context) {
|
|
|
24901
25027
|
command: hookCommand(context, "gemini", event),
|
|
24902
25028
|
timeout
|
|
24903
25029
|
}] });
|
|
24904
|
-
return hooksFile(
|
|
25030
|
+
return hooksFile(join8(geminiHome(context.env), "settings.json"), "gemini", [
|
|
24905
25031
|
["SessionStart", group("session-start", 1e4)],
|
|
24906
25032
|
["BeforeAgent", group("user-prompt-submit", 1e4)],
|
|
24907
25033
|
["AfterTool", group("post-tool-use", 1e4)],
|
|
@@ -24910,9 +25036,9 @@ function gemini(context) {
|
|
|
24910
25036
|
], Boolean(context.remove));
|
|
24911
25037
|
}
|
|
24912
25038
|
function antigravity(context) {
|
|
24913
|
-
const dir =
|
|
25039
|
+
const dir = join8(home(context.env), ".gemini/config");
|
|
24914
25040
|
const lines = [];
|
|
24915
|
-
const hooksPath =
|
|
25041
|
+
const hooksPath = join8(dir, "hooks.json");
|
|
24916
25042
|
const hooks = readJson(hooksPath);
|
|
24917
25043
|
if (context.remove)
|
|
24918
25044
|
delete hooks[NAME];
|
|
@@ -24928,13 +25054,13 @@ function antigravity(context) {
|
|
|
24928
25054
|
};
|
|
24929
25055
|
}
|
|
24930
25056
|
lines.push(...saveJson(hooksPath, hooks, Boolean(context.remove)));
|
|
24931
|
-
const sidecar =
|
|
24932
|
-
const configPath =
|
|
25057
|
+
const sidecar = join8(dir, "sidecars", NAME, "sidecar.json");
|
|
25058
|
+
const configPath = join8(dir, "config.json");
|
|
24933
25059
|
const config = readJson(configPath);
|
|
24934
25060
|
const sidecars = object2(config, "sidecars");
|
|
24935
25061
|
if (context.remove) {
|
|
24936
25062
|
delete sidecars[NAME];
|
|
24937
|
-
rmSync4(
|
|
25063
|
+
rmSync4(dirname7(sidecar), { recursive: true, force: true });
|
|
24938
25064
|
} else {
|
|
24939
25065
|
if (writeJson(sidecar, {
|
|
24940
25066
|
command: context.node,
|
|
@@ -24961,31 +25087,31 @@ function pluginFile(path, content, remove) {
|
|
|
24961
25087
|
return writeFile3(path, content) ? [`updated ${path}`] : [];
|
|
24962
25088
|
}
|
|
24963
25089
|
function opencode(context) {
|
|
24964
|
-
return pluginFile(
|
|
25090
|
+
return pluginFile(join8(home(context.env), ".config/opencode/plugins", `${NAME}.ts`), fill(OPENCODE_PLUGIN, context.node, context.bundle), Boolean(context.remove));
|
|
24965
25091
|
}
|
|
24966
25092
|
function piHome(env) {
|
|
24967
|
-
return env.PI_CODING_AGENT_DIR ||
|
|
25093
|
+
return env.PI_CODING_AGENT_DIR || join8(home(env), ".pi/agent");
|
|
24968
25094
|
}
|
|
24969
25095
|
function pi(context) {
|
|
24970
|
-
return pluginFile(
|
|
25096
|
+
return pluginFile(join8(piHome(context.env), "extensions", `${NAME}.ts`), fill(PI_EXTENSION, context.node, context.bundle), Boolean(context.remove));
|
|
24971
25097
|
}
|
|
24972
25098
|
function hermesRoot(env) {
|
|
24973
|
-
const base = env.HERMES_HOME ? env.HERMES_HOME.replace(/^~(?=\/|$)/, home(env)) :
|
|
25099
|
+
const base = env.HERMES_HOME ? env.HERMES_HOME.replace(/^~(?=\/|$)/, home(env)) : join8(home(env), `.hermes${env.HERMES_DATA_DIR_SUFFIX ?? ""}`);
|
|
24974
25100
|
let active = "";
|
|
24975
25101
|
try {
|
|
24976
|
-
active = readFileSync7(
|
|
25102
|
+
active = readFileSync7(join8(base, "active_profile"), "utf8").trim();
|
|
24977
25103
|
} catch {
|
|
24978
25104
|
}
|
|
24979
|
-
if (active && active !== "default" && active !== "." && active !== ".." && !/[/\\]/.test(active) && existsSync3(
|
|
24980
|
-
return
|
|
25105
|
+
if (active && active !== "default" && active !== "." && active !== ".." && !/[/\\]/.test(active) && existsSync3(join8(base, "profiles", active)))
|
|
25106
|
+
return join8(base, "profiles", active);
|
|
24981
25107
|
return base;
|
|
24982
25108
|
}
|
|
24983
25109
|
function hermes(context) {
|
|
24984
|
-
const dir =
|
|
25110
|
+
const dir = join8(hermesRoot(context.env), "plugins", NAME);
|
|
24985
25111
|
const remove = Boolean(context.remove);
|
|
24986
25112
|
const lines = [
|
|
24987
|
-
...pluginFile(
|
|
24988
|
-
...pluginFile(
|
|
25113
|
+
...pluginFile(join8(dir, "__init__.py"), fill(HERMES_PLUGIN, context.node, context.bundle), remove),
|
|
25114
|
+
...pluginFile(join8(dir, "plugin.yaml"), HERMES_MANIFEST, remove)
|
|
24989
25115
|
];
|
|
24990
25116
|
if (remove)
|
|
24991
25117
|
rmSync4(dir, { recursive: true, force: true });
|
|
@@ -24995,7 +25121,7 @@ function hermes(context) {
|
|
|
24995
25121
|
return lines;
|
|
24996
25122
|
}
|
|
24997
25123
|
function zcodeIn(homeDir, context) {
|
|
24998
|
-
const native =
|
|
25124
|
+
const native = join8(homeDir, ".zcode/cli/config.json"), fallback = join8(homeDir, ".agents/mcp.json");
|
|
24999
25125
|
const servers = (value, isNative) => isNative ? object2(object2(value, "mcp"), "servers") : object2(value, "mcpServers");
|
|
25000
25126
|
const remove = Boolean(context.remove);
|
|
25001
25127
|
const toFallback = !remove && !Object.keys(servers(readJson(native), true)).some((key) => key !== NAME) && Object.keys(servers(readJson(fallback), false)).length > 0;
|
|
@@ -25045,11 +25171,11 @@ var init_setup = __esm({
|
|
|
25045
25171
|
|
|
25046
25172
|
// apps/body/dist/session-join/claude-inbound.js
|
|
25047
25173
|
import { existsSync as existsSync4, readFileSync as readFileSync8, rmSync as rmSync5 } from "node:fs";
|
|
25048
|
-
import { join as
|
|
25174
|
+
import { join as join9 } from "node:path";
|
|
25049
25175
|
function assertClaudePolicy(env) {
|
|
25050
25176
|
const paths = [
|
|
25051
25177
|
env.CLAUDE_CODE_MANAGED_SETTINGS_PATH,
|
|
25052
|
-
|
|
25178
|
+
join9(claudeConfigDir(env), "managed-settings.json"),
|
|
25053
25179
|
process.platform === "darwin" ? "/Library/Application Support/ClaudeCode/managed-settings.json" : "/etc/claude-code/managed-settings.json"
|
|
25054
25180
|
];
|
|
25055
25181
|
for (const path of paths) {
|
|
@@ -25064,8 +25190,8 @@ async function acceptClaudeInbound(env) {
|
|
|
25064
25190
|
const dir = stateDir(env);
|
|
25065
25191
|
await withLock(dir, () => {
|
|
25066
25192
|
assertClaudePolicy(env);
|
|
25067
|
-
const path =
|
|
25068
|
-
const saved =
|
|
25193
|
+
const path = join9(claudeConfigDir(env), "settings.json");
|
|
25194
|
+
const saved = join9(dir, "claude-inbound.json");
|
|
25069
25195
|
const value = readJson(path);
|
|
25070
25196
|
if (!existsSync4(saved))
|
|
25071
25197
|
writeFile3(saved, JSON.stringify({ present: Object.hasOwn(value, "crossSessionInbound"), value: value.crossSessionInbound }));
|
|
@@ -25079,12 +25205,12 @@ async function restoreClaudeInbound(env) {
|
|
|
25079
25205
|
await withLock(dir, () => {
|
|
25080
25206
|
if (readState(dir).sessions.length)
|
|
25081
25207
|
return;
|
|
25082
|
-
const saved =
|
|
25208
|
+
const saved = join9(dir, "claude-inbound.json");
|
|
25083
25209
|
if (!existsSync4(saved))
|
|
25084
25210
|
return;
|
|
25085
25211
|
assertClaudePolicy(env);
|
|
25086
25212
|
const old = JSON.parse(readFileSync8(saved, "utf8"));
|
|
25087
|
-
const path =
|
|
25213
|
+
const path = join9(claudeConfigDir(env), "settings.json");
|
|
25088
25214
|
const value = readJson(path);
|
|
25089
25215
|
if (value.crossSessionInbound === "accept") {
|
|
25090
25216
|
if (old.present)
|
|
@@ -25107,9 +25233,9 @@ var init_claude_inbound = __esm({
|
|
|
25107
25233
|
|
|
25108
25234
|
// apps/body/dist/session-join/codex-trust.js
|
|
25109
25235
|
import { spawn as spawn6 } from "node:child_process";
|
|
25110
|
-
import { join as
|
|
25236
|
+
import { join as join10 } from "node:path";
|
|
25111
25237
|
function beelineTrustEdits(hooks, context) {
|
|
25112
|
-
const path =
|
|
25238
|
+
const path = join10(codexHome(context.env), "hooks.json");
|
|
25113
25239
|
const expected = hookCommand(context, "codex", "session-start");
|
|
25114
25240
|
const own2 = hooks.filter((h) => h.sourcePath === path && h.source === "user" && !h.isManaged && h.pluginId === null && h.eventName === "sessionStart" && h.handlerType === "command" && h.command === expected && h.matcher === "*" && h.timeoutSec === 10 && h.key.startsWith(path) && /^:session_start:\d+:\d+$/.test(h.key.slice(path.length)) && /^sha256:[0-9a-f]{64}$/.test(h.currentHash));
|
|
25115
25241
|
if (own2.length !== 1)
|
|
@@ -25156,9 +25282,9 @@ async function trustCodexHook(context, bin, cwd) {
|
|
|
25156
25282
|
}
|
|
25157
25283
|
}
|
|
25158
25284
|
});
|
|
25159
|
-
const request2 = (method, params) => new Promise((
|
|
25285
|
+
const request2 = (method, params) => new Promise((resolve12, reject) => {
|
|
25160
25286
|
const key = ++id;
|
|
25161
|
-
pending.set(key, { resolve:
|
|
25287
|
+
pending.set(key, { resolve: resolve12, reject: () => reject(new Error("Codex hook trust unavailable")) });
|
|
25162
25288
|
child.stdin.write(JSON.stringify({ id: key, method, params }) + "\n");
|
|
25163
25289
|
});
|
|
25164
25290
|
try {
|
|
@@ -25339,7 +25465,7 @@ var init_pull_apps = __esm({
|
|
|
25339
25465
|
"use strict";
|
|
25340
25466
|
init_store();
|
|
25341
25467
|
init_beeline_api();
|
|
25342
|
-
agentapi = (sessionId, text) => new Promise((
|
|
25468
|
+
agentapi = (sessionId, text) => new Promise((resolve12, reject) => execFile4("agentapi", ["send-message", sessionId, text], { timeout: 3e4 }, (error) => error ? reject(error) : resolve12()));
|
|
25343
25469
|
}
|
|
25344
25470
|
});
|
|
25345
25471
|
|
|
@@ -25351,7 +25477,7 @@ __export(command_exports, {
|
|
|
25351
25477
|
});
|
|
25352
25478
|
import { spawn as spawn7, spawnSync as spawnSync2 } from "node:child_process";
|
|
25353
25479
|
import { closeSync as closeSync4, copyFileSync as copyFileSync2, existsSync as existsSync5, fsyncSync, mkdirSync as mkdirSync5, openSync as openSync4, readFileSync as readFileSync9, readdirSync as readdirSync6, renameSync as renameSync4, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
25354
|
-
import { delimiter, dirname as
|
|
25480
|
+
import { delimiter, dirname as dirname8, join as join11, resolve as resolve10 } from "node:path";
|
|
25355
25481
|
import { createHash as createHash7, randomUUID as randomUUID2 } from "node:crypto";
|
|
25356
25482
|
function writePending(file, pending) {
|
|
25357
25483
|
const temporary = file + "." + randomUUID2() + ".tmp";
|
|
@@ -25365,7 +25491,7 @@ function writePending(file, pending) {
|
|
|
25365
25491
|
}
|
|
25366
25492
|
renameSync4(temporary, file);
|
|
25367
25493
|
if (process.platform !== "win32") {
|
|
25368
|
-
const directory = openSync4(
|
|
25494
|
+
const directory = openSync4(dirname8(file), "r");
|
|
25369
25495
|
try {
|
|
25370
25496
|
fsyncSync(directory);
|
|
25371
25497
|
} finally {
|
|
@@ -25379,14 +25505,14 @@ function writePending(file, pending) {
|
|
|
25379
25505
|
function existingPending(dir, own2, server) {
|
|
25380
25506
|
let names;
|
|
25381
25507
|
try {
|
|
25382
|
-
names = readdirSync6(
|
|
25508
|
+
names = readdirSync6(join11(dir, "pending"));
|
|
25383
25509
|
} catch {
|
|
25384
25510
|
return;
|
|
25385
25511
|
}
|
|
25386
25512
|
if (names.length > 256)
|
|
25387
25513
|
throw new Error("Too many pending Beeline sign-ins");
|
|
25388
25514
|
return names.filter((name) => /^[a-f0-9]{24}\.json$/.test(name)).flatMap((name) => {
|
|
25389
|
-
const file =
|
|
25515
|
+
const file = join11(dir, "pending", name);
|
|
25390
25516
|
try {
|
|
25391
25517
|
const pending = JSON.parse(readFileSync9(file, "utf8"));
|
|
25392
25518
|
return pending.agent === own2.agent && pending.cwd === own2.cwd && pending.server === server && (!pending.sessionId || !own2.sessionId || pending.sessionId === own2.sessionId) ? [{ file, pending }] : [];
|
|
@@ -25411,7 +25537,7 @@ function words(args, valued) {
|
|
|
25411
25537
|
}
|
|
25412
25538
|
function which(bin, env) {
|
|
25413
25539
|
for (const dir of (env.PATH ?? "").split(delimiter)) {
|
|
25414
|
-
const path =
|
|
25540
|
+
const path = join11(dir, bin);
|
|
25415
25541
|
if (dir && existsSync5(path))
|
|
25416
25542
|
return path;
|
|
25417
25543
|
}
|
|
@@ -25420,8 +25546,8 @@ function which(bin, env) {
|
|
|
25420
25546
|
function runner(dir, env) {
|
|
25421
25547
|
if (env.BEELINE_SESSION_BUNDLE)
|
|
25422
25548
|
return { node: process.execPath, bundle: env.BEELINE_SESSION_BUNDLE };
|
|
25423
|
-
const bundle =
|
|
25424
|
-
const running =
|
|
25549
|
+
const bundle = join11(dir, "usebeeline.mjs");
|
|
25550
|
+
const running = resolve10(process.argv[1] ?? "");
|
|
25425
25551
|
if (running !== bundle && running.endsWith(".mjs")) {
|
|
25426
25552
|
mkdirSync5(dir, { recursive: true, mode: 448 });
|
|
25427
25553
|
copyFileSync2(running, bundle);
|
|
@@ -25511,13 +25637,13 @@ async function joinCommand(args, env) {
|
|
|
25511
25637
|
startedAt: Date.now(),
|
|
25512
25638
|
claudeInboundFallback: own2.claudeInboundFallback
|
|
25513
25639
|
};
|
|
25514
|
-
mkdirSync5(
|
|
25515
|
-
const file =
|
|
25640
|
+
mkdirSync5(join11(dir, "pending"), { recursive: true, mode: 448 });
|
|
25641
|
+
const file = join11(dir, "pending", `${createHash7("sha256").update(signIn.state).digest("hex").slice(0, 24)}.json`);
|
|
25516
25642
|
if (!resume)
|
|
25517
25643
|
writePending(file, pending);
|
|
25518
25644
|
if (!resume && previous && previous.file !== file)
|
|
25519
25645
|
rmSync6(previous.file, { force: true });
|
|
25520
|
-
const out =
|
|
25646
|
+
const out = join11(dir, "bridge.log");
|
|
25521
25647
|
const child = spawn7(run2.node, [run2.bundle, "session", "finish-join", file], { detached: true, stdio: "ignore", env: { ...env, BEELINE_SESSION_BUNDLE: run2.bundle } });
|
|
25522
25648
|
child.unref();
|
|
25523
25649
|
console.log([
|
|
@@ -25643,7 +25769,7 @@ function own(args, env) {
|
|
|
25643
25769
|
}
|
|
25644
25770
|
async function ownTool(dir, joined2, name, args) {
|
|
25645
25771
|
let bridged = await toolViaBridge(dir, joined2.key, name, args);
|
|
25646
|
-
if (!bridged && existsSync5(
|
|
25772
|
+
if (!bridged && existsSync5(join11(dir, "bridge.pid")) && process.cwd().startsWith(joined2.cwd))
|
|
25647
25773
|
bridged = await toolViaOutbox(joined2.cwd, name, args);
|
|
25648
25774
|
if (bridged) {
|
|
25649
25775
|
if (!bridged.ok)
|
|
@@ -25752,14 +25878,14 @@ async function session(args, env) {
|
|
|
25752
25878
|
throw new Error("Usage: usebeeline join | usebeeline session reply|read|tool|status|leave");
|
|
25753
25879
|
}
|
|
25754
25880
|
function readStdin(_limitMs) {
|
|
25755
|
-
return new Promise((
|
|
25881
|
+
return new Promise((resolve12) => {
|
|
25756
25882
|
let text = "";
|
|
25757
25883
|
process.stdin.setEncoding("utf8");
|
|
25758
25884
|
process.stdin.on("data", (chunk) => {
|
|
25759
25885
|
text += chunk;
|
|
25760
25886
|
});
|
|
25761
25887
|
process.stdin.on("end", () => {
|
|
25762
|
-
|
|
25888
|
+
resolve12(text);
|
|
25763
25889
|
});
|
|
25764
25890
|
});
|
|
25765
25891
|
}
|
|
@@ -25797,19 +25923,19 @@ var init_command = __esm({
|
|
|
25797
25923
|
init_setup();
|
|
25798
25924
|
init_store();
|
|
25799
25925
|
init_kernel_lock();
|
|
25800
|
-
finisherKey = (file) => "beeline-session-sign-in:" +
|
|
25926
|
+
finisherKey = (file) => "beeline-session-sign-in:" + resolve10(file);
|
|
25801
25927
|
VALUED = ["--as", "--room", "--reply-to", "--server", "--name", "--session", "--state", "--limit"];
|
|
25802
25928
|
}
|
|
25803
25929
|
});
|
|
25804
25930
|
|
|
25805
25931
|
// apps/body/dist/recovery-cli.js
|
|
25806
25932
|
import { spawn as spawn8 } from "node:child_process";
|
|
25807
|
-
import { readFile as
|
|
25808
|
-
import { resolve as
|
|
25933
|
+
import { readFile as readFile5, readdir as readdir5, stat as stat3, unlink } from "node:fs/promises";
|
|
25934
|
+
import { resolve as resolve11 } from "node:path";
|
|
25809
25935
|
|
|
25810
25936
|
// apps/body/dist/recovery.js
|
|
25811
|
-
import { readFile as
|
|
25812
|
-
import { resolve as
|
|
25937
|
+
import { readFile as readFile4, readdir as readdir4, stat } from "node:fs/promises";
|
|
25938
|
+
import { resolve as resolve9 } from "node:path";
|
|
25813
25939
|
|
|
25814
25940
|
// apps/body/dist/machine-control.js
|
|
25815
25941
|
import { watch } from "node:fs";
|
|
@@ -26170,8 +26296,8 @@ async function prepareMachineRelease(layout, options = {}) {
|
|
|
26170
26296
|
return withInstallLock(layout, () => prepareLatestRelease(layout, { ...options, deadlineAt }), {
|
|
26171
26297
|
waitMs: Math.max(0, deadlineAt - Date.now())
|
|
26172
26298
|
});
|
|
26173
|
-
const stable =
|
|
26174
|
-
const entrypoint = env.BEELINE_RECOVERY_ENTRY || await
|
|
26299
|
+
const stable = resolve9(layout.libDir, "../beeline-bootstrap.mjs");
|
|
26300
|
+
const entrypoint = env.BEELINE_RECOVERY_ENTRY || await readFile4(stable).then(() => stable, () => process.argv[1]);
|
|
26175
26301
|
return prepareReleaseInWorker({ ...env, ...options?.force ? { BEELINE_FORCE_REPAIR: "1" } : {} }, deadlineAt, entrypoint);
|
|
26176
26302
|
}
|
|
26177
26303
|
async function convergeMachine(options = {}) {
|
|
@@ -26179,9 +26305,9 @@ async function convergeMachine(options = {}) {
|
|
|
26179
26305
|
assertLifecycleTestIsolation(env, Boolean(options.run));
|
|
26180
26306
|
const layout = options.layout ?? beelineInstallLayout(env) ?? discoveredBeelineInstallLayout(env);
|
|
26181
26307
|
const deadlineAt = options.deadlineAt ?? Date.now() + (options.timeoutMs ?? 6e5);
|
|
26182
|
-
const stateRoot = env.XDG_STATE_HOME ||
|
|
26183
|
-
const root =
|
|
26184
|
-
const configured = await Promise.all((await readdir4(root).catch(() => [])).filter((id) => /^[0-9a-f]{64}$/i.test(id)).map(async (id) => await stat(
|
|
26308
|
+
const stateRoot = env.XDG_STATE_HOME || resolve9(env.HOME || "", ".local/state");
|
|
26309
|
+
const root = resolve9(stateRoot, "beeline/agents");
|
|
26310
|
+
const configured = await Promise.all((await readdir4(root).catch(() => [])).filter((id) => /^[0-9a-f]{64}$/i.test(id)).map(async (id) => await stat(resolve9(root, id, "runtime.json")).then(() => true, () => false) && !await stat(resolve9(root, id, "stopped")).then(() => true, () => false) ? id : void 0));
|
|
26185
26311
|
const required = /* @__PURE__ */ new Set([
|
|
26186
26312
|
...configured.filter((id) => Boolean(id)),
|
|
26187
26313
|
...options.agentIds ?? []
|
|
@@ -26202,7 +26328,7 @@ async function convergeMachine(options = {}) {
|
|
|
26202
26328
|
let expectedRelease = options.releaseId;
|
|
26203
26329
|
const targetIdentity = options.releaseId ? await readInstalledBundleIdentity({
|
|
26204
26330
|
...layout,
|
|
26205
|
-
libDir:
|
|
26331
|
+
libDir: resolve9(layout.releasesRoot, options.releaseId)
|
|
26206
26332
|
}) : void 0;
|
|
26207
26333
|
const request2 = options.releaseId && hasControl ? {
|
|
26208
26334
|
operation: "update",
|
|
@@ -26239,8 +26365,8 @@ async function bootstrapMachine(env = process.env) {
|
|
|
26239
26365
|
for (const id of [state.stagedReleaseId, active]) {
|
|
26240
26366
|
if (!id || !/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(id))
|
|
26241
26367
|
continue;
|
|
26242
|
-
const digest = await
|
|
26243
|
-
if (/^[0-9a-f]{64}$/i.test(digest.trim()) && await resolveBundleEntrypoint(
|
|
26368
|
+
const digest = await readFile4(resolve9(layout.releasesRoot, id, ".stage-ok"), "utf8").catch(() => "");
|
|
26369
|
+
if (/^[0-9a-f]{64}$/i.test(digest.trim()) && await resolveBundleEntrypoint(resolve9(layout.releasesRoot, id))) {
|
|
26244
26370
|
releaseId = id;
|
|
26245
26371
|
break;
|
|
26246
26372
|
}
|
|
@@ -26256,7 +26382,7 @@ async function bootstrapMachine(env = process.env) {
|
|
|
26256
26382
|
await withInstallLock(layout, () => activateRelease(layout, releaseId, { deferPruning: true }), {
|
|
26257
26383
|
waitMs: Math.max(0, bootDeadlineAt - Date.now())
|
|
26258
26384
|
});
|
|
26259
|
-
const entry = await resolveBundleEntrypoint(
|
|
26385
|
+
const entry = await resolveBundleEntrypoint(resolve9(layout.releasesRoot, releaseId));
|
|
26260
26386
|
if (!entry)
|
|
26261
26387
|
throw new Error(`selected release ${releaseId} has no body entry`);
|
|
26262
26388
|
return entry;
|
|
@@ -26322,18 +26448,18 @@ async function main() {
|
|
|
26322
26448
|
if (args[i] === "--manifest-url" && !args[++i])
|
|
26323
26449
|
throw new Error("--manifest-url requires a URL");
|
|
26324
26450
|
}
|
|
26325
|
-
const stateRoot2 = process.env.XDG_STATE_HOME ||
|
|
26451
|
+
const stateRoot2 = process.env.XDG_STATE_HOME || resolve11(process.env.HOME || "", ".local/state");
|
|
26326
26452
|
if (args.includes("--status")) {
|
|
26327
26453
|
const [native, helper] = await Promise.all([
|
|
26328
26454
|
nativeHelperStatus(),
|
|
26329
26455
|
requestMachine(stateRoot2, { operation: "status" }, () => true, 2e3).catch(() => void 0)
|
|
26330
26456
|
]);
|
|
26331
|
-
const root =
|
|
26457
|
+
const root = resolve11(stateRoot2, "beeline/agents");
|
|
26332
26458
|
const agents = await Promise.all((await readdir5(root).catch(() => [])).filter((id) => /^[0-9a-f]{64}$/.test(id)).map(async (id) => ({
|
|
26333
26459
|
agentId: id,
|
|
26334
|
-
enabled: !await stat3(
|
|
26460
|
+
enabled: !await stat3(resolve11(root, id, "stopped")).then(() => true, () => false),
|
|
26335
26461
|
...helper?.agents[id] ?? { state: "not hosted" },
|
|
26336
|
-
validRecord: await
|
|
26462
|
+
validRecord: await readFile5(resolve11(root, id, "runtime.json"), "utf8").then((raw) => Boolean(JSON.parse(raw).agent)).catch(() => false)
|
|
26337
26463
|
})));
|
|
26338
26464
|
console.log(JSON.stringify({
|
|
26339
26465
|
native,
|
|
@@ -26382,7 +26508,7 @@ async function main() {
|
|
|
26382
26508
|
console.log(`[beeline] executing release ${status.loadedRelease}; helper ${status.pid}; every enabled agent serving`);
|
|
26383
26509
|
return;
|
|
26384
26510
|
}
|
|
26385
|
-
const stateRoot = process.env.XDG_STATE_HOME ||
|
|
26511
|
+
const stateRoot = process.env.XDG_STATE_HOME || resolve11(process.env.HOME || "", ".local/state");
|
|
26386
26512
|
let selectedRelease;
|
|
26387
26513
|
if (command2 === "start") {
|
|
26388
26514
|
for (let i = 1; i < args.length; i++) {
|
|
@@ -26397,13 +26523,13 @@ async function main() {
|
|
|
26397
26523
|
const requested = agentFlag >= 0 ? args[agentFlag + 1] : args[1] && !args[1].startsWith("--") ? args[1] : void 0;
|
|
26398
26524
|
if (agentFlag >= 0 && !requested)
|
|
26399
26525
|
throw new Error("--agent requires an agent public key");
|
|
26400
|
-
const agentRoot =
|
|
26526
|
+
const agentRoot = resolve11(stateRoot, "beeline/agents");
|
|
26401
26527
|
const ids = (await readdir5(agentRoot).catch(() => [])).filter((id) => /^[0-9a-f]{64}$/.test(id));
|
|
26402
26528
|
const selected = requested ? ids.filter((id) => id.startsWith(requested)) : args.includes("--all") ? ids : [];
|
|
26403
26529
|
if (requested && selected.length !== 1)
|
|
26404
26530
|
throw new Error(`no unique paired agent matches ${requested}`);
|
|
26405
26531
|
for (const id of selected)
|
|
26406
|
-
await unlink(
|
|
26532
|
+
await unlink(resolve11(agentRoot, id, "stopped")).catch((error) => {
|
|
26407
26533
|
if (error.code !== "ENOENT")
|
|
26408
26534
|
throw error;
|
|
26409
26535
|
});
|