usebeeline 0.0.33 → 0.0.35

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 +627 -193
  2. package/package.json +1 -1
@@ -309,12 +309,12 @@ __export(self_update_exports, {
309
309
  });
310
310
  import { createHash as createHash2 } from "node:crypto";
311
311
  import { constants as fsConstants } from "node:fs";
312
- import { access, chmod as chmod2, lstat as lstat2, mkdir as mkdir7, open, readFile as readFile3, rename as rename3, rm as rm4, symlink as symlink2, writeFile as writeFile4 } from "node:fs/promises";
312
+ import { access, chmod as chmod3, lstat as lstat2, mkdir as mkdir8, open, readFile as readFile4, rename as rename3, rm as rm4, symlink as symlink2, writeFile as writeFile5 } from "node:fs/promises";
313
313
  import { spawn as spawn4 } from "node:child_process";
314
- import { homedir as homedir7 } from "node:os";
315
- import { dirname as dirname7, join as join2, resolve as resolve13 } from "node:path";
314
+ import { homedir as homedir9 } from "node:os";
315
+ import { dirname as dirname8, join as join3, resolve as resolve14 } from "node:path";
316
316
  function anchorLayout(rawLibDir) {
317
- const libDir = resolve13(rawLibDir);
317
+ const libDir = resolve14(rawLibDir);
318
318
  const segments = libDir.split(/[/\\]/);
319
319
  const idx = segments.lastIndexOf(RELEASES_SEGMENT);
320
320
  if (idx >= 2 && segments[idx - 1] === "lib") {
@@ -330,9 +330,9 @@ function anchorLayout(rawLibDir) {
330
330
  // prefix's bin, NOT <prefix>/lib/bin — deriving it one level up was the
331
331
  // defect that made activateRelease write its stable forwarders where
332
332
  // nothing executed them, leaving stale raw wrappers in <prefix>/bin.
333
- binDir: resolve13(libDir, "../../bin"),
333
+ binDir: resolve14(libDir, "../../bin"),
334
334
  libDir,
335
- releasesRoot: resolve13(libDir, `../${RELEASES_SEGMENT}`)
335
+ releasesRoot: resolve14(libDir, `../${RELEASES_SEGMENT}`)
336
336
  };
337
337
  }
338
338
  function beelineInstallLayout(env = process.env) {
@@ -342,8 +342,8 @@ function beelineInstallLayout(env = process.env) {
342
342
  return anchorLayout(raw);
343
343
  }
344
344
  function defaultBeelineInstallLayout(env = process.env) {
345
- const home = env.HOME?.trim() || homedir7();
346
- return anchorLayout(resolve13(home, ".local", "lib", "beeline"));
345
+ const home = env.HOME?.trim() || homedir9();
346
+ return anchorLayout(resolve14(home, ".local", "lib", "beeline"));
347
347
  }
348
348
  function hostPlatformKey() {
349
349
  const os = process.platform === "linux" ? "linux" : process.platform === "darwin" ? "darwin" : "";
@@ -353,13 +353,13 @@ function hostPlatformKey() {
353
353
  return `${os}-${arch}`;
354
354
  }
355
355
  function bundleJsonCandidates(bundleDir) {
356
- return [join2(bundleDir, "lib", "beeline", "bundle.json"), join2(bundleDir, "bundle.json")];
356
+ return [join3(bundleDir, "lib", "beeline", "bundle.json"), join3(bundleDir, "bundle.json")];
357
357
  }
358
358
  async function readBundleJson(bundleDir) {
359
359
  let raw;
360
360
  for (const candidate of bundleJsonCandidates(bundleDir)) {
361
361
  try {
362
- raw = await readFile3(candidate, "utf8");
362
+ raw = await readFile4(candidate, "utf8");
363
363
  break;
364
364
  } catch {
365
365
  }
@@ -377,18 +377,18 @@ async function readBundleJson(bundleDir) {
377
377
  }
378
378
  }
379
379
  function updateStatePath(layout) {
380
- return join2(layout.releasesRoot, ".state", "update-state.json");
380
+ return join3(layout.releasesRoot, ".state", "update-state.json");
381
381
  }
382
382
  async function readUpdateState(layout) {
383
383
  try {
384
- return JSON.parse(await readFile3(updateStatePath(layout), "utf8"));
384
+ return JSON.parse(await readFile4(updateStatePath(layout), "utf8"));
385
385
  } catch {
386
386
  return {};
387
387
  }
388
388
  }
389
389
  async function writeUpdateState(layout, state) {
390
- await mkdir7(join2(layout.releasesRoot, ".state"), { recursive: true });
391
- await writeFile4(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
390
+ await mkdir8(join3(layout.releasesRoot, ".state"), { recursive: true });
391
+ await writeFile5(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
392
392
  `, "utf8");
393
393
  }
394
394
  async function readInstalledBundleIdentity(layout, _state = {}) {
@@ -469,7 +469,7 @@ function run(command, args, timeoutMs) {
469
469
  });
470
470
  }
471
471
  function entrypointCandidates(bundleDir) {
472
- return [join2(bundleDir, BUNDLE_ENTRYPOINT), join2(bundleDir, "beeline-cli.mjs")];
472
+ return [join3(bundleDir, BUNDLE_ENTRYPOINT), join3(bundleDir, "beeline-cli.mjs")];
473
473
  }
474
474
  async function resolveBundleEntrypoint(bundleDir) {
475
475
  for (const candidate of entrypointCandidates(bundleDir)) {
@@ -491,18 +491,18 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
491
491
  const fetchImpl = opts.fetchImpl ?? fetch;
492
492
  const log = opts.logger ?? ((line) => console.log(`[body] self-update: ${line}`));
493
493
  const releaseId = sanitizeReleaseId(published.commit ?? published.version ?? `release-${Date.now()}`);
494
- const releaseDir = join2(layout.releasesRoot, releaseId);
495
- const okMarker = join2(releaseDir, ".stage-ok");
494
+ const releaseDir = join3(layout.releasesRoot, releaseId);
495
+ const okMarker = join3(releaseDir, ".stage-ok");
496
496
  let previouslyVerified = false;
497
497
  try {
498
- const recorded = await readFile3(okMarker, "utf8");
498
+ const recorded = await readFile4(okMarker, "utf8");
499
499
  if (recorded.trim() === published.sha256)
500
500
  return releaseId;
501
501
  previouslyVerified = true;
502
502
  } catch {
503
503
  }
504
- await mkdir7(releaseDir, { recursive: true });
505
- const tempArchive = join2(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
504
+ await mkdir8(releaseDir, { recursive: true });
505
+ const tempArchive = join3(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
506
506
  try {
507
507
  log(`downloading ${published.file}`);
508
508
  const response = await fetchImpl(archiveUrlFor(manifestUrl, published.file), {
@@ -522,7 +522,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
522
522
  if (actual !== published.sha256.toLowerCase()) {
523
523
  throw new Error(`checksum mismatch for ${published.file}: expected ${published.sha256}, got ${actual} \u2014 aborting without touching the installed bundle`);
524
524
  }
525
- await writeFile4(tempArchive, Buffer.concat(chunks), { mode: 384 });
525
+ await writeFile5(tempArchive, Buffer.concat(chunks), { mode: 384 });
526
526
  const entries = (await new Promise((resolveList, rejectList) => {
527
527
  const child = spawn4("tar", ["-tzf", tempArchive], { stdio: ["ignore", "pipe", "inherit"] });
528
528
  let out = "";
@@ -542,18 +542,18 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
542
542
  throw new Error(`extracting bundle failed: ${extract2.stderr}`);
543
543
  for (const relative3 of requiredBundlePaths()) {
544
544
  try {
545
- await access(join2(releaseDir, relative3), fsConstants.F_OK);
545
+ await access(join3(releaseDir, relative3), fsConstants.F_OK);
546
546
  } catch {
547
547
  throw new Error(`staged bundle is missing ${relative3}`);
548
548
  }
549
549
  }
550
550
  if (opts.smokeTestCli !== false) {
551
- const probe = await run(process.execPath, [join2(releaseDir, BUNDLE_ENTRYPOINT), "--version"], 6e4);
551
+ const probe = await run(process.execPath, [join3(releaseDir, BUNDLE_ENTRYPOINT), "--version"], 6e4);
552
552
  if (probe.status !== 0) {
553
553
  throw new Error(`staged bundle failed its startup smoke test (--version exited ${probe.status})${probe.stderr ? `: ${probe.stderr.trim()}` : ""}`);
554
554
  }
555
555
  }
556
- await writeFile4(okMarker, `${published.sha256}
556
+ await writeFile5(okMarker, `${published.sha256}
557
557
  `, "utf8");
558
558
  log(`staged release ${releaseId} (sha256 verified)`);
559
559
  return releaseId;
@@ -581,26 +581,26 @@ function forwarderScript(tool) {
581
581
  }
582
582
  async function replaceFile(path, contents, mode) {
583
583
  const temp = `${path}.new-${process.pid}`;
584
- await writeFile4(temp, contents, { mode });
585
- await chmod2(temp, mode);
584
+ await writeFile5(temp, contents, { mode });
585
+ await chmod3(temp, mode);
586
586
  await rename3(temp, path);
587
587
  }
588
588
  async function activateRelease(layout, releaseId) {
589
- const releaseDir = join2(layout.releasesRoot, releaseId);
590
- await access(join2(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
591
- await mkdir7(layout.releasesRoot, { recursive: true });
592
- await mkdir7(layout.binDir, { recursive: true });
589
+ const releaseDir = join3(layout.releasesRoot, releaseId);
590
+ await access(join3(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
591
+ await mkdir8(layout.releasesRoot, { recursive: true });
592
+ await mkdir8(layout.binDir, { recursive: true });
593
593
  let previousReleaseId = await activeReleaseId(layout);
594
594
  const kind = await pathKind(layout.libDir);
595
595
  if (kind === "directory") {
596
596
  const legacyIdentity = await readBundleJson(layout.libDir);
597
597
  const legacyId = sanitizeReleaseId(legacyIdentity?.commit ?? legacyIdentity?.version ?? `legacy-${Date.now()}`);
598
- const legacyDir = join2(layout.releasesRoot, legacyId);
598
+ const legacyDir = join3(layout.releasesRoot, legacyId);
599
599
  try {
600
600
  await access(legacyDir, fsConstants.F_OK);
601
601
  previousReleaseId = `${legacyId}-${Date.now()}`;
602
- await rename3(layout.libDir, join2(layout.releasesRoot, previousReleaseId));
603
- await normalizeLegacyBundleShape(join2(layout.releasesRoot, previousReleaseId));
602
+ await rename3(layout.libDir, join3(layout.releasesRoot, previousReleaseId));
603
+ await normalizeLegacyBundleShape(join3(layout.releasesRoot, previousReleaseId));
604
604
  } catch {
605
605
  await rename3(layout.libDir, legacyDir);
606
606
  await normalizeLegacyBundleShape(legacyDir);
@@ -609,18 +609,18 @@ async function activateRelease(layout, releaseId) {
609
609
  }
610
610
  const tempLink = `${layout.libDir}.new-${process.pid}`;
611
611
  await rm4(tempLink, { force: true });
612
- await symlink2(join2("beeline-releases", releaseId), tempLink);
612
+ await symlink2(join3("beeline-releases", releaseId), tempLink);
613
613
  await rename3(tempLink, layout.libDir);
614
- await fsyncDir(dirname7(layout.libDir));
614
+ await fsyncDir(dirname8(layout.libDir));
615
615
  await writeBinForwarders(layout, releaseDir);
616
616
  return { previousReleaseId };
617
617
  }
618
618
  async function normalizeLegacyBundleShape(bundleDir) {
619
- const innerLib = join2(bundleDir, "lib", "beeline");
619
+ const innerLib = join3(bundleDir, "lib", "beeline");
620
620
  let anyFlat = false;
621
621
  for (const name of LEGACY_FLAT_BUNDLE_FILES) {
622
622
  try {
623
- await access(join2(bundleDir, name), fsConstants.F_OK);
623
+ await access(join3(bundleDir, name), fsConstants.F_OK);
624
624
  anyFlat = true;
625
625
  break;
626
626
  } catch {
@@ -628,62 +628,62 @@ async function normalizeLegacyBundleShape(bundleDir) {
628
628
  }
629
629
  if (!anyFlat)
630
630
  return;
631
- await mkdir7(innerLib, { recursive: true });
631
+ await mkdir8(innerLib, { recursive: true });
632
632
  for (const name of LEGACY_FLAT_BUNDLE_FILES) {
633
633
  try {
634
- await access(join2(innerLib, name), fsConstants.F_OK);
634
+ await access(join3(innerLib, name), fsConstants.F_OK);
635
635
  continue;
636
636
  } catch {
637
637
  }
638
- await rename3(join2(bundleDir, name), join2(innerLib, name)).catch(() => void 0);
638
+ await rename3(join3(bundleDir, name), join3(innerLib, name)).catch(() => void 0);
639
639
  }
640
640
  }
641
641
  async function writeBinForwarders(layout, activeBundleRoot) {
642
642
  for (const tool of FORWARDER_TOOLS) {
643
- const target = join2(activeBundleRoot, "bin", tool);
643
+ const target = join3(activeBundleRoot, "bin", tool);
644
644
  try {
645
645
  await access(target, fsConstants.X_OK);
646
646
  } catch {
647
647
  continue;
648
648
  }
649
- await replaceFile(join2(layout.binDir, tool), forwarderScript(tool), 493);
649
+ await replaceFile(join3(layout.binDir, tool), forwarderScript(tool), 493);
650
650
  }
651
651
  }
652
652
  async function repairInstallForwarders(layout, opts = {}) {
653
653
  if (await pathKind(layout.libDir) !== "symlink")
654
654
  return false;
655
- const forwarderPath = join2(layout.binDir, "beeline");
655
+ const forwarderPath = join3(layout.binDir, "beeline");
656
656
  let current;
657
657
  try {
658
- current = await readFile3(forwarderPath, "utf8");
658
+ current = await readFile4(forwarderPath, "utf8");
659
659
  } catch {
660
660
  current = void 0;
661
661
  }
662
662
  if (current === forwarderScript("beeline"))
663
663
  return false;
664
- await mkdir7(layout.binDir, { recursive: true });
664
+ await mkdir8(layout.binDir, { recursive: true });
665
665
  await writeBinForwarders(layout, layout.libDir);
666
666
  opts.logger?.(`[body] self-update: repaired <prefix>/bin forwarders to follow the active-bundle anchor (${layout.libDir})`);
667
667
  return true;
668
668
  }
669
669
  async function rollbackToPreviousRelease(layout, previousReleaseId) {
670
- const releaseDir = join2(layout.releasesRoot, previousReleaseId);
670
+ const releaseDir = join3(layout.releasesRoot, previousReleaseId);
671
671
  const entrypoint = await resolveBundleEntrypoint(releaseDir);
672
672
  if (!entrypoint) {
673
673
  throw new Error(`release ${previousReleaseId} has no runnable CLI entrypoint`);
674
674
  }
675
675
  const tempLink = `${layout.libDir}.rollback-${process.pid}`;
676
676
  await rm4(tempLink, { force: true });
677
- await symlink2(join2("beeline-releases", previousReleaseId), tempLink);
677
+ await symlink2(join3("beeline-releases", previousReleaseId), tempLink);
678
678
  await rename3(tempLink, layout.libDir);
679
- await fsyncDir(dirname7(layout.libDir));
679
+ await fsyncDir(dirname8(layout.libDir));
680
680
  }
681
681
  function updateAttemptPath(layout) {
682
- return join2(layout.releasesRoot, ".state", "update-attempt.json");
682
+ return join3(layout.releasesRoot, ".state", "update-attempt.json");
683
683
  }
684
684
  async function readUpdateAttempt(layout) {
685
685
  try {
686
- const raw = JSON.parse(await readFile3(updateAttemptPath(layout), "utf8"));
686
+ const raw = JSON.parse(await readFile4(updateAttemptPath(layout), "utf8"));
687
687
  if (raw.version !== 1 || typeof raw.appliedAt !== "number" || typeof raw.confirmBy !== "number" || typeof raw.releaseId !== "string" || !["pending", "confirmed", "reverted"].includes(raw.status)) {
688
688
  return void 0;
689
689
  }
@@ -693,10 +693,10 @@ async function readUpdateAttempt(layout) {
693
693
  }
694
694
  }
695
695
  async function writeUpdateAttempt(layout, record2) {
696
- await mkdir7(join2(layout.releasesRoot, ".state"), { recursive: true });
696
+ await mkdir8(join3(layout.releasesRoot, ".state"), { recursive: true });
697
697
  const path = updateAttemptPath(layout);
698
698
  const staged = `${path}.${process.pid}.tmp`;
699
- await writeFile4(staged, `${JSON.stringify(record2, null, 2)}
699
+ await writeFile5(staged, `${JSON.stringify(record2, null, 2)}
700
700
  `, { mode: 384 });
701
701
  await rename3(staged, path);
702
702
  }
@@ -955,8 +955,8 @@ var init_self_update = __esm({
955
955
  });
956
956
 
957
957
  // apps/body/dist/cli.js
958
- import { dirname as dirname12, resolve as resolve20 } from "node:path";
959
- import { readFile as readFile8, unlink as unlink3, writeFile as writeFile10 } from "node:fs/promises";
958
+ import { dirname as dirname13, resolve as resolve21 } from "node:path";
959
+ import { readFile as readFile9, unlink as unlink3, writeFile as writeFile11 } from "node:fs/promises";
960
960
  import { stdin as stdin4, stdout as stdout5 } from "node:process";
961
961
 
962
962
  // node_modules/@clack/core/dist/index.mjs
@@ -2327,8 +2327,9 @@ import { accessSync as accessSync2, constants as constants2, existsSync as exist
2327
2327
  import { basename, dirname, resolve as resolve2 } from "node:path";
2328
2328
 
2329
2329
  // apps/body/dist/agent-command.js
2330
- import { accessSync, constants, existsSync } from "node:fs";
2331
- import { delimiter, isAbsolute, resolve } from "node:path";
2330
+ import { accessSync, constants, existsSync, readdirSync } from "node:fs";
2331
+ import { homedir } from "node:os";
2332
+ import { delimiter, isAbsolute, join, resolve } from "node:path";
2332
2333
  var AGENT_KINDS = [
2333
2334
  "codex",
2334
2335
  "claude",
@@ -2363,13 +2364,74 @@ var ADAPTER_INSTALL_COMMANDS = {
2363
2364
  function adapterInstallHint(kind) {
2364
2365
  return formatAdapterInstallCommand(ADAPTER_INSTALL_COMMANDS[kind]);
2365
2366
  }
2367
+ function nodeVersionRank(name) {
2368
+ const match = /^v?(\d+)\.(\d+)\.(\d+)$/.exec(name);
2369
+ if (!match)
2370
+ return void 0;
2371
+ return [Number(match[1] ?? 0), Number(match[2] ?? 0), Number(match[3] ?? 0)];
2372
+ }
2373
+ function nodeVersionBins(versionsDir, binSuffix) {
2374
+ let entries;
2375
+ try {
2376
+ entries = readdirSync(versionsDir);
2377
+ } catch {
2378
+ return [];
2379
+ }
2380
+ return entries.map((name) => ({ name, rank: nodeVersionRank(name) })).filter((entry) => Boolean(entry.rank)).sort((a2, b) => {
2381
+ for (let i3 = 0; i3 < 3; i3 += 1) {
2382
+ const delta = (b.rank[i3] ?? 0) - (a2.rank[i3] ?? 0);
2383
+ if (delta !== 0)
2384
+ return delta;
2385
+ }
2386
+ return 0;
2387
+ }).map((entry) => join(versionsDir, entry.name, binSuffix));
2388
+ }
2389
+ function wellKnownExecutableDirs(env = process.env) {
2390
+ const home = env.HOME?.trim() || homedir();
2391
+ const xdgData = env.XDG_DATA_HOME?.trim() || resolve(home, ".local", "share");
2392
+ const fnmRoots = [
2393
+ env.FNM_DIR?.trim(),
2394
+ resolve(xdgData, "fnm"),
2395
+ resolve(home, ".fnm")
2396
+ ].filter((root) => Boolean(root));
2397
+ const nvmRoots = [env.NVM_DIR?.trim(), resolve(home, ".nvm")].filter((root) => Boolean(root));
2398
+ const versioned = [];
2399
+ for (const root of fnmRoots) {
2400
+ versioned.push(...nodeVersionBins(join(root, "node-versions"), "installation/bin"));
2401
+ }
2402
+ for (const root of nvmRoots) {
2403
+ versioned.push(...nodeVersionBins(join(root, "versions", "node"), "bin"));
2404
+ }
2405
+ return [
2406
+ ...versioned,
2407
+ resolve(home, ".local", "bin"),
2408
+ "/usr/local/bin",
2409
+ "/opt/homebrew/bin"
2410
+ ];
2411
+ }
2412
+ function augmentedSearchDirectories(env = process.env) {
2413
+ const directories = [];
2414
+ const pushAll = (paths) => {
2415
+ for (const directory of paths) {
2416
+ if (directory && !directories.includes(directory))
2417
+ directories.push(directory);
2418
+ }
2419
+ };
2420
+ pushAll((env.PATH ?? "").split(delimiter));
2421
+ if (env.BEELINE_HARNESS_PATH_AUGMENT === "0")
2422
+ return directories;
2423
+ pushAll(wellKnownExecutableDirs(env));
2424
+ pushAll((env.BEELINE_LAUNCHER_PATH ?? "").split(delimiter));
2425
+ return directories;
2426
+ }
2427
+ function describeExecutableSearch(env = process.env) {
2428
+ return augmentedSearchDirectories(env).join(", ");
2429
+ }
2366
2430
  function firstExisting(paths) {
2367
2431
  return paths.find((path) => path && existsSync(path));
2368
2432
  }
2369
2433
  function executableOnPath(name, env = process.env) {
2370
- for (const directory of (env.PATH ?? "").split(delimiter)) {
2371
- if (!directory)
2372
- continue;
2434
+ for (const directory of augmentedSearchDirectories(env)) {
2373
2435
  const candidate = resolve(directory, name);
2374
2436
  try {
2375
2437
  accessSync(candidate, constants.X_OK);
@@ -2389,7 +2451,7 @@ function requireExecutable(command, env, cwd, missingMessage) {
2389
2451
  } catch {
2390
2452
  }
2391
2453
  }
2392
- throw new Error(missingMessage);
2454
+ throw new Error(`${missingMessage} Searched: ${describeExecutableSearch(env)}.`);
2393
2455
  }
2394
2456
  function parseAgentCommand(value) {
2395
2457
  const words = [];
@@ -3644,7 +3706,7 @@ var AcpClient = class extends EventEmitter {
3644
3706
  const current = this.activeRunIds.get(sessionId);
3645
3707
  if (current)
3646
3708
  return Promise.resolve(current);
3647
- return new Promise((resolve21, reject) => {
3709
+ return new Promise((resolve22, reject) => {
3648
3710
  const onUpdate = (update) => {
3649
3711
  if (update.sessionId !== sessionId)
3650
3712
  return;
@@ -3652,7 +3714,7 @@ var AcpClient = class extends EventEmitter {
3652
3714
  if (!runId)
3653
3715
  return;
3654
3716
  cleanup();
3655
- resolve21(runId);
3717
+ resolve22(runId);
3656
3718
  };
3657
3719
  const timer = setTimeout(() => {
3658
3720
  cleanup();
@@ -3736,13 +3798,13 @@ var AcpClient = class extends EventEmitter {
3736
3798
  }
3737
3799
  const id = this.nextId++;
3738
3800
  const payload = { jsonrpc: "2.0", id, method, params };
3739
- return new Promise((resolve21, reject) => {
3801
+ return new Promise((resolve22, reject) => {
3740
3802
  const timer = setTimeout(() => {
3741
3803
  this.pending.delete(id);
3742
3804
  reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, Boolean(onStart)));
3743
3805
  }, timeoutMs);
3744
3806
  this.pending.set(id, {
3745
- resolve: resolve21,
3807
+ resolve: resolve22,
3746
3808
  reject,
3747
3809
  timer,
3748
3810
  method,
@@ -4075,7 +4137,13 @@ async function withAgentModelCatalog(agent, agentEnv, selection, inspect) {
4075
4137
  agentCommand: agent.command,
4076
4138
  agentArgs: agentArgsWithModelSelection(agent, selection),
4077
4139
  agentEnv,
4078
- agentCwd: scratchCwd
4140
+ agentCwd: scratchCwd,
4141
+ // The wizard probe runs on the human's own machine for a few seconds —
4142
+ // inherit the caller's environment so harness launchers resolve (`pi`,
4143
+ // `pi-acp`, `claude-agent-acp`'s `env node`) and fnm/homebrew toolchains
4144
+ // work. Daemon sessions keep the allowlisted-env boundary; only this
4145
+ // probe opts in.
4146
+ inheritProcessEnv: true
4079
4147
  });
4080
4148
  try {
4081
4149
  await client.start();
@@ -4153,14 +4221,14 @@ import { promisify as promisify3 } from "node:util";
4153
4221
  // apps/body/dist/monolith-corner-turn.js
4154
4222
  import { execFile as execFile2 } from "node:child_process";
4155
4223
  import { mkdir as mkdir3 } from "node:fs/promises";
4156
- import { homedir as homedir4 } from "node:os";
4224
+ import { homedir as homedir5 } from "node:os";
4157
4225
  import { promisify as promisify2 } from "node:util";
4158
4226
 
4159
4227
  // apps/body/dist/agent-home.js
4160
4228
  import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
4161
4229
  import { randomUUID } from "node:crypto";
4162
4230
  import { chmod, copyFile, lstat, mkdir, readdir, realpath, rename, rm as rm2, symlink, unlink, writeFile } from "node:fs/promises";
4163
- import { homedir } from "node:os";
4231
+ import { homedir as homedir2 } from "node:os";
4164
4232
  import { basename as basename3, dirname as dirname2, relative, resolve as resolve6, sep } from "node:path";
4165
4233
 
4166
4234
  // apps/body/dist/beeline-skill.js
@@ -4172,18 +4240,31 @@ var BEELINE_ROOM_CAPABILITIES = [
4172
4240
  "You may address any Room member, including another agent, by writing @name in your reply; the server routes that mention to them.",
4173
4241
  "Tag another agent only when you need something from them: a question, a handoff, a task. Never tag to acknowledge, agree, or say you are ready. If nothing is actionable, do not reply.",
4174
4242
  "Tag the user only when you need a decision or input, or when the task they asked for is finished. Never tag for progress, acknowledgement, or questions the transcript already answers.",
4175
- "The beeline-readonly-mcp inspection tools and beeline-agent Room action tools are mounted. You can use beeline-readonly-mcp to search and read the bound repository without opening a corner; beeline-agent provides the host-governed Room actions.",
4243
+ "Every MCP server mounted into this session is approved tool by tool - use operator and host tools freely; the read-only filesystem sandbox is the boundary, not a tool list. Network web search is enabled.",
4176
4244
  "To send a file, call beeline-agent attach_file with a path inside your checkout; it is attached to your reply.",
4245
+ "To run something later or repeatedly, call beeline-agent create_schedule (interval in minutes or a 5-field cron, optional maxRuns); list_schedules / delete_schedule manage them.",
4177
4246
  "When repository work is needed, you MUST call beeline-agent open_corner with a one-paragraph summary of the complete objective. The host-governed call is the only way to start write work.",
4178
4247
  "Never claim an action or reply happened unless the prompt or a tool result proves it."
4179
4248
  ].join(" ");
4180
- function beelinePrimer(repository) {
4249
+ var BEELINE_DM_CAPABILITIES = [
4250
+ "This is a private direct-message conversation with one person. Every message they send is addressed to you; reply without tagging.",
4251
+ "This Room is strictly conversational: there is no repository binding and no corner can be opened from here.",
4252
+ "The repository filesystem is read-only in this session.",
4253
+ "Every MCP server mounted into this session is approved tool by tool - use operator and host tools freely; the read-only filesystem sandbox is the boundary, not a tool list. Network web search is enabled.",
4254
+ "To send a file, call beeline-agent attach_file with a path inside your checkout; it is attached to your reply.",
4255
+ "Tag the person only when you need a decision or input, or when the task they asked for is finished.",
4256
+ "Never claim an action or reply happened unless the prompt or a tool result proves it."
4257
+ ].join(" ");
4258
+ function beelinePrimer(repository, directMessage) {
4259
+ if (directMessage) {
4260
+ return `Consult the release-versioned using-beeline skill (SKILL.md) when you need the managed Room mechanics. ${BEELINE_DM_CAPABILITIES}`;
4261
+ }
4181
4262
  const repositoryLine = repository ? ` This Room is bound to ${repository.name} (branch ${repository.branch}); you have a read-only checkout at the session root.` : "";
4182
4263
  return `Consult the release-versioned using-beeline skill (SKILL.md) when you need the managed Room mechanics. ${BEELINE_ROOM_CAPABILITIES}${repositoryLine}`;
4183
4264
  }
4184
4265
  var BEELINE_CAPABILITIES_PRIMER = beelinePrimer();
4185
- function beelineCapabilityContextForHarness(agentCommand, repository) {
4186
- const primer = beelinePrimer(repository);
4266
+ function beelineCapabilityContextForHarness(agentCommand, repository, directMessage) {
4267
+ const primer = beelinePrimer(repository, directMessage);
4187
4268
  return {
4188
4269
  sessionPrompt: primer,
4189
4270
  ...harnessHonorsSessionSystemPrompt(agentCommand) ? {} : { compatibilityTurnPrefix: primer }
@@ -4210,7 +4291,7 @@ description: How to answer inside a Beeline Room.
4210
4291
 
4211
4292
  # Using Beeline
4212
4293
 
4213
- You are answering inside a read-only Room. ${BEELINE_ROOM_CAPABILITIES}
4294
+ You are answering inside a Room whose filesystem is read-only. ${BEELINE_ROOM_CAPABILITIES}
4214
4295
  `;
4215
4296
  }
4216
4297
 
@@ -4391,7 +4472,12 @@ var SHARED_CREDENTIALS = [
4391
4472
  var BEELINE_DEFAULT_SKILL_NAMES = [
4392
4473
  USING_BEELINE_SKILL_NAME
4393
4474
  ];
4394
- var EXPLICIT_SKILL_SOURCE_DIRS = [".agents/skills"];
4475
+ var OPERATOR_SKILL_SOURCE_DIRS = [
4476
+ ".agents/skills",
4477
+ ".claude/skills",
4478
+ ".codex/skills",
4479
+ ".pi/agent/skills"
4480
+ ];
4395
4481
  var AGENT_SKILL_DIRS = ["claude", "codex", "grok", "pi"];
4396
4482
  var SHARED_SKILL_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
4397
4483
  function isSharedSkillName(value) {
@@ -4409,10 +4495,11 @@ var PI_CUSTOM_MODEL_CONFIG = {
4409
4495
  target: "models.json"
4410
4496
  };
4411
4497
  var CODEX_ROOM_AGENT_LOCKDOWN_TOML = "[agents]\nenabled = false\n";
4498
+ var CODEX_ROOM_WEB_SEARCH_TOML = "[features]\nstandalone_web_search = true\n";
4412
4499
  var HOME_SUBDIRS = ["user", "claude", "codex", "grok", "pi", "state", "cache", "tmp"];
4413
4500
  async function prepareRoomAgentHome(input) {
4414
4501
  const root = resolve6(input.root);
4415
- const operatorHome = input.operatorHome ?? homedir();
4502
+ const operatorHome = input.operatorHome ?? homedir2();
4416
4503
  try {
4417
4504
  await mkdir(root, { recursive: true, mode: 448 });
4418
4505
  const rootStats = await lstat(root);
@@ -4452,17 +4539,17 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
4452
4539
  const managedSkills = [
4453
4540
  { name: USING_BEELINE_SKILL_NAME, content: usingBeelineSkillMarkdown(skillReleaseId) }
4454
4541
  ];
4455
- const shared = await resolveExplicitSkillSources(operatorHome, sharedSkills);
4542
+ const shared = await resolveSharedSkillSources(operatorHome, sharedSkills);
4456
4543
  for (const dir of AGENT_SKILL_DIRS) {
4457
4544
  const target = resolve6(root, dir, "skills");
4458
- await provisionManagedSkillsDir(target, managedSkills, shared);
4545
+ await provisionManagedSkillsDir(target, managedSkills, shared, sharedSkills.length === 0);
4459
4546
  }
4460
4547
  for (const config of HARNESS_MCP_CONFIGS) {
4461
4548
  try {
4462
4549
  const source = resolve6(operatorHome, config.toml);
4463
4550
  const target = resolve6(root, config.dir, "config.toml");
4464
4551
  const mcpSection = existsSync3(source) ? filteredHarnessMcpToml(readFileSync4(source, "utf8")) : void 0;
4465
- const section = config.dir === "codex" ? [CODEX_ROOM_AGENT_LOCKDOWN_TOML, mcpSection].filter(Boolean).join("\n") : mcpSection;
4552
+ const section = config.dir === "codex" ? [CODEX_ROOM_AGENT_LOCKDOWN_TOML, CODEX_ROOM_WEB_SEARCH_TOML, mcpSection].filter(Boolean).join("\n") : mcpSection;
4466
4553
  if (!section) {
4467
4554
  await unlink(target).catch(() => void 0);
4468
4555
  continue;
@@ -4489,6 +4576,15 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
4489
4576
  throw error;
4490
4577
  console.warn("[body] operator MCP passthrough failed for claude:", error);
4491
4578
  }
4579
+ try {
4580
+ const settings2 = { permissions: { allow: ["WebSearch"] } };
4581
+ await writeIsolatedHarnessFile(resolve6(root, "claude", "settings.json"), `${JSON.stringify(settings2, null, 2)}
4582
+ `);
4583
+ } catch (error) {
4584
+ if (failClosed)
4585
+ throw error;
4586
+ console.warn("[body] claude web-search settings provisioning failed:", error);
4587
+ }
4492
4588
  await provisionPiCustomModelConfig(root, operatorHome, failClosed);
4493
4589
  }
4494
4590
  async function provisionPiCustomModelConfig(root, operatorHome, failClosed) {
@@ -4540,7 +4636,7 @@ function filteredHarnessMcpToml(source) {
4540
4636
  });
4541
4637
  return extractTomlSections(source, ["mcp_servers"], excluded);
4542
4638
  }
4543
- async function provisionManagedSkillsDir(target, managedSkills, sharedSkills) {
4639
+ async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, optionalShares) {
4544
4640
  const parent = dirname2(target);
4545
4641
  await assertRealContainedDirectory(parent, dirname2(parent));
4546
4642
  const staged = resolve6(parent, `.skills.${process.pid}.${randomUUID()}.tmp`);
@@ -4557,7 +4653,13 @@ async function provisionManagedSkillsDir(target, managedSkills, sharedSkills) {
4557
4653
  throw new Error(`shared skill collides with Beeline-owned skill: ${shared.name}`);
4558
4654
  }
4559
4655
  names.add(shared.name);
4560
- await copySafeSkillTree(shared.source, resolve6(staged, shared.name), shared.source);
4656
+ try {
4657
+ await copySafeSkillTree(shared.source, resolve6(staged, shared.name), shared.source);
4658
+ } catch (error) {
4659
+ if (!optionalShares)
4660
+ throw error;
4661
+ console.warn(`[body] skipping shared skill ${shared.name}:`, error);
4662
+ }
4561
4663
  }
4562
4664
  const existing = await lstat(target).catch(() => void 0);
4563
4665
  if (existing)
@@ -4567,6 +4669,39 @@ async function provisionManagedSkillsDir(target, managedSkills, sharedSkills) {
4567
4669
  await rm2(staged, { recursive: true, force: true });
4568
4670
  }
4569
4671
  }
4672
+ async function resolveSharedSkillSources(operatorHome, names) {
4673
+ if (names.length > 0)
4674
+ return resolveExplicitSkillSources(operatorHome, names);
4675
+ const seen = /* @__PURE__ */ new Set();
4676
+ const resolved = [];
4677
+ for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
4678
+ const sourceRoot = resolve6(operatorHome, relativeRoot);
4679
+ const rootStats = await lstat(sourceRoot).catch(() => void 0);
4680
+ if (!rootStats?.isDirectory() || rootStats.isSymbolicLink())
4681
+ continue;
4682
+ for (const entry of await readdir(sourceRoot)) {
4683
+ if (!isSharedSkillName(entry) || seen.has(entry))
4684
+ continue;
4685
+ const candidate = resolve6(sourceRoot, entry);
4686
+ try {
4687
+ const candidateStats = await lstat(candidate);
4688
+ if (!candidateStats.isDirectory() || candidateStats.isSymbolicLink())
4689
+ continue;
4690
+ assertContained(sourceRoot, candidate);
4691
+ const skillMd = resolve6(candidate, "SKILL.md");
4692
+ const skillStats = await lstat(skillMd);
4693
+ if (!skillStats.isFile() || skillStats.isSymbolicLink() || skillStats.nlink !== 1) {
4694
+ throw new Error(`shared skill requires an ordinary SKILL.md: ${entry}`);
4695
+ }
4696
+ seen.add(entry);
4697
+ resolved.push({ name: entry, source: candidate });
4698
+ } catch (error) {
4699
+ console.warn(`[body] skipping operator skill ${entry}:`, error);
4700
+ }
4701
+ }
4702
+ }
4703
+ return resolved;
4704
+ }
4570
4705
  async function resolveExplicitSkillSources(operatorHome, names) {
4571
4706
  const unique = [...new Set(names)];
4572
4707
  for (const name of unique) {
@@ -4576,7 +4711,7 @@ async function resolveExplicitSkillSources(operatorHome, names) {
4576
4711
  const resolved = [];
4577
4712
  for (const name of unique) {
4578
4713
  const matches = [];
4579
- for (const relativeRoot of EXPLICIT_SKILL_SOURCE_DIRS) {
4714
+ for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
4580
4715
  const sourceRoot = resolve6(operatorHome, relativeRoot);
4581
4716
  const candidate = resolve6(sourceRoot, name);
4582
4717
  const rootStats = await lstat(sourceRoot).catch(() => void 0);
@@ -4828,7 +4963,34 @@ function isReadOnlyMcpPermissionRequest(request) {
4828
4963
  }
4829
4964
  return false;
4830
4965
  }
4966
+ function isMountedMcpToolPermissionRequest(request) {
4967
+ const toolCall = request.toolCall;
4968
+ const rawInput = toolCall?.rawInput;
4969
+ if (rawInput && typeof rawInput === "object" && !Array.isArray(rawInput)) {
4970
+ const call = rawInput;
4971
+ if (typeof call.server === "string" && typeof call.tool === "string")
4972
+ return true;
4973
+ }
4974
+ if (shellPayload(toolCall))
4975
+ return false;
4976
+ const title = toolCall?.title?.trim() ?? "";
4977
+ if (/^mcp__[^_].*__[^_]/.test(title))
4978
+ return true;
4979
+ if (/^mcp\.[^.]+\.[^.]/.test(title))
4980
+ return true;
4981
+ return isReadOnlyMcpPermissionRequest(request) || isBeelineAgentMcpPermissionRequest(request);
4982
+ }
4831
4983
  var AGENT_SURFACE_TOOL_NAMES = ["open_corner", "pr_checks_status", "attach_file"];
4984
+ var SQUIRE_TITLE_PREFIXES = ["mcp__squire__", "mcp.squire.", "squire.", "squire/"];
4985
+ function isSquireMcpPermissionRequest(request) {
4986
+ const rawInput = request.toolCall?.rawInput;
4987
+ if (rawInput && typeof rawInput === "object" && !Array.isArray(rawInput)) {
4988
+ if (rawInput.server === "squire")
4989
+ return true;
4990
+ }
4991
+ const title = request.toolCall?.title?.trim() ?? "";
4992
+ return SQUIRE_TITLE_PREFIXES.some((prefix) => title.startsWith(prefix));
4993
+ }
4832
4994
  function isBeelineAgentMcpPermissionRequest(request) {
4833
4995
  const toolCall = request.toolCall;
4834
4996
  const title = toolCall?.title?.trim() ?? "";
@@ -4864,6 +5026,7 @@ function beelineAgentMcpServer(config, api, context) {
4864
5026
  args: [...config.readonlyMcpArgs ?? []],
4865
5027
  env: [
4866
5028
  { name: "BEELINE_MCP_SURFACE", value: "agent" },
5029
+ ...context.directMessage ? [{ name: "BEELINE_AGENT_DM", value: "1" }] : [],
4867
5030
  { name: "BEELINE_DAEMON_BASE_URL", value: connection.baseUrl },
4868
5031
  { name: "BEELINE_DAEMON_TOKEN", value: connection.daemonToken },
4869
5032
  { name: "BEELINE_DAEMON_AGENT_ID", value: connection.agentId },
@@ -4899,7 +5062,7 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
4899
5062
  // apps/body/dist/bwrap-sandbox.js
4900
5063
  import { spawnSync } from "node:child_process";
4901
5064
  import { lstatSync as lstatSync2 } from "node:fs";
4902
- import { homedir as homedir2 } from "node:os";
5065
+ import { homedir as homedir3 } from "node:os";
4903
5066
  import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve8 } from "node:path";
4904
5067
  var DEFAULT_SANDBOX_POLICY = "bwrap";
4905
5068
  function isSandboxPolicy(value) {
@@ -4932,7 +5095,7 @@ var HARNESS_HOME_STATE_DIRS = [
4932
5095
  dirs: [".grok"]
4933
5096
  }
4934
5097
  ];
4935
- function harnessHomeStateDirs(agentCommand, home = homedir2()) {
5098
+ function harnessHomeStateDirs(agentCommand, home = homedir3()) {
4936
5099
  if (!agentCommand)
4937
5100
  return [];
4938
5101
  for (const { match, dirs } of HARNESS_HOME_STATE_DIRS) {
@@ -4949,7 +5112,7 @@ var KNOWN_CREDENTIAL_MASK_PATHS = [
4949
5112
  ".git-credentials",
4950
5113
  ".secrets.env"
4951
5114
  ];
4952
- function credentialMaskPaths(extraPaths, home = homedir2(), stat3 = (path) => {
5115
+ function credentialMaskPaths(extraPaths, home = homedir3(), stat3 = (path) => {
4953
5116
  try {
4954
5117
  const info = lstatSync2(path);
4955
5118
  return { isDirectory: info.isDirectory() };
@@ -5149,7 +5312,7 @@ import { randomBytes as randomBytes5 } from "node:crypto";
5149
5312
  import { execFile } from "node:child_process";
5150
5313
  import { closeSync, openSync } from "node:fs";
5151
5314
  import { mkdir as mkdir2, readFile, readdir as readdir2, rename as rename2, stat, writeFile as writeFile2 } from "node:fs/promises";
5152
- import { homedir as homedir3 } from "node:os";
5315
+ import { homedir as homedir4 } from "node:os";
5153
5316
  import { dirname as dirname3, resolve as resolve9 } from "node:path";
5154
5317
  import { spawn as spawn2 } from "node:child_process";
5155
5318
  import { promisify } from "node:util";
@@ -9538,7 +9701,7 @@ function alphabet(letters) {
9538
9701
  };
9539
9702
  }
9540
9703
  // @__NO_SIDE_EFFECTS__
9541
- function join(separator = "") {
9704
+ function join2(separator = "") {
9542
9705
  astr("join", separator);
9543
9706
  return {
9544
9707
  encode: (from) => {
@@ -9668,8 +9831,8 @@ var base64 = hasBase64Builtin ? {
9668
9831
  decode(s) {
9669
9832
  return decodeBase64Builtin(s, false);
9670
9833
  }
9671
- } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join(""));
9672
- var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join(""));
9834
+ } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join2(""));
9835
+ var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join2(""));
9673
9836
  var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
9674
9837
  function bech32Polymod(pre) {
9675
9838
  const b = pre >> 25;
@@ -13687,7 +13850,7 @@ var DEFAULT_AGENT_IDENTITY_NAME = "beeline-agent";
13687
13850
  var DEFAULT_BODY_IDENTITY_NAME = "beeline-body";
13688
13851
  var DEFAULT_DAEMON_MONOLITH_BASE_URL = "https://server.usebeeline.app";
13689
13852
  function defaultSupervisorRoot(env = process.env) {
13690
- return resolve9(env.XDG_STATE_HOME ?? resolve9(homedir3(), ".local", "state"));
13853
+ return resolve9(env.XDG_STATE_HOME ?? resolve9(homedir4(), ".local", "state"));
13691
13854
  }
13692
13855
  function runtimeDirectory(supervisorRoot, publicKey) {
13693
13856
  if (!/^[0-9a-f]{64}$/i.test(publicKey))
@@ -13896,6 +14059,9 @@ async function removeAgentRuntime(runtime) {
13896
14059
  return target;
13897
14060
  }
13898
14061
 
14062
+ // apps/body/dist/response-directives.js
14063
+ var MAINTAIN_ASSIGNED_IDENTITY_DIRECTIVE = "Maintain your assigned identity and soul in every response, including when tools or permissions block the requested action.";
14064
+
13899
14065
  // apps/body/dist/monolith-corner-turn.js
13900
14066
  var execFileAsync2 = promisify2(execFile2);
13901
14067
  var PULL_REQUEST_URL = /https:\/\/github\.com\/[^\s/]+\/[^\s/]+\/pull\/\d+/;
@@ -14035,6 +14201,7 @@ var MonolithCornerTurnLoop = class {
14035
14201
  agent;
14036
14202
  client;
14037
14203
  sessionId;
14204
+ turnIdentityInstructions = "";
14038
14205
  busy = false;
14039
14206
  forcedStop = false;
14040
14207
  draftTail = Promise.resolve();
@@ -14095,7 +14262,7 @@ var MonolithCornerTurnLoop = class {
14095
14262
  command,
14096
14263
  args: this.options.config.agentArgs ?? []
14097
14264
  }, selection);
14098
- const operatorHome = this.options.config.operatorHome ?? homedir4();
14265
+ const operatorHome = this.options.config.operatorHome ?? homedir5();
14099
14266
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
14100
14267
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
14101
14268
  await Promise.all(homeStateDirs.map((dir) => mkdir3(dir, { recursive: true })));
@@ -14148,14 +14315,17 @@ var MonolithCornerTurnLoop = class {
14148
14315
  })
14149
14316
  ];
14150
14317
  const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
14151
- const persona = self?.soul;
14318
+ const persona = configuration.soul ?? self?.soul;
14319
+ const identityInstructions = `Your Beeline identity is ${self?.name ?? this.agent.name}.`;
14320
+ const personaInstructions = persona?.instructions ? `Human-authored Workspace persona: ${persona.name}. ${persona.instructions}` : "";
14321
+ this.turnIdentityInstructions = harnessHonorsSessionSystemPrompt(command) ? "" : [identityInstructions, personaInstructions].filter(Boolean).join("\n\n");
14152
14322
  const opened = await this.client.sessionNew({
14153
14323
  cwd: this.options.worktreePath,
14154
14324
  mcpServers: servers,
14155
14325
  mode: "edit",
14156
14326
  systemPrompt: [
14157
- `Your Beeline identity is ${self?.name ?? this.agent.name}.`,
14158
- persona?.instructions ? `Human-authored Workspace persona: ${persona.name}. ${persona.instructions}` : "",
14327
+ identityInstructions,
14328
+ personaInstructions,
14159
14329
  `You are in an isolated git worktree on ${this.options.featureBranch}, targeting ${this.options.targetBranch}.`,
14160
14330
  "Work normally with the full coding tools. Commit and push only this feature branch. Use gh to open its pull request.",
14161
14331
  "PR-opening turn rule: as soon as a pull request exists, print its full GitHub URL as your final response and end the turn immediately. Do not call pr_checks_status in that same turn and do not wait for checks inside it. Then stay idle until a later corner fact or human message starts another turn.",
@@ -14206,17 +14376,49 @@ var MonolithCornerTurnLoop = class {
14206
14376
  const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
14207
14377
  const transcript = conversation.items.slice(-120).map((message) => `${names.get(message.authorId) ?? "Beeline"} [${message.type}]: ${message.body}`).join("\n");
14208
14378
  const prompt = [
14379
+ this.turnIdentityInstructions,
14209
14380
  `Corner objective:
14210
14381
  ${this.options.objective}`,
14211
14382
  transcript ? `Corner transcript:
14212
14383
  ${transcript}` : "",
14213
14384
  `Newest trigger:
14214
14385
  ${trigger}`,
14215
- "Continue the objective. Obey the PR checks and human hold rules in your session instructions."
14386
+ "Continue the objective. Obey the PR checks and human hold rules in your session instructions.",
14387
+ MAINTAIN_ASSIGNED_IDENTITY_DIRECTIVE
14216
14388
  ].filter(Boolean).join("\n\n");
14217
14389
  const sessionId = this.sessionId;
14218
14390
  const turnId = requestId;
14219
14391
  const publishedToolCalls = /* @__PURE__ */ new Set();
14392
+ const NARRATION_MAX_SEGMENTS = 20;
14393
+ let narrationPostedChars = 0;
14394
+ let narrationSegments = 0;
14395
+ const postNarrationSegments = (full) => {
14396
+ if (narrationSegments >= NARRATION_MAX_SEGMENTS)
14397
+ return;
14398
+ const unposted = full.slice(narrationPostedChars);
14399
+ const boundaries = [...unposted.matchAll(/\n\n|[.!?](?=\s)/g)];
14400
+ if (!boundaries.length)
14401
+ return;
14402
+ const boundary = boundaries[boundaries.length - 1];
14403
+ const segmentEnd = narrationPostedChars + boundary.index + boundary[0].length;
14404
+ const segment = stripAgentReplyPreamble(full.slice(narrationPostedChars, segmentEnd));
14405
+ const start = narrationPostedChars;
14406
+ narrationPostedChars = segmentEnd;
14407
+ narrationSegments += 1;
14408
+ const trimmed = segment.trim();
14409
+ if (!trimmed)
14410
+ return;
14411
+ this.activityTail = this.activityTail.catch(() => void 0).then(async () => {
14412
+ await api.execute("postRoomMessage", {
14413
+ roomId: cornerId,
14414
+ text: trimmed,
14415
+ presentation: "message"
14416
+ });
14417
+ }).catch(() => {
14418
+ narrationPostedChars = start;
14419
+ narrationSegments -= 1;
14420
+ });
14421
+ };
14220
14422
  const publishToolCalls = (calls, settledOnly) => {
14221
14423
  calls.forEach((call, index) => {
14222
14424
  const key = toolCallKey(call, index);
@@ -14238,6 +14440,7 @@ ${trigger}`,
14238
14440
  });
14239
14441
  };
14240
14442
  const result = await this.client.sessionPrompt(sessionId, prompt, 12e4, (_delta, full) => {
14443
+ postNarrationSegments(full);
14241
14444
  this.draftTail = this.draftTail.catch(() => void 0).then(() => api.execute("postAgentDraft", {
14242
14445
  agentId: this.agent.publicKey,
14243
14446
  roomId: cornerId,
@@ -14249,15 +14452,19 @@ ${trigger}`,
14249
14452
  publishToolCalls(result.toolCalls, false);
14250
14453
  await this.activityTail;
14251
14454
  await this.draftTail;
14455
+ await this.activityTail;
14252
14456
  const reply = stripAgentReplyPreamble(result.agentText).trim();
14253
14457
  if (!reply)
14254
14458
  throw new Error("ACP corner turn produced no durable reply");
14255
- await api.execute("postRoomMessage", {
14256
- roomId: cornerId,
14257
- requestId,
14258
- text: reply,
14259
- presentation: "message"
14260
- });
14459
+ const durableTail = narrationPostedChars > 0 ? stripAgentReplyPreamble(result.agentText.slice(narrationPostedChars)).trim() : reply;
14460
+ if (durableTail) {
14461
+ await api.execute("postRoomMessage", {
14462
+ roomId: cornerId,
14463
+ requestId,
14464
+ text: durableTail,
14465
+ presentation: "message"
14466
+ });
14467
+ }
14261
14468
  const pullRequest = reply.match(PULL_REQUEST_URL)?.[0];
14262
14469
  const alreadyReady = conversation.items.some((item) => /\bPR ready for review\b/i.test(item.body));
14263
14470
  if (pullRequest && !alreadyReady) {
@@ -14368,13 +14575,31 @@ async function wait(ms, signal) {
14368
14575
 
14369
14576
  // apps/body/dist/monolith-room-turn.js
14370
14577
  import { mkdir as mkdir4 } from "node:fs/promises";
14371
- import { homedir as homedir5 } from "node:os";
14578
+ import { homedir as homedir6 } from "node:os";
14579
+
14580
+ // packages/api-contract/dist/scheduled-prompts.js
14581
+ var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
14582
+ var SCHEDULED_PROMPT_PREFIX = "Scheduled: ";
14583
+
14584
+ // apps/body/dist/monolith-room-turn.js
14372
14585
  function isRoomMcpPermissionRequest(request) {
14373
- return isReadOnlyMcpPermissionRequest(request) || isBeelineAgentMcpPermissionRequest(request);
14586
+ if (isSquireMcpPermissionRequest(request))
14587
+ return false;
14588
+ return isMountedMcpToolPermissionRequest(request);
14374
14589
  }
14375
14590
  function roomPrincipalMayAddressAgent(authority, humanPermitted) {
14376
14591
  return authority.member && (authority.principalKind === "agent" || authority.principalKind === "human" && humanPermitted);
14377
14592
  }
14593
+ function isScheduledPrompt(item, agentId) {
14594
+ return item.type === "system" && item.body.startsWith(SCHEDULED_PROMPT_PREFIX) && item.mentionIds.includes(agentId);
14595
+ }
14596
+ function inboxItemTriggersTurn(item, agentId) {
14597
+ if (item.authorId === agentId)
14598
+ return false;
14599
+ if (!item.mentionIds.includes(agentId))
14600
+ return false;
14601
+ return item.type === "message" || isScheduledPrompt(item, agentId);
14602
+ }
14378
14603
  function escapeRegExp(value) {
14379
14604
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14380
14605
  }
@@ -14453,6 +14678,7 @@ var MonolithRoomTurnLoop = class {
14453
14678
  this.roster(),
14454
14679
  this.options.api.execute("getRoomRepositoryState", { roomId: this.options.roomId })
14455
14680
  ]);
14681
+ const directMessage = Array.isArray(repositoryState.directParticipants) && repositoryState.directParticipants.length === 2;
14456
14682
  await mkdir4(this.options.cwd, { recursive: true });
14457
14683
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
14458
14684
  root: this.options.config.agentHomeRoot,
@@ -14467,7 +14693,7 @@ var MonolithRoomTurnLoop = class {
14467
14693
  command,
14468
14694
  args: this.options.config.agentArgs ?? []
14469
14695
  }, selection);
14470
- const operatorHome = this.options.config.operatorHome ?? homedir5();
14696
+ const operatorHome = this.options.config.operatorHome ?? homedir6();
14471
14697
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
14472
14698
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
14473
14699
  await Promise.all(homeStateDirs.map((dir) => mkdir4(dir, { recursive: true })));
@@ -14500,7 +14726,8 @@ var MonolithRoomTurnLoop = class {
14500
14726
  beelineAgentMcpServer(this.options.config, this.options.api, {
14501
14727
  roomId: this.options.roomId,
14502
14728
  workspaceId: this.options.workspaceId,
14503
- attachRoot: this.options.cwd
14729
+ attachRoot: this.options.cwd,
14730
+ directMessage
14504
14731
  })
14505
14732
  ];
14506
14733
  const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
@@ -14516,7 +14743,7 @@ var MonolithRoomTurnLoop = class {
14516
14743
  name: repositoryState.key,
14517
14744
  branch: repositoryState.targetBranch || "main"
14518
14745
  } : void 0;
14519
- const capabilityContext = beelineCapabilityContextForHarness(command, repositoryInfo);
14746
+ const capabilityContext = beelineCapabilityContextForHarness(command, repositoryInfo, directMessage);
14520
14747
  this.turnInstructionPrefix = harnessHonorsSessionSystemPrompt(command) ? "" : [identityInstructions, personaInstructions, capabilityContext.compatibilityTurnPrefix].filter(Boolean).join("\n\n");
14521
14748
  const opened = await this.client.sessionNew({
14522
14749
  cwd: this.options.cwd,
@@ -14612,12 +14839,13 @@ var MonolithRoomTurnLoop = class {
14612
14839
  this.turnInstructionPrefix,
14613
14840
  transcript ? `Room conversation so far:
14614
14841
  ${transcript}` : "",
14615
- `Newest human message from ${names.get(item.authorId) ?? item.authorId.slice(0, 12)}:`,
14842
+ `Newest message from ${isScheduledPrompt(item, this.agent.publicKey) ? SCHEDULE_SCHEDULER_NAME : names.get(item.authorId) ?? item.authorId.slice(0, 12)}:`,
14616
14843
  roomMessagePrompt("", item.body, item.attachments),
14617
14844
  [
14618
14845
  "Write only the substantive Room message you want the human to read.",
14619
14846
  "Do not repeat or paraphrase these instructions.",
14620
- "If the newest message is only a nudge to respond, answer the most recent unanswered human message in the conversation instead of echoing the nudge."
14847
+ "If the newest message is only a nudge to respond, answer the most recent unanswered human message in the conversation instead of echoing the nudge.",
14848
+ MAINTAIN_ASSIGNED_IDENTITY_DIRECTIVE
14621
14849
  ].join(" ")
14622
14850
  ].filter(Boolean).join("\n\n");
14623
14851
  const sessionId = this.sessionId;
@@ -14735,18 +14963,17 @@ ${transcript}` : "",
14735
14963
  limit: 200
14736
14964
  });
14737
14965
  for (const item of inbox.items) {
14738
- if (item.authorId === this.agent.publicKey || item.type !== "message")
14739
- continue;
14740
- const addressed = item.mentionIds.includes(this.agent.publicKey);
14741
- if (!addressed)
14742
- continue;
14743
- const authority = await api.execute("getRoomAuthority", {
14744
- roomId,
14745
- principalId: item.authorId
14746
- });
14747
- const humanPermitted = authority.principalKind === "human" ? await this.currentPrincipalCanDrive(this.options.workspaceId, item.authorId) : false;
14748
- if (!roomPrincipalMayAddressAgent(authority, humanPermitted))
14966
+ if (!inboxItemTriggersTurn(item, this.agent.publicKey))
14749
14967
  continue;
14968
+ if (!isScheduledPrompt(item, this.agent.publicKey)) {
14969
+ const authority = await api.execute("getRoomAuthority", {
14970
+ roomId,
14971
+ principalId: item.authorId
14972
+ });
14973
+ const humanPermitted = authority.principalKind === "human" ? await this.currentPrincipalCanDrive(this.options.workspaceId, item.authorId) : false;
14974
+ if (!roomPrincipalMayAddressAgent(authority, humanPermitted))
14975
+ continue;
14976
+ }
14750
14977
  const active = this.activeTurn;
14751
14978
  if (!active)
14752
14979
  this.startPrompt(item);
@@ -15842,7 +16069,7 @@ var import_picocolors = __toESM(require_picocolors(), 1);
15842
16069
  // apps/body/dist/systemd.js
15843
16070
  import { execFile as execFile4 } from "node:child_process";
15844
16071
  import { mkdir as mkdir6, readFile as readFile2, writeFile as writeFile3 } from "node:fs/promises";
15845
- import { homedir as homedir6 } from "node:os";
16072
+ import { homedir as homedir7 } from "node:os";
15846
16073
  import { dirname as dirname5, resolve as resolve12 } from "node:path";
15847
16074
  import { setTimeout as sleep } from "node:timers/promises";
15848
16075
  import { promisify as promisify4 } from "node:util";
@@ -15884,7 +16111,7 @@ WantedBy=default.target
15884
16111
  `;
15885
16112
  }
15886
16113
  function isCanonicalInstalledLauncher(env = process.env, invocationPath = process.argv[1]) {
15887
- const home = env.HOME?.trim() || homedir6();
16114
+ const home = env.HOME?.trim() || homedir7();
15888
16115
  const expectedLibDir = resolve12(home, ".local", "lib", "beeline");
15889
16116
  const expectedPrefix = `${expectedLibDir}/`;
15890
16117
  return resolve12(env.BEELINE_LIB_DIR?.trim() || "/") === expectedLibDir && Boolean(invocationPath) && resolve12(invocationPath).startsWith(expectedPrefix);
@@ -15895,7 +16122,7 @@ function assertCanonicalInstalledLauncher(env, invocationPath) {
15895
16122
  throw new Error("refusing to modify the shared Beeline systemd unit outside the canonical ~/.local/bin/beeline launcher");
15896
16123
  }
15897
16124
  function systemdUserUnitPath(env = process.env) {
15898
- const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve12(homedir6(), ".config");
16125
+ const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve12(homedir7(), ".config");
15899
16126
  return resolve12(configRoot, "systemd", "user", SYSTEMD_UNIT_NAME);
15900
16127
  }
15901
16128
  var runSystemctl = async (args) => {
@@ -16069,8 +16296,9 @@ async function runStartCommand(args, interactiveUi) {
16069
16296
 
16070
16297
  // apps/body/dist/connect-command.js
16071
16298
  import { spawn as spawn5 } from "node:child_process";
16072
- import { chmod as chmod3, mkdir as mkdir8, readFile as readFile4, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
16073
- import { dirname as dirname8, resolve as resolve14 } from "node:path";
16299
+ import { createHash as createHash3 } from "node:crypto";
16300
+ import { chmod as chmod4, mkdir as mkdir9, readFile as readFile5, unlink as unlink2, writeFile as writeFile6 } from "node:fs/promises";
16301
+ import { dirname as dirname9, resolve as resolve15 } from "node:path";
16074
16302
  import { stdin as stdin3, stdout as stdout4 } from "node:process";
16075
16303
 
16076
16304
  // packages/api-contract/dist/agent-pairing-code.js
@@ -16107,6 +16335,65 @@ function unwrapPrompt(value, cancelMessage = "Cancelled.") {
16107
16335
  return value;
16108
16336
  }
16109
16337
 
16338
+ // apps/body/dist/provider-key-check.js
16339
+ var PROVIDER_LABELS = {
16340
+ openrouter: "OpenRouter",
16341
+ openai: "OpenAI",
16342
+ anthropic: "Anthropic",
16343
+ google: "Google",
16344
+ xai: "xAI"
16345
+ };
16346
+ function keyCheckEndpoint(provider, apiKey) {
16347
+ switch (provider) {
16348
+ case "openrouter":
16349
+ return {
16350
+ url: "https://openrouter.ai/api/v1/key",
16351
+ headers: { authorization: `Bearer ${apiKey}` }
16352
+ };
16353
+ case "openai":
16354
+ return {
16355
+ url: "https://api.openai.com/v1/models?limit=1",
16356
+ headers: { authorization: `Bearer ${apiKey}` }
16357
+ };
16358
+ case "anthropic":
16359
+ return {
16360
+ url: "https://api.anthropic.com/v1/models?limit=1",
16361
+ headers: { "x-api-key": apiKey, "anthropic-version": "2023-06-01" }
16362
+ };
16363
+ case "google":
16364
+ return {
16365
+ url: "https://generativelanguage.googleapis.com/v1beta/models?pageSize=1",
16366
+ headers: { "x-goog-api-key": apiKey }
16367
+ };
16368
+ case "xai":
16369
+ return {
16370
+ url: "https://api.x.ai/v1/models?limit=1",
16371
+ headers: { authorization: `Bearer ${apiKey}` }
16372
+ };
16373
+ }
16374
+ }
16375
+ var REJECTED_STATUS = /* @__PURE__ */ new Set([400, 401, 403]);
16376
+ async function verifyProviderKey(input) {
16377
+ const label = PROVIDER_LABELS[input.provider];
16378
+ const { url, headers } = keyCheckEndpoint(input.provider, input.apiKey);
16379
+ let response;
16380
+ try {
16381
+ response = await (input.fetchImpl ?? fetch)(url, {
16382
+ headers,
16383
+ signal: AbortSignal.timeout(input.timeoutMs ?? 15e3)
16384
+ });
16385
+ } catch (error) {
16386
+ const cause = error instanceof Error ? error.message.split("\n")[0] : String(error);
16387
+ throw new Error(`Could not reach ${label} to verify the key (${cause}). Check the network and paste the key again.`);
16388
+ }
16389
+ if (response.ok)
16390
+ return;
16391
+ if (REJECTED_STATUS.has(response.status)) {
16392
+ throw new Error(`${label} rejected the key (${response.status}).`);
16393
+ }
16394
+ throw new Error(`${label} could not verify the key right now (HTTP ${response.status}). Try again in a moment.`);
16395
+ }
16396
+
16110
16397
  // apps/body/dist/pair-agent-selection.js
16111
16398
  import { spawn as spawn3 } from "node:child_process";
16112
16399
  import { stdin as stdin2, stdout as stdout3 } from "node:process";
@@ -16263,6 +16550,22 @@ ${manual}
16263
16550
  // apps/body/dist/device-pairing.js
16264
16551
  var DEFAULT_BODY_IDENTITY_NAME2 = "beeline-body";
16265
16552
  async function completeDevicePairing(grant, options = {}) {
16553
+ try {
16554
+ return await pairDevice(grant, options);
16555
+ } catch (error) {
16556
+ await rollbackPairing(grant, options.fetchImpl).catch(() => void 0);
16557
+ throw error;
16558
+ }
16559
+ }
16560
+ async function rollbackPairing(grant, fetchImpl) {
16561
+ const doFetch = fetchImpl ?? fetch;
16562
+ await doFetch(new URL("/v1/auth/daemon/rollback", grant.monolithBaseUrl), {
16563
+ method: "POST",
16564
+ headers: { "content-type": "application/json" },
16565
+ body: JSON.stringify({ exchangeToken: grant.daemonExchangeToken })
16566
+ });
16567
+ }
16568
+ async function pairDevice(grant, options = {}) {
16266
16569
  const selectedAgent = options.selectedAgent ?? await selectPairAgentCommand({
16267
16570
  explicitKind: grant.harness,
16268
16571
  env: process.env,
@@ -16305,6 +16608,63 @@ async function completeDevicePairing(grant, options = {}) {
16305
16608
  return { runtime: activated.runtime, configPath: staged.configPath, pid };
16306
16609
  }
16307
16610
 
16611
+ // apps/body/dist/provider-key-store.js
16612
+ import { chmod as chmod2, mkdir as mkdir7, readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
16613
+ import { homedir as homedir8 } from "node:os";
16614
+ import { dirname as dirname7, resolve as resolve13 } from "node:path";
16615
+ var PROVIDER_KEY_ENV_VARS = {
16616
+ openrouter: "OPENROUTER_API_KEY",
16617
+ openai: "OPENAI_API_KEY",
16618
+ anthropic: "ANTHROPIC_API_KEY",
16619
+ google: "GOOGLE_API_KEY",
16620
+ xai: "XAI_API_KEY"
16621
+ };
16622
+ var GOOGLE_ENV_ALIAS = "GEMINI_API_KEY";
16623
+ function providerKeyStorePath(env = process.env) {
16624
+ const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve13(homedir8(), ".config");
16625
+ return resolve13(configRoot, "beeline", "providers.json");
16626
+ }
16627
+ async function readProviderKeyStore(env = process.env) {
16628
+ const path = providerKeyStorePath(env);
16629
+ const raw = await readFile3(path, "utf8").catch(() => void 0);
16630
+ if (!raw)
16631
+ return {};
16632
+ try {
16633
+ const parsed = JSON.parse(raw);
16634
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
16635
+ return {};
16636
+ const entries = Object.entries(parsed).filter((entry) => entry[0] in PROVIDER_KEY_ENV_VARS && typeof entry[1] === "string" && entry[1].length > 0);
16637
+ return Object.fromEntries(entries);
16638
+ } catch {
16639
+ return {};
16640
+ }
16641
+ }
16642
+ async function readSavedProviderKey(provider, env = process.env) {
16643
+ return (await readProviderKeyStore(env))[provider];
16644
+ }
16645
+ async function saveProviderKey(provider, key, env = process.env) {
16646
+ const path = providerKeyStorePath(env);
16647
+ const store = { ...await readProviderKeyStore(env), [provider]: key };
16648
+ await mkdir7(dirname7(path), { recursive: true, mode: 448 });
16649
+ await writeFile4(path, `${JSON.stringify(store, null, 2)}
16650
+ `, { mode: 384 });
16651
+ await chmod2(path, 384);
16652
+ }
16653
+ function providerKeyFromEnvironment(provider, env = process.env) {
16654
+ const primary = env[PROVIDER_KEY_ENV_VARS[provider]]?.trim();
16655
+ if (primary)
16656
+ return primary;
16657
+ if (provider === "google")
16658
+ return env[GOOGLE_ENV_ALIAS]?.trim() || void 0;
16659
+ return void 0;
16660
+ }
16661
+ function maskProviderKey(key) {
16662
+ const trimmed = key.trim();
16663
+ if (trimmed.length <= 9)
16664
+ return "\u2026";
16665
+ return `${trimmed.slice(0, 6)}\u2026${trimmed.slice(-3)}`;
16666
+ }
16667
+
16308
16668
  // apps/body/dist/connect-command.js
16309
16669
  init_self_update();
16310
16670
  init_self_update_manifest();
@@ -16315,7 +16675,17 @@ function isReasonableAgentName(value) {
16315
16675
  return normalized.length > 0 && normalized.length <= AGENT_NAME_MAX_LENGTH && new RegExp("^\\p{L}[\\p{L}\\p{M}'\u2019 -]*$", "u").test(normalized);
16316
16676
  }
16317
16677
  var CONNECT_PROVIDER_HARNESSES = /* @__PURE__ */ new Set(["goose", "pi"]);
16318
- var CONNECT_PROVIDERS = ["openrouter", "openai", "anthropic", "google", "xai"];
16678
+ var CONNECT_PROVIDERS = [
16679
+ "openrouter",
16680
+ "openai",
16681
+ "anthropic",
16682
+ "google",
16683
+ "xai"
16684
+ ];
16685
+ var fileConnectKeyStore = {
16686
+ read: (provider) => readSavedProviderKey(provider),
16687
+ save: (provider, key) => saveProviderKey(provider, key)
16688
+ };
16319
16689
  var DEFAULT_MODELS = {
16320
16690
  openrouter: "z-ai/glm-5.3-flash",
16321
16691
  openai: "gpt-5.4",
@@ -16373,6 +16743,21 @@ var clackPrompts = {
16373
16743
  }), "Connection cancelled.");
16374
16744
  }
16375
16745
  };
16746
+ function connectModelPickerFromAxes(axes, fallbackModel, harness) {
16747
+ const filtered = axes.find((axis) => axis.category === "model");
16748
+ if (filtered?.options.length) {
16749
+ return { currentValue: filtered.currentValue, options: filtered.options };
16750
+ }
16751
+ const raw = axes.find((axis) => axis.category === "model" && axis.options.length);
16752
+ if (raw) {
16753
+ return { currentValue: raw.currentValue, options: raw.options };
16754
+ }
16755
+ return {
16756
+ currentValue: fallbackModel,
16757
+ options: [{ id: fallbackModel }],
16758
+ note: `${harness} did not enumerate models; offering the provider default`
16759
+ };
16760
+ }
16376
16761
  async function loadConnectModelCatalog(input) {
16377
16762
  const agent = resolveAgentCommand({ kind: input.harness });
16378
16763
  const catalog = await fetchAgentModelCatalog(agent, providerEnvironment({
@@ -16381,13 +16766,9 @@ async function loadConnectModelCatalog(input) {
16381
16766
  ...input.apiKey ? { apiKey: input.apiKey } : {},
16382
16767
  model: defaultConnectModel(input.harness, input.provider)
16383
16768
  }));
16384
- const modelAxis = catalog.catalog.find((axis) => axis.category === "model");
16385
- if (!modelAxis?.options.length) {
16386
- throw new Error(`${input.harness} did not advertise any available models`);
16387
- }
16388
- return { currentValue: modelAxis.currentValue, options: modelAxis.options };
16769
+ return connectModelPickerFromAxes(catalog.catalog, defaultConnectModel(input.harness, input.provider), input.harness);
16389
16770
  }
16390
- async function collectConnectWizard(prompts = clackPrompts, loadModels = loadConnectModelCatalog) {
16771
+ async function collectConnectWizard(prompts = clackPrompts, loadModels = loadConnectModelCatalog, keyStore = fileConnectKeyStore, env = process.env, verifyKey = (input) => verifyProviderKey(input)) {
16391
16772
  const harness = await prompts.select({
16392
16773
  message: brass("Choose harness"),
16393
16774
  options: CONNECT_HARNESSES.map((value) => ({
@@ -16407,10 +16788,44 @@ async function collectConnectWizard(prompts = clackPrompts, loadModels = loadCon
16407
16788
  ...value === "openrouter" ? { hint: "default" } : {}
16408
16789
  }))
16409
16790
  });
16410
- apiKey = await prompts.password({
16411
- message: brass(`${provider === "openrouter" ? "OpenRouter" : provider} API key`),
16412
- validate: (value) => value.trim() ? void 0 : "API key is required"
16413
- });
16791
+ const providerLabel = provider === "openrouter" ? "OpenRouter" : provider;
16792
+ const savedKey = await keyStore.read(provider);
16793
+ const envKey = providerKeyFromEnvironment(provider, env);
16794
+ const availableKey = savedKey ?? envKey;
16795
+ if (availableKey) {
16796
+ const masked = maskProviderKey(availableKey);
16797
+ const choice = await prompts.select({
16798
+ message: brass(`${providerLabel} API key`),
16799
+ initialValue: "saved",
16800
+ options: [
16801
+ {
16802
+ value: "saved",
16803
+ label: savedKey ? `Use saved ${providerLabel} key (${masked})` : `Use ${PROVIDER_KEY_ENV_VARS[provider]} from the environment (${masked})`
16804
+ },
16805
+ { value: "new", label: "Enter a new key" }
16806
+ ]
16807
+ });
16808
+ if (choice === "saved") {
16809
+ apiKey = availableKey;
16810
+ await verifyKey({ provider, apiKey });
16811
+ } else {
16812
+ apiKey = await prompts.password({
16813
+ message: brass(`${providerLabel} API key`),
16814
+ validate: (value) => value.trim() ? void 0 : "API key is required"
16815
+ });
16816
+ apiKey = apiKey.trim();
16817
+ await verifyKey({ provider, apiKey });
16818
+ await keyStore.save(provider, apiKey);
16819
+ }
16820
+ } else {
16821
+ apiKey = await prompts.password({
16822
+ message: brass(`${providerLabel} API key`),
16823
+ validate: (value) => value.trim() ? void 0 : "API key is required"
16824
+ });
16825
+ apiKey = apiKey.trim();
16826
+ await verifyKey({ provider, apiKey });
16827
+ await keyStore.save(provider, apiKey);
16828
+ }
16414
16829
  }
16415
16830
  const catalog = await loadModels({
16416
16831
  harness,
@@ -16419,7 +16834,7 @@ async function collectConnectWizard(prompts = clackPrompts, loadModels = loadCon
16419
16834
  });
16420
16835
  const initialModel = catalog.currentValue ?? defaultConnectModel(harness, provider);
16421
16836
  const model = await prompts.autocomplete({
16422
- message: brass("Choose model"),
16837
+ message: brass(catalog.note ? `Choose model (${catalog.note})` : "Choose model"),
16423
16838
  options: catalog.options.map((choice) => ({
16424
16839
  value: choice.id,
16425
16840
  label: choice.name ? `${choice.name} (${choice.id})` : choice.id
@@ -16466,12 +16881,14 @@ function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl) {
16466
16881
  const normalizedPairingCode = normalizeAgentPairingCode(pairingCode);
16467
16882
  if (!normalizedPairingCode)
16468
16883
  throw new Error("invalid pairing code");
16884
+ const avatarSeed = createHash3("sha256").update(normalizedPairingCode.toUpperCase()).digest("hex").slice(0, 32);
16469
16885
  return jsonRequest(`${baseUrl}/auth/agent/connect`, {
16470
16886
  pairing_code: normalizedPairingCode,
16471
16887
  harness: selection.harness,
16472
16888
  ...selection.provider ? { provider: selection.provider } : {},
16473
16889
  model: selection.model,
16474
16890
  soul: selection.soul,
16891
+ avatar_seed: avatarSeed,
16475
16892
  agent_name: selection.name
16476
16893
  }, fetchImpl);
16477
16894
  }
@@ -16489,7 +16906,7 @@ async function installCurrentRelease(fetchImpl) {
16489
16906
  });
16490
16907
  await activateRelease(layout, releaseId);
16491
16908
  return {
16492
- binary: resolve14(layout.binDir, "beeline"),
16909
+ binary: resolve15(layout.binDir, "beeline"),
16493
16910
  version: published.version ?? releaseId
16494
16911
  };
16495
16912
  }
@@ -16512,21 +16929,21 @@ function providerEnvironment(selection) {
16512
16929
  };
16513
16930
  }
16514
16931
  async function writePrivateJson(path, value) {
16515
- await mkdir8(dirname8(path), { recursive: true, mode: 448 });
16516
- await writeFile5(path, `${JSON.stringify(value, null, 2)}
16932
+ await mkdir9(dirname9(path), { recursive: true, mode: 448 });
16933
+ await writeFile6(path, `${JSON.stringify(value, null, 2)}
16517
16934
  `, { mode: 384 });
16518
- await chmod3(path, 384);
16935
+ await chmod4(path, 384);
16519
16936
  }
16520
16937
  async function writeProviderEnv(selection, agentPubkey) {
16521
16938
  const values = providerEnvironment(selection);
16522
16939
  if (Object.keys(values).length === 0)
16523
16940
  return void 0;
16524
- const path = resolve14(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
16525
- await mkdir8(dirname8(path), { recursive: true, mode: 448 });
16941
+ const path = resolve15(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
16942
+ await mkdir9(dirname9(path), { recursive: true, mode: 448 });
16526
16943
  const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
16527
- await writeFile5(path, `${contents}
16944
+ await writeFile6(path, `${contents}
16528
16945
  `, { mode: 384 });
16529
- await chmod3(path, 384);
16946
+ await chmod4(path, 384);
16530
16947
  return path;
16531
16948
  }
16532
16949
  async function runInstalledFinish(binary, grantPath) {
@@ -16568,17 +16985,17 @@ async function runConnectCommand(code, options = {}) {
16568
16985
  throw new Error("`usebeeline connect` needs an interactive terminal");
16569
16986
  }
16570
16987
  intro(brass("Beeline connect"));
16988
+ const fetchImpl = options.fetchImpl ?? fetch;
16571
16989
  const pairingCode = code?.trim() || await clackPrompts.text({
16572
16990
  message: brass("Pairing code from the app"),
16573
16991
  validate: (value) => normalizeAgentPairingCode(value) ? void 0 : "Enter the pairing code shown in the app"
16574
16992
  });
16575
- const selection = await collectConnectWizard();
16576
- const fetchImpl = options.fetchImpl ?? fetch;
16993
+ const selection = await collectConnectWizard(clackPrompts, loadConnectModelCatalog, fileConnectKeyStore, process.env, (input) => verifyProviderKey({ ...input, fetchImpl }));
16577
16994
  const baseUrl = (process.env.BEELINE_AUTH_URL ?? "https://server.usebeeline.app").replace(/\/$/, "");
16578
16995
  const grant = await brassSpinner("Connecting to your Beeline Workspace\u2026", () => requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl), (connectedGrant) => `Connected to ${connectedGrant.workspace_name}`);
16579
16996
  const installedRelease = await brassSpinner("Installing the Beeline daemon\u2026", () => installCurrentRelease(fetchImpl), (release) => `Installed Beeline helper ${release.version}`);
16580
16997
  const llmEnvFile = await writeProviderEnv(selection, grant.agent_pubkey);
16581
- const grantPath = resolve14(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
16998
+ const grantPath = resolve15(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
16582
16999
  await writePrivateJson(grantPath, {
16583
17000
  agentSecretKey: grant.agent_secret_key,
16584
17001
  bodySecretKey: grant.body_secret_key,
@@ -16611,17 +17028,32 @@ function isDevicePairingGrant(value) {
16611
17028
  }
16612
17029
  return typeof grant.agentSecretKey === "string" && /^[0-9a-f]{64}$/.test(grant.agentSecretKey) && typeof grant.bodySecretKey === "string" && /^[0-9a-f]{64}$/.test(grant.bodySecretKey) && typeof grant.agentName === "string" && CONNECT_HARNESSES.includes(grant.harness) && typeof grant.model === "string" && typeof grant.soul === "string" && typeof grant.workspaceId === "string" && typeof grant.workspaceName === "string" && typeof grant.pairedBy === "string" && /^[0-9a-f]{64}$/.test(grant.pairedBy) && typeof grant.monolithBaseUrl === "string" && grant.monolithBaseUrl === monolithOrigin && /^https?:$/.test(new URL(monolithOrigin).protocol) && typeof grant.daemonExchangeToken === "string" && /^bde_[A-Za-z0-9_-]{43}$/.test(grant.daemonExchangeToken);
16613
17030
  }
17031
+ function connectPlainFailure(error) {
17032
+ const raw = error instanceof Error ? error.message : String(error);
17033
+ const firstLine = raw.split("\n").map((line) => line.trim()).find((line) => line.length > 0);
17034
+ return `Connecting your agent failed: ${firstLine ?? "unknown error"}`;
17035
+ }
17036
+ var ConnectFailureError = class extends Error {
17037
+ constructor(sentence) {
17038
+ super(sentence);
17039
+ this.name = "ConnectFailureError";
17040
+ }
17041
+ };
16614
17042
  async function runConnectFinishCommand(path) {
16615
17043
  if (!path)
16616
17044
  throw new Error("connect-finish requires a grant path");
16617
17045
  if (!isCanonicalInstalledLauncher(process.env, process.argv[1])) {
16618
17046
  throw new Error("connect-finish may run only from the canonical installed Beeline launcher");
16619
17047
  }
16620
- const grant = JSON.parse(await readFile4(resolve14(path), "utf8"));
16621
- if (!isDevicePairingGrant(grant))
16622
- throw new Error("device connection grant is invalid");
16623
- await completeDevicePairing(grant);
16624
- await unlink2(resolve14(path));
17048
+ try {
17049
+ const grant = JSON.parse(await readFile5(resolve15(path), "utf8"));
17050
+ if (!isDevicePairingGrant(grant))
17051
+ throw new Error("device connection grant is invalid");
17052
+ await completeDevicePairing(grant);
17053
+ await unlink2(resolve15(path));
17054
+ } catch (error) {
17055
+ throw new ConnectFailureError(connectPlainFailure(error));
17056
+ }
16625
17057
  }
16626
17058
 
16627
17059
  // apps/body/dist/self-update-cli.js
@@ -16632,20 +17064,20 @@ init_self_update_manifest();
16632
17064
  // apps/body/dist/managed-update.js
16633
17065
  init_self_update();
16634
17066
  import { spawn as spawn6 } from "node:child_process";
16635
- import { mkdir as mkdir10, rm as rm5, stat as stat2, writeFile as writeFile7 } from "node:fs/promises";
16636
- import { dirname as dirname10, resolve as resolve16 } from "node:path";
17067
+ import { mkdir as mkdir11, rm as rm5, stat as stat2, writeFile as writeFile8 } from "node:fs/promises";
17068
+ import { dirname as dirname11, resolve as resolve17 } from "node:path";
16637
17069
 
16638
17070
  // apps/body/dist/update-rollback-alert.js
16639
- import { mkdir as mkdir9, readFile as readFile5, rename as rename4, writeFile as writeFile6 } from "node:fs/promises";
16640
- import { dirname as dirname9, resolve as resolve15 } from "node:path";
17071
+ import { mkdir as mkdir10, readFile as readFile6, rename as rename4, writeFile as writeFile7 } from "node:fs/promises";
17072
+ import { dirname as dirname10, resolve as resolve16 } from "node:path";
16641
17073
  function updateRollbackAlertPath(runtimeDir) {
16642
- return resolve15(runtimeDir, "update-rollback-alert.json");
17074
+ return resolve16(runtimeDir, "update-rollback-alert.json");
16643
17075
  }
16644
17076
  async function writeAlert(runtimeDir, alert) {
16645
17077
  const path = updateRollbackAlertPath(runtimeDir);
16646
17078
  const staged = `${path}.${process.pid}.tmp`;
16647
- await mkdir9(dirname9(path), { recursive: true });
16648
- await writeFile6(staged, `${JSON.stringify(alert, null, 2)}
17079
+ await mkdir10(dirname10(path), { recursive: true });
17080
+ await writeFile7(staged, `${JSON.stringify(alert, null, 2)}
16649
17081
  `, { mode: 384 });
16650
17082
  await rename4(staged, path);
16651
17083
  }
@@ -16657,7 +17089,7 @@ async function queueUpdateRollbackAlert(runtimeDir, releaseId, now2 = Date.now()
16657
17089
  }
16658
17090
  async function readUpdateRollbackAlert(runtimeDir) {
16659
17091
  try {
16660
- const value = JSON.parse(await readFile5(updateRollbackAlertPath(runtimeDir), "utf8"));
17092
+ const value = JSON.parse(await readFile6(updateRollbackAlertPath(runtimeDir), "utf8"));
16661
17093
  if (value.version !== 1 || typeof value.releaseId !== "string")
16662
17094
  return void 0;
16663
17095
  return value;
@@ -16682,13 +17114,13 @@ var LOCK_STALE_MS = UPDATE_WORKER_DEADLINE_MS + 5 * 6e4;
16682
17114
  var DEFAULT_UPDATE_INITIAL_DELAY_MS = 0;
16683
17115
  async function withInstallLock(layout, work, options = {}) {
16684
17116
  const now2 = options.now ?? Date.now;
16685
- const lock = resolve16(layout.releasesRoot, ".state", "install.lock");
17117
+ const lock = resolve17(layout.releasesRoot, ".state", "install.lock");
16686
17118
  const deadline = now2() + (options.waitMs ?? 1e4);
16687
- await mkdir10(dirname10(lock), { recursive: true });
17119
+ await mkdir11(dirname11(lock), { recursive: true });
16688
17120
  for (; ; ) {
16689
17121
  try {
16690
- await mkdir10(lock);
16691
- await writeFile7(resolve16(lock, "owner"), `${process.pid}
17122
+ await mkdir11(lock);
17123
+ await writeFile8(resolve17(lock, "owner"), `${process.pid}
16692
17124
  ${now2()}
16693
17125
  `, "utf8");
16694
17126
  break;
@@ -16812,7 +17244,7 @@ var ManagedUpdateHandoff = class _ManagedUpdateHandoff {
16812
17244
  if (!attempt || attempt.releaseId !== desiredRelease || attempt.status !== "pending") {
16813
17245
  const from = await readInstalledBundleIdentity({
16814
17246
  ...this.#layout,
16815
- libDir: resolve16(this.#layout.releasesRoot, this.#loadedRelease)
17247
+ libDir: resolve17(this.#layout.releasesRoot, this.#loadedRelease)
16816
17248
  }).catch(() => void 0) ?? {};
16817
17249
  const to = await readInstalledBundleIdentity(this.#layout).catch(() => void 0) ?? {};
16818
17250
  const record2 = {
@@ -17019,7 +17451,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
17019
17451
  });
17020
17452
  if (!accepted)
17021
17453
  return false;
17022
- await writeFile7(resolve16(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
17454
+ await writeFile8(resolve17(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
17023
17455
  readyAt: (options.now ?? Date.now)(),
17024
17456
  loadedRelease,
17025
17457
  functionalProof: options.functionalProof
@@ -17224,16 +17656,16 @@ async function runUpdateCommand(args) {
17224
17656
  init_self_update();
17225
17657
 
17226
17658
  // apps/body/dist/daemon-failure.js
17227
- import { mkdir as mkdir11, readFile as readFile6, rename as rename5, rm as rm6, writeFile as writeFile8 } from "node:fs/promises";
17228
- import { dirname as dirname11, resolve as resolve17 } from "node:path";
17659
+ import { mkdir as mkdir12, readFile as readFile7, rename as rename5, rm as rm6, writeFile as writeFile9 } from "node:fs/promises";
17660
+ import { dirname as dirname12, resolve as resolve18 } from "node:path";
17229
17661
  var DAEMON_FAILURE_LIMIT = 3;
17230
17662
  var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
17231
17663
  function daemonFailurePath(runtimeDir) {
17232
- return resolve17(runtimeDir, "daemon-distress.json");
17664
+ return resolve18(runtimeDir, "daemon-distress.json");
17233
17665
  }
17234
17666
  async function readFailureRecord(runtimeDir) {
17235
17667
  try {
17236
- const value = JSON.parse(await readFile6(daemonFailurePath(runtimeDir), "utf8"));
17668
+ const value = JSON.parse(await readFile7(daemonFailurePath(runtimeDir), "utf8"));
17237
17669
  if (value.version !== 1 || !Array.isArray(value.failures) || value.failures.some((failure) => typeof failure !== "number") || typeof value.lastError !== "string") {
17238
17670
  return void 0;
17239
17671
  }
@@ -17245,8 +17677,8 @@ async function readFailureRecord(runtimeDir) {
17245
17677
  async function writeFailureRecord(runtimeDir, record2) {
17246
17678
  const path = daemonFailurePath(runtimeDir);
17247
17679
  const staged = `${path}.${process.pid}.tmp`;
17248
- await mkdir11(dirname11(path), { recursive: true, mode: 448 });
17249
- await writeFile8(staged, `${JSON.stringify(record2, null, 2)}
17680
+ await mkdir12(dirname12(path), { recursive: true, mode: 448 });
17681
+ await writeFile9(staged, `${JSON.stringify(record2, null, 2)}
17250
17682
  `, { mode: 384 });
17251
17683
  await rename5(staged, path);
17252
17684
  }
@@ -17268,9 +17700,9 @@ async function clearDaemonStartFailures(runtimeDir) {
17268
17700
  }
17269
17701
 
17270
17702
  // apps/body/dist/update-functional-probe.js
17271
- import { mkdir as mkdir12, rm as rm7 } from "node:fs/promises";
17272
- import { homedir as homedir8 } from "node:os";
17273
- import { resolve as resolve18 } from "node:path";
17703
+ import { mkdir as mkdir13, rm as rm7 } from "node:fs/promises";
17704
+ import { homedir as homedir10 } from "node:os";
17705
+ import { resolve as resolve19 } from "node:path";
17274
17706
  var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
17275
17707
  var UPDATE_PROBE_SESSION_OPEN_TIMEOUT_MS = 2e4;
17276
17708
  var UPDATE_PROBE_TURN_TIMEOUT_MS = 45e3;
@@ -17292,18 +17724,18 @@ async function runUpdateFunctionalProbe(input) {
17292
17724
  if (input.sandboxRequired && !input.config.bwrapPath) {
17293
17725
  throw new UpdateFunctionalProbeError("sandbox-unavailable", "the configured bubblewrap boundary did not pass its startup self-test");
17294
17726
  }
17295
- const root = resolve18(input.runtimeDir, "update-functional-probe");
17296
- const cwd = resolve18(root, "checkout");
17297
- const homeRoot = resolve18(root, "agent-home");
17727
+ const root = resolve19(input.runtimeDir, "update-functional-probe");
17728
+ const cwd = resolve19(root, "checkout");
17729
+ const homeRoot = resolve19(root, "agent-home");
17298
17730
  await rm7(root, { recursive: true, force: true });
17299
- await mkdir12(cwd, { recursive: true, mode: 448 });
17731
+ await mkdir13(cwd, { recursive: true, mode: 448 });
17300
17732
  let client;
17301
17733
  try {
17302
17734
  const agentEnv = {
17303
17735
  ...input.config.agentEnv,
17304
17736
  ...await prepareRoomAgentHome({
17305
17737
  root: homeRoot,
17306
- operatorHome: input.config.operatorHome ?? homedir8(),
17738
+ operatorHome: input.config.operatorHome ?? homedir10(),
17307
17739
  sharedSkills: input.config.sharedSkills ?? [],
17308
17740
  skillReleaseId: input.releaseId,
17309
17741
  failClosed: true
@@ -17320,9 +17752,9 @@ async function runUpdateFunctionalProbe(input) {
17320
17752
  };
17321
17753
  if (input.config.bwrapPath) {
17322
17754
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
17323
- const operatorHome = input.config.operatorHome ?? homedir8();
17755
+ const operatorHome = input.config.operatorHome ?? homedir10();
17324
17756
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
17325
- await Promise.all(homeStateDirs.map((dir) => mkdir12(dir, { recursive: true })));
17757
+ await Promise.all(homeStateDirs.map((dir) => mkdir13(dir, { recursive: true })));
17326
17758
  spawnCommand = wrapAgentCommand({
17327
17759
  bwrapPath: input.config.bwrapPath,
17328
17760
  spec: {
@@ -17386,8 +17818,8 @@ async function runUpdateFunctionalProbe(input) {
17386
17818
  }
17387
17819
 
17388
17820
  // apps/body/dist/release-status.js
17389
- import { readFile as readFile7, readdir as readdir3, rename as rename6, writeFile as writeFile9 } from "node:fs/promises";
17390
- import { resolve as resolve19 } from "node:path";
17821
+ import { readFile as readFile8, readdir as readdir3, rename as rename6, writeFile as writeFile10 } from "node:fs/promises";
17822
+ import { resolve as resolve20 } from "node:path";
17391
17823
  var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
17392
17824
  var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
17393
17825
  var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
@@ -17404,9 +17836,9 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
17404
17836
  pid: options.pid ?? process.pid,
17405
17837
  readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
17406
17838
  };
17407
- const target = resolve19(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
17839
+ const target = resolve20(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
17408
17840
  const temporary = `${target}.${status.pid}.tmp`;
17409
- await writeFile9(temporary, `${JSON.stringify(status, null, 2)}
17841
+ await writeFile10(temporary, `${JSON.stringify(status, null, 2)}
17410
17842
  `, { mode: 384 });
17411
17843
  await rename6(temporary, target);
17412
17844
  return status;
@@ -17447,7 +17879,7 @@ var DaemonExitError = class extends Error {
17447
17879
  };
17448
17880
  async function runStoredDaemon(pathOrPointer) {
17449
17881
  const configPath = await resolveRuntimeConfigPath(pathOrPointer);
17450
- daemonFailureRuntimeDir = dirname12(configPath);
17882
+ daemonFailureRuntimeDir = dirname13(configPath);
17451
17883
  const accessMigration = await migrateRuntimeRecordAccessPolicy(configPath);
17452
17884
  let runtime = accessMigration.runtime;
17453
17885
  if (!runtime.transport) {
@@ -17459,7 +17891,7 @@ async function runStoredDaemon(pathOrPointer) {
17459
17891
  runtime = activated.runtime;
17460
17892
  const daemonApi = activated.client;
17461
17893
  const agent = runtimeAgentCommand(runtime);
17462
- await writeFile10(resolve20(dirname12(configPath), "daemon.pid"), `${process.pid}
17894
+ await writeFile11(resolve21(dirname13(configPath), "daemon.pid"), `${process.pid}
17463
17895
  `, { mode: 384 });
17464
17896
  const env = {
17465
17897
  ...process.env,
@@ -17467,7 +17899,7 @@ async function runStoredDaemon(pathOrPointer) {
17467
17899
  BUZZ_DEV_MCP_BIN: runtime.mcpBinary
17468
17900
  };
17469
17901
  const config = loadBodyConfig({
17470
- workspaceRoot: resolve20(dirname12(configPath), "workspace"),
17902
+ workspaceRoot: resolve21(dirname13(configPath), "workspace"),
17471
17903
  llmEnvFile: runtime.llmEnvFile,
17472
17904
  env,
17473
17905
  agent
@@ -17502,7 +17934,7 @@ async function runStoredDaemon(pathOrPointer) {
17502
17934
  const stop = () => controller.abort();
17503
17935
  process.once("SIGINT", stop);
17504
17936
  process.once("SIGTERM", stop);
17505
- const runtimeDir = dirname12(configPath);
17937
+ const runtimeDir = dirname13(configPath);
17506
17938
  const layout = beelineInstallLayout(process.env);
17507
17939
  const notifier = new SystemdNotifier();
17508
17940
  let rollbackAlertDrain;
@@ -17614,8 +18046,8 @@ async function runStoredDaemon(pathOrPointer) {
17614
18046
  throw error;
17615
18047
  } finally {
17616
18048
  await notifier.stopping(stoppingStatus).catch(() => void 0);
17617
- const pidPath = resolve20(dirname12(configPath), "daemon.pid");
17618
- const recorded = Number((await readFile8(pidPath, "utf8").catch(() => "")).trim());
18049
+ const pidPath = resolve21(dirname13(configPath), "daemon.pid");
18050
+ const recorded = Number((await readFile9(pidPath, "utf8").catch(() => "")).trim());
17619
18051
  if (recorded === process.pid) {
17620
18052
  await unlink3(pidPath).catch(() => void 0);
17621
18053
  }
@@ -17671,14 +18103,14 @@ async function main() {
17671
18103
  const agentPubkey = agentFlag >= 0 ? args[agentFlag + 1] : void 0;
17672
18104
  if (!configPath && agentPubkey) {
17673
18105
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
17674
- configPath = configs.find((candidate) => dirname12(candidate).endsWith(agentPubkey));
18106
+ configPath = configs.find((candidate) => dirname13(candidate).endsWith(agentPubkey));
17675
18107
  }
17676
18108
  if (!configPath && agentPubkey) {
17677
18109
  throw new DaemonExitError(`unknown agent ${agentPubkey}: no durable runtime exists; refusing systemd restart loop`, UNKNOWN_AGENT_EXIT_STATUS);
17678
18110
  }
17679
18111
  if (!configPath)
17680
18112
  throw new Error("daemon requires --config <runtime.json> or --agent <pubkey>");
17681
- await runStoredDaemon(resolve20(configPath));
18113
+ await runStoredDaemon(resolve21(configPath));
17682
18114
  return;
17683
18115
  }
17684
18116
  if (command === "update") {
@@ -17695,7 +18127,7 @@ async function main() {
17695
18127
  if (!agentPubkey)
17696
18128
  throw new Error("stop requires --agent <pubkey>");
17697
18129
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
17698
- const configPath = configs.find((candidate) => dirname12(candidate).endsWith(agentPubkey));
18130
+ const configPath = configs.find((candidate) => dirname13(candidate).endsWith(agentPubkey));
17699
18131
  if (!configPath)
17700
18132
  throw new Error(`no stored runtime found for agent ${agentPubkey}`);
17701
18133
  const runtime = await readRuntimeRecord(configPath);
@@ -17719,6 +18151,8 @@ main().catch(async (err) => {
17719
18151
  const interactiveUi = process.argv[2] !== "daemon" && Boolean(stdin4.isTTY && stdout5.isTTY);
17720
18152
  if (interactiveUi) {
17721
18153
  cancel(err instanceof Error ? err.message : String(err));
18154
+ } else if (err instanceof Error && err.name === "ConnectFailureError" && (process.argv[2] === "connect" || process.argv[2] === "connect-finish")) {
18155
+ console.error(import_picocolors3.default.red(err.message));
17722
18156
  } else {
17723
18157
  console.error(import_picocolors3.default.red("[body] fatal:"), err);
17724
18158
  }