usebeeline 0.1.180 → 0.1.183

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/usebeeline.mjs +878 -638
  2. package/package.json +1 -1
@@ -173,6 +173,121 @@ 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
+ if (override)
180
+ return override;
181
+ const channel = env.BEELINE_RELEASE_CHANNEL?.trim() || "latest";
182
+ if (!["latest", "next"].includes(channel))
183
+ throw new Error(`invalid helper release channel: ${channel}`);
184
+ return channel === "next" ? "https://usebeeline.app/dl/next/manifest.json" : DEFAULT_UPDATE_MANIFEST_URL;
185
+ }
186
+ function parseUpdateManifest(raw, platform) {
187
+ let parsed;
188
+ try {
189
+ parsed = JSON.parse(raw);
190
+ } catch (error) {
191
+ throw new Error(`update manifest is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
192
+ }
193
+ if (typeof parsed !== "object" || parsed === null) {
194
+ throw new Error("update manifest is not an object");
195
+ }
196
+ const manifest = parsed;
197
+ const bundles = manifest.bundles;
198
+ if (typeof bundles !== "object" || bundles === null) {
199
+ throw new Error("update manifest has no bundles table");
200
+ }
201
+ const entry = bundles[platform];
202
+ if (typeof entry !== "object" || entry === null) {
203
+ throw new Error(`update manifest has no bundle for platform ${platform}`);
204
+ }
205
+ const bundle = entry;
206
+ const file = typeof bundle.file === "string" ? bundle.file : "";
207
+ const sha256 = typeof bundle.sha256 === "string" ? bundle.sha256.toLowerCase() : "";
208
+ if (!file || !/^[a-z0-9][a-z0-9._-]*$/i.test(file)) {
209
+ throw new Error(`update manifest names an unusable bundle file: ${JSON.stringify(bundle.file)}`);
210
+ }
211
+ if (!/^[0-9a-f]{64}$/.test(sha256)) {
212
+ throw new Error(`update manifest carries no usable sha256 for ${platform}`);
213
+ }
214
+ const sourceCommit = typeof bundle.commit === "string" && bundle.commit ? bundle.commit : typeof manifest.sourceCommit === "string" ? manifest.sourceCommit : void 0;
215
+ const version = typeof bundle.version === "string" && bundle.version ? bundle.version : typeof manifest.version === "string" ? manifest.version : void 0;
216
+ return {
217
+ schemaVersion: typeof manifest.schemaVersion === "number" ? manifest.schemaVersion : 1,
218
+ ...sourceCommit ? { sourceCommit } : {},
219
+ ...version ? { version } : {},
220
+ bundles,
221
+ bundle: {
222
+ file,
223
+ sha256,
224
+ ...typeof bundle.bytes === "number" ? { bytes: bundle.bytes } : {},
225
+ ...sourceCommit ? { commit: sourceCommit } : {},
226
+ ...version ? { version } : {},
227
+ ...typeof bundle.node === "string" ? { node: bundle.node } : {}
228
+ }
229
+ };
230
+ }
231
+ function compareBundleIdentity(installed, published) {
232
+ if (installed?.commit && published.commit) {
233
+ if (installed.commit === published.commit)
234
+ return { kind: "current" };
235
+ return { kind: "update-available", published };
236
+ }
237
+ if (installed?.version && published.version) {
238
+ const ordering = compareVersions(installed.version, published.version);
239
+ if (ordering > 0)
240
+ return { kind: "current" };
241
+ if (ordering < 0)
242
+ return { kind: "update-available", published };
243
+ if (installed.commit && published.commit)
244
+ return { kind: "current" };
245
+ return { kind: "current" };
246
+ }
247
+ const missing = [
248
+ ...installed?.commit || installed?.version ? [] : ["installed identity"],
249
+ ...published.commit || published.version ? [] : ["published identity"]
250
+ ];
251
+ return {
252
+ kind: "indeterminate",
253
+ reason: `cannot compare: ${missing.join(" and ")} unknown`
254
+ };
255
+ }
256
+ function compareVersions(a, b) {
257
+ const parse = (value) => {
258
+ const parts = value.split(/[.+-]/).filter(Boolean);
259
+ if (parts.length === 0)
260
+ return void 0;
261
+ return parts.map((part) => /^\d+$/.test(part) ? Number(part) : part);
262
+ };
263
+ const left = parse(a);
264
+ const right = parse(b);
265
+ if (!left || !right)
266
+ return a === b ? 0 : a > b ? 1 : -1;
267
+ const length = Math.max(left.length, right.length);
268
+ for (let index = 0; index < length; index += 1) {
269
+ const l = left[index];
270
+ const r = right[index];
271
+ if (l === void 0)
272
+ return -1;
273
+ if (r === void 0)
274
+ return 1;
275
+ if (l === r)
276
+ continue;
277
+ if (typeof l === "number" && typeof r === "number")
278
+ return l > r ? 1 : -1;
279
+ return String(l) > String(r) ? 1 : -1;
280
+ }
281
+ return 0;
282
+ }
283
+ var DEFAULT_UPDATE_MANIFEST_URL;
284
+ var init_self_update_manifest = __esm({
285
+ "apps/body/dist/self-update-manifest.js"() {
286
+ "use strict";
287
+ DEFAULT_UPDATE_MANIFEST_URL = "https://usebeeline.app/dl/manifest.json";
288
+ }
289
+ });
290
+
176
291
  // apps/body/dist/trusty-squire-storage.js
177
292
  import { homedir as homedir2 } from "node:os";
178
293
  import { isAbsolute, resolve as resolve4 } from "node:path";
@@ -328,151 +443,250 @@ visit(root)
328
443
  }
329
444
  });
330
445
 
331
- // apps/body/dist/self-update-manifest.js
332
- function resolveManifestUrl(env = process.env) {
333
- const override = env.BEELINE_UPDATE_MANIFEST_URL?.trim();
334
- return override && override.length > 0 ? override : DEFAULT_UPDATE_MANIFEST_URL;
335
- }
336
- function parseUpdateManifest(raw, platform) {
337
- let parsed;
338
- try {
339
- parsed = JSON.parse(raw);
340
- } catch (error) {
341
- throw new Error(`update manifest is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
342
- }
343
- if (typeof parsed !== "object" || parsed === null) {
344
- throw new Error("update manifest is not an object");
446
+ // apps/body/dist/self-update-activate-release.js
447
+ import { join, dirname as dirname4, resolve as resolve6 } from "node:path";
448
+ 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";
449
+ import { constants as fsConstants } from "node:fs";
450
+ async function activateRelease(layout, releaseId, options = {}) {
451
+ assertInstallTestIsolation(layout);
452
+ let releaseDir = join(layout.releasesRoot, releaseId);
453
+ let previousReleaseId = await activeReleaseId(layout);
454
+ await access(join(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
455
+ await mkdir3(layout.releasesRoot, { recursive: true });
456
+ await mkdir3(layout.binDir, { recursive: true });
457
+ const kind = await pathKind(layout.libDir);
458
+ if (kind === "directory") {
459
+ const legacyIdentity = await readBundleJson(layout.libDir);
460
+ const legacyId = sanitizeReleaseId(legacyIdentity?.commit ?? legacyIdentity?.version ?? `legacy-${Date.now()}`);
461
+ const legacyDir = join(layout.releasesRoot, legacyId);
462
+ try {
463
+ await access(legacyDir, fsConstants.F_OK);
464
+ const preservedId = `${legacyId}-${Date.now()}`;
465
+ await rename2(layout.libDir, join(layout.releasesRoot, preservedId));
466
+ await normalizeLegacyBundleShape(join(layout.releasesRoot, preservedId));
467
+ previousReleaseId = preservedId;
468
+ } catch {
469
+ await rename2(layout.libDir, legacyDir);
470
+ await normalizeLegacyBundleShape(legacyDir);
471
+ previousReleaseId = legacyId;
472
+ }
345
473
  }
346
- const manifest = parsed;
347
- const bundles = manifest.bundles;
348
- if (typeof bundles !== "object" || bundles === null) {
349
- throw new Error("update manifest has no bundles table");
474
+ const tempLink = `${layout.libDir}.new-${process.pid}`;
475
+ await rm3(tempLink, { force: true });
476
+ await symlink(join("beeline-releases", releaseId), tempLink);
477
+ await rename2(tempLink, layout.libDir);
478
+ await fsyncDir(dirname4(layout.libDir));
479
+ await installRecoveryLauncher(layout, releaseDir);
480
+ await writeBinForwarders(layout, releaseDir);
481
+ const state = await readUpdateState(layout);
482
+ await writeUpdateState(layout, {
483
+ ...state,
484
+ stagedReleaseId: void 0,
485
+ previousReleaseId: previousReleaseId && previousReleaseId !== releaseId ? previousReleaseId : state.previousReleaseId
486
+ });
487
+ if (!options.deferPruning)
488
+ await pruneHelperReleases(layout);
489
+ }
490
+ async function installRecoveryLauncher(layout, releaseDir) {
491
+ const bootstrap = join(releaseDir, "lib/beeline/recovery-cli.mjs");
492
+ if (await access(bootstrap).then(() => true, () => false)) {
493
+ const stable = resolve6(layout.libDir, "../beeline-bootstrap.mjs");
494
+ const temporary = `${stable}.${process.pid}.tmp`;
495
+ await copyFile(bootstrap, temporary);
496
+ await rename2(temporary, stable);
497
+ await replaceFile(resolve6(layout.libDir, "../beeline-node-path"), `${process.execPath}
498
+ `, 384);
350
499
  }
351
- const entry = bundles[platform];
352
- if (typeof entry !== "object" || entry === null) {
353
- throw new Error(`update manifest has no bundle for platform ${platform}`);
500
+ }
501
+ async function normalizeLegacyBundleShape(bundleDir) {
502
+ const innerLib = join(bundleDir, "lib", "beeline");
503
+ let anyFlat = false;
504
+ for (const name of LEGACY_FLAT_BUNDLE_FILES) {
505
+ try {
506
+ await access(join(bundleDir, name), fsConstants.F_OK);
507
+ anyFlat = true;
508
+ break;
509
+ } catch {
510
+ }
354
511
  }
355
- const bundle = entry;
356
- const file = typeof bundle.file === "string" ? bundle.file : "";
357
- const sha256 = typeof bundle.sha256 === "string" ? bundle.sha256.toLowerCase() : "";
358
- if (!file || !/^[a-z0-9][a-z0-9._-]*$/i.test(file)) {
359
- throw new Error(`update manifest names an unusable bundle file: ${JSON.stringify(bundle.file)}`);
512
+ if (!anyFlat)
513
+ return;
514
+ await mkdir3(innerLib, { recursive: true });
515
+ for (const name of LEGACY_FLAT_BUNDLE_FILES) {
516
+ try {
517
+ await access(join(innerLib, name), fsConstants.F_OK);
518
+ continue;
519
+ } catch {
520
+ }
521
+ await rename2(join(bundleDir, name), join(innerLib, name)).catch(() => void 0);
360
522
  }
361
- if (!/^[0-9a-f]{64}$/.test(sha256)) {
362
- throw new Error(`update manifest carries no usable sha256 for ${platform}`);
523
+ }
524
+ async function writeBinForwarders(layout, activeBundleRoot) {
525
+ const entries = [
526
+ ...FORWARDER_TOOLS.map((tool) => [tool, tool]),
527
+ ...Object.entries(FORWARDER_ALIASES).map(([alias, tool]) => [alias, tool])
528
+ ];
529
+ for (const [name, tool] of entries) {
530
+ const target = join(activeBundleRoot, "bin", tool);
531
+ try {
532
+ await access(target, fsConstants.X_OK);
533
+ } catch {
534
+ continue;
535
+ }
536
+ const independent = await access(resolve6(layout.libDir, "../beeline-bootstrap.mjs")).then(() => true, () => false);
537
+ await replaceFile(join(layout.binDir, name), independent || tool !== "beeline" ? forwarderScript(tool) : forwarderScript("legacy-beeline").replace("/bin/legacy-beeline", "/bin/beeline"), 493);
363
538
  }
364
- const sourceCommit = typeof bundle.commit === "string" && bundle.commit ? bundle.commit : typeof manifest.sourceCommit === "string" ? manifest.sourceCommit : void 0;
365
- const version = typeof bundle.version === "string" && bundle.version ? bundle.version : typeof manifest.version === "string" ? manifest.version : void 0;
366
- return {
367
- schemaVersion: typeof manifest.schemaVersion === "number" ? manifest.schemaVersion : 1,
368
- ...sourceCommit ? { sourceCommit } : {},
369
- ...version ? { version } : {},
370
- bundles,
371
- bundle: {
372
- file,
373
- sha256,
374
- ...typeof bundle.bytes === "number" ? { bytes: bundle.bytes } : {},
375
- ...sourceCommit ? { commit: sourceCommit } : {},
376
- ...version ? { version } : {},
377
- ...typeof bundle.node === "string" ? { node: bundle.node } : {}
539
+ }
540
+ async function repairInstallForwarders(layout, opts = {}) {
541
+ assertInstallTestIsolation(layout);
542
+ if (await pathKind(layout.libDir) !== "symlink")
543
+ return false;
544
+ await installRecoveryLauncher(layout, layout.libDir);
545
+ const forwarderHealthy = async (name, tool) => {
546
+ let current;
547
+ try {
548
+ current = await readFile2(join(layout.binDir, name), "utf8");
549
+ } catch {
550
+ current = void 0;
378
551
  }
552
+ const independent = await access(resolve6(layout.libDir, "../beeline-bootstrap.mjs")).then(() => true, () => false);
553
+ const expected = independent || tool !== "beeline" ? forwarderScript(tool) : forwarderScript("legacy-beeline").replace("/bin/legacy-beeline", "/bin/beeline");
554
+ return current === expected;
379
555
  };
380
- }
381
- function compareBundleIdentity(installed, published) {
382
- if (installed?.commit && published.commit) {
383
- if (installed.commit === published.commit)
384
- return { kind: "current" };
385
- return { kind: "update-available", published };
386
- }
387
- if (installed?.version && published.version) {
388
- const ordering = compareVersions(installed.version, published.version);
389
- if (ordering > 0)
390
- return { kind: "current" };
391
- if (ordering < 0)
392
- return { kind: "update-available", published };
393
- if (installed.commit && published.commit)
394
- return { kind: "current" };
395
- return { kind: "current" };
556
+ let healthy = await forwarderHealthy("beeline", "beeline");
557
+ for (const [alias, tool] of Object.entries(FORWARDER_ALIASES)) {
558
+ if (!await forwarderHealthy(alias, tool))
559
+ healthy = false;
396
560
  }
397
- const missing = [
398
- ...installed?.commit || installed?.version ? [] : ["installed identity"],
399
- ...published.commit || published.version ? [] : ["published identity"]
400
- ];
401
- return {
402
- kind: "indeterminate",
403
- reason: `cannot compare: ${missing.join(" and ")} unknown`
404
- };
561
+ if (healthy)
562
+ return false;
563
+ await mkdir3(layout.binDir, { recursive: true });
564
+ await writeBinForwarders(layout, layout.libDir);
565
+ opts.logger?.(`[body] self-update: repaired <prefix>/bin forwarders to follow the active-bundle anchor (${layout.libDir})`);
566
+ return true;
405
567
  }
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)
568
+ function describeIdentity(identity) {
569
+ if (!identity)
570
+ return "unknown";
571
+ const parts = [];
572
+ if (identity.version)
573
+ parts.push(identity.version);
574
+ if (identity.commit)
575
+ parts.push(identity.commit.slice(0, 12));
576
+ return parts.join(" ") || "unknown";
577
+ }
578
+ async function pruneHelperReleases(layout, loadedRelease) {
579
+ assertInstallTestIsolation(layout);
580
+ if (!await ordinaryDirectory(layout.releasesRoot))
581
+ return [];
582
+ const active = await activeReleaseId(layout);
583
+ if (!active)
584
+ return [];
585
+ const state = await readUpdateState(layout);
586
+ const candidates = [];
587
+ for (const entry of await readdir3(layout.releasesRoot, { withFileTypes: true })) {
588
+ if (entry.name.startsWith("."))
589
+ continue;
590
+ if (entry.isSymbolicLink()) {
591
+ if (![active, state.previousReleaseId, state.stagedReleaseId, loadedRelease].includes(entry.name))
592
+ await rm3(join(layout.releasesRoot, entry.name), { force: true });
426
593
  continue;
427
- if (typeof l === "number" && typeof r === "number")
428
- return l > r ? 1 : -1;
429
- return String(l) > String(r) ? 1 : -1;
594
+ }
595
+ if (!entry.isDirectory())
596
+ continue;
597
+ const path = join(layout.releasesRoot, entry.name);
598
+ if (!await ordinaryDirectory(path))
599
+ continue;
600
+ candidates.push({
601
+ id: entry.name,
602
+ modified: (await lstat3(path)).mtimeMs,
603
+ bootable: await access(join(path, BUNDLE_ENTRYPOINT)).then(() => true, () => false)
604
+ });
430
605
  }
431
- return 0;
606
+ const recordedPrevious = candidates.find((entry) => entry.id === state.previousReleaseId && entry.id !== active && entry.bootable)?.id;
607
+ const previous = recordedPrevious ?? candidates.filter((entry) => entry.bootable && entry.id !== active && entry.id !== state.stagedReleaseId).sort((a, b) => b.modified - a.modified)[0]?.id;
608
+ const keep = /* @__PURE__ */ new Set([active, previous, loadedRelease, state.stagedReleaseId]);
609
+ const removed = [];
610
+ for (const entry of candidates) {
611
+ if (keep.has(entry.id))
612
+ continue;
613
+ await removeStoragePath(join(layout.releasesRoot, entry.id));
614
+ removed.push(entry.id);
615
+ }
616
+ if (previous !== state.previousReleaseId)
617
+ await writeUpdateState(layout, { ...state, previousReleaseId: previous });
618
+ return removed;
432
619
  }
433
- var DEFAULT_UPDATE_MANIFEST_URL;
434
- var init_self_update_manifest = __esm({
435
- "apps/body/dist/self-update-manifest.js"() {
620
+ var LEGACY_FLAT_BUNDLE_FILES;
621
+ var init_self_update_activate_release = __esm({
622
+ "apps/body/dist/self-update-activate-release.js"() {
436
623
  "use strict";
437
- DEFAULT_UPDATE_MANIFEST_URL = "https://usebeeline.app/dl/manifest.json";
624
+ init_lifecycle_test_guard();
625
+ init_storage_filesystem();
626
+ init_self_update();
627
+ LEGACY_FLAT_BUNDLE_FILES = [
628
+ "beeline-cli.mjs",
629
+ "beeline-readonly-mcp.mjs",
630
+ "pi-mcp-adapter.mjs",
631
+ "bundle.json"
632
+ ];
438
633
  }
439
634
  });
440
635
 
441
636
  // apps/body/dist/self-update.js
442
637
  var self_update_exports = {};
443
638
  __export(self_update_exports, {
639
+ BUNDLE_ENTRYPOINT: () => BUNDLE_ENTRYPOINT,
640
+ CODEGRAPH_ENTRYPOINT: () => CODEGRAPH_ENTRYPOINT,
641
+ FORWARDER_ALIASES: () => FORWARDER_ALIASES,
642
+ FORWARDER_TOOLS: () => FORWARDER_TOOLS,
643
+ PI_MCP_ADAPTER_ENTRYPOINT: () => PI_MCP_ADAPTER_ENTRYPOINT,
644
+ RELEASES_SEGMENT: () => RELEASES_SEGMENT,
444
645
  STAGED_NODE_PATH_FILE: () => STAGED_NODE_PATH_FILE,
445
646
  SelfUpdateManager: () => SelfUpdateManager,
446
647
  activateRelease: () => activateRelease,
447
648
  activeReleaseId: () => activeReleaseId,
649
+ anchorLayout: () => anchorLayout,
448
650
  archiveUrlFor: () => archiveUrlFor,
449
651
  beelineInstallLayout: () => beelineInstallLayout,
652
+ bundleJsonCandidates: () => bundleJsonCandidates,
450
653
  defaultBeelineInstallLayout: () => defaultBeelineInstallLayout,
451
654
  describeIdentity: () => describeIdentity,
452
655
  discoveredBeelineInstallLayout: () => discoveredBeelineInstallLayout,
656
+ entrypointCandidates: () => entrypointCandidates,
657
+ fetchText: () => fetchText,
658
+ forwarderScript: () => forwarderScript,
659
+ fsyncDir: () => fsyncDir,
453
660
  hostPlatformKey: () => hostPlatformKey,
454
661
  nodeVersionAtLeast: () => nodeVersionAtLeast,
455
662
  normalizeLegacyBundleShape: () => normalizeLegacyBundleShape,
663
+ pathKind: () => pathKind,
456
664
  prepareLatestRelease: () => prepareLatestRelease,
457
665
  pruneHelperReleases: () => pruneHelperReleases,
458
666
  readBundleEngineMinimum: () => readBundleEngineMinimum,
667
+ readBundleJson: () => readBundleJson,
459
668
  readInstalledBundleIdentity: () => readInstalledBundleIdentity,
460
669
  readUpdateState: () => readUpdateState,
461
670
  releaseIdFromPath: () => releaseIdFromPath,
462
671
  repairInstallForwarders: () => repairInstallForwarders,
672
+ replaceFile: () => replaceFile,
673
+ requiredBundlePaths: () => requiredBundlePaths,
463
674
  resolveBundleEntrypoint: () => resolveBundleEntrypoint,
675
+ run: () => run,
464
676
  runningReleaseId: () => runningReleaseId,
677
+ sanitizeReleaseId: () => sanitizeReleaseId,
465
678
  stageRelease: () => stageRelease,
679
+ updateStatePath: () => updateStatePath,
466
680
  writeUpdateState: () => writeUpdateState
467
681
  });
468
- import { createHash as createHash3 } from "node:crypto";
469
- import { constants as fsConstants } from "node:fs";
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";
682
+ 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";
683
+ import { join as join2, resolve as resolve7, dirname as dirname5 } from "node:path";
472
684
  import { homedir as homedir3 } from "node:os";
473
- import { dirname as dirname4, join, resolve as resolve6 } from "node:path";
685
+ import { spawn as spawn2 } from "node:child_process";
686
+ import { constants as fsConstants2 } from "node:fs";
687
+ import { createHash as createHash3 } from "node:crypto";
474
688
  function anchorLayout(rawLibDir) {
475
- const libDir = resolve6(rawLibDir);
689
+ const libDir = resolve7(rawLibDir);
476
690
  const segments = libDir.split(/[/\\]/);
477
691
  const idx = segments.lastIndexOf(RELEASES_SEGMENT);
478
692
  if (idx >= 2 && segments[idx - 1] === "lib") {
@@ -488,9 +702,9 @@ function anchorLayout(rawLibDir) {
488
702
  // prefix's bin, NOT <prefix>/lib/bin — deriving it one level up was the
489
703
  // defect that made activateRelease write its stable forwarders where
490
704
  // nothing executed them, leaving stale raw wrappers in <prefix>/bin.
491
- binDir: resolve6(libDir, "../../bin"),
705
+ binDir: resolve7(libDir, "../../bin"),
492
706
  libDir,
493
- releasesRoot: resolve6(libDir, `../${RELEASES_SEGMENT}`)
707
+ releasesRoot: resolve7(libDir, `../${RELEASES_SEGMENT}`)
494
708
  };
495
709
  }
496
710
  function beelineInstallLayout(env = process.env) {
@@ -502,18 +716,18 @@ function beelineInstallLayout(env = process.env) {
502
716
  function releaseIdFromPath(path) {
503
717
  if (!path?.trim())
504
718
  return void 0;
505
- const segments = resolve6(path.trim()).split(/[/\\]/);
719
+ const segments = resolve7(path.trim()).split(/[/\\]/);
506
720
  const idx = segments.lastIndexOf(RELEASES_SEGMENT);
507
721
  const id = idx >= 0 ? segments[idx + 1] : void 0;
508
722
  return id ? sanitizeReleaseId(id) : void 0;
509
723
  }
510
724
  function runningReleaseId(layout, env = process.env, invocationPath = process.argv[1]) {
511
- const releasesRoot = resolve6(layout.releasesRoot);
512
- const anchor = resolve6(layout.libDir);
725
+ const releasesRoot = resolve7(layout.releasesRoot);
726
+ const anchor = resolve7(layout.libDir);
513
727
  for (const raw of [env.BEELINE_LIB_DIR, invocationPath]) {
514
728
  if (!raw?.trim())
515
729
  continue;
516
- const resolved = resolve6(raw.trim());
730
+ const resolved = resolve7(raw.trim());
517
731
  if (resolved !== anchor && !resolved.startsWith(`${releasesRoot}/`))
518
732
  continue;
519
733
  const id = releaseIdFromPath(resolved);
@@ -524,7 +738,7 @@ function runningReleaseId(layout, env = process.env, invocationPath = process.ar
524
738
  }
525
739
  function defaultBeelineInstallLayout(env = process.env) {
526
740
  const home2 = env.HOME?.trim() || homedir3();
527
- return anchorLayout(resolve6(home2, ".local", "lib", "beeline"));
741
+ return anchorLayout(resolve7(home2, ".local", "lib", "beeline"));
528
742
  }
529
743
  function discoveredBeelineInstallLayout(env = process.env) {
530
744
  const explicitAnchor = env.BEELINE_INSTALL_LIB_DIR?.trim();
@@ -532,7 +746,7 @@ function discoveredBeelineInstallLayout(env = process.env) {
532
746
  return anchorLayout(explicitAnchor);
533
747
  const explicitBinDir = env.BEELINE_INSTALL_DIR?.trim();
534
748
  if (explicitBinDir)
535
- return anchorLayout(resolve6(dirname4(resolve6(explicitBinDir)), "lib", "beeline"));
749
+ return anchorLayout(resolve7(dirname5(resolve7(explicitBinDir)), "lib", "beeline"));
536
750
  return defaultBeelineInstallLayout(env);
537
751
  }
538
752
  function hostPlatformKey() {
@@ -543,13 +757,13 @@ function hostPlatformKey() {
543
757
  return `${os}-${arch}`;
544
758
  }
545
759
  function bundleJsonCandidates(bundleDir) {
546
- return [join(bundleDir, "lib", "beeline", "bundle.json"), join(bundleDir, "bundle.json")];
760
+ return [join2(bundleDir, "lib", "beeline", "bundle.json"), join2(bundleDir, "bundle.json")];
547
761
  }
548
762
  async function readBundleJson(bundleDir) {
549
763
  let raw;
550
764
  for (const candidate of bundleJsonCandidates(bundleDir)) {
551
765
  try {
552
- raw = await readFile2(candidate, "utf8");
766
+ raw = await readFile3(candidate, "utf8");
553
767
  break;
554
768
  } catch {
555
769
  }
@@ -569,7 +783,7 @@ async function readBundleJson(bundleDir) {
569
783
  async function readBundleEngineMinimum(bundleDir) {
570
784
  for (const candidate of bundleJsonCandidates(bundleDir)) {
571
785
  try {
572
- const parsed = JSON.parse(await readFile2(candidate, "utf8"));
786
+ const parsed = JSON.parse(await readFile3(candidate, "utf8"));
573
787
  const match = /^>=(\d+)\.(\d+)\.(\d+)$/.exec(parsed.node ?? "");
574
788
  if (match)
575
789
  return [Number(match[1]), Number(match[2]), Number(match[3])];
@@ -589,17 +803,17 @@ function nodeVersionAtLeast(version, minimum) {
589
803
  return true;
590
804
  }
591
805
  function updateStatePath(layout) {
592
- return join(layout.releasesRoot, ".state", "update-state.json");
806
+ return join2(layout.releasesRoot, ".state", "update-state.json");
593
807
  }
594
808
  async function readUpdateState(layout) {
595
809
  try {
596
- return JSON.parse(await readFile2(updateStatePath(layout), "utf8"));
810
+ return JSON.parse(await readFile3(updateStatePath(layout), "utf8"));
597
811
  } catch {
598
812
  return {};
599
813
  }
600
814
  }
601
815
  async function writeUpdateState(layout, state) {
602
- await mkdir3(join(layout.releasesRoot, ".state"), { recursive: true });
816
+ await mkdir4(join2(layout.releasesRoot, ".state"), { recursive: true });
603
817
  const path = updateStatePath(layout);
604
818
  const temporary = `${path}.${process.pid}.tmp`;
605
819
  const handle = await open(temporary, "w", 384);
@@ -610,8 +824,8 @@ async function writeUpdateState(layout, state) {
610
824
  } finally {
611
825
  await handle.close();
612
826
  }
613
- await rename2(temporary, path);
614
- await fsyncDir(dirname4(path));
827
+ await rename3(temporary, path);
828
+ await fsyncDir(dirname5(path));
615
829
  }
616
830
  async function readInstalledBundleIdentity(layout, _state = {}) {
617
831
  const fromDisk = await readBundleJson(layout.libDir);
@@ -625,7 +839,7 @@ function sanitizeReleaseId(id) {
625
839
  }
626
840
  async function pathKind(path) {
627
841
  try {
628
- const info = await lstat3(path);
842
+ const info = await lstat4(path);
629
843
  if (info.isSymbolicLink())
630
844
  return "symlink";
631
845
  return info.isDirectory() ? "directory" : "missing";
@@ -688,12 +902,12 @@ function run(command2, args, _timeoutMs) {
688
902
  });
689
903
  }
690
904
  function entrypointCandidates(bundleDir) {
691
- return [join(bundleDir, BUNDLE_ENTRYPOINT), join(bundleDir, "beeline-cli.mjs")];
905
+ return [join2(bundleDir, BUNDLE_ENTRYPOINT), join2(bundleDir, "beeline-cli.mjs")];
692
906
  }
693
907
  async function resolveBundleEntrypoint(bundleDir) {
694
908
  for (const candidate of entrypointCandidates(bundleDir)) {
695
909
  try {
696
- await access(candidate, fsConstants.F_OK);
910
+ await access2(candidate, fsConstants2.F_OK);
697
911
  return candidate;
698
912
  } catch {
699
913
  }
@@ -717,17 +931,17 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
717
931
  });
718
932
  const log2 = opts.logger ?? ((line) => console.log(`[body] self-update: ${line}`));
719
933
  let releaseId = sanitizeReleaseId((published.commit ?? published.version ?? `release-${Date.now()}`) + (opts.force ? `-repair-${Date.now()}` : ""));
720
- let releaseDir = join(layout.releasesRoot, releaseId);
721
- let okMarker = join(releaseDir, ".stage-ok");
934
+ let releaseDir = join2(layout.releasesRoot, releaseId);
935
+ let okMarker = join2(releaseDir, ".stage-ok");
722
936
  let previouslyVerified = false;
723
937
  try {
724
- const recorded = await readFile2(okMarker, "utf8");
938
+ const recorded = await readFile3(okMarker, "utf8");
725
939
  if (recorded.trim() === published.sha256 && !opts.force)
726
940
  return releaseId;
727
941
  releaseId = sanitizeReleaseId(`${releaseId}-${published.sha256.slice(0, 12)}`);
728
- releaseDir = join(layout.releasesRoot, releaseId);
729
- okMarker = join(releaseDir, ".stage-ok");
730
- const matching = await readFile2(okMarker, "utf8").catch(() => "");
942
+ releaseDir = join2(layout.releasesRoot, releaseId);
943
+ okMarker = join2(releaseDir, ".stage-ok");
944
+ const matching = await readFile3(okMarker, "utf8").catch(() => "");
731
945
  if (matching.trim() === published.sha256 && !opts.force)
732
946
  return releaseId;
733
947
  previouslyVerified = Boolean(matching);
@@ -735,12 +949,12 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
735
949
  }
736
950
  if (await activeReleaseId(layout) === releaseId) {
737
951
  releaseId = sanitizeReleaseId(`${releaseId}-repair-${Date.now()}`);
738
- releaseDir = join(layout.releasesRoot, releaseId);
739
- okMarker = join(releaseDir, ".stage-ok");
952
+ releaseDir = join2(layout.releasesRoot, releaseId);
953
+ okMarker = join2(releaseDir, ".stage-ok");
740
954
  previouslyVerified = false;
741
955
  }
742
- await mkdir3(releaseDir, { recursive: true });
743
- const tempArchive = join(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
956
+ await mkdir4(releaseDir, { recursive: true });
957
+ const tempArchive = join2(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
744
958
  try {
745
959
  log2(`downloading ${published.file}`);
746
960
  const response = await fetchImpl(archiveUrlFor(manifestUrl, published.file), {
@@ -784,7 +998,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
784
998
  throw new Error(`extracting bundle failed: ${extract.stderr}`);
785
999
  for (const relative of requiredBundlePaths()) {
786
1000
  try {
787
- await access(join(releaseDir, relative), fsConstants.F_OK);
1001
+ await access2(join2(releaseDir, relative), fsConstants2.F_OK);
788
1002
  } catch {
789
1003
  throw new Error(`staged bundle is missing ${relative}`);
790
1004
  }
@@ -797,11 +1011,11 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
797
1011
  if (!nodeVersionAtLeast(process.versions.node, engineMinimum)) {
798
1012
  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
1013
  }
800
- await writeFile2(join(releaseDir, STAGED_NODE_PATH_FILE), `${process.execPath}
1014
+ await writeFile2(join2(releaseDir, STAGED_NODE_PATH_FILE), `${process.execPath}
801
1015
  `, "utf8");
802
1016
  }
803
1017
  if (opts.smokeTestCli !== false) {
804
- const probe = await run(process.execPath, [join(releaseDir, BUNDLE_ENTRYPOINT), "--version"], Math.min(6e4, remaining()));
1018
+ const probe = await run(process.execPath, [join2(releaseDir, BUNDLE_ENTRYPOINT), "--version"], Math.min(6e4, remaining()));
805
1019
  if (probe.status !== 0) {
806
1020
  throw new Error(`staged bundle failed its startup smoke test (--version exited ${probe.status})${probe.stderr ? `: ${probe.stderr.trim()}` : ""}`);
807
1021
  }
@@ -812,10 +1026,10 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
812
1026
  return releaseId;
813
1027
  } catch (error) {
814
1028
  if (!previouslyVerified)
815
- await rm3(releaseDir, { recursive: true, force: true });
1029
+ await rm4(releaseDir, { recursive: true, force: true });
816
1030
  throw error;
817
1031
  } finally {
818
- await rm3(tempArchive, { force: true });
1032
+ await rm4(tempArchive, { force: true });
819
1033
  }
820
1034
  }
821
1035
  function forwarderScript(tool) {
@@ -850,142 +1064,14 @@ async function replaceFile(path, contents, mode) {
850
1064
  const temp = `${path}.new-${process.pid}`;
851
1065
  await writeFile2(temp, contents, { mode });
852
1066
  await chmod2(temp, mode);
853
- await rename2(temp, path);
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";
1067
+ await rename3(temp, path);
982
1068
  }
983
1069
  async function prepareLatestRelease(layout, options = {}) {
984
1070
  try {
985
1071
  const manifestUrl = options.manifest?.url ?? resolveManifestUrl(options.env ?? process.env);
986
1072
  const bundle = options.manifest?.bundle ?? parseUpdateManifest(await fetchText(manifestUrl, options.fetchImpl ?? fetch), hostPlatformKey()).bundle;
987
1073
  const pending = (await readUpdateState(layout)).stagedReleaseId;
988
- const pendingDigest = pending ? await readFile2(join(layout.releasesRoot, pending, ".stage-ok"), "utf8").catch(() => "") : "";
1074
+ const pendingDigest = pending ? await readFile3(join2(layout.releasesRoot, pending, ".stage-ok"), "utf8").catch(() => "") : "";
989
1075
  const releaseId = !options.force && pending && pendingDigest.trim() === bundle.sha256 ? pending : await stageRelease(layout, manifestUrl, bundle, {
990
1076
  fetchImpl: options.fetchImpl,
991
1077
  logger: options.logger,
@@ -1009,55 +1095,18 @@ async function prepareLatestRelease(layout, options = {}) {
1009
1095
  throw error;
1010
1096
  }
1011
1097
  }
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);
1049
- }
1050
- if (previous !== state.previousReleaseId)
1051
- await writeUpdateState(layout, { ...state, previousReleaseId: previous });
1052
- return removed;
1053
- }
1054
- var RELEASES_SEGMENT, STAGED_NODE_PATH_FILE, BUNDLE_ENTRYPOINT, PI_MCP_ADAPTER_ENTRYPOINT, CODEGRAPH_ENTRYPOINT, FORWARDER_TOOLS, FORWARDER_ALIASES, LEGACY_FLAT_BUNDLE_FILES, SelfUpdateManager;
1098
+ var RELEASES_SEGMENT, STAGED_NODE_PATH_FILE, BUNDLE_ENTRYPOINT, PI_MCP_ADAPTER_ENTRYPOINT, CODEGRAPH_ENTRYPOINT, FORWARDER_TOOLS, FORWARDER_ALIASES, SelfUpdateManager;
1055
1099
  var init_self_update = __esm({
1056
1100
  "apps/body/dist/self-update.js"() {
1057
1101
  "use strict";
1058
- init_storage_filesystem();
1059
1102
  init_lifecycle_test_guard();
1060
1103
  init_self_update_manifest();
1104
+ init_self_update_activate_release();
1105
+ init_self_update_activate_release();
1106
+ init_self_update_activate_release();
1107
+ init_self_update_activate_release();
1108
+ init_self_update_activate_release();
1109
+ init_self_update_activate_release();
1061
1110
  RELEASES_SEGMENT = "beeline-releases";
1062
1111
  STAGED_NODE_PATH_FILE = ".node-path";
1063
1112
  BUNDLE_ENTRYPOINT = "lib/beeline/beeline-cli.mjs";
@@ -1073,12 +1122,6 @@ var init_self_update = __esm({
1073
1122
  FORWARDER_ALIASES = {
1074
1123
  usebeeline: "beeline"
1075
1124
  };
1076
- LEGACY_FLAT_BUNDLE_FILES = [
1077
- "beeline-cli.mjs",
1078
- "beeline-readonly-mcp.mjs",
1079
- "pi-mcp-adapter.mjs",
1080
- "bundle.json"
1081
- ];
1082
1125
  SelfUpdateManager = class {
1083
1126
  options;
1084
1127
  constructor(options) {
@@ -1108,9 +1151,9 @@ __export(managed_update_exports, {
1108
1151
  withInstallLock: () => withInstallLock
1109
1152
  });
1110
1153
  import { spawn as spawn3 } from "node:child_process";
1111
- import { resolve as resolve7 } from "node:path";
1154
+ import { resolve as resolve8 } from "node:path";
1112
1155
  function withInstallLock(layout, work, options = {}) {
1113
- return withKernelLock(`beeline-install:${resolve7(layout.libDir)}`, work, options.waitMs);
1156
+ return withKernelLock(`beeline-install:${resolve8(layout.libDir)}`, work, options.waitMs);
1114
1157
  }
1115
1158
  function versionAtLeast(actual, minimum) {
1116
1159
  const parse = (value) => /^v?(\d+)\.(\d+)\.(\d+)$/.exec(value)?.slice(1).map(Number);
@@ -1135,7 +1178,7 @@ async function runManagedUpdateWorker() {
1135
1178
  }
1136
1179
  async function prepareReleaseInWorker(env, deadlineAt, entrypoint) {
1137
1180
  const layout = beelineInstallLayout(env);
1138
- const bootstrap = entrypoint ?? resolve7(layout.libDir, "../beeline-bootstrap.mjs");
1181
+ const bootstrap = entrypoint ?? resolve8(layout.libDir, "../beeline-bootstrap.mjs");
1139
1182
  return new Promise((done, reject) => {
1140
1183
  const child = spawn3(process.execPath, [bootstrap, "managed-update-worker"], {
1141
1184
  detached: true,
@@ -1193,7 +1236,6 @@ var init_managed_update = __esm({
1193
1236
  #interruptAt;
1194
1237
  #deadlineAt;
1195
1238
  #handingOff;
1196
- #notice;
1197
1239
  #completed = false;
1198
1240
  #draining = false;
1199
1241
  constructor(options) {
@@ -1205,10 +1247,7 @@ var init_managed_update = __esm({
1205
1247
  get pending() {
1206
1248
  return this.#preparing ?? this.#handingOff;
1207
1249
  }
1208
- notify(releaseKey, minimum) {
1209
- if (releaseKey && releaseKey === this.#notice)
1210
- return;
1211
- this.#notice = releaseKey;
1250
+ notify(_releaseKey, minimum) {
1212
1251
  if (minimum && (!this.#minimum || !versionAtLeast(this.#minimum, minimum))) {
1213
1252
  this.#minimum = minimum;
1214
1253
  this.#handoffAt = this.now();
@@ -1227,7 +1266,7 @@ var init_managed_update = __esm({
1227
1266
  if (this.#minimum) {
1228
1267
  const identity = await readInstalledBundleIdentity({
1229
1268
  ...this.options.layout,
1230
- libDir: resolve7(this.options.layout.releasesRoot, releaseId)
1269
+ libDir: resolve8(this.options.layout.releasesRoot, releaseId)
1231
1270
  });
1232
1271
  if (!identity?.version || !versionAtLeast(identity.version, this.#minimum)) {
1233
1272
  this.#prepared = void 0;
@@ -3407,9 +3446,9 @@ var require_dispatcher_base = __commonJS({
3407
3446
  }
3408
3447
  close(callback) {
3409
3448
  if (callback === void 0) {
3410
- return new Promise((resolve11, reject) => {
3449
+ return new Promise((resolve13, reject) => {
3411
3450
  this.close((err, data) => {
3412
- return err ? reject(err) : resolve11(data);
3451
+ return err ? reject(err) : resolve13(data);
3413
3452
  });
3414
3453
  });
3415
3454
  }
@@ -3447,12 +3486,12 @@ var require_dispatcher_base = __commonJS({
3447
3486
  err = null;
3448
3487
  }
3449
3488
  if (callback === void 0) {
3450
- return new Promise((resolve11, reject) => {
3489
+ return new Promise((resolve13, reject) => {
3451
3490
  this.destroy(err, (err2, data) => {
3452
3491
  return err2 ? (
3453
3492
  /* istanbul ignore next: should never error */
3454
3493
  reject(err2)
3455
- ) : resolve11(data);
3494
+ ) : resolve13(data);
3456
3495
  });
3457
3496
  });
3458
3497
  }
@@ -5719,8 +5758,8 @@ var require_util2 = __commonJS({
5719
5758
  function createDeferredPromise() {
5720
5759
  let res;
5721
5760
  let rej;
5722
- const promise = new Promise((resolve11, reject) => {
5723
- res = resolve11;
5761
+ const promise = new Promise((resolve13, reject) => {
5762
+ res = resolve13;
5724
5763
  rej = reject;
5725
5764
  });
5726
5765
  return { promise, resolve: res, reject: rej };
@@ -7966,12 +8005,12 @@ upgrade: ${upgrade}\r
7966
8005
  cb();
7967
8006
  }
7968
8007
  }
7969
- const waitForDrain = () => new Promise((resolve11, reject) => {
8008
+ const waitForDrain = () => new Promise((resolve13, reject) => {
7970
8009
  assert(callback === null);
7971
8010
  if (socket[kError]) {
7972
8011
  reject(socket[kError]);
7973
8012
  } else {
7974
- callback = resolve11;
8013
+ callback = resolve13;
7975
8014
  }
7976
8015
  });
7977
8016
  socket.on("close", onDrain).on("drain", onDrain);
@@ -8608,12 +8647,12 @@ var require_client_h2 = __commonJS({
8608
8647
  cb();
8609
8648
  }
8610
8649
  }
8611
- const waitForDrain = () => new Promise((resolve11, reject) => {
8650
+ const waitForDrain = () => new Promise((resolve13, reject) => {
8612
8651
  assert(callback === null);
8613
8652
  if (socket[kError]) {
8614
8653
  reject(socket[kError]);
8615
8654
  } else {
8616
- callback = resolve11;
8655
+ callback = resolve13;
8617
8656
  }
8618
8657
  });
8619
8658
  h2stream.on("close", onDrain).on("drain", onDrain);
@@ -9091,16 +9130,16 @@ var require_client = __commonJS({
9091
9130
  return this[kNeedDrain] < 2;
9092
9131
  }
9093
9132
  async [kClose]() {
9094
- return new Promise((resolve11) => {
9133
+ return new Promise((resolve13) => {
9095
9134
  if (this[kSize]) {
9096
- this[kClosedResolve] = resolve11;
9135
+ this[kClosedResolve] = resolve13;
9097
9136
  } else {
9098
- resolve11(null);
9137
+ resolve13(null);
9099
9138
  }
9100
9139
  });
9101
9140
  }
9102
9141
  async [kDestroy](err) {
9103
- return new Promise((resolve11) => {
9142
+ return new Promise((resolve13) => {
9104
9143
  const requests = this[kQueue].splice(this[kPendingIdx]);
9105
9144
  for (let i = 0; i < requests.length; i++) {
9106
9145
  const request2 = requests[i];
@@ -9111,7 +9150,7 @@ var require_client = __commonJS({
9111
9150
  this[kClosedResolve]();
9112
9151
  this[kClosedResolve] = null;
9113
9152
  }
9114
- resolve11(null);
9153
+ resolve13(null);
9115
9154
  };
9116
9155
  if (this[kHTTPContext]) {
9117
9156
  this[kHTTPContext].destroy(err, callback);
@@ -9162,7 +9201,7 @@ var require_client = __commonJS({
9162
9201
  });
9163
9202
  }
9164
9203
  try {
9165
- const socket = await new Promise((resolve11, reject) => {
9204
+ const socket = await new Promise((resolve13, reject) => {
9166
9205
  client[kConnector]({
9167
9206
  host,
9168
9207
  hostname,
@@ -9174,7 +9213,7 @@ var require_client = __commonJS({
9174
9213
  if (err) {
9175
9214
  reject(err);
9176
9215
  } else {
9177
- resolve11(socket2);
9216
+ resolve13(socket2);
9178
9217
  }
9179
9218
  });
9180
9219
  });
@@ -9510,8 +9549,8 @@ var require_pool_base = __commonJS({
9510
9549
  if (this[kQueue].isEmpty()) {
9511
9550
  await Promise.all(this[kClients].map((c) => c.close()));
9512
9551
  } else {
9513
- await new Promise((resolve11) => {
9514
- this[kClosedResolve] = resolve11;
9552
+ await new Promise((resolve13) => {
9553
+ this[kClosedResolve] = resolve13;
9515
9554
  });
9516
9555
  }
9517
9556
  }
@@ -10754,7 +10793,7 @@ var require_readable = __commonJS({
10754
10793
  if (this._readableState.closeEmitted) {
10755
10794
  return null;
10756
10795
  }
10757
- return await new Promise((resolve11, reject) => {
10796
+ return await new Promise((resolve13, reject) => {
10758
10797
  if (this[kContentLength] > limit) {
10759
10798
  this.destroy(new AbortError());
10760
10799
  }
@@ -10767,7 +10806,7 @@ var require_readable = __commonJS({
10767
10806
  if (signal?.aborted) {
10768
10807
  reject(signal.reason ?? new AbortError());
10769
10808
  } else {
10770
- resolve11(null);
10809
+ resolve13(null);
10771
10810
  }
10772
10811
  }).on("error", noop).on("data", function(chunk) {
10773
10812
  limit -= chunk.length;
@@ -10786,7 +10825,7 @@ var require_readable = __commonJS({
10786
10825
  }
10787
10826
  async function consume(stream, type) {
10788
10827
  assert(!stream[kConsume]);
10789
- return new Promise((resolve11, reject) => {
10828
+ return new Promise((resolve13, reject) => {
10790
10829
  if (isUnusable(stream)) {
10791
10830
  const rState = stream._readableState;
10792
10831
  if (rState.destroyed && rState.closeEmitted === false) {
@@ -10803,7 +10842,7 @@ var require_readable = __commonJS({
10803
10842
  stream[kConsume] = {
10804
10843
  type,
10805
10844
  stream,
10806
- resolve: resolve11,
10845
+ resolve: resolve13,
10807
10846
  reject,
10808
10847
  length: 0,
10809
10848
  body: []
@@ -10873,18 +10912,18 @@ var require_readable = __commonJS({
10873
10912
  return buffer;
10874
10913
  }
10875
10914
  function consumeEnd(consume2) {
10876
- const { type, body, resolve: resolve11, stream, length } = consume2;
10915
+ const { type, body, resolve: resolve13, stream, length } = consume2;
10877
10916
  try {
10878
10917
  if (type === "text") {
10879
- resolve11(chunksDecode(body, length));
10918
+ resolve13(chunksDecode(body, length));
10880
10919
  } else if (type === "json") {
10881
- resolve11(JSON.parse(chunksDecode(body, length)));
10920
+ resolve13(JSON.parse(chunksDecode(body, length)));
10882
10921
  } else if (type === "arrayBuffer") {
10883
- resolve11(chunksConcat(body, length).buffer);
10922
+ resolve13(chunksConcat(body, length).buffer);
10884
10923
  } else if (type === "blob") {
10885
- resolve11(new Blob(body, { type: stream[kContentType] }));
10924
+ resolve13(new Blob(body, { type: stream[kContentType] }));
10886
10925
  } else if (type === "bytes") {
10887
- resolve11(chunksConcat(body, length));
10926
+ resolve13(chunksConcat(body, length));
10888
10927
  }
10889
10928
  consumeFinish(consume2);
10890
10929
  } catch (err) {
@@ -11141,9 +11180,9 @@ var require_api_request = __commonJS({
11141
11180
  };
11142
11181
  function request2(opts, callback) {
11143
11182
  if (callback === void 0) {
11144
- return new Promise((resolve11, reject) => {
11183
+ return new Promise((resolve13, reject) => {
11145
11184
  request2.call(this, opts, (err, data) => {
11146
- return err ? reject(err) : resolve11(data);
11185
+ return err ? reject(err) : resolve13(data);
11147
11186
  });
11148
11187
  });
11149
11188
  }
@@ -11366,9 +11405,9 @@ var require_api_stream = __commonJS({
11366
11405
  };
11367
11406
  function stream(opts, factory, callback) {
11368
11407
  if (callback === void 0) {
11369
- return new Promise((resolve11, reject) => {
11408
+ return new Promise((resolve13, reject) => {
11370
11409
  stream.call(this, opts, factory, (err, data) => {
11371
- return err ? reject(err) : resolve11(data);
11410
+ return err ? reject(err) : resolve13(data);
11372
11411
  });
11373
11412
  });
11374
11413
  }
@@ -11653,9 +11692,9 @@ var require_api_upgrade = __commonJS({
11653
11692
  };
11654
11693
  function upgrade(opts, callback) {
11655
11694
  if (callback === void 0) {
11656
- return new Promise((resolve11, reject) => {
11695
+ return new Promise((resolve13, reject) => {
11657
11696
  upgrade.call(this, opts, (err, data) => {
11658
- return err ? reject(err) : resolve11(data);
11697
+ return err ? reject(err) : resolve13(data);
11659
11698
  });
11660
11699
  });
11661
11700
  }
@@ -11747,9 +11786,9 @@ var require_api_connect = __commonJS({
11747
11786
  };
11748
11787
  function connect(opts, callback) {
11749
11788
  if (callback === void 0) {
11750
- return new Promise((resolve11, reject) => {
11789
+ return new Promise((resolve13, reject) => {
11751
11790
  connect.call(this, opts, (err, data) => {
11752
- return err ? reject(err) : resolve11(data);
11791
+ return err ? reject(err) : resolve13(data);
11753
11792
  });
11754
11793
  });
11755
11794
  }
@@ -12976,16 +13015,16 @@ var require_dns = __commonJS({
12976
13015
  setRecords(origin, addresses) {
12977
13016
  const timestamp = Date.now();
12978
13017
  const records = { records: { 4: null, 6: null } };
12979
- for (const record of addresses) {
12980
- record.timestamp = timestamp;
12981
- if (typeof record.ttl === "number") {
12982
- record.ttl = Math.min(record.ttl, this.#maxTTL);
13018
+ for (const record2 of addresses) {
13019
+ record2.timestamp = timestamp;
13020
+ if (typeof record2.ttl === "number") {
13021
+ record2.ttl = Math.min(record2.ttl, this.#maxTTL);
12983
13022
  } else {
12984
- record.ttl = this.#maxTTL;
13023
+ record2.ttl = this.#maxTTL;
12985
13024
  }
12986
- const familyRecords = records.records[record.family] ?? { ips: [] };
12987
- familyRecords.ips.push(record);
12988
- records.records[record.family] = familyRecords;
13025
+ const familyRecords = records.records[record2.family] ?? { ips: [] };
13026
+ familyRecords.ips.push(record2);
13027
+ records.records[record2.family] = familyRecords;
12989
13028
  }
12990
13029
  this.#records.set(origin.hostname, records);
12991
13030
  }
@@ -15611,7 +15650,7 @@ var require_fetch = __commonJS({
15611
15650
  function dispatch({ body }) {
15612
15651
  const url = requestCurrentURL(request2);
15613
15652
  const agent = fetchParams.controller.dispatcher;
15614
- return new Promise((resolve11, reject) => agent.dispatch(
15653
+ return new Promise((resolve13, reject) => agent.dispatch(
15615
15654
  {
15616
15655
  path: url.pathname + url.search,
15617
15656
  origin: url.origin,
@@ -15687,7 +15726,7 @@ var require_fetch = __commonJS({
15687
15726
  }
15688
15727
  }
15689
15728
  const onError = this.onError.bind(this);
15690
- resolve11({
15729
+ resolve13({
15691
15730
  status,
15692
15731
  statusText,
15693
15732
  headersList,
@@ -15733,7 +15772,7 @@ var require_fetch = __commonJS({
15733
15772
  for (let i = 0; i < rawHeaders.length; i += 2) {
15734
15773
  headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true);
15735
15774
  }
15736
- resolve11({
15775
+ resolve13({
15737
15776
  status,
15738
15777
  statusText: STATUS_CODES[status],
15739
15778
  headersList,
@@ -19463,8 +19502,8 @@ var require_util8 = __commonJS({
19463
19502
  return true;
19464
19503
  }
19465
19504
  function delay(ms) {
19466
- return new Promise((resolve11) => {
19467
- setTimeout(resolve11, ms).unref();
19505
+ return new Promise((resolve13) => {
19506
+ setTimeout(resolve13, ms).unref();
19468
19507
  });
19469
19508
  }
19470
19509
  module.exports = {
@@ -19630,41 +19669,41 @@ var require_eventsource_stream = __commonJS({
19630
19669
  if (colonPosition === 0) {
19631
19670
  return;
19632
19671
  }
19633
- let field = "";
19672
+ let field2 = "";
19634
19673
  let value = "";
19635
19674
  if (colonPosition !== -1) {
19636
- field = line.subarray(0, colonPosition).toString("utf8");
19675
+ field2 = line.subarray(0, colonPosition).toString("utf8");
19637
19676
  let valueStart = colonPosition + 1;
19638
19677
  if (line[valueStart] === SPACE) {
19639
19678
  ++valueStart;
19640
19679
  }
19641
19680
  value = line.subarray(valueStart).toString("utf8");
19642
19681
  } else {
19643
- field = line.toString("utf8");
19682
+ field2 = line.toString("utf8");
19644
19683
  value = "";
19645
19684
  }
19646
- switch (field) {
19685
+ switch (field2) {
19647
19686
  case "data":
19648
- if (event[field] === void 0) {
19649
- event[field] = value;
19687
+ if (event[field2] === void 0) {
19688
+ event[field2] = value;
19650
19689
  } else {
19651
- event[field] += `
19690
+ event[field2] += `
19652
19691
  ${value}`;
19653
19692
  }
19654
19693
  break;
19655
19694
  case "retry":
19656
19695
  if (isASCIINumber(value)) {
19657
- event[field] = value;
19696
+ event[field2] = value;
19658
19697
  }
19659
19698
  break;
19660
19699
  case "id":
19661
19700
  if (isValidLastEventId(value)) {
19662
- event[field] = value;
19701
+ event[field2] = value;
19663
19702
  }
19664
19703
  break;
19665
19704
  case "event":
19666
19705
  if (value.length > 0) {
19667
- event[field] = value;
19706
+ event[field2] = value;
19668
19707
  }
19669
19708
  break;
19670
19709
  }
@@ -20147,9 +20186,9 @@ var require_undici = __commonJS({
20147
20186
  // apps/body/dist/filesystem-change.js
20148
20187
  import { watch as watch2 } from "node:fs";
20149
20188
  import { stat as stat2 } from "node:fs/promises";
20150
- import { dirname as dirname5 } from "node:path";
20189
+ import { dirname as dirname6 } from "node:path";
20151
20190
  function waitForPathRemoval(path) {
20152
- return new Promise((resolve11, reject) => {
20191
+ return new Promise((resolve13, reject) => {
20153
20192
  let reading = false, dirty = false, ended = false;
20154
20193
  const finish = (error) => {
20155
20194
  if (ended)
@@ -20159,7 +20198,7 @@ function waitForPathRemoval(path) {
20159
20198
  if (error)
20160
20199
  reject(error);
20161
20200
  else
20162
- resolve11();
20201
+ resolve13();
20163
20202
  };
20164
20203
  const inspect = async () => {
20165
20204
  dirty = true;
@@ -20185,7 +20224,7 @@ function waitForPathRemoval(path) {
20185
20224
  reading = false;
20186
20225
  }
20187
20226
  };
20188
- const watcher = watch2(dirname5(path), () => {
20227
+ const watcher = watch2(dirname6(path), () => {
20189
20228
  void inspect();
20190
20229
  });
20191
20230
  watcher.once("error", finish);
@@ -20219,9 +20258,9 @@ __export(store_exports, {
20219
20258
  import { createHash as createHash4, randomUUID } from "node:crypto";
20220
20259
  import { chmodSync, mkdirSync, readFileSync as readFileSync3, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
20221
20260
  import { homedir as homedir4 } from "node:os";
20222
- import { join as join2 } from "node:path";
20261
+ import { join as join3 } from "node:path";
20223
20262
  function stateDir(env = process.env) {
20224
- return join2(env.XDG_STATE_HOME || join2(env.HOME || homedir4(), ".local/state"), "beeline-sessions");
20263
+ return join3(env.XDG_STATE_HOME || join3(env.HOME || homedir4(), ".local/state"), "beeline-sessions");
20225
20264
  }
20226
20265
  function pidAlive(pid) {
20227
20266
  try {
@@ -20243,17 +20282,17 @@ function writePrivate(path, text) {
20243
20282
  }
20244
20283
  function readState(dir = stateDir()) {
20245
20284
  try {
20246
- const value = JSON.parse(readFileSync3(join2(dir, "state.json"), "utf8"));
20285
+ const value = JSON.parse(readFileSync3(join3(dir, "state.json"), "utf8"));
20247
20286
  return Array.isArray(value.sessions) ? value : { sessions: [] };
20248
20287
  } catch {
20249
20288
  return { sessions: [] };
20250
20289
  }
20251
20290
  }
20252
20291
  function writeState(dir, state) {
20253
- writePrivate(join2(ensureDir(dir), "state.json"), JSON.stringify(state, null, 2) + "\n");
20292
+ writePrivate(join3(ensureDir(dir), "state.json"), JSON.stringify(state, null, 2) + "\n");
20254
20293
  }
20255
20294
  async function withLock(dir, run2) {
20256
- const lock = join2(ensureDir(dir), "state.lock");
20295
+ const lock = join3(ensureDir(dir), "state.lock");
20257
20296
  for (let attempt = 0; ; attempt++) {
20258
20297
  try {
20259
20298
  mkdirSync(lock);
@@ -20292,16 +20331,16 @@ function safe(value) {
20292
20331
  return value.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 120);
20293
20332
  }
20294
20333
  function inboxPath(dir, key) {
20295
- return join2(dir, "inbox", `${createHash4("sha256").update(key).digest("hex").slice(0, 24)}.txt`);
20334
+ return join3(dir, "inbox", `${createHash4("sha256").update(key).digest("hex").slice(0, 24)}.txt`);
20296
20335
  }
20297
20336
  function queueInbox(dir, key, text) {
20298
20337
  adoptInboxText(dir, key);
20299
20338
  queueInboxOnce(dir, key, `local:${randomUUID()}`, text);
20300
20339
  }
20301
20340
  function adoptInboxText(dir, key) {
20302
- const folder = ensureDir(join2(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24)));
20341
+ const folder = ensureDir(join3(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24)));
20303
20342
  try {
20304
- renameSync(inboxPath(dir, key), join2(folder, `${randomUUID()}.text.pending`));
20343
+ renameSync(inboxPath(dir, key), join3(folder, `${randomUUID()}.text.pending`));
20305
20344
  } catch (error) {
20306
20345
  if (error.code !== "ENOENT")
20307
20346
  throw error;
@@ -20312,8 +20351,8 @@ function queueInboxOnce(dir, key, deliveryId, text) {
20312
20351
  const queuedAt = lastInboxOrder;
20313
20352
  if (!deliveryId || deliveryId.length > 256)
20314
20353
  throw new Error("Invalid inbox delivery identity");
20315
- const folder = ensureDir(join2(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24)));
20316
- const stem = join2(folder, createHash4("sha256").update(deliveryId).digest("hex"));
20354
+ const folder = ensureDir(join3(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24)));
20355
+ const stem = join3(folder, createHash4("sha256").update(deliveryId).digest("hex"));
20317
20356
  if (existsDelivery(stem + ".pending") || existsDelivery(stem + ".done"))
20318
20357
  return false;
20319
20358
  writePrivate(stem + ".pending", JSON.stringify({ id: deliveryId, text, queuedAt }));
@@ -20328,7 +20367,7 @@ function existsDelivery(path) {
20328
20367
  }
20329
20368
  }
20330
20369
  function takeDeliveries(dir, key) {
20331
- const folder = join2(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24));
20370
+ const folder = join3(dir, "deliveries", createHash4("sha256").update(key).digest("hex").slice(0, 24));
20332
20371
  let names;
20333
20372
  try {
20334
20373
  names = readdirSync(folder);
@@ -20337,7 +20376,7 @@ function takeDeliveries(dir, key) {
20337
20376
  }
20338
20377
  const pending = names.filter((name) => name.endsWith(".pending")).flatMap((name) => {
20339
20378
  try {
20340
- const contents = readFileSync3(join2(folder, name), "utf8");
20379
+ const contents = readFileSync3(join3(folder, name), "utf8");
20341
20380
  const item = name.endsWith(".text.pending") ? { text: contents, queuedAt: 0 } : JSON.parse(contents);
20342
20381
  return typeof item.text === "string" ? [{ name, ...item }] : [];
20343
20382
  } catch {
@@ -20346,7 +20385,7 @@ function takeDeliveries(dir, key) {
20346
20385
  }).sort((a, b) => a.queuedAt - b.queuedAt || a.name.localeCompare(b.name));
20347
20386
  const text = [];
20348
20387
  for (const item of pending) {
20349
- const path = join2(folder, item.name), done = path.replace(/\.pending$/, ".done");
20388
+ const path = join3(folder, item.name), done = path.replace(/\.pending$/, ".done");
20350
20389
  try {
20351
20390
  renameSync(path, done);
20352
20391
  } catch {
@@ -20362,15 +20401,15 @@ function takeInbox(dir, key) {
20362
20401
  return takeDeliveries(dir, key).join("\n\n");
20363
20402
  }
20364
20403
  function recordHookSession(dir, session2) {
20365
- writePrivate(join2(ensureDir(join2(dir, "hooks")), `${safe(session2.agent)}-${safe(session2.sessionId)}.json`), JSON.stringify(session2));
20404
+ writePrivate(join3(ensureDir(join3(dir, "hooks")), `${safe(session2.agent)}-${safe(session2.sessionId)}.json`), JSON.stringify(session2));
20366
20405
  }
20367
20406
  function forgetHookSession(dir, agent, sessionId) {
20368
- rmSync(join2(dir, "hooks", `${safe(agent)}-${safe(sessionId)}.json`), { force: true });
20407
+ rmSync(join3(dir, "hooks", `${safe(agent)}-${safe(sessionId)}.json`), { force: true });
20369
20408
  }
20370
20409
  function hookSessions(dir, now = Date.now(), alive = pidAlive) {
20371
20410
  let names;
20372
20411
  try {
20373
- names = readdirSync(join2(dir, "hooks"));
20412
+ names = readdirSync(join3(dir, "hooks"));
20374
20413
  } catch {
20375
20414
  return [];
20376
20415
  }
@@ -20379,7 +20418,7 @@ function hookSessions(dir, now = Date.now(), alive = pidAlive) {
20379
20418
  if (!name.endsWith(".json"))
20380
20419
  continue;
20381
20420
  try {
20382
- const session2 = JSON.parse(readFileSync3(join2(dir, "hooks", name), "utf8"));
20421
+ const session2 = JSON.parse(readFileSync3(join3(dir, "hooks", name), "utf8"));
20383
20422
  if (now - session2.seenAt <= HOOK_TTL_MS && (session2.pid === void 0 || alive(session2.pid)))
20384
20423
  found.push(session2);
20385
20424
  } catch {
@@ -20404,7 +20443,7 @@ function admitHeldMcpCompletion(url, body) {
20404
20443
  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
20444
  throw new Error("Held MCP completion route unavailable");
20406
20445
  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((field) => !("value" in field)) || 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)
20446
+ 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
20447
  throw new Error("Held MCP completion admission invalid");
20409
20448
  }
20410
20449
  async function request(url, body, headers, stream, cancellation, held = false) {
@@ -20636,10 +20675,47 @@ var init_beeline_api = __esm({
20636
20675
  }
20637
20676
  });
20638
20677
 
20678
+ // apps/body/dist/process-exit.js
20679
+ import { spawn as spawn5 } from "node:child_process";
20680
+ function waitForProcessExit(pid, signal) {
20681
+ return new Promise((resolve13, reject) => {
20682
+ const child = spawn5("/usr/bin/python3", ["-c", WAIT, String(pid)], { stdio: "ignore", signal });
20683
+ child.once("error", reject);
20684
+ child.once("close", (code) => code === 0 ? resolve13() : reject(new Error(`process exit observer failed (${code})`)));
20685
+ });
20686
+ }
20687
+ var WAIT;
20688
+ var init_process_exit = __esm({
20689
+ "apps/body/dist/process-exit.js"() {
20690
+ "use strict";
20691
+ WAIT = `import os,sys,select
20692
+ pid=int(sys.argv[1])
20693
+ try:
20694
+ if hasattr(os,'pidfd_open'):
20695
+ fd=os.pidfd_open(pid)
20696
+ try: select.select([fd],[],[])
20697
+ finally: os.close(fd)
20698
+ else:
20699
+ queue=select.kqueue()
20700
+ try: queue.control([select.kevent(pid,filter=select.KQ_FILTER_PROC,flags=select.KQ_EV_ADD|select.KQ_EV_ONESHOT,fflags=select.KQ_NOTE_EXIT)],1)
20701
+ finally: queue.close()
20702
+ except ProcessLookupError: pass
20703
+ `;
20704
+ }
20705
+ });
20706
+
20707
+ // packages/api-contract/dist/phone-types-room-live-delta.js
20708
+ var init_phone_types_room_live_delta = __esm({
20709
+ "packages/api-contract/dist/phone-types-room-live-delta.js"() {
20710
+ "use strict";
20711
+ }
20712
+ });
20713
+
20639
20714
  // packages/api-contract/dist/phone-types.js
20640
20715
  var init_phone_types = __esm({
20641
20716
  "packages/api-contract/dist/phone-types.js"() {
20642
20717
  "use strict";
20718
+ init_phone_types_room_live_delta();
20643
20719
  }
20644
20720
  });
20645
20721
 
@@ -20650,21 +20726,12 @@ var init_model_choice = __esm({
20650
20726
  }
20651
20727
  });
20652
20728
 
20653
- // packages/api-contract/dist/system-message-catalog.js
20654
- function systemMessage(key, ...values) {
20655
- const entry = SYSTEM_MESSAGE_CATALOG[key];
20656
- if (values.length !== entry.variables.length)
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"() {
20729
+ // packages/api-contract/dist/system-message-catalog-away-auto-pause.js
20730
+ var SYSTEM_MESSAGE_AWAY_AUTO_PAUSE;
20731
+ var init_system_message_catalog_away_auto_pause = __esm({
20732
+ "packages/api-contract/dist/system-message-catalog-away-auto-pause.js"() {
20666
20733
  "use strict";
20667
- SYSTEM_MESSAGE_CATALOG = {
20734
+ SYSTEM_MESSAGE_AWAY_AUTO_PAUSE = {
20668
20735
  "away-auto-pause.warning": { parts: ["will pause schedules and subscriptions for"], variables: [] },
20669
20736
  "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
20737
  "agent-command.agent-mention": {
@@ -21312,7 +21379,17 @@ var init_system_message_catalog = __esm({
21312
21379
  "daemon-service.instead-of": {
21313
21380
  parts: ["instead of ", ""],
21314
21381
  variables: ["input_from"]
21315
- },
21382
+ }
21383
+ };
21384
+ }
21385
+ });
21386
+
21387
+ // packages/api-contract/dist/system-message-catalog-daemon-service.js
21388
+ var SYSTEM_MESSAGE_DAEMON_SERVICE;
21389
+ var init_system_message_catalog_daemon_service = __esm({
21390
+ "packages/api-contract/dist/system-message-catalog-daemon-service.js"() {
21391
+ "use strict";
21392
+ SYSTEM_MESSAGE_DAEMON_SERVICE = {
21316
21393
  "daemon-service.needs-a-connection-to": {
21317
21394
  parts: ["needs a connection to"],
21318
21395
  variables: []
@@ -21960,7 +22037,17 @@ var init_system_message_catalog = __esm({
21960
22037
  "vault-save-http.list-separator": {
21961
22038
  parts: [", "],
21962
22039
  variables: []
21963
- },
22040
+ }
22041
+ };
22042
+ }
22043
+ });
22044
+
22045
+ // packages/api-contract/dist/system-message-catalog-voice-service.js
22046
+ var SYSTEM_MESSAGE_VOICE_SERVICE;
22047
+ var init_system_message_catalog_voice_service = __esm({
22048
+ "packages/api-contract/dist/system-message-catalog-voice-service.js"() {
22049
+ "use strict";
22050
+ SYSTEM_MESSAGE_VOICE_SERVICE = {
21964
22051
  "voice-service.voice-call": {
21965
22052
  parts: ["Voice call"],
21966
22053
  variables: []
@@ -22605,7 +22692,17 @@ var init_system_message_catalog = __esm({
22605
22692
  "turn-silence.the-helper-couldn-t-get-a-working-copy-of-check-the-repository-is": {
22606
22693
  parts: ["the helper couldn't get a working copy of ", ". Check the repository is reachable."],
22607
22694
  variables: ["classified_repo_the_repository"]
22608
- },
22695
+ }
22696
+ };
22697
+ }
22698
+ });
22699
+
22700
+ // packages/api-contract/dist/system-message-catalog-turn-silence.js
22701
+ var SYSTEM_MESSAGE_TURN_SILENCE;
22702
+ var init_system_message_catalog_turn_silence = __esm({
22703
+ "packages/api-contract/dist/system-message-catalog-turn-silence.js"() {
22704
+ "use strict";
22705
+ SYSTEM_MESSAGE_TURN_SILENCE = {
22609
22706
  "turn-silence.the-helper-is-out-of-date-run-beeline-start-on-the-helper-s-machi": {
22610
22707
  parts: ["the helper is out of date. Run `beeline start` on the helper's machine."],
22611
22708
  variables: []
@@ -22812,6 +22909,33 @@ var init_system_message_catalog = __esm({
22812
22909
  }
22813
22910
  });
22814
22911
 
22912
+ // packages/api-contract/dist/system-message-catalog.js
22913
+ function systemMessage(key, ...values) {
22914
+ const entry = SYSTEM_MESSAGE_CATALOG[key];
22915
+ if (values.length !== entry.variables.length)
22916
+ throw new Error(`System message ${key} needs ${entry.variables.length} variables`);
22917
+ let text = entry.parts[0];
22918
+ for (let index = 0; index < values.length; index++)
22919
+ text += `${values[index]}${entry.parts[index + 1]}`;
22920
+ return text;
22921
+ }
22922
+ var SYSTEM_MESSAGE_CATALOG;
22923
+ var init_system_message_catalog = __esm({
22924
+ "packages/api-contract/dist/system-message-catalog.js"() {
22925
+ "use strict";
22926
+ init_system_message_catalog_away_auto_pause();
22927
+ init_system_message_catalog_daemon_service();
22928
+ init_system_message_catalog_voice_service();
22929
+ init_system_message_catalog_turn_silence();
22930
+ SYSTEM_MESSAGE_CATALOG = {
22931
+ ...SYSTEM_MESSAGE_AWAY_AUTO_PAUSE,
22932
+ ...SYSTEM_MESSAGE_DAEMON_SERVICE,
22933
+ ...SYSTEM_MESSAGE_VOICE_SERVICE,
22934
+ ...SYSTEM_MESSAGE_TURN_SILENCE
22935
+ };
22936
+ }
22937
+ });
22938
+
22815
22939
  // packages/api-contract/dist/voice.js
22816
22940
  var init_voice = __esm({
22817
22941
  "packages/api-contract/dist/voice.js"() {
@@ -22852,20 +22976,6 @@ var init_artifacts = __esm({
22852
22976
  }
22853
22977
  });
22854
22978
 
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
22979
  // packages/api-contract/dist/agent-usage.js
22870
22980
  var USAGE_OLD_SECONDS, USAGE_WINDOW_LABELS;
22871
22981
  var init_agent_usage = __esm({
@@ -22885,52 +22995,6 @@ var init_agent_usage = __esm({
22885
22995
  }
22886
22996
  });
22887
22997
 
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
22998
  // packages/api-contract/dist/agent-sign-in.js
22935
22999
  var AGENT_SIGN_IN_ATTEMPT_TTL_MS, AGENT_SIGN_IN_SERVICE_LABELS;
22936
23000
  var init_agent_sign_in = __esm({
@@ -22950,15 +23014,6 @@ var init_agent_sign_in = __esm({
22950
23014
  }
22951
23015
  });
22952
23016
 
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
23017
  // packages/api-contract/dist/agent-grants.js
22963
23018
  var AGENT_GRANT_KINDS, REQUESTABLE_AGENT_GRANT_KINDS, DECISION_LINE;
22964
23019
  var init_agent_grants = __esm({
@@ -23049,23 +23104,124 @@ var init_room_choices = __esm({
23049
23104
  }
23050
23105
  });
23051
23106
 
23107
+ // packages/api-contract/dist/repository-onboarding.js
23108
+ var init_repository_onboarding = __esm({
23109
+ "packages/api-contract/dist/repository-onboarding.js"() {
23110
+ "use strict";
23111
+ }
23112
+ });
23113
+
23114
+ // packages/api-contract/dist/vault-save.js
23115
+ var init_vault_save = __esm({
23116
+ "packages/api-contract/dist/vault-save.js"() {
23117
+ "use strict";
23118
+ }
23119
+ });
23120
+
23121
+ // packages/api-contract/dist/system-events.js
23122
+ function isPerItemEventKind(value) {
23123
+ return PER_ITEM_EVENT_KINDS.includes(value);
23124
+ }
23125
+ var SYSTEM_LINE_SEPARATOR, SERVER_EVENT_KINDS, PER_ITEM_EVENT_KINDS, SUBSCRIBABLE_EVENT_KINDS, AGENT_EVENT_SLUG_MAX_LENGTH, AGENT_KIND;
23126
+ var init_system_events = __esm({
23127
+ "packages/api-contract/dist/system-events.js"() {
23128
+ "use strict";
23129
+ init_system_message_catalog();
23130
+ SYSTEM_LINE_SEPARATOR = systemMessage("system-events.separator");
23131
+ SERVER_EVENT_KINDS = [
23132
+ "joined",
23133
+ "left",
23134
+ "schedule-ran",
23135
+ "corner-opened",
23136
+ "check-passed",
23137
+ "check-failed",
23138
+ "merged",
23139
+ "grant-decided",
23140
+ "squire-approval-decided",
23141
+ "connector-offer-decided",
23142
+ "turn-cancelled",
23143
+ "choice-answered",
23144
+ "choice-skipped",
23145
+ "poll-closed",
23146
+ "workflow-handoff",
23147
+ "subscription-fired",
23148
+ "computer-session-activity"
23149
+ ];
23150
+ PER_ITEM_EVENT_KINDS = [
23151
+ "grant-decided",
23152
+ "squire-approval-decided",
23153
+ "connector-offer-decided",
23154
+ "turn-cancelled",
23155
+ "choice-answered",
23156
+ "choice-skipped",
23157
+ "poll-closed",
23158
+ "subscription-fired",
23159
+ "computer-session-activity"
23160
+ ];
23161
+ SUBSCRIBABLE_EVENT_KINDS = SERVER_EVENT_KINDS.filter((kind) => !isPerItemEventKind(kind) && kind !== "merged");
23162
+ AGENT_EVENT_SLUG_MAX_LENGTH = 40;
23163
+ AGENT_KIND = new RegExp(`^agent:[a-z0-9-]{1,${AGENT_EVENT_SLUG_MAX_LENGTH}}$`);
23164
+ }
23165
+ });
23166
+
23167
+ // packages/api-contract/dist/phone-guards-read-choice-card.js
23168
+ var init_phone_guards_read_choice_card = __esm({
23169
+ "packages/api-contract/dist/phone-guards-read-choice-card.js"() {
23170
+ "use strict";
23171
+ init_repository_onboarding();
23172
+ init_vault_save();
23173
+ init_system_events();
23174
+ init_voice();
23175
+ init_phone_types();
23176
+ init_room_choices();
23177
+ init_phone_guards();
23178
+ }
23179
+ });
23180
+
23181
+ // packages/api-contract/dist/agent-access.js
23182
+ var ACCESS_NOTICE_WINDOW_MS;
23183
+ var init_agent_access = __esm({
23184
+ "packages/api-contract/dist/agent-access.js"() {
23185
+ "use strict";
23186
+ ACCESS_NOTICE_WINDOW_MS = 10 * 6e4;
23187
+ }
23188
+ });
23189
+
23190
+ // packages/api-contract/dist/phone-guards-read-corner-lifecycle.js
23191
+ var init_phone_guards_read_corner_lifecycle = __esm({
23192
+ "packages/api-contract/dist/phone-guards-read-corner-lifecycle.js"() {
23193
+ "use strict";
23194
+ init_agent_access();
23195
+ init_phone_types();
23196
+ init_phone_guards();
23197
+ init_phone_guards_read_choice_card();
23198
+ }
23199
+ });
23200
+
23201
+ // packages/api-contract/dist/phone-guards-read-agent-detail-view.js
23202
+ var init_phone_guards_read_agent_detail_view = __esm({
23203
+ "packages/api-contract/dist/phone-guards-read-agent-detail-view.js"() {
23204
+ "use strict";
23205
+ init_agent_usage();
23206
+ init_phone_guards();
23207
+ init_phone_guards_read_corner_lifecycle();
23208
+ }
23209
+ });
23210
+
23052
23211
  // packages/api-contract/dist/phone-guards.js
23053
23212
  var CLOSED_VIEWER;
23054
23213
  var init_phone_guards = __esm({
23055
23214
  "packages/api-contract/dist/phone-guards.js"() {
23056
23215
  "use strict";
23057
- init_repository_onboarding();
23058
- init_vault_save();
23059
23216
  init_agent_usage();
23060
- init_system_events();
23061
23217
  init_agent_sign_in();
23062
- init_agent_access();
23063
- init_voice();
23064
- init_phone_types();
23065
23218
  init_agent_grants();
23066
23219
  init_connector_offers();
23067
23220
  init_workbench();
23068
23221
  init_room_choices();
23222
+ init_phone_guards_read_choice_card();
23223
+ init_phone_guards_read_corner_lifecycle();
23224
+ init_phone_guards_read_agent_detail_view();
23069
23225
  CLOSED_VIEWER = {
23070
23226
  identity: { pubkey: "0".repeat(64), kind: "human", name: "" },
23071
23227
  role: "member",
@@ -23697,9 +23853,9 @@ var init_stream_frame = __esm({
23697
23853
  import { execFile as execFile3 } from "node:child_process";
23698
23854
  import { closeSync, fstatSync, openSync, readSync, readdirSync as readdirSync2, readlinkSync, statSync as statSync2 } from "node:fs";
23699
23855
  import { homedir as homedir5 } from "node:os";
23700
- import { basename as basename3, join as join3 } from "node:path";
23856
+ import { basename as basename3, join as join4 } from "node:path";
23701
23857
  function codexHome(env = process.env) {
23702
- return env.CODEX_HOME || join3(env.HOME || homedir5(), ".codex");
23858
+ return env.CODEX_HOME || join4(env.HOME || homedir5(), ".codex");
23703
23859
  }
23704
23860
  function turnEvent(line) {
23705
23861
  if (!line.includes("event_msg") || !(line.includes("task_") || line.includes("turn_")))
@@ -23763,14 +23919,14 @@ function scanCodex(proc = "/proc") {
23763
23919
  continue;
23764
23920
  let fds;
23765
23921
  try {
23766
- fds = readdirSync2(join3(proc, name, "fd"));
23922
+ fds = readdirSync2(join4(proc, name, "fd"));
23767
23923
  } catch {
23768
23924
  continue;
23769
23925
  }
23770
23926
  for (const fd of fds) {
23771
23927
  let target;
23772
23928
  try {
23773
- target = readlinkSync(join3(proc, name, "fd", fd));
23929
+ target = readlinkSync(join4(proc, name, "fd", fd));
23774
23930
  } catch {
23775
23931
  continue;
23776
23932
  }
@@ -23779,7 +23935,7 @@ function scanCodex(proc = "/proc") {
23779
23935
  continue;
23780
23936
  let cwd;
23781
23937
  try {
23782
- cwd = readlinkSync(join3(proc, name, "cwd"));
23938
+ cwd = readlinkSync(join4(proc, name, "cwd"));
23783
23939
  } catch {
23784
23940
  }
23785
23941
  if (!found.some((s) => s.threadId === threadId))
@@ -23789,12 +23945,12 @@ function scanCodex(proc = "/proc") {
23789
23945
  return found;
23790
23946
  }
23791
23947
  function codexQueue(threadId, text, bin = "codex", timeoutMs = 3e4) {
23792
- return new Promise((resolve11, reject) => {
23948
+ return new Promise((resolve13, reject) => {
23793
23949
  execFile3(bin, ["queue", "--thread", threadId, "--message", text], { timeout: timeoutMs }, (error, _stdout, stderr) => {
23794
23950
  if (error)
23795
23951
  reject(new Error(String(stderr).trim() || error.message));
23796
23952
  else
23797
- resolve11();
23953
+ resolve13();
23798
23954
  });
23799
23955
  });
23800
23956
  }
@@ -23812,12 +23968,12 @@ var init_codex = __esm({
23812
23968
  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
23969
  import { createConnection as createConnection3 } from "node:net";
23814
23970
  import { homedir as homedir6 } from "node:os";
23815
- import { join as join4 } from "node:path";
23971
+ import { join as join5 } from "node:path";
23816
23972
  function claudeConfigDir(env = process.env) {
23817
- return env.CLAUDE_CONFIG_DIR || join4(env.HOME || homedir6(), ".claude");
23973
+ return env.CLAUDE_CONFIG_DIR || join5(env.HOME || homedir6(), ".claude");
23818
23974
  }
23819
23975
  function scanClaude(env = process.env, alive = pidAlive) {
23820
- const dir = join4(claudeConfigDir(env), "sessions");
23976
+ const dir = join5(claudeConfigDir(env), "sessions");
23821
23977
  let names;
23822
23978
  try {
23823
23979
  names = readdirSync3(dir);
@@ -23829,7 +23985,7 @@ function scanClaude(env = process.env, alive = pidAlive) {
23829
23985
  if (!/^\d+\.json$/.test(name))
23830
23986
  continue;
23831
23987
  try {
23832
- const value = JSON.parse(readFileSync4(join4(dir, name), "utf8"));
23988
+ const value = JSON.parse(readFileSync4(join5(dir, name), "utf8"));
23833
23989
  if (Number.isInteger(value.pid) && alive(value.pid))
23834
23990
  sessions.push(value);
23835
23991
  } catch {
@@ -23841,7 +23997,7 @@ function chosenName(session2) {
23841
23997
  return ["user", "peer", "hook"].includes(session2.nameSource ?? "") ? session2.name : void 0;
23842
23998
  }
23843
23999
  function postToClaude(socket, text, _timeoutMs = 5e3) {
23844
- return new Promise((resolve11, reject) => {
24000
+ return new Promise((resolve13, reject) => {
23845
24001
  const connection = createConnection3(socket.path);
23846
24002
  connection.once("error", (error) => {
23847
24003
  reject(error);
@@ -23850,13 +24006,13 @@ function postToClaude(socket, text, _timeoutMs = 5e3) {
23850
24006
  if (socket.token)
23851
24007
  connection.write(JSON.stringify({ type: "auth", token: socket.token }) + "\n");
23852
24008
  connection.end(JSON.stringify({ type: "user", message: { role: "user", content: text } }) + "\n", () => {
23853
- resolve11();
24009
+ resolve13();
23854
24010
  });
23855
24011
  });
23856
24012
  });
23857
24013
  }
23858
24014
  function claudeTranscript(sessionId, env = process.env) {
23859
- const root = join4(claudeConfigDir(env), "projects");
24015
+ const root = join5(claudeConfigDir(env), "projects");
23860
24016
  let projects;
23861
24017
  try {
23862
24018
  projects = readdirSync3(root);
@@ -23864,7 +24020,7 @@ function claudeTranscript(sessionId, env = process.env) {
23864
24020
  return void 0;
23865
24021
  }
23866
24022
  for (const project of projects) {
23867
- const path = join4(root, project, `${sessionId}.jsonl`);
24023
+ const path = join5(root, project, `${sessionId}.jsonl`);
23868
24024
  try {
23869
24025
  if (statSync3(path).isFile())
23870
24026
  return path;
@@ -23903,7 +24059,7 @@ function heldBy(mode, setting) {
23903
24059
  }
23904
24060
  function inboundSetting(env = process.env) {
23905
24061
  try {
23906
- const value = JSON.parse(readFileSync4(join4(claudeConfigDir(env), "settings.json"), "utf8"));
24062
+ const value = JSON.parse(readFileSync4(join5(claudeConfigDir(env), "settings.json"), "utf8"));
23907
24063
  return typeof value.crossSessionInbound === "string" ? value.crossSessionInbound : void 0;
23908
24064
  } catch {
23909
24065
  return void 0;
@@ -23918,20 +24074,20 @@ var init_claude = __esm({
23918
24074
 
23919
24075
  // apps/body/dist/session-join/claude-mcp.js
23920
24076
  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 join5 } from "node:path";
24077
+ import { join as join6 } from "node:path";
23922
24078
  import { createInterface } from "node:readline";
23923
24079
  function hasClaudeMcp(dir, claudePid) {
23924
24080
  if (!claudePid)
23925
24081
  return false;
23926
24082
  let files;
23927
24083
  try {
23928
- files = readdirSync4(join5(dir, "claude-mcp"));
24084
+ files = readdirSync4(join6(dir, "claude-mcp"));
23929
24085
  } catch {
23930
24086
  return false;
23931
24087
  }
23932
24088
  return files.some((file) => {
23933
24089
  try {
23934
- const entry = JSON.parse(readFileSync5(join5(dir, "claude-mcp", file), "utf8"));
24090
+ const entry = JSON.parse(readFileSync5(join6(dir, "claude-mcp", file), "utf8"));
23935
24091
  return entry.claudePid === claudePid && pidAlive(entry.pid);
23936
24092
  } catch {
23937
24093
  return false;
@@ -23940,17 +24096,19 @@ function hasClaudeMcp(dir, claudePid) {
23940
24096
  }
23941
24097
  async function flushClaudeMcp(dir, session2, token, post = postToClaude) {
23942
24098
  if (!session2.messagingSocketPath)
23943
- return;
24099
+ return false;
23944
24100
  const joined2 = readState(dir).sessions.find((s) => s.agent === "claude-code" && (s.pid === session2.pid || s.sessionId === session2.sessionId));
23945
24101
  if (!joined2)
23946
- return;
24102
+ return false;
23947
24103
  const text = takeInbox(dir, joined2.key);
23948
24104
  if (!text)
23949
- return;
24105
+ return false;
23950
24106
  try {
23951
24107
  await post({ path: session2.messagingSocketPath, token }, text);
24108
+ return true;
23952
24109
  } catch {
23953
24110
  queueInbox(dir, joined2.key, text);
24111
+ return false;
23954
24112
  }
23955
24113
  }
23956
24114
  function joinedClaude(dir, env, chain) {
@@ -23960,32 +24118,38 @@ function joinedClaude(dir, env, chain) {
23960
24118
  return void 0;
23961
24119
  return readState(dir).sessions.find((s) => s.agent === "claude-code" && (s.pid === session2.pid || s.sessionId === session2.sessionId));
23962
24120
  }
23963
- async function runClaudeMcp(dir, env, rulesFor) {
24121
+ async function runClaudeMcp(dir, env, rulesFor, post = postToClaude) {
23964
24122
  const chain = ancestors(process.pid);
23965
24123
  let registration;
23966
- let flushing = false;
24124
+ let flushing = false, dirty = false;
23967
24125
  const flush2 = async () => {
24126
+ dirty = true;
23968
24127
  if (flushing || !env.CLAUDE_CODE_MESSAGING_TOKEN)
23969
24128
  return;
23970
24129
  flushing = true;
23971
24130
  try {
23972
- const live = scanClaude(env);
23973
- const session2 = chain.map((pid) => live.find((s) => s.pid === pid)).find(Boolean);
23974
- if (!session2)
23975
- return;
23976
- if (!registration) {
23977
- const folder = join5(dir, "claude-mcp");
23978
- mkdirSync2(folder, { recursive: true, mode: 448 });
23979
- registration = join5(folder, `${process.pid}.json`);
23980
- writeFileSync2(registration, JSON.stringify({ pid: process.pid, claudePid: session2.pid }), { mode: 384 });
24131
+ while (dirty) {
24132
+ dirty = false;
24133
+ const live = scanClaude(env);
24134
+ const session2 = chain.map((pid) => live.find((s) => s.pid === pid)).find(Boolean);
24135
+ if (!session2)
24136
+ return;
24137
+ if (!registration) {
24138
+ const folder = join6(dir, "claude-mcp");
24139
+ mkdirSync2(folder, { recursive: true, mode: 448 });
24140
+ registration = join6(folder, `${process.pid}.json`);
24141
+ writeFileSync2(registration, JSON.stringify({ pid: process.pid, claudePid: session2.pid }), { mode: 384 });
24142
+ }
24143
+ if (!await flushClaudeMcp(dir, session2, env.CLAUDE_CODE_MESSAGING_TOKEN, post))
24144
+ break;
23981
24145
  }
23982
- await flushClaudeMcp(dir, session2, env.CLAUDE_CODE_MESSAGING_TOKEN);
23983
24146
  } finally {
23984
24147
  flushing = false;
23985
24148
  }
23986
24149
  };
23987
24150
  const watcher = watch3(dir, { recursive: true }, (_event, name) => {
23988
- if (String(name ?? "").startsWith("inbox/"))
24151
+ const path = String(name ?? "");
24152
+ if (path === "state.json" || path.startsWith("inbox/"))
23989
24153
  void flush2().catch(() => void 0);
23990
24154
  });
23991
24155
  try {
@@ -24074,10 +24238,10 @@ var init_sessions = __esm({
24074
24238
  });
24075
24239
 
24076
24240
  // apps/body/dist/session-join/bridge.js
24077
- import { spawn as spawn5 } from "node:child_process";
24241
+ import { execFileSync, spawn as spawn6 } from "node:child_process";
24078
24242
  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
24243
  import { createConnection as createConnection4, createServer as createServer3 } from "node:net";
24080
- import { join as join6 } from "node:path";
24244
+ import { basename as basename4, join as join7, resolve as resolve10 } from "node:path";
24081
24245
  import { createHash as createHash6 } from "node:crypto";
24082
24246
  function command(runner2, joined2, args) {
24083
24247
  const q = (v) => /^[A-Za-z0-9_./:@=-]+$/.test(v) ? v : `"${v.replace(/(["\\$`])/g, "\\$1")}"`;
@@ -24179,7 +24343,7 @@ async function acceptMemberDelivery(dir, key, runner2, raw) {
24179
24343
  }
24180
24344
  function log(dir, line) {
24181
24345
  try {
24182
- writeFileSync3(join6(dir, "bridge.log"), `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
24346
+ writeFileSync3(join7(dir, "bridge.log"), `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
24183
24347
  `, { flag: "a", mode: 384 });
24184
24348
  } catch {
24185
24349
  }
@@ -24205,7 +24369,7 @@ async function flush(dir, sources, deps = realDeps) {
24205
24369
  }
24206
24370
  }
24207
24371
  function serveTools(dir) {
24208
- const path = join6(dir, "bridge.sock");
24372
+ const path = join7(dir, "bridge.sock");
24209
24373
  rmSync3(path, { force: true });
24210
24374
  const server = createServer3((connection) => {
24211
24375
  let buffer = "", taken = false;
@@ -24233,7 +24397,7 @@ function serveTools(dir) {
24233
24397
  server.unref();
24234
24398
  }
24235
24399
  function outboxDir(cwd) {
24236
- return join6(cwd, ".beeline", "outbox");
24400
+ return join7(cwd, ".beeline", "outbox");
24237
24401
  }
24238
24402
  async function serveOutboxes(dir) {
24239
24403
  let served = 0;
@@ -24245,7 +24409,7 @@ async function serveOutboxes(dir) {
24245
24409
  continue;
24246
24410
  }
24247
24411
  for (const name of names.filter((n) => n.endsWith(".request.json"))) {
24248
- const path = join6(outboxDir(joined2.cwd), name);
24412
+ const path = join7(outboxDir(joined2.cwd), name);
24249
24413
  const taking = `${path}.taking`;
24250
24414
  try {
24251
24415
  renameSync2(path, taking);
@@ -24271,19 +24435,19 @@ async function serveOutboxes(dir) {
24271
24435
  async function toolViaOutbox(cwd, name, args) {
24272
24436
  const dirPath = outboxDir(cwd);
24273
24437
  mkdirSync3(dirPath, { recursive: true });
24274
- writeFileSync3(join6(cwd, ".beeline", ".gitignore"), "*\n");
24438
+ writeFileSync3(join7(cwd, ".beeline", ".gitignore"), "*\n");
24275
24439
  const id = `${Date.now()}-${process.pid}`;
24276
- const request2 = join6(dirPath, `${id}.request.json`), result = join6(dirPath, `${id}.result.json`);
24440
+ const request2 = join7(dirPath, `${id}.request.json`), result = join7(dirPath, `${id}.result.json`);
24277
24441
  writeFileSync3(`${request2}.tmp`, JSON.stringify({ name, args }));
24278
24442
  renameSync2(`${request2}.tmp`, request2);
24279
- return new Promise((resolve11) => {
24443
+ return new Promise((resolve13) => {
24280
24444
  let settled = false;
24281
24445
  const finish = (answer) => {
24282
24446
  if (settled)
24283
24447
  return;
24284
24448
  settled = true;
24285
24449
  watcher.close();
24286
- resolve11(answer);
24450
+ resolve13(answer);
24287
24451
  };
24288
24452
  const inspect = () => {
24289
24453
  try {
@@ -24301,15 +24465,15 @@ async function toolViaOutbox(cwd, name, args) {
24301
24465
  });
24302
24466
  }
24303
24467
  function toolViaBridge(dir, key, name, args) {
24304
- return new Promise((resolve11) => {
24305
- const connection = createConnection4(join6(dir, "bridge.sock"));
24468
+ return new Promise((resolve13) => {
24469
+ const connection = createConnection4(join7(dir, "bridge.sock"));
24306
24470
  let text = "", sent = false, settled = false;
24307
24471
  const unknown = { ok: false, error: "Beeline tool result is awaiting confirmation" };
24308
24472
  const finish = (answer) => {
24309
24473
  if (settled)
24310
24474
  return;
24311
24475
  settled = true;
24312
- resolve11(answer);
24476
+ resolve13(answer);
24313
24477
  connection.destroy();
24314
24478
  };
24315
24479
  connection.setEncoding("utf8");
@@ -24331,7 +24495,7 @@ function toolViaBridge(dir, key, name, args) {
24331
24495
  });
24332
24496
  }
24333
24497
  async function runBridge(dir, runner2) {
24334
- const pidFile = join6(dir, "bridge.pid");
24498
+ const pidFile = join7(dir, "bridge.pid");
24335
24499
  try {
24336
24500
  const fd = openSync3(pidFile, "wx", 384);
24337
24501
  writeFileSync3(fd, String(process.pid));
@@ -24351,6 +24515,7 @@ async function runBridge(dir, runner2) {
24351
24515
  wake?.();
24352
24516
  };
24353
24517
  serveTools(dir);
24518
+ writeFileSync3(join7(dir, "bridge-owner.json"), JSON.stringify({ pid: process.pid, digest: bundleDigest(runner2) }), { mode: 384 });
24354
24519
  const localWatch = watch4(dir, { recursive: true }, (_event, name) => {
24355
24520
  const path = String(name ?? "");
24356
24521
  if (path === "state.json" || path.startsWith("hooks/") || path.startsWith("inbox/") || path.startsWith("deliveries/"))
@@ -24364,7 +24529,7 @@ async function runBridge(dir, runner2) {
24364
24529
  for (const watcher of outboxWatches.values())
24365
24530
  watcher.close();
24366
24531
  rmSync3(pidFile, { force: true });
24367
- rmSync3(join6(dir, "bridge.sock"), { force: true });
24532
+ rmSync3(join7(dir, "bridge.sock"), { force: true });
24368
24533
  process.exit(0);
24369
24534
  };
24370
24535
  process.once("SIGTERM", stop);
@@ -24435,7 +24600,7 @@ async function runBridge(dir, runner2) {
24435
24600
  const path = outboxDir(joined2.cwd);
24436
24601
  if (!outboxWatches.has(path)) {
24437
24602
  mkdirSync3(path, { recursive: true, mode: 448 });
24438
- const ignore = join6(joined2.cwd, ".beeline", ".gitignore");
24603
+ const ignore = join7(joined2.cwd, ".beeline", ".gitignore");
24439
24604
  if (!existsSync2(ignore))
24440
24605
  writeFileSync3(ignore, "*\n", { mode: 384 });
24441
24606
  outboxWatches.set(path, watch4(path, (_event, name) => {
@@ -24447,8 +24612,8 @@ async function runBridge(dir, runner2) {
24447
24612
  await serveOutboxes(dir).catch((error) => log(dir, `outbox: ${String(error)}`));
24448
24613
  await flush(dir, sources).catch((error) => log(dir, `flush: ${String(error)}`));
24449
24614
  if (!localDirty)
24450
- await new Promise((resolve11) => {
24451
- wake = resolve11;
24615
+ await new Promise((resolve13) => {
24616
+ wake = resolve13;
24452
24617
  });
24453
24618
  wake = void 0;
24454
24619
  }
@@ -24462,30 +24627,101 @@ async function runBridge(dir, runner2) {
24462
24627
  }
24463
24628
  log(dir, `bridge ${process.pid} stopped: no joined sessions`);
24464
24629
  rmSync3(pidFile, { force: true });
24465
- rmSync3(join6(dir, "bridge.sock"), { force: true });
24630
+ rmSync3(join7(dir, "bridge.sock"), { force: true });
24466
24631
  process.exit(0);
24467
24632
  }
24468
24633
  function bridgeRunning(dir) {
24469
24634
  try {
24470
- const holder = Number(readFileSync6(join6(dir, "bridge.pid"), "utf8"));
24635
+ const holder = Number(readFileSync6(join7(dir, "bridge.pid"), "utf8"));
24471
24636
  return Boolean(holder) && pidAlive(holder);
24472
24637
  } catch {
24473
24638
  return false;
24474
24639
  }
24475
24640
  }
24476
- function ensureBridge(dir, runner2, env = process.env) {
24477
- if (bridgeRunning(dir))
24478
- return;
24479
- const out = openSync3(join6(dir, "bridge.log"), "a", 384);
24480
- const child = spawn5(runner2.node, [runner2.bundle, "session", "bridge"], { detached: true, stdio: ["ignore", out, out], env });
24481
- child.unref();
24482
- closeSync3(out);
24641
+ function bundleDigest(runner2) {
24642
+ return createHash6("sha256").update(readFileSync6(runner2.bundle)).digest("hex");
24643
+ }
24644
+ function bridgeOwner(dir) {
24645
+ try {
24646
+ return JSON.parse(readFileSync6(join7(dir, "bridge-owner.json"), "utf8"));
24647
+ } catch {
24648
+ return void 0;
24649
+ }
24650
+ }
24651
+ function isBridgeProcess(pid) {
24652
+ try {
24653
+ if (process.platform === "linux") {
24654
+ const args2 = readFileSync6(`/proc/${pid}/cmdline`, "utf8").split("\0").filter(Boolean);
24655
+ return args2.length === 4 && /^node(?:\.exe)?$/.test(basename4(args2[0])) && /^(?:beeline|usebeeline\.mjs|recovery-cli\.mjs)$/.test(basename4(args2[1])) && args2[2] === "session" && args2[3] === "bridge";
24656
+ }
24657
+ const args = execFileSync("ps", ["-ww", "-p", String(pid), "-o", "args="], { encoding: "utf8" }).trim();
24658
+ return /(?:^|\/)node\s+.*\/(?:beeline|usebeeline\.mjs|recovery-cli\.mjs) session bridge$/.test(args);
24659
+ } catch {
24660
+ return false;
24661
+ }
24662
+ }
24663
+ async function ensureBridge(dir, runner2, env = process.env) {
24664
+ await withKernelLock(`beeline-session-bridge:${resolve10(dir)}`, async () => {
24665
+ const digest = bundleDigest(runner2);
24666
+ const pidFile = join7(dir, "bridge.pid");
24667
+ if (bridgeRunning(dir)) {
24668
+ const pid = Number(readFileSync6(pidFile, "utf8"));
24669
+ if (!isBridgeProcess(pid))
24670
+ throw new Error("Beeline bridge PID belongs to an unrecognized process; refusing takeover");
24671
+ const owner = bridgeOwner(dir);
24672
+ if (owner?.pid === pid && owner.digest === digest)
24673
+ return;
24674
+ log(dir, `replacing stale bridge ${pid}`);
24675
+ await withLock(dir, async () => {
24676
+ try {
24677
+ process.kill(pid, "SIGTERM");
24678
+ } catch (error) {
24679
+ if (error.code !== "ESRCH")
24680
+ throw error;
24681
+ }
24682
+ await waitForProcessExit(pid);
24683
+ });
24684
+ if (existsSync2(pidFile) && Number(readFileSync6(pidFile, "utf8")) === pid)
24685
+ rmSync3(pidFile);
24686
+ }
24687
+ const out = openSync3(join7(dir, "bridge.log"), "a", 384);
24688
+ const child = spawn6(runner2.node, [runner2.bundle, "session", "bridge"], { detached: true, stdio: ["ignore", out, out], env });
24689
+ closeSync3(out);
24690
+ child.unref();
24691
+ await new Promise((done, fail) => {
24692
+ const finish = (error) => {
24693
+ watcher.close();
24694
+ child.removeListener("error", failed);
24695
+ child.removeListener("exit", exited);
24696
+ if (error)
24697
+ fail(error);
24698
+ else
24699
+ done();
24700
+ };
24701
+ const inspect = () => {
24702
+ const owner = bridgeOwner(dir);
24703
+ if (owner && owner.pid === child.pid && owner.digest === digest)
24704
+ finish();
24705
+ };
24706
+ const failed = (error) => finish(error);
24707
+ const exited = () => finish(new Error("Beeline bridge exited before readiness; see bridge.log"));
24708
+ const watcher = watch4(dir, (_event, name) => {
24709
+ if (String(name) === "bridge-owner.json")
24710
+ inspect();
24711
+ });
24712
+ child.once("error", failed);
24713
+ child.once("exit", exited);
24714
+ inspect();
24715
+ });
24716
+ });
24483
24717
  }
24484
24718
  var realDeps;
24485
24719
  var init_bridge = __esm({
24486
24720
  "apps/body/dist/session-join/bridge.js"() {
24487
24721
  "use strict";
24488
24722
  init_agent_command();
24723
+ init_kernel_lock();
24724
+ init_process_exit();
24489
24725
  init_phone();
24490
24726
  init_beeline_api();
24491
24727
  init_stream_frame();
@@ -24735,7 +24971,7 @@ def register(ctx):
24735
24971
  import { spawnSync } from "node:child_process";
24736
24972
  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
24973
  import { homedir as homedir7 } from "node:os";
24738
- import { dirname as dirname6, join as join7 } from "node:path";
24974
+ import { dirname as dirname7, join as join8 } from "node:path";
24739
24975
  function home(env) {
24740
24976
  return env.HOME || homedir7();
24741
24977
  }
@@ -24771,7 +25007,7 @@ function writeFile3(path, content, expected) {
24771
25007
  }
24772
25008
  if (before === content)
24773
25009
  return false;
24774
- mkdirSync4(dirname6(path), { recursive: true });
25010
+ mkdirSync4(dirname7(path), { recursive: true });
24775
25011
  const backup = `${path}.bak-${NAME}`;
24776
25012
  if (before !== void 0 && !existsSync3(backup) && !before.includes(" session hook "))
24777
25013
  copyFileSync(path, backup);
@@ -24881,18 +25117,18 @@ function saveJson(path, value, remove) {
24881
25117
  function claudeCode(context) {
24882
25118
  const command2 = (event) => ({ hooks: [{ type: "command", command: hookCommand(context, "claude-code", event), timeout: 10 }] });
24883
25119
  const remove = Boolean(context.remove);
24884
- const path = context.env.CLAUDE_CONFIG_DIR ? join7(context.env.CLAUDE_CONFIG_DIR, ".claude.json") : join7(home(context.env), ".claude.json");
24885
- return [...mergeClaudeMcp(path, context), ...hooksFile(join7(claudeConfigDir(context.env), "settings.json"), "claude-code", [["SessionStart", command2("session-start")]], remove)];
25120
+ const path = context.env.CLAUDE_CONFIG_DIR ? join8(context.env.CLAUDE_CONFIG_DIR, ".claude.json") : join8(home(context.env), ".claude.json");
25121
+ return [...mergeClaudeMcp(path, context), ...hooksFile(join8(claudeConfigDir(context.env), "settings.json"), "claude-code", [["SessionStart", command2("session-start")]], remove)];
24886
25122
  }
24887
25123
  function codex(context) {
24888
25124
  const group = (event) => ({ matcher: "*", hooks: [{ type: "command", command: hookCommand(context, "codex", event), timeout: 10 }] });
24889
- const lines = hooksFile(join7(codexHome(context.env), "hooks.json"), "codex", [["SessionStart", group("session-start")]], Boolean(context.remove));
25125
+ const lines = hooksFile(join8(codexHome(context.env), "hooks.json"), "codex", [["SessionStart", group("session-start")]], Boolean(context.remove));
24890
25126
  if (lines.length && !context.remove)
24891
25127
  lines.push("Codex asks once to trust Beeline\u2019s SessionStart hook if automatic trust is unavailable: open /hooks and trust only Beeline.");
24892
25128
  return lines;
24893
25129
  }
24894
25130
  function geminiHome(env) {
24895
- return env.GEMINI_CLI_HOME || join7(home(env), ".gemini");
25131
+ return env.GEMINI_CLI_HOME || join8(home(env), ".gemini");
24896
25132
  }
24897
25133
  function gemini(context) {
24898
25134
  const group = (event, timeout) => ({ matcher: "*", hooks: [{
@@ -24901,7 +25137,7 @@ function gemini(context) {
24901
25137
  command: hookCommand(context, "gemini", event),
24902
25138
  timeout
24903
25139
  }] });
24904
- return hooksFile(join7(geminiHome(context.env), "settings.json"), "gemini", [
25140
+ return hooksFile(join8(geminiHome(context.env), "settings.json"), "gemini", [
24905
25141
  ["SessionStart", group("session-start", 1e4)],
24906
25142
  ["BeforeAgent", group("user-prompt-submit", 1e4)],
24907
25143
  ["AfterTool", group("post-tool-use", 1e4)],
@@ -24910,9 +25146,9 @@ function gemini(context) {
24910
25146
  ], Boolean(context.remove));
24911
25147
  }
24912
25148
  function antigravity(context) {
24913
- const dir = join7(home(context.env), ".gemini/config");
25149
+ const dir = join8(home(context.env), ".gemini/config");
24914
25150
  const lines = [];
24915
- const hooksPath = join7(dir, "hooks.json");
25151
+ const hooksPath = join8(dir, "hooks.json");
24916
25152
  const hooks = readJson(hooksPath);
24917
25153
  if (context.remove)
24918
25154
  delete hooks[NAME];
@@ -24928,13 +25164,13 @@ function antigravity(context) {
24928
25164
  };
24929
25165
  }
24930
25166
  lines.push(...saveJson(hooksPath, hooks, Boolean(context.remove)));
24931
- const sidecar = join7(dir, "sidecars", NAME, "sidecar.json");
24932
- const configPath = join7(dir, "config.json");
25167
+ const sidecar = join8(dir, "sidecars", NAME, "sidecar.json");
25168
+ const configPath = join8(dir, "config.json");
24933
25169
  const config = readJson(configPath);
24934
25170
  const sidecars = object2(config, "sidecars");
24935
25171
  if (context.remove) {
24936
25172
  delete sidecars[NAME];
24937
- rmSync4(dirname6(sidecar), { recursive: true, force: true });
25173
+ rmSync4(dirname7(sidecar), { recursive: true, force: true });
24938
25174
  } else {
24939
25175
  if (writeJson(sidecar, {
24940
25176
  command: context.node,
@@ -24961,31 +25197,31 @@ function pluginFile(path, content, remove) {
24961
25197
  return writeFile3(path, content) ? [`updated ${path}`] : [];
24962
25198
  }
24963
25199
  function opencode(context) {
24964
- return pluginFile(join7(home(context.env), ".config/opencode/plugins", `${NAME}.ts`), fill(OPENCODE_PLUGIN, context.node, context.bundle), Boolean(context.remove));
25200
+ return pluginFile(join8(home(context.env), ".config/opencode/plugins", `${NAME}.ts`), fill(OPENCODE_PLUGIN, context.node, context.bundle), Boolean(context.remove));
24965
25201
  }
24966
25202
  function piHome(env) {
24967
- return env.PI_CODING_AGENT_DIR || join7(home(env), ".pi/agent");
25203
+ return env.PI_CODING_AGENT_DIR || join8(home(env), ".pi/agent");
24968
25204
  }
24969
25205
  function pi(context) {
24970
- return pluginFile(join7(piHome(context.env), "extensions", `${NAME}.ts`), fill(PI_EXTENSION, context.node, context.bundle), Boolean(context.remove));
25206
+ return pluginFile(join8(piHome(context.env), "extensions", `${NAME}.ts`), fill(PI_EXTENSION, context.node, context.bundle), Boolean(context.remove));
24971
25207
  }
24972
25208
  function hermesRoot(env) {
24973
- const base = env.HERMES_HOME ? env.HERMES_HOME.replace(/^~(?=\/|$)/, home(env)) : join7(home(env), `.hermes${env.HERMES_DATA_DIR_SUFFIX ?? ""}`);
25209
+ const base = env.HERMES_HOME ? env.HERMES_HOME.replace(/^~(?=\/|$)/, home(env)) : join8(home(env), `.hermes${env.HERMES_DATA_DIR_SUFFIX ?? ""}`);
24974
25210
  let active = "";
24975
25211
  try {
24976
- active = readFileSync7(join7(base, "active_profile"), "utf8").trim();
25212
+ active = readFileSync7(join8(base, "active_profile"), "utf8").trim();
24977
25213
  } catch {
24978
25214
  }
24979
- if (active && active !== "default" && active !== "." && active !== ".." && !/[/\\]/.test(active) && existsSync3(join7(base, "profiles", active)))
24980
- return join7(base, "profiles", active);
25215
+ if (active && active !== "default" && active !== "." && active !== ".." && !/[/\\]/.test(active) && existsSync3(join8(base, "profiles", active)))
25216
+ return join8(base, "profiles", active);
24981
25217
  return base;
24982
25218
  }
24983
25219
  function hermes(context) {
24984
- const dir = join7(hermesRoot(context.env), "plugins", NAME);
25220
+ const dir = join8(hermesRoot(context.env), "plugins", NAME);
24985
25221
  const remove = Boolean(context.remove);
24986
25222
  const lines = [
24987
- ...pluginFile(join7(dir, "__init__.py"), fill(HERMES_PLUGIN, context.node, context.bundle), remove),
24988
- ...pluginFile(join7(dir, "plugin.yaml"), HERMES_MANIFEST, remove)
25223
+ ...pluginFile(join8(dir, "__init__.py"), fill(HERMES_PLUGIN, context.node, context.bundle), remove),
25224
+ ...pluginFile(join8(dir, "plugin.yaml"), HERMES_MANIFEST, remove)
24989
25225
  ];
24990
25226
  if (remove)
24991
25227
  rmSync4(dir, { recursive: true, force: true });
@@ -24995,7 +25231,7 @@ function hermes(context) {
24995
25231
  return lines;
24996
25232
  }
24997
25233
  function zcodeIn(homeDir, context) {
24998
- const native = join7(homeDir, ".zcode/cli/config.json"), fallback = join7(homeDir, ".agents/mcp.json");
25234
+ const native = join8(homeDir, ".zcode/cli/config.json"), fallback = join8(homeDir, ".agents/mcp.json");
24999
25235
  const servers = (value, isNative) => isNative ? object2(object2(value, "mcp"), "servers") : object2(value, "mcpServers");
25000
25236
  const remove = Boolean(context.remove);
25001
25237
  const toFallback = !remove && !Object.keys(servers(readJson(native), true)).some((key) => key !== NAME) && Object.keys(servers(readJson(fallback), false)).length > 0;
@@ -25045,11 +25281,11 @@ var init_setup = __esm({
25045
25281
 
25046
25282
  // apps/body/dist/session-join/claude-inbound.js
25047
25283
  import { existsSync as existsSync4, readFileSync as readFileSync8, rmSync as rmSync5 } from "node:fs";
25048
- import { join as join8 } from "node:path";
25284
+ import { join as join9 } from "node:path";
25049
25285
  function assertClaudePolicy(env) {
25050
25286
  const paths = [
25051
25287
  env.CLAUDE_CODE_MANAGED_SETTINGS_PATH,
25052
- join8(claudeConfigDir(env), "managed-settings.json"),
25288
+ join9(claudeConfigDir(env), "managed-settings.json"),
25053
25289
  process.platform === "darwin" ? "/Library/Application Support/ClaudeCode/managed-settings.json" : "/etc/claude-code/managed-settings.json"
25054
25290
  ];
25055
25291
  for (const path of paths) {
@@ -25064,8 +25300,8 @@ async function acceptClaudeInbound(env) {
25064
25300
  const dir = stateDir(env);
25065
25301
  await withLock(dir, () => {
25066
25302
  assertClaudePolicy(env);
25067
- const path = join8(claudeConfigDir(env), "settings.json");
25068
- const saved = join8(dir, "claude-inbound.json");
25303
+ const path = join9(claudeConfigDir(env), "settings.json");
25304
+ const saved = join9(dir, "claude-inbound.json");
25069
25305
  const value = readJson(path);
25070
25306
  if (!existsSync4(saved))
25071
25307
  writeFile3(saved, JSON.stringify({ present: Object.hasOwn(value, "crossSessionInbound"), value: value.crossSessionInbound }));
@@ -25079,12 +25315,12 @@ async function restoreClaudeInbound(env) {
25079
25315
  await withLock(dir, () => {
25080
25316
  if (readState(dir).sessions.length)
25081
25317
  return;
25082
- const saved = join8(dir, "claude-inbound.json");
25318
+ const saved = join9(dir, "claude-inbound.json");
25083
25319
  if (!existsSync4(saved))
25084
25320
  return;
25085
25321
  assertClaudePolicy(env);
25086
25322
  const old = JSON.parse(readFileSync8(saved, "utf8"));
25087
- const path = join8(claudeConfigDir(env), "settings.json");
25323
+ const path = join9(claudeConfigDir(env), "settings.json");
25088
25324
  const value = readJson(path);
25089
25325
  if (value.crossSessionInbound === "accept") {
25090
25326
  if (old.present)
@@ -25106,10 +25342,10 @@ var init_claude_inbound = __esm({
25106
25342
  });
25107
25343
 
25108
25344
  // apps/body/dist/session-join/codex-trust.js
25109
- import { spawn as spawn6 } from "node:child_process";
25110
- import { join as join9 } from "node:path";
25345
+ import { spawn as spawn7 } from "node:child_process";
25346
+ import { join as join10 } from "node:path";
25111
25347
  function beelineTrustEdits(hooks, context) {
25112
- const path = join9(codexHome(context.env), "hooks.json");
25348
+ const path = join10(codexHome(context.env), "hooks.json");
25113
25349
  const expected = hookCommand(context, "codex", "session-start");
25114
25350
  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
25351
  if (own2.length !== 1)
@@ -25118,7 +25354,7 @@ function beelineTrustEdits(hooks, context) {
25118
25354
  return [{ keyPath: `hooks.state.${JSON.stringify(hook.key)}.trusted_hash`, value: hook.currentHash, mergeStrategy: "replace" }];
25119
25355
  }
25120
25356
  async function trustCodexHook(context, bin, cwd) {
25121
- const child = spawn6(bin, ["app-server", "--stdio"], { env: context.env, cwd, stdio: ["pipe", "pipe", "ignore"] });
25357
+ const child = spawn7(bin, ["app-server", "--stdio"], { env: context.env, cwd, stdio: ["pipe", "pipe", "ignore"] });
25122
25358
  let id = 0, buffer = "";
25123
25359
  const pending = /* @__PURE__ */ new Map();
25124
25360
  const fail = () => {
@@ -25156,9 +25392,9 @@ async function trustCodexHook(context, bin, cwd) {
25156
25392
  }
25157
25393
  }
25158
25394
  });
25159
- const request2 = (method, params) => new Promise((resolve11, reject) => {
25395
+ const request2 = (method, params) => new Promise((resolve13, reject) => {
25160
25396
  const key = ++id;
25161
- pending.set(key, { resolve: resolve11, reject: () => reject(new Error("Codex hook trust unavailable")) });
25397
+ pending.set(key, { resolve: resolve13, reject: () => reject(new Error("Codex hook trust unavailable")) });
25162
25398
  child.stdin.write(JSON.stringify({ id: key, method, params }) + "\n");
25163
25399
  });
25164
25400
  try {
@@ -25339,7 +25575,7 @@ var init_pull_apps = __esm({
25339
25575
  "use strict";
25340
25576
  init_store();
25341
25577
  init_beeline_api();
25342
- agentapi = (sessionId, text) => new Promise((resolve11, reject) => execFile4("agentapi", ["send-message", sessionId, text], { timeout: 3e4 }, (error) => error ? reject(error) : resolve11()));
25578
+ agentapi = (sessionId, text) => new Promise((resolve13, reject) => execFile4("agentapi", ["send-message", sessionId, text], { timeout: 3e4 }, (error) => error ? reject(error) : resolve13()));
25343
25579
  }
25344
25580
  });
25345
25581
 
@@ -25349,9 +25585,9 @@ __export(command_exports, {
25349
25585
  findOwnSession: () => findOwnSession,
25350
25586
  runSessionCommand: () => runSessionCommand
25351
25587
  });
25352
- import { spawn as spawn7, spawnSync as spawnSync2 } from "node:child_process";
25588
+ import { spawn as spawn8, spawnSync as spawnSync2 } from "node:child_process";
25353
25589
  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 dirname7, join as join10, resolve as resolve9 } from "node:path";
25590
+ import { delimiter, dirname as dirname8, join as join11, resolve as resolve11 } from "node:path";
25355
25591
  import { createHash as createHash7, randomUUID as randomUUID2 } from "node:crypto";
25356
25592
  function writePending(file, pending) {
25357
25593
  const temporary = file + "." + randomUUID2() + ".tmp";
@@ -25365,7 +25601,7 @@ function writePending(file, pending) {
25365
25601
  }
25366
25602
  renameSync4(temporary, file);
25367
25603
  if (process.platform !== "win32") {
25368
- const directory = openSync4(dirname7(file), "r");
25604
+ const directory = openSync4(dirname8(file), "r");
25369
25605
  try {
25370
25606
  fsyncSync(directory);
25371
25607
  } finally {
@@ -25379,14 +25615,14 @@ function writePending(file, pending) {
25379
25615
  function existingPending(dir, own2, server) {
25380
25616
  let names;
25381
25617
  try {
25382
- names = readdirSync6(join10(dir, "pending"));
25618
+ names = readdirSync6(join11(dir, "pending"));
25383
25619
  } catch {
25384
25620
  return;
25385
25621
  }
25386
25622
  if (names.length > 256)
25387
25623
  throw new Error("Too many pending Beeline sign-ins");
25388
25624
  return names.filter((name) => /^[a-f0-9]{24}\.json$/.test(name)).flatMap((name) => {
25389
- const file = join10(dir, "pending", name);
25625
+ const file = join11(dir, "pending", name);
25390
25626
  try {
25391
25627
  const pending = JSON.parse(readFileSync9(file, "utf8"));
25392
25628
  return pending.agent === own2.agent && pending.cwd === own2.cwd && pending.server === server && (!pending.sessionId || !own2.sessionId || pending.sessionId === own2.sessionId) ? [{ file, pending }] : [];
@@ -25411,7 +25647,7 @@ function words(args, valued) {
25411
25647
  }
25412
25648
  function which(bin, env) {
25413
25649
  for (const dir of (env.PATH ?? "").split(delimiter)) {
25414
- const path = join10(dir, bin);
25650
+ const path = join11(dir, bin);
25415
25651
  if (dir && existsSync5(path))
25416
25652
  return path;
25417
25653
  }
@@ -25420,8 +25656,8 @@ function which(bin, env) {
25420
25656
  function runner(dir, env) {
25421
25657
  if (env.BEELINE_SESSION_BUNDLE)
25422
25658
  return { node: process.execPath, bundle: env.BEELINE_SESSION_BUNDLE };
25423
- const bundle = join10(dir, "usebeeline.mjs");
25424
- const running = resolve9(process.argv[1] ?? "");
25659
+ const bundle = join11(dir, "usebeeline.mjs");
25660
+ const running = resolve11(process.argv[1] ?? "");
25425
25661
  if (running !== bundle && running.endsWith(".mjs")) {
25426
25662
  mkdirSync5(dir, { recursive: true, mode: 448 });
25427
25663
  copyFileSync2(running, bundle);
@@ -25474,6 +25710,7 @@ async function joinCommand(args, env) {
25474
25710
  const server = serverUrl(args, env);
25475
25711
  const existing = readState(dir).sessions.find((s) => s.key === key && s.server === server);
25476
25712
  if (existing) {
25713
+ let connected = false;
25477
25714
  try {
25478
25715
  await accessToken(dir, key);
25479
25716
  await updateState(dir, (state) => {
@@ -25483,10 +25720,13 @@ async function joinCommand(args, env) {
25483
25720
  s.pid = own2.pid ?? s.pid;
25484
25721
  }
25485
25722
  });
25486
- ensureBridge(dir, run2, env);
25723
+ connected = true;
25724
+ } catch {
25725
+ }
25726
+ if (connected) {
25727
+ await ensureBridge(dir, run2, env);
25487
25728
  console.log(`This ${agentLabel(own2.agent)} session is on Beeline as @${existing.handle ?? existing.name}. Tags in its Rooms arrive here.`);
25488
25729
  return;
25489
- } catch {
25490
25730
  }
25491
25731
  }
25492
25732
  const taken = new Set(readState(dir).sessions.filter((s) => s.key !== key).map((s) => s.name));
@@ -25511,14 +25751,14 @@ async function joinCommand(args, env) {
25511
25751
  startedAt: Date.now(),
25512
25752
  claudeInboundFallback: own2.claudeInboundFallback
25513
25753
  };
25514
- mkdirSync5(join10(dir, "pending"), { recursive: true, mode: 448 });
25515
- const file = join10(dir, "pending", `${createHash7("sha256").update(signIn.state).digest("hex").slice(0, 24)}.json`);
25754
+ mkdirSync5(join11(dir, "pending"), { recursive: true, mode: 448 });
25755
+ const file = join11(dir, "pending", `${createHash7("sha256").update(signIn.state).digest("hex").slice(0, 24)}.json`);
25516
25756
  if (!resume)
25517
25757
  writePending(file, pending);
25518
25758
  if (!resume && previous && previous.file !== file)
25519
25759
  rmSync6(previous.file, { force: true });
25520
- const out = join10(dir, "bridge.log");
25521
- const child = spawn7(run2.node, [run2.bundle, "session", "finish-join", file], { detached: true, stdio: "ignore", env: { ...env, BEELINE_SESSION_BUNDLE: run2.bundle } });
25760
+ const out = join11(dir, "bridge.log");
25761
+ const child = spawn8(run2.node, [run2.bundle, "session", "finish-join", file], { detached: true, stdio: "ignore", env: { ...env, BEELINE_SESSION_BUNDLE: run2.bundle } });
25522
25762
  child.unref();
25523
25763
  console.log([
25524
25764
  `Show your person this link. They open it on any device (a phone works) and sign in with GitHub or Google:`,
@@ -25595,7 +25835,7 @@ async function finishJoinOwned(file, env) {
25595
25835
  changes.splice(prompt, 1);
25596
25836
  changes.push("Trusted only Beeline\u2019s SessionStart hook, pinned to its current Codex hash.");
25597
25837
  }
25598
- ensureBridge(dir, run2, env);
25838
+ await ensureBridge(dir, run2, env);
25599
25839
  const rooms = me.rooms.map((r) => r.name).slice(0, 5).join(", ");
25600
25840
  await announce(joined2, `Beeline: you joined as @${joined2.handle ?? joined2.name}${rooms ? ` in ${rooms}` : ""}. When someone tags you there, the message arrives here with the command that answers it.${changes.length ? `
25601
25841
  (${changes.join("; ")})` : ""}
@@ -25643,7 +25883,7 @@ function own(args, env) {
25643
25883
  }
25644
25884
  async function ownTool(dir, joined2, name, args) {
25645
25885
  let bridged = await toolViaBridge(dir, joined2.key, name, args);
25646
- if (!bridged && existsSync5(join10(dir, "bridge.pid")) && process.cwd().startsWith(joined2.cwd))
25886
+ if (!bridged && existsSync5(join11(dir, "bridge.pid")) && process.cwd().startsWith(joined2.cwd))
25647
25887
  bridged = await toolViaOutbox(joined2.cwd, name, args);
25648
25888
  if (bridged) {
25649
25889
  if (!bridged.ok)
@@ -25689,7 +25929,7 @@ async function session(args, env) {
25689
25929
  if (out)
25690
25930
  process.stdout.write(out + "\n");
25691
25931
  if (event === "session-start" && readState(dir).sessions.length)
25692
- ensureBridge(dir, runner(dir, env), env);
25932
+ await ensureBridge(dir, runner(dir, env), env);
25693
25933
  } catch {
25694
25934
  }
25695
25935
  return;
@@ -25752,14 +25992,14 @@ async function session(args, env) {
25752
25992
  throw new Error("Usage: usebeeline join | usebeeline session reply|read|tool|status|leave");
25753
25993
  }
25754
25994
  function readStdin(_limitMs) {
25755
- return new Promise((resolve11) => {
25995
+ return new Promise((resolve13) => {
25756
25996
  let text = "";
25757
25997
  process.stdin.setEncoding("utf8");
25758
25998
  process.stdin.on("data", (chunk) => {
25759
25999
  text += chunk;
25760
26000
  });
25761
26001
  process.stdin.on("end", () => {
25762
- resolve11(text);
26002
+ resolve13(text);
25763
26003
  });
25764
26004
  });
25765
26005
  }
@@ -25797,19 +26037,19 @@ var init_command = __esm({
25797
26037
  init_setup();
25798
26038
  init_store();
25799
26039
  init_kernel_lock();
25800
- finisherKey = (file) => "beeline-session-sign-in:" + resolve9(file);
26040
+ finisherKey = (file) => "beeline-session-sign-in:" + resolve11(file);
25801
26041
  VALUED = ["--as", "--room", "--reply-to", "--server", "--name", "--session", "--state", "--limit"];
25802
26042
  }
25803
26043
  });
25804
26044
 
25805
26045
  // apps/body/dist/recovery-cli.js
25806
- import { spawn as spawn8 } from "node:child_process";
25807
- import { readFile as readFile4, readdir as readdir5, stat as stat3, unlink } from "node:fs/promises";
25808
- import { resolve as resolve10 } from "node:path";
26046
+ import { spawn as spawn9 } from "node:child_process";
26047
+ import { readFile as readFile5, readdir as readdir5, stat as stat3, unlink } from "node:fs/promises";
26048
+ import { resolve as resolve12 } from "node:path";
25809
26049
 
25810
26050
  // apps/body/dist/recovery.js
25811
- import { readFile as readFile3, readdir as readdir4, stat } from "node:fs/promises";
25812
- import { resolve as resolve8 } from "node:path";
26051
+ import { readFile as readFile4, readdir as readdir4, stat } from "node:fs/promises";
26052
+ import { resolve as resolve9 } from "node:path";
25813
26053
 
25814
26054
  // apps/body/dist/machine-control.js
25815
26055
  import { watch } from "node:fs";
@@ -26170,8 +26410,8 @@ async function prepareMachineRelease(layout, options = {}) {
26170
26410
  return withInstallLock(layout, () => prepareLatestRelease(layout, { ...options, deadlineAt }), {
26171
26411
  waitMs: Math.max(0, deadlineAt - Date.now())
26172
26412
  });
26173
- const stable = resolve8(layout.libDir, "../beeline-bootstrap.mjs");
26174
- const entrypoint = env.BEELINE_RECOVERY_ENTRY || await readFile3(stable).then(() => stable, () => process.argv[1]);
26413
+ const stable = resolve9(layout.libDir, "../beeline-bootstrap.mjs");
26414
+ const entrypoint = env.BEELINE_RECOVERY_ENTRY || await readFile4(stable).then(() => stable, () => process.argv[1]);
26175
26415
  return prepareReleaseInWorker({ ...env, ...options?.force ? { BEELINE_FORCE_REPAIR: "1" } : {} }, deadlineAt, entrypoint);
26176
26416
  }
26177
26417
  async function convergeMachine(options = {}) {
@@ -26179,9 +26419,9 @@ async function convergeMachine(options = {}) {
26179
26419
  assertLifecycleTestIsolation(env, Boolean(options.run));
26180
26420
  const layout = options.layout ?? beelineInstallLayout(env) ?? discoveredBeelineInstallLayout(env);
26181
26421
  const deadlineAt = options.deadlineAt ?? Date.now() + (options.timeoutMs ?? 6e5);
26182
- const stateRoot = env.XDG_STATE_HOME || resolve8(env.HOME || "", ".local/state");
26183
- const root = resolve8(stateRoot, "beeline/agents");
26184
- const configured = await Promise.all((await readdir4(root).catch(() => [])).filter((id) => /^[0-9a-f]{64}$/i.test(id)).map(async (id) => await stat(resolve8(root, id, "runtime.json")).then(() => true, () => false) && !await stat(resolve8(root, id, "stopped")).then(() => true, () => false) ? id : void 0));
26422
+ const stateRoot = env.XDG_STATE_HOME || resolve9(env.HOME || "", ".local/state");
26423
+ const root = resolve9(stateRoot, "beeline/agents");
26424
+ 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
26425
  const required = /* @__PURE__ */ new Set([
26186
26426
  ...configured.filter((id) => Boolean(id)),
26187
26427
  ...options.agentIds ?? []
@@ -26202,7 +26442,7 @@ async function convergeMachine(options = {}) {
26202
26442
  let expectedRelease = options.releaseId;
26203
26443
  const targetIdentity = options.releaseId ? await readInstalledBundleIdentity({
26204
26444
  ...layout,
26205
- libDir: resolve8(layout.releasesRoot, options.releaseId)
26445
+ libDir: resolve9(layout.releasesRoot, options.releaseId)
26206
26446
  }) : void 0;
26207
26447
  const request2 = options.releaseId && hasControl ? {
26208
26448
  operation: "update",
@@ -26239,8 +26479,8 @@ async function bootstrapMachine(env = process.env) {
26239
26479
  for (const id of [state.stagedReleaseId, active]) {
26240
26480
  if (!id || !/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(id))
26241
26481
  continue;
26242
- const digest = await readFile3(resolve8(layout.releasesRoot, id, ".stage-ok"), "utf8").catch(() => "");
26243
- if (/^[0-9a-f]{64}$/i.test(digest.trim()) && await resolveBundleEntrypoint(resolve8(layout.releasesRoot, id))) {
26482
+ const digest = await readFile4(resolve9(layout.releasesRoot, id, ".stage-ok"), "utf8").catch(() => "");
26483
+ if (/^[0-9a-f]{64}$/i.test(digest.trim()) && await resolveBundleEntrypoint(resolve9(layout.releasesRoot, id))) {
26244
26484
  releaseId = id;
26245
26485
  break;
26246
26486
  }
@@ -26256,7 +26496,7 @@ async function bootstrapMachine(env = process.env) {
26256
26496
  await withInstallLock(layout, () => activateRelease(layout, releaseId, { deferPruning: true }), {
26257
26497
  waitMs: Math.max(0, bootDeadlineAt - Date.now())
26258
26498
  });
26259
- const entry = await resolveBundleEntrypoint(resolve8(layout.releasesRoot, releaseId));
26499
+ const entry = await resolveBundleEntrypoint(resolve9(layout.releasesRoot, releaseId));
26260
26500
  if (!entry)
26261
26501
  throw new Error(`selected release ${releaseId} has no body entry`);
26262
26502
  return entry;
@@ -26322,18 +26562,18 @@ async function main() {
26322
26562
  if (args[i] === "--manifest-url" && !args[++i])
26323
26563
  throw new Error("--manifest-url requires a URL");
26324
26564
  }
26325
- const stateRoot2 = process.env.XDG_STATE_HOME || resolve10(process.env.HOME || "", ".local/state");
26565
+ const stateRoot2 = process.env.XDG_STATE_HOME || resolve12(process.env.HOME || "", ".local/state");
26326
26566
  if (args.includes("--status")) {
26327
26567
  const [native, helper] = await Promise.all([
26328
26568
  nativeHelperStatus(),
26329
26569
  requestMachine(stateRoot2, { operation: "status" }, () => true, 2e3).catch(() => void 0)
26330
26570
  ]);
26331
- const root = resolve10(stateRoot2, "beeline/agents");
26571
+ const root = resolve12(stateRoot2, "beeline/agents");
26332
26572
  const agents = await Promise.all((await readdir5(root).catch(() => [])).filter((id) => /^[0-9a-f]{64}$/.test(id)).map(async (id) => ({
26333
26573
  agentId: id,
26334
- enabled: !await stat3(resolve10(root, id, "stopped")).then(() => true, () => false),
26574
+ enabled: !await stat3(resolve12(root, id, "stopped")).then(() => true, () => false),
26335
26575
  ...helper?.agents[id] ?? { state: "not hosted" },
26336
- validRecord: await readFile4(resolve10(root, id, "runtime.json"), "utf8").then((raw) => Boolean(JSON.parse(raw).agent)).catch(() => false)
26576
+ validRecord: await readFile5(resolve12(root, id, "runtime.json"), "utf8").then((raw) => Boolean(JSON.parse(raw).agent)).catch(() => false)
26337
26577
  })));
26338
26578
  console.log(JSON.stringify({
26339
26579
  native,
@@ -26382,7 +26622,7 @@ async function main() {
26382
26622
  console.log(`[beeline] executing release ${status.loadedRelease}; helper ${status.pid}; every enabled agent serving`);
26383
26623
  return;
26384
26624
  }
26385
- const stateRoot = process.env.XDG_STATE_HOME || resolve10(process.env.HOME || "", ".local/state");
26625
+ const stateRoot = process.env.XDG_STATE_HOME || resolve12(process.env.HOME || "", ".local/state");
26386
26626
  let selectedRelease;
26387
26627
  if (command2 === "start") {
26388
26628
  for (let i = 1; i < args.length; i++) {
@@ -26397,13 +26637,13 @@ async function main() {
26397
26637
  const requested = agentFlag >= 0 ? args[agentFlag + 1] : args[1] && !args[1].startsWith("--") ? args[1] : void 0;
26398
26638
  if (agentFlag >= 0 && !requested)
26399
26639
  throw new Error("--agent requires an agent public key");
26400
- const agentRoot = resolve10(stateRoot, "beeline/agents");
26640
+ const agentRoot = resolve12(stateRoot, "beeline/agents");
26401
26641
  const ids = (await readdir5(agentRoot).catch(() => [])).filter((id) => /^[0-9a-f]{64}$/.test(id));
26402
26642
  const selected = requested ? ids.filter((id) => id.startsWith(requested)) : args.includes("--all") ? ids : [];
26403
26643
  if (requested && selected.length !== 1)
26404
26644
  throw new Error(`no unique paired agent matches ${requested}`);
26405
26645
  for (const id of selected)
26406
- await unlink(resolve10(agentRoot, id, "stopped")).catch((error) => {
26646
+ await unlink(resolve12(agentRoot, id, "stopped")).catch((error) => {
26407
26647
  if (error.code !== "ENOENT")
26408
26648
  throw error;
26409
26649
  });
@@ -26427,7 +26667,7 @@ async function main() {
26427
26667
  const entry = await resolveBundleEntrypoint(layout.libDir);
26428
26668
  if (!entry)
26429
26669
  throw new Error("no installed Beeline body; run npx usebeeline connect");
26430
- const child = spawn8(process.execPath, [entry, ...args], {
26670
+ const child = spawn9(process.execPath, [entry, ...args], {
26431
26671
  env: {
26432
26672
  ...process.env,
26433
26673
  BEELINE_LIB_DIR: layout.libDir,
@@ -26445,7 +26685,7 @@ async function convergeDependencies(layout, _deadlineAt) {
26445
26685
  if (!entry)
26446
26686
  throw new Error("dependency phase has no selected body");
26447
26687
  await new Promise((done, reject) => {
26448
- const child = spawn8(process.execPath, [entry, "converge-dependencies"], {
26688
+ const child = spawn9(process.execPath, [entry, "converge-dependencies"], {
26449
26689
  env: { ...process.env, BEELINE_LIB_DIR: layout.libDir, BEELINE_INTERNAL_RECOVERY: "1" },
26450
26690
  stdio: "inherit"
26451
26691
  });