usebeeline 0.0.48 → 0.0.49

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 +314 -105
  2. package/package.json +1 -1
@@ -309,12 +309,12 @@ __export(self_update_exports, {
309
309
  });
310
310
  import { createHash as createHash5 } from "node:crypto";
311
311
  import { constants as fsConstants } from "node:fs";
312
- import { access, chmod as chmod3, lstat as lstat2, mkdir as mkdir11, open, readFile as readFile9, rename as rename3, rm as rm5, symlink as symlink2, writeFile as writeFile8 } from "node:fs/promises";
312
+ import { access, chmod as chmod3, lstat as lstat2, mkdir as mkdir12, open, readFile as readFile9, rename as rename3, rm as rm5, symlink as symlink2, writeFile as writeFile8 } from "node:fs/promises";
313
313
  import { spawn as spawn4 } from "node:child_process";
314
314
  import { homedir as homedir9 } from "node:os";
315
- import { dirname as dirname9, join as join7, resolve as resolve19 } from "node:path";
315
+ import { dirname as dirname9, join as join7, resolve as resolve20 } from "node:path";
316
316
  function anchorLayout(rawLibDir) {
317
- const libDir = resolve19(rawLibDir);
317
+ const libDir = resolve20(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: resolve19(libDir, "../../bin"),
333
+ binDir: resolve20(libDir, "../../bin"),
334
334
  libDir,
335
- releasesRoot: resolve19(libDir, `../${RELEASES_SEGMENT}`)
335
+ releasesRoot: resolve20(libDir, `../${RELEASES_SEGMENT}`)
336
336
  };
337
337
  }
338
338
  function beelineInstallLayout(env = process.env) {
@@ -343,7 +343,7 @@ function beelineInstallLayout(env = process.env) {
343
343
  }
344
344
  function defaultBeelineInstallLayout(env = process.env) {
345
345
  const home = env.HOME?.trim() || homedir9();
346
- return anchorLayout(resolve19(home, ".local", "lib", "beeline"));
346
+ return anchorLayout(resolve20(home, ".local", "lib", "beeline"));
347
347
  }
348
348
  function hostPlatformKey() {
349
349
  const os = process.platform === "linux" ? "linux" : process.platform === "darwin" ? "darwin" : "";
@@ -387,7 +387,7 @@ async function readUpdateState(layout) {
387
387
  }
388
388
  }
389
389
  async function writeUpdateState(layout, state) {
390
- await mkdir11(join7(layout.releasesRoot, ".state"), { recursive: true });
390
+ await mkdir12(join7(layout.releasesRoot, ".state"), { recursive: true });
391
391
  await writeFile8(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
392
392
  `, "utf8");
393
393
  }
@@ -501,7 +501,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
501
501
  previouslyVerified = true;
502
502
  } catch {
503
503
  }
504
- await mkdir11(releaseDir, { recursive: true });
504
+ await mkdir12(releaseDir, { recursive: true });
505
505
  const tempArchive = join7(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
506
506
  try {
507
507
  log2(`downloading ${published.file}`);
@@ -588,8 +588,8 @@ async function replaceFile(path, contents, mode) {
588
588
  async function activateRelease(layout, releaseId) {
589
589
  const releaseDir = join7(layout.releasesRoot, releaseId);
590
590
  await access(join7(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
591
- await mkdir11(layout.releasesRoot, { recursive: true });
592
- await mkdir11(layout.binDir, { recursive: true });
591
+ await mkdir12(layout.releasesRoot, { recursive: true });
592
+ await mkdir12(layout.binDir, { recursive: true });
593
593
  let previousReleaseId = await activeReleaseId(layout);
594
594
  const kind = await pathKind(layout.libDir);
595
595
  if (kind === "directory") {
@@ -628,7 +628,7 @@ async function normalizeLegacyBundleShape(bundleDir) {
628
628
  }
629
629
  if (!anyFlat)
630
630
  return;
631
- await mkdir11(innerLib, { recursive: true });
631
+ await mkdir12(innerLib, { recursive: true });
632
632
  for (const name of LEGACY_FLAT_BUNDLE_FILES) {
633
633
  try {
634
634
  await access(join7(innerLib, name), fsConstants.F_OK);
@@ -661,7 +661,7 @@ async function repairInstallForwarders(layout, opts = {}) {
661
661
  }
662
662
  if (current === forwarderScript("beeline"))
663
663
  return false;
664
- await mkdir11(layout.binDir, { recursive: true });
664
+ await mkdir12(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;
@@ -693,7 +693,7 @@ async function readUpdateAttempt(layout) {
693
693
  }
694
694
  }
695
695
  async function writeUpdateAttempt(layout, record2) {
696
- await mkdir11(join7(layout.releasesRoot, ".state"), { recursive: true });
696
+ await mkdir12(join7(layout.releasesRoot, ".state"), { recursive: true });
697
697
  const path = updateAttemptPath(layout);
698
698
  const staged = `${path}.${process.pid}.tmp`;
699
699
  await writeFile8(staged, `${JSON.stringify(record2, null, 2)}
@@ -955,7 +955,7 @@ var init_self_update = __esm({
955
955
  });
956
956
 
957
957
  // apps/body/dist/cli.js
958
- import { dirname as dirname15, resolve as resolve26 } from "node:path";
958
+ import { dirname as dirname15, resolve as resolve27 } from "node:path";
959
959
  import { readFile as readFile14, unlink as unlink3, writeFile as writeFile14 } from "node:fs/promises";
960
960
  import { stdin as stdin4, stdout as stdout5 } from "node:process";
961
961
 
@@ -3832,7 +3832,7 @@ var AcpClient = class extends EventEmitter {
3832
3832
  const current = this.activeRunIds.get(sessionId);
3833
3833
  if (current)
3834
3834
  return Promise.resolve(current);
3835
- return new Promise((resolve27, reject) => {
3835
+ return new Promise((resolve28, reject) => {
3836
3836
  const onUpdate = (update) => {
3837
3837
  if (update.sessionId !== sessionId)
3838
3838
  return;
@@ -3840,7 +3840,7 @@ var AcpClient = class extends EventEmitter {
3840
3840
  if (!runId)
3841
3841
  return;
3842
3842
  cleanup();
3843
- resolve27(runId);
3843
+ resolve28(runId);
3844
3844
  };
3845
3845
  const timer = setTimeout(() => {
3846
3846
  cleanup();
@@ -3924,13 +3924,13 @@ var AcpClient = class extends EventEmitter {
3924
3924
  }
3925
3925
  const id = this.nextId++;
3926
3926
  const payload = { jsonrpc: "2.0", id, method, params };
3927
- return new Promise((resolve27, reject) => {
3927
+ return new Promise((resolve28, reject) => {
3928
3928
  const timer = setTimeout(() => {
3929
3929
  this.pending.delete(id);
3930
3930
  reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, Boolean(onStart), detail));
3931
3931
  }, timeoutMs);
3932
3932
  this.pending.set(id, {
3933
- resolve: resolve27,
3933
+ resolve: resolve28,
3934
3934
  reject,
3935
3935
  timer,
3936
3936
  method,
@@ -13283,8 +13283,8 @@ async function activateDaemonTransport(path, fetchImpl = fetch) {
13283
13283
  import { execFile as execFile4 } from "node:child_process";
13284
13284
  import { createHash as createHash4 } from "node:crypto";
13285
13285
  import { existsSync as existsSync4, mkdirSync } from "node:fs";
13286
- import { mkdir as mkdir9, rm as rm4 } from "node:fs/promises";
13287
- import { dirname as dirname6, resolve as resolve17 } from "node:path";
13286
+ import { mkdir as mkdir10, rm as rm4 } from "node:fs/promises";
13287
+ import { dirname as dirname6, resolve as resolve18 } from "node:path";
13288
13288
  import { promisify as promisify3 } from "node:util";
13289
13289
 
13290
13290
  // apps/body/dist/grant-runner.js
@@ -14126,7 +14126,7 @@ var GrantRunnerServer = class {
14126
14126
 
14127
14127
  // apps/body/dist/monolith-corner-turn.js
14128
14128
  import { execFile as execFile3 } from "node:child_process";
14129
- import { mkdir as mkdir7 } from "node:fs/promises";
14129
+ import { mkdir as mkdir8 } from "node:fs/promises";
14130
14130
  import { homedir as homedir6 } from "node:os";
14131
14131
  import { join as join5 } from "node:path";
14132
14132
  import { promisify as promisify2 } from "node:util";
@@ -14151,6 +14151,8 @@ var BEELINE_ROOM_CAPABILITIES = [
14151
14151
  "Files and photos people share are downloaded for you: read them at the local path named in the prompt (photos may also arrive inline); never fetch the reference URL.",
14152
14152
  "To create a file (this Room has no other way to write one), call beeline-agent write_scratch_file with a relative path and content - text by default, or base64 for bytes you computed; it returns a path in your writable session home. To send a file, call beeline-agent attach_file with a path inside your checkout or anywhere in your writable session home (wherever a file you or your harness generated actually landed, including one you just wrote); it is attached to your reply. write_scratch_file produces the file, not a picture - turning it into a raster image needs a converter, which needs shell, which this Room does not have.",
14153
14153
  "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.",
14154
+ "To react to things that HAPPEN in this Room rather than only to what is said to you, call beeline-agent subscribe_events with the kinds you want (joined, schedule-ran, corner-opened, check-passed, check-failed, merged); each one then wakes you for a turn. It replaces your list, so send every kind you want - list_event_subscriptions shows the current one. You do this yourself: nobody has to configure it for you.",
14155
+ "To state something that happened so the Room and other agents can act on it, call beeline-agent emit_event with your own agent:<slug> kind, one sentence, and optionally the agent members to wake. Chains of events are bounded and a refused emit posts nothing.",
14154
14156
  "When repository work is needed, you MUST call beeline-agent open_corner with a name of at most three words - it titles the corner everywhere - and a complete objective of no more than 24 words. The host-governed call is the only way to start write work.",
14155
14157
  "When open_corner succeeds, the server posts the corner card: do not announce or restate the opening. End the turn with nothing more unless the person asked something else.",
14156
14158
  "Never claim an action or reply happened unless the prompt or a tool result proves it."
@@ -15668,8 +15670,191 @@ function sessionConfigFingerprint(input) {
15668
15670
  ]);
15669
15671
  }
15670
15672
 
15671
- // apps/body/dist/room-session.js
15673
+ // apps/body/dist/pi-mcp-bridge.js
15674
+ import { mkdir as mkdir6 } from "node:fs/promises";
15672
15675
  import { resolve as resolve14 } from "node:path";
15676
+ var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
15677
+ function harnessMountsSessionMcpServers(agentCommand) {
15678
+ return !(agentCommand && /(^|[/\\])pi-acp(\.[a-z]+)?$/i.test(agentCommand));
15679
+ }
15680
+ function piMcpBridgeSource(servers) {
15681
+ const manifest = servers.map((server) => ({
15682
+ name: server.name,
15683
+ command: server.command,
15684
+ args: server.args ?? [],
15685
+ env: Object.fromEntries((server.env ?? []).map((entry) => [entry.name, entry.value]))
15686
+ }));
15687
+ return `${BRIDGE_PREAMBLE}const SERVERS = ${JSON.stringify(manifest, null, 2)};
15688
+ ${BRIDGE_BODY}`;
15689
+ }
15690
+ async function installPiMcpBridge(input) {
15691
+ if (harnessMountsSessionMcpServers(input.agentCommand))
15692
+ return void 0;
15693
+ if (!input.piHome || !input.servers.length)
15694
+ return void 0;
15695
+ const directory = resolve14(input.piHome, "extensions");
15696
+ const path = resolve14(directory, PI_MCP_BRIDGE_FILENAME);
15697
+ try {
15698
+ await mkdir6(directory, { recursive: true, mode: 448 });
15699
+ await writeIsolatedHarnessFile(path, piMcpBridgeSource(input.servers));
15700
+ return path;
15701
+ } catch (error) {
15702
+ console.error("[body] pi MCP bridge could not be written", path, error);
15703
+ return void 0;
15704
+ }
15705
+ }
15706
+ var BRIDGE_PREAMBLE = `// Generated by Beeline for one Room session. Do not edit: it is rewritten on
15707
+ // every activation. It republishes this session's MCP servers as pi tools,
15708
+ // because pi has no MCP client of its own (apps/body/src/pi-mcp-bridge.ts).
15709
+ import { spawn } from 'node:child_process';
15710
+
15711
+ `;
15712
+ var BRIDGE_BODY = `const LIST_TIMEOUT_MS = 20000;
15713
+
15714
+ /**
15715
+ * One request/response against one MCP server over a short-lived process.
15716
+ *
15717
+ * A fresh process per call keeps nothing alive between turns: these servers
15718
+ * hold no session state - each tool call is a bounded daemon HTTP request - so
15719
+ * a pool would buy latency at the cost of processes outliving the session that
15720
+ * spawned them.
15721
+ */
15722
+ function callServer(server, request, signal, timeoutMs) {
15723
+ return new Promise((resolvePromise, rejectPromise) => {
15724
+ const child = spawn(server.command, server.args, {
15725
+ env: { ...process.env, ...server.env },
15726
+ stdio: ['pipe', 'pipe', 'ignore'],
15727
+ });
15728
+ let settled = false;
15729
+ let buffer = '';
15730
+ let timer;
15731
+ const finish = (error, value) => {
15732
+ if (settled) return;
15733
+ settled = true;
15734
+ if (timer) clearTimeout(timer);
15735
+ signal?.removeEventListener?.('abort', onAbort);
15736
+ child.kill('SIGKILL');
15737
+ if (error) rejectPromise(error); else resolvePromise(value);
15738
+ };
15739
+ const onAbort = () => finish(new Error(server.name + ' call cancelled'));
15740
+ if (timeoutMs) {
15741
+ timer = setTimeout(
15742
+ () => finish(new Error(server.name + ' did not answer in ' + timeoutMs + 'ms')),
15743
+ timeoutMs,
15744
+ );
15745
+ }
15746
+ if (signal) {
15747
+ if (signal.aborted) { onAbort(); return; }
15748
+ signal.addEventListener?.('abort', onAbort, { once: true });
15749
+ }
15750
+ child.on('error', (error) => finish(error));
15751
+ child.on('exit', () => finish(new Error(server.name + ' exited before answering')));
15752
+ child.stdout.setEncoding('utf8');
15753
+ child.stdout.on('data', (chunk) => {
15754
+ buffer += chunk;
15755
+ let newline = buffer.indexOf('\\n');
15756
+ while (newline >= 0) {
15757
+ const line = buffer.slice(0, newline).trim();
15758
+ buffer = buffer.slice(newline + 1);
15759
+ if (line) {
15760
+ let message;
15761
+ try { message = JSON.parse(line); } catch { message = undefined; }
15762
+ // Only the answer to OUR id: the initialize reply and any
15763
+ // notification the server writes share this stream.
15764
+ if (message && message.id === request.id) {
15765
+ if (message.error) {
15766
+ finish(new Error(message.error.message || 'MCP error'));
15767
+ } else {
15768
+ finish(undefined, message.result ?? {});
15769
+ }
15770
+ return;
15771
+ }
15772
+ }
15773
+ newline = buffer.indexOf('\\n');
15774
+ }
15775
+ });
15776
+ child.stdin.write(
15777
+ JSON.stringify({
15778
+ jsonrpc: '2.0',
15779
+ id: 0,
15780
+ method: 'initialize',
15781
+ params: {
15782
+ protocolVersion: '2024-11-05',
15783
+ capabilities: {},
15784
+ clientInfo: { name: 'beeline-pi-bridge', version: '1.0.0' },
15785
+ },
15786
+ }) + '\\n',
15787
+ );
15788
+ child.stdin.write(JSON.stringify(request) + '\\n');
15789
+ });
15790
+ }
15791
+
15792
+ function textOf(result) {
15793
+ const content = Array.isArray(result?.content) ? result.content : [];
15794
+ const text = content
15795
+ .filter((part) => part && part.type === 'text' && typeof part.text === 'string')
15796
+ .map((part) => part.text)
15797
+ .join('\\n');
15798
+ return text || 'The tool returned no text.';
15799
+ }
15800
+
15801
+ function labelOf(name) {
15802
+ return name.replace(/_/g, ' ').replace(/^./, (first) => first.toUpperCase());
15803
+ }
15804
+
15805
+ export default async function (pi) {
15806
+ for (const server of SERVERS) {
15807
+ let tools = [];
15808
+ try {
15809
+ const listed = await callServer(
15810
+ server,
15811
+ { jsonrpc: '2.0', id: 1, method: 'tools/list', params: {} },
15812
+ undefined,
15813
+ LIST_TIMEOUT_MS,
15814
+ );
15815
+ tools = Array.isArray(listed?.tools) ? listed.tools : [];
15816
+ } catch (error) {
15817
+ // A server that will not list is a server whose tools this session does
15818
+ // not have. Say so once; never fail the session over it.
15819
+ console.error('[beeline] MCP server ' + server.name + ' did not list its tools:', error);
15820
+ continue;
15821
+ }
15822
+ for (const tool of tools) {
15823
+ if (!tool || typeof tool.name !== 'string') continue;
15824
+ const schema =
15825
+ tool.inputSchema && typeof tool.inputSchema === 'object'
15826
+ ? tool.inputSchema
15827
+ : { type: 'object', properties: {} };
15828
+ pi.registerTool({
15829
+ name: server.name + '__' + tool.name,
15830
+ label: labelOf(tool.name),
15831
+ description: typeof tool.description === 'string' ? tool.description : tool.name,
15832
+ parameters: schema,
15833
+ async execute(_toolCallId, params, signal) {
15834
+ const result = await callServer(
15835
+ server,
15836
+ {
15837
+ jsonrpc: '2.0',
15838
+ id: 1,
15839
+ method: 'tools/call',
15840
+ params: { name: tool.name, arguments: params ?? {} },
15841
+ },
15842
+ signal,
15843
+ );
15844
+ // An MCP refusal is a RESULT carrying isError. Throwing is how a pi
15845
+ // tool reports failure, so the sentence explaining the refusal is
15846
+ // what the model reads.
15847
+ if (result?.isError) throw new Error(textOf(result));
15848
+ return { content: [{ type: 'text', text: textOf(result) }], details: {} };
15849
+ },
15850
+ });
15851
+ }
15852
+ }
15853
+ }
15854
+ `;
15855
+
15856
+ // apps/body/dist/room-session.js
15857
+ import { resolve as resolve15 } from "node:path";
15673
15858
 
15674
15859
  // apps/body/dist/read-only-policy.js
15675
15860
  var READ_ONLY_MCP_SERVER_NAME = "beeline-readonly-mcp";
@@ -15892,21 +16077,21 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
15892
16077
  command: config.readonlyMcpCommand,
15893
16078
  args: [...config.readonlyMcpArgs ?? []],
15894
16079
  env: [
15895
- { name: "BEELINE_READONLY_ROOT", value: resolve14(cwd) },
16080
+ { name: "BEELINE_READONLY_ROOT", value: resolve15(cwd) },
15896
16081
  ...config.agentHomeRoot ? [
15897
16082
  {
15898
16083
  name: "BEELINE_READONLY_AGENT_SKILLS_ROOT",
15899
- value: resolve14(config.agentHomeRoot, skillDir, "skills")
16084
+ value: resolve15(config.agentHomeRoot, skillDir, "skills")
15900
16085
  }
15901
16086
  ] : [],
15902
- ...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve14(agentMemoryDir) }] : []
16087
+ ...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve15(agentMemoryDir) }] : []
15903
16088
  ]
15904
16089
  };
15905
16090
  }
15906
16091
 
15907
16092
  // apps/body/dist/pi-turn-record.js
15908
16093
  import { readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
15909
- import { resolve as resolve15 } from "node:path";
16094
+ import { resolve as resolve16 } from "node:path";
15910
16095
  function summarizeProviderError(errorMessage2) {
15911
16096
  const trimmed = errorMessage2.trim();
15912
16097
  const statusMatch = /^(\d{3}):\s*([\s\S]*)$/.exec(trimmed);
@@ -15927,7 +16112,7 @@ function summarizeProviderError(errorMessage2) {
15927
16112
  }
15928
16113
  async function sessionFileFromMap(home, sessionId) {
15929
16114
  try {
15930
- const raw = await readFile7(resolve15(home, ".pi", "pi-acp", "session-map.json"), "utf8");
16115
+ const raw = await readFile7(resolve16(home, ".pi", "pi-acp", "session-map.json"), "utf8");
15931
16116
  const map = JSON.parse(raw);
15932
16117
  const file = map.sessions?.[sessionId]?.sessionFile;
15933
16118
  return typeof file === "string" && file ? file : void 0;
@@ -15936,7 +16121,7 @@ async function sessionFileFromMap(home, sessionId) {
15936
16121
  }
15937
16122
  }
15938
16123
  async function sessionFileFromLayout(piDir, sessionId) {
15939
- const sessionsRoot = resolve15(piDir, "sessions");
16124
+ const sessionsRoot = resolve16(piDir, "sessions");
15940
16125
  const suffix = `_${sessionId}.jsonl`;
15941
16126
  let projects;
15942
16127
  try {
@@ -15945,7 +16130,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
15945
16130
  return void 0;
15946
16131
  }
15947
16132
  for (const project of projects) {
15948
- const dir = resolve15(sessionsRoot, project);
16133
+ const dir = resolve16(sessionsRoot, project);
15949
16134
  let files;
15950
16135
  try {
15951
16136
  files = await readdir3(dir);
@@ -15954,7 +16139,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
15954
16139
  }
15955
16140
  const match = files.find((file) => file.endsWith(suffix));
15956
16141
  if (match)
15957
- return resolve15(dir, match);
16142
+ return resolve16(dir, match);
15958
16143
  }
15959
16144
  return void 0;
15960
16145
  }
@@ -16149,8 +16334,8 @@ async function withTurnReceiptHeartbeat(api, receipt, task, onHeartbeatError) {
16149
16334
  }
16150
16335
 
16151
16336
  // apps/body/dist/turn-trace.js
16152
- import { appendFile, mkdir as mkdir6, readdir as readdir4, rm as rm3 } from "node:fs/promises";
16153
- import { resolve as resolve16 } from "node:path";
16337
+ import { appendFile, mkdir as mkdir7, readdir as readdir4, rm as rm3 } from "node:fs/promises";
16338
+ import { resolve as resolve17 } from "node:path";
16154
16339
  import { performance as performance2 } from "node:perf_hooks";
16155
16340
  var TURN_PHASES = [
16156
16341
  /** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
@@ -16380,7 +16565,7 @@ function formatTurnTraceLine(record2) {
16380
16565
  return [head, ...record2.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
16381
16566
  }
16382
16567
  function turnTraceDirectory(runtimeDir) {
16383
- return resolve16(runtimeDir, "turn-traces");
16568
+ return resolve17(runtimeDir, "turn-traces");
16384
16569
  }
16385
16570
  var TURN_TRACE_RETENTION_DAYS = 7;
16386
16571
  function traceFileName(date) {
@@ -16397,13 +16582,13 @@ var TurnTraceFile = class {
16397
16582
  this.options = options;
16398
16583
  }
16399
16584
  path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
16400
- return resolve16(this.directory, traceFileName(now2));
16585
+ return resolve17(this.directory, traceFileName(now2));
16401
16586
  }
16402
16587
  write(record2) {
16403
16588
  this.tail = this.tail.catch(() => void 0).then(async () => {
16404
16589
  const now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))();
16405
16590
  const path = this.path(now2);
16406
- await mkdir6(this.directory, { recursive: true, mode: 448 });
16591
+ await mkdir7(this.directory, { recursive: true, mode: 448 });
16407
16592
  await appendFile(path, `${JSON.stringify(record2)}
16408
16593
  `, { mode: 384 });
16409
16594
  await this.prune(now2);
@@ -16421,7 +16606,7 @@ var TurnTraceFile = class {
16421
16606
  this.prunedDay = day;
16422
16607
  const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
16423
16608
  const names = await readdir4(this.directory).catch(() => []);
16424
- await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm3(resolve16(this.directory, name), { force: true })));
16609
+ await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm3(resolve17(this.directory, name), { force: true })));
16425
16610
  }
16426
16611
  };
16427
16612
 
@@ -16681,7 +16866,7 @@ var MonolithCornerTurnLoop = class {
16681
16866
  soul: configuration.soul ?? self?.soul,
16682
16867
  agentName: self?.name ?? this.agent.name
16683
16868
  });
16684
- await mkdir7(this.options.worktreePath, { recursive: true });
16869
+ await mkdir8(this.options.worktreePath, { recursive: true });
16685
16870
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
16686
16871
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
16687
16872
  root: this.options.config.agentHomeRoot,
@@ -16715,7 +16900,7 @@ var MonolithCornerTurnLoop = class {
16715
16900
  this.attachmentDir = tmpDir ? join5(tmpDir, "beeline-attachments") : void 0;
16716
16901
  this.sessionScratchDir = tmpDir;
16717
16902
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
16718
- await Promise.all(homeStateDirs.map((dir) => mkdir7(dir, { recursive: true })));
16903
+ await Promise.all(homeStateDirs.map((dir) => mkdir8(dir, { recursive: true })));
16719
16904
  const spawnCommand = wrapAgentCommand({
16720
16905
  bwrapPath: this.options.config.bwrapPath,
16721
16906
  spec: {
@@ -16768,6 +16953,11 @@ var MonolithCornerTurnLoop = class {
16768
16953
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
16769
16954
  })
16770
16955
  ];
16956
+ await installPiMcpBridge({
16957
+ agentCommand: command,
16958
+ piHome: agentEnv.PI_CODING_AGENT_DIR,
16959
+ servers
16960
+ });
16771
16961
  const persona = configuration.soul ?? self?.soul;
16772
16962
  const identityInstructions = `Your Beeline identity is ${self?.name ?? this.agent.name}.`;
16773
16963
  const personaInstructions = [
@@ -17146,7 +17336,7 @@ async function wait(ms, signal) {
17146
17336
  }
17147
17337
 
17148
17338
  // apps/body/dist/monolith-room-turn.js
17149
- import { mkdir as mkdir8 } from "node:fs/promises";
17339
+ import { mkdir as mkdir9 } from "node:fs/promises";
17150
17340
  import { homedir as homedir7 } from "node:os";
17151
17341
  import { join as join6 } from "node:path";
17152
17342
 
@@ -17461,7 +17651,7 @@ var MonolithRoomTurnLoop = class {
17461
17651
  agentName: self?.name ?? this.agent.name
17462
17652
  });
17463
17653
  const directMessage = Array.isArray(repositoryState.directParticipants) && repositoryState.directParticipants.length === 2;
17464
- await mkdir8(this.options.cwd, { recursive: true });
17654
+ await mkdir9(this.options.cwd, { recursive: true });
17465
17655
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
17466
17656
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
17467
17657
  root: this.options.config.agentHomeRoot,
@@ -17491,7 +17681,7 @@ var MonolithRoomTurnLoop = class {
17491
17681
  this.sessionScratchDir = tmpDir;
17492
17682
  this.sessionStateDirs = stateDirs;
17493
17683
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
17494
- await Promise.all(homeStateDirs.map((dir) => mkdir8(dir, { recursive: true })));
17684
+ await Promise.all(homeStateDirs.map((dir) => mkdir9(dir, { recursive: true })));
17495
17685
  const spawnCommand = wrapAgentCommand({
17496
17686
  bwrapPath: this.options.config.bwrapPath,
17497
17687
  spec: {
@@ -17520,6 +17710,11 @@ var MonolithRoomTurnLoop = class {
17520
17710
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
17521
17711
  })
17522
17712
  ];
17713
+ await installPiMcpBridge({
17714
+ agentCommand: command,
17715
+ piHome: agentEnv.PI_CODING_AGENT_DIR,
17716
+ servers
17717
+ });
17523
17718
  const mountedServers = servers.map((server) => server.name);
17524
17719
  const clientOptions = {
17525
17720
  agentCommand: spawnCommand.command,
@@ -18535,13 +18730,13 @@ var RoomRuntimeCoordinator = class {
18535
18730
  return this.runtime.rooms.find((room) => room.channelId === roomId);
18536
18731
  }
18537
18732
  roomRoot(roomId) {
18538
- return this.roomRecord(roomId)?.root ?? resolve17(dirname6(this.configPath), "rooms", roomId);
18733
+ return this.roomRecord(roomId)?.root ?? resolve18(dirname6(this.configPath), "rooms", roomId);
18539
18734
  }
18540
18735
  roomAgentHomeRoot(workspaceRoot, required = false) {
18541
18736
  const flag = process.env.BUZZY_BODY_ROOM_HOME;
18542
18737
  if (!required && flag === "0")
18543
18738
  return void 0;
18544
- const home = resolve17(workspaceRoot, "agent-home");
18739
+ const home = resolve18(workspaceRoot, "agent-home");
18545
18740
  if (!required && flag !== "1" && !existsSync4(home) && existsSync4(workspaceRoot))
18546
18741
  return void 0;
18547
18742
  try {
@@ -18558,8 +18753,8 @@ var RoomRuntimeCoordinator = class {
18558
18753
  return {
18559
18754
  ...this.baseConfig,
18560
18755
  workspaceRoot,
18561
- agentPrivateRoot: resolve17(workspaceRoot, "agent-private"),
18562
- agentMemoryRoot: resolve17(dirname6(this.configPath), "memory"),
18756
+ agentPrivateRoot: resolve18(workspaceRoot, "agent-private"),
18757
+ agentMemoryRoot: resolve18(dirname6(this.configPath), "memory"),
18563
18758
  openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname6(this.configPath)),
18564
18759
  turnTraceDir: turnTraceDirectory(dirname6(this.configPath)),
18565
18760
  ...agentHomeRoot ? { agentHomeRoot } : {}
@@ -18628,11 +18823,11 @@ var RoomRuntimeCoordinator = class {
18628
18823
  const remote = roomCheckoutRemote(repository.remote);
18629
18824
  const targetBranch = repository.targetBranch || "main";
18630
18825
  const checkoutId = createHash4("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
18631
- const path = resolve17(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
18632
- await mkdir9(dirname6(path), { recursive: true, mode: 448 });
18826
+ const path = resolve18(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
18827
+ await mkdir10(dirname6(path), { recursive: true, mode: 448 });
18633
18828
  const token = remote.startsWith("https://github.com/") ? await this.options.daemonApi.execute("getRoomGitHubToken", { roomId }) : void 0;
18634
18829
  const env = token ? githubGitEnv(token.token) : process.env;
18635
- if (!existsSync4(resolve17(path, ".git"))) {
18830
+ if (!existsSync4(resolve18(path, ".git"))) {
18636
18831
  await execFileAsync3("git", ["clone", "--no-checkout", remote, path], {
18637
18832
  env,
18638
18833
  maxBuffer: 4 * 1024 * 1024
@@ -18757,12 +18952,12 @@ var RoomRuntimeCoordinator = class {
18757
18952
  async materializeCornerWorktree(input) {
18758
18953
  const remote = githubHttpsRemote(input.remote);
18759
18954
  const repositoryHash = createHash4("sha256").update(remote).digest("hex").slice(0, 24);
18760
- const gitCommonDir = resolve17(this.runtime.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
18761
- const path = resolve17(this.runtime.supervisorRoot, "beeline", "corners", input.cornerId);
18762
- await mkdir9(dirname6(gitCommonDir), { recursive: true, mode: 448 });
18763
- await mkdir9(dirname6(path), { recursive: true, mode: 448 });
18955
+ const gitCommonDir = resolve18(this.runtime.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
18956
+ const path = resolve18(this.runtime.supervisorRoot, "beeline", "corners", input.cornerId);
18957
+ await mkdir10(dirname6(gitCommonDir), { recursive: true, mode: 448 });
18958
+ await mkdir10(dirname6(path), { recursive: true, mode: 448 });
18764
18959
  const authEnv = githubGitEnv(input.token);
18765
- if (!existsSync4(resolve17(gitCommonDir, "HEAD"))) {
18960
+ if (!existsSync4(resolve18(gitCommonDir, "HEAD"))) {
18766
18961
  await execFileAsync3("git", ["clone", "--bare", remote, gitCommonDir], {
18767
18962
  env: authEnv,
18768
18963
  maxBuffer: 4 * 1024 * 1024
@@ -18775,7 +18970,7 @@ var RoomRuntimeCoordinator = class {
18775
18970
  "origin",
18776
18971
  `+refs/heads/${input.targetBranch}:refs/remotes/origin/${input.targetBranch}`
18777
18972
  ], { env: authEnv, maxBuffer: 4 * 1024 * 1024 });
18778
- if (!existsSync4(resolve17(path, ".git"))) {
18973
+ if (!existsSync4(resolve18(path, ".git"))) {
18779
18974
  await rm4(path, { recursive: true, force: true });
18780
18975
  await execFileAsync3("git", [
18781
18976
  `--git-dir=${gitCommonDir}`,
@@ -18812,7 +19007,7 @@ var RoomRuntimeCoordinator = class {
18812
19007
  `${this.agent.publicKey.slice(0, 16)}@users.noreply.github.com`
18813
19008
  ]);
18814
19009
  const top = await execFileAsync3("git", ["-C", path, "rev-parse", "--show-toplevel"]);
18815
- if (resolve17(top.stdout.trim()) !== resolve17(path)) {
19010
+ if (resolve18(top.stdout.trim()) !== resolve18(path)) {
18816
19011
  throw new Error(`corner worktree escaped its isolated root: ${top.stdout.trim()}`);
18817
19012
  }
18818
19013
  return { path, gitCommonDir };
@@ -18990,9 +19185,9 @@ var ThinDaemonCore = class {
18990
19185
 
18991
19186
  // apps/body/dist/systemd.js
18992
19187
  import { execFile as execFile5 } from "node:child_process";
18993
- import { mkdir as mkdir10, readFile as readFile8, writeFile as writeFile7 } from "node:fs/promises";
19188
+ import { mkdir as mkdir11, readFile as readFile8, writeFile as writeFile7 } from "node:fs/promises";
18994
19189
  import { homedir as homedir8 } from "node:os";
18995
- import { dirname as dirname7, resolve as resolve18 } from "node:path";
19190
+ import { dirname as dirname7, resolve as resolve19 } from "node:path";
18996
19191
  import { setTimeout as sleep } from "node:timers/promises";
18997
19192
  import { promisify as promisify4 } from "node:util";
18998
19193
  var execFileAsync4 = promisify4(execFile5);
@@ -19034,9 +19229,9 @@ WantedBy=default.target
19034
19229
  }
19035
19230
  function isCanonicalInstalledLauncher(env = process.env, invocationPath = process.argv[1]) {
19036
19231
  const home = env.HOME?.trim() || homedir8();
19037
- const expectedLibDir = resolve18(home, ".local", "lib", "beeline");
19232
+ const expectedLibDir = resolve19(home, ".local", "lib", "beeline");
19038
19233
  const expectedPrefix = `${expectedLibDir}/`;
19039
- return resolve18(env.BEELINE_LIB_DIR?.trim() || "/") === expectedLibDir && Boolean(invocationPath) && resolve18(invocationPath).startsWith(expectedPrefix);
19234
+ return resolve19(env.BEELINE_LIB_DIR?.trim() || "/") === expectedLibDir && Boolean(invocationPath) && resolve19(invocationPath).startsWith(expectedPrefix);
19040
19235
  }
19041
19236
  function assertCanonicalInstalledLauncher(env, invocationPath) {
19042
19237
  if (isCanonicalInstalledLauncher(env, invocationPath))
@@ -19044,8 +19239,8 @@ function assertCanonicalInstalledLauncher(env, invocationPath) {
19044
19239
  throw new Error("refusing to modify the shared Beeline systemd unit outside the canonical ~/.local/bin/beeline launcher");
19045
19240
  }
19046
19241
  function systemdUserUnitPath(env = process.env) {
19047
- const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve18(homedir8(), ".config");
19048
- return resolve18(configRoot, "systemd", "user", SYSTEMD_UNIT_NAME);
19242
+ const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve19(homedir8(), ".config");
19243
+ return resolve19(configRoot, "systemd", "user", SYSTEMD_UNIT_NAME);
19049
19244
  }
19050
19245
  var runSystemctl = async (args) => {
19051
19246
  const result = await execFileAsync4("systemctl", ["--user", ...args], {
@@ -19063,7 +19258,7 @@ async function installAgentService(publicKey, options = {}) {
19063
19258
  const content = agentServiceUnit();
19064
19259
  const existing = await readFile8(path, "utf8").catch(() => "");
19065
19260
  if (existing !== content) {
19066
- await mkdir10(dirname7(path), { recursive: true, mode: 448 });
19261
+ await mkdir11(dirname7(path), { recursive: true, mode: 448 });
19067
19262
  await writeFile7(path, content, { mode: 384 });
19068
19263
  }
19069
19264
  const run2 = options.run ?? runSystemctl;
@@ -19236,8 +19431,8 @@ async function runStartCommand(args, interactiveUi) {
19236
19431
  // apps/body/dist/connect-command.js
19237
19432
  import { spawn as spawn5 } from "node:child_process";
19238
19433
  import { createHash as createHash6 } from "node:crypto";
19239
- import { chmod as chmod4, mkdir as mkdir12, readFile as readFile10, unlink as unlink2, writeFile as writeFile9 } from "node:fs/promises";
19240
- import { dirname as dirname10, resolve as resolve20 } from "node:path";
19434
+ import { chmod as chmod4, mkdir as mkdir13, readFile as readFile10, unlink as unlink2, writeFile as writeFile9 } from "node:fs/promises";
19435
+ import { dirname as dirname10, resolve as resolve21 } from "node:path";
19241
19436
  import { stdin as stdin3, stdout as stdout4 } from "node:process";
19242
19437
 
19243
19438
  // packages/api-contract/dist/agent-pairing-code.js
@@ -19820,7 +20015,7 @@ function parseConnectSubscriptions(value) {
19820
20015
  ...new Set((value ?? "").split(",").map((entry) => entry.trim().toLowerCase()).filter(Boolean))
19821
20016
  ];
19822
20017
  }
19823
- function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl, eventSubscriptions = []) {
20018
+ function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl) {
19824
20019
  const normalizedPairingCode = normalizeAgentPairingCode(pairingCode);
19825
20020
  if (!normalizedPairingCode)
19826
20021
  throw new Error("invalid pairing code");
@@ -19831,7 +20026,10 @@ function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl, eventSu
19831
20026
  ...selection.provider ? { provider: selection.provider } : {},
19832
20027
  model: selection.model,
19833
20028
  avatar_seed: avatarSeed,
19834
- ...eventSubscriptions.length ? { event_subscriptions: [...eventSubscriptions] } : {}
20029
+ // This wizard always finishes the join itself (`finishConnectedAgentPairing`,
20030
+ // called once the rename prompt below settles), so the claim must not
20031
+ // join Rooms or announce yet.
20032
+ defer_join: true
19835
20033
  }, fetchImpl);
19836
20034
  }
19837
20035
  async function renameConnectedAgent(baseUrl, pairingCode, name, fetchImpl) {
@@ -19841,6 +20039,16 @@ async function renameConnectedAgent(baseUrl, pairingCode, name, fetchImpl) {
19841
20039
  const renamed = await jsonRequest(`${baseUrl}/auth/agent/connect/name`, { pairing_code: normalizedPairingCode, agent_name: name.trim().replace(/\s+/g, " ") }, fetchImpl);
19842
20040
  return renamed.agent_name;
19843
20041
  }
20042
+ async function finishConnectedAgentPairing(baseUrl, pairingCode, workspaceJoined, eventSubscriptions, fetchImpl) {
20043
+ const normalizedPairingCode = normalizeAgentPairingCode(pairingCode);
20044
+ if (!normalizedPairingCode)
20045
+ throw new Error("invalid pairing code");
20046
+ await jsonRequest(`${baseUrl}/auth/agent/connect/finish`, {
20047
+ pairing_code: normalizedPairingCode,
20048
+ workspace_joined: workspaceJoined,
20049
+ ...eventSubscriptions.length ? { event_subscriptions: [...eventSubscriptions] } : {}
20050
+ }, fetchImpl);
20051
+ }
19844
20052
  function seededIdentityLine(grant) {
19845
20053
  return grant.agent_face ? `${grant.agent_name} the ${grant.agent_face}` : grant.agent_name;
19846
20054
  }
@@ -19858,7 +20066,7 @@ async function installCurrentRelease(fetchImpl) {
19858
20066
  });
19859
20067
  await activateRelease(layout, releaseId);
19860
20068
  return {
19861
- binary: resolve20(layout.binDir, "beeline"),
20069
+ binary: resolve21(layout.binDir, "beeline"),
19862
20070
  version: published.version ?? releaseId
19863
20071
  };
19864
20072
  }
@@ -19881,7 +20089,7 @@ function providerEnvironment(selection) {
19881
20089
  };
19882
20090
  }
19883
20091
  async function writePrivateJson(path, value) {
19884
- await mkdir12(dirname10(path), { recursive: true, mode: 448 });
20092
+ await mkdir13(dirname10(path), { recursive: true, mode: 448 });
19885
20093
  await writeFile9(path, `${JSON.stringify(value, null, 2)}
19886
20094
  `, { mode: 384 });
19887
20095
  await chmod4(path, 384);
@@ -19890,8 +20098,8 @@ async function writeProviderEnv(selection, agentPubkey) {
19890
20098
  const values = providerEnvironment(selection);
19891
20099
  if (Object.keys(values).length === 0)
19892
20100
  return void 0;
19893
- const path = resolve20(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
19894
- await mkdir12(dirname10(path), { recursive: true, mode: 448 });
20101
+ const path = resolve21(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
20102
+ await mkdir13(dirname10(path), { recursive: true, mode: 448 });
19895
20103
  const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
19896
20104
  await writeFile9(path, `${contents}
19897
20105
  `, { mode: 384 });
@@ -19951,11 +20159,12 @@ async function runConnectWizard(code, fetchImpl, eventSubscriptions, accessPolic
19951
20159
  });
19952
20160
  const selection = await collectConnectWizard(clackPrompts, loadConnectModelCatalog, fileConnectKeyStore, process.env, (input) => verifyProviderKey({ ...input, fetchImpl }));
19953
20161
  const baseUrl = (process.env.BEELINE_AUTH_URL ?? "https://server.usebeeline.app").replace(/\/$/, "");
19954
- const claimed = await brassSpinner("Connecting to your Beeline Workspace\u2026", () => requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl, eventSubscriptions), (connectedGrant) => `Connected to ${connectedGrant.workspace_name}`);
20162
+ const claimed = await brassSpinner("Connecting to your Beeline Workspace\u2026", () => requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl), (connectedGrant) => `Connected to ${connectedGrant.workspace_name}`);
19955
20163
  const grant = { ...claimed, agent_name: await confirmSeededName(baseUrl, pairingCode, claimed, fetchImpl) };
20164
+ await finishConnectedAgentPairing(baseUrl, pairingCode, grant.workspace_joined, eventSubscriptions, fetchImpl);
19956
20165
  const installedRelease = await brassSpinner("Installing the Beeline daemon\u2026", () => installCurrentRelease(fetchImpl), (release) => `Installed Beeline helper ${release.version}`);
19957
20166
  const llmEnvFile = await writeProviderEnv(selection, grant.agent_pubkey);
19958
- const grantPath = resolve20(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
20167
+ const grantPath = resolve21(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
19959
20168
  await writePrivateJson(grantPath, {
19960
20169
  agentSecretKey: grant.agent_secret_key,
19961
20170
  bodySecretKey: grant.body_secret_key,
@@ -20037,11 +20246,11 @@ async function runConnectFinishCommand(path) {
20037
20246
  throw new Error("connect-finish may run only from the canonical installed Beeline launcher");
20038
20247
  }
20039
20248
  try {
20040
- const grant = JSON.parse(await readFile10(resolve20(path), "utf8"));
20249
+ const grant = JSON.parse(await readFile10(resolve21(path), "utf8"));
20041
20250
  if (!isDevicePairingGrant(grant))
20042
20251
  throw new Error("device connection grant is invalid");
20043
20252
  const connected = await completeDevicePairing(grant);
20044
- await unlink2(resolve20(path));
20253
+ await unlink2(resolve21(path));
20045
20254
  const providerEnv = grant.llmEnvFile ? await readFile10(grant.llmEnvFile, "utf8").catch(() => "") : "";
20046
20255
  const apiKey = (/^OPENROUTER_API_KEY=(\S+)/m.exec(providerEnv)?.[1] ?? "").replace(/^["']|["']$/g, "");
20047
20256
  const model = openRouterModelId(grant.model, { OPENROUTER_API_KEY: apiKey });
@@ -20070,19 +20279,19 @@ init_self_update_manifest();
20070
20279
  // apps/body/dist/managed-update.js
20071
20280
  init_self_update();
20072
20281
  import { spawn as spawn6 } from "node:child_process";
20073
- import { mkdir as mkdir14, rm as rm6, stat as stat2, writeFile as writeFile11 } from "node:fs/promises";
20074
- import { dirname as dirname12, resolve as resolve22 } from "node:path";
20282
+ import { mkdir as mkdir15, rm as rm6, stat as stat2, writeFile as writeFile11 } from "node:fs/promises";
20283
+ import { dirname as dirname12, resolve as resolve23 } from "node:path";
20075
20284
 
20076
20285
  // apps/body/dist/update-rollback-alert.js
20077
- import { mkdir as mkdir13, readFile as readFile11, rename as rename4, writeFile as writeFile10 } from "node:fs/promises";
20078
- import { dirname as dirname11, resolve as resolve21 } from "node:path";
20286
+ import { mkdir as mkdir14, readFile as readFile11, rename as rename4, writeFile as writeFile10 } from "node:fs/promises";
20287
+ import { dirname as dirname11, resolve as resolve22 } from "node:path";
20079
20288
  function updateRollbackAlertPath(runtimeDir) {
20080
- return resolve21(runtimeDir, "update-rollback-alert.json");
20289
+ return resolve22(runtimeDir, "update-rollback-alert.json");
20081
20290
  }
20082
20291
  async function writeAlert(runtimeDir, alert) {
20083
20292
  const path = updateRollbackAlertPath(runtimeDir);
20084
20293
  const staged = `${path}.${process.pid}.tmp`;
20085
- await mkdir13(dirname11(path), { recursive: true });
20294
+ await mkdir14(dirname11(path), { recursive: true });
20086
20295
  await writeFile10(staged, `${JSON.stringify(alert, null, 2)}
20087
20296
  `, { mode: 384 });
20088
20297
  await rename4(staged, path);
@@ -20120,13 +20329,13 @@ var LOCK_STALE_MS = UPDATE_WORKER_DEADLINE_MS + 5 * 6e4;
20120
20329
  var DEFAULT_UPDATE_INITIAL_DELAY_MS = 0;
20121
20330
  async function withInstallLock(layout, work, options = {}) {
20122
20331
  const now2 = options.now ?? Date.now;
20123
- const lock = resolve22(layout.releasesRoot, ".state", "install.lock");
20332
+ const lock = resolve23(layout.releasesRoot, ".state", "install.lock");
20124
20333
  const deadline = now2() + (options.waitMs ?? 1e4);
20125
- await mkdir14(dirname12(lock), { recursive: true });
20334
+ await mkdir15(dirname12(lock), { recursive: true });
20126
20335
  for (; ; ) {
20127
20336
  try {
20128
- await mkdir14(lock);
20129
- await writeFile11(resolve22(lock, "owner"), `${process.pid}
20337
+ await mkdir15(lock);
20338
+ await writeFile11(resolve23(lock, "owner"), `${process.pid}
20130
20339
  ${now2()}
20131
20340
  `, "utf8");
20132
20341
  break;
@@ -20249,7 +20458,7 @@ var ManagedUpdateHandoff = class _ManagedUpdateHandoff {
20249
20458
  if (!attempt || attempt.releaseId !== desiredRelease || attempt.status !== "pending") {
20250
20459
  const from = await readInstalledBundleIdentity({
20251
20460
  ...this.#layout,
20252
- libDir: resolve22(this.#layout.releasesRoot, this.#loadedRelease)
20461
+ libDir: resolve23(this.#layout.releasesRoot, this.#loadedRelease)
20253
20462
  }).catch(() => void 0) ?? {};
20254
20463
  const to = await readInstalledBundleIdentity(this.#layout).catch(() => void 0) ?? {};
20255
20464
  const record2 = {
@@ -20536,7 +20745,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
20536
20745
  });
20537
20746
  if (!accepted)
20538
20747
  return false;
20539
- await writeFile11(resolve22(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
20748
+ await writeFile11(resolve23(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
20540
20749
  readyAt: (options.now ?? Date.now)(),
20541
20750
  loadedRelease,
20542
20751
  functionalProof: options.functionalProof
@@ -20741,12 +20950,12 @@ async function runUpdateCommand(args) {
20741
20950
  init_self_update();
20742
20951
 
20743
20952
  // apps/body/dist/daemon-failure.js
20744
- import { mkdir as mkdir15, readFile as readFile12, rename as rename5, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
20745
- import { dirname as dirname13, resolve as resolve23 } from "node:path";
20953
+ import { mkdir as mkdir16, readFile as readFile12, rename as rename5, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
20954
+ import { dirname as dirname13, resolve as resolve24 } from "node:path";
20746
20955
  var DAEMON_FAILURE_LIMIT = 3;
20747
20956
  var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
20748
20957
  function daemonFailurePath(runtimeDir) {
20749
- return resolve23(runtimeDir, "daemon-distress.json");
20958
+ return resolve24(runtimeDir, "daemon-distress.json");
20750
20959
  }
20751
20960
  async function readFailureRecord(runtimeDir) {
20752
20961
  try {
@@ -20762,7 +20971,7 @@ async function readFailureRecord(runtimeDir) {
20762
20971
  async function writeFailureRecord(runtimeDir, record2) {
20763
20972
  const path = daemonFailurePath(runtimeDir);
20764
20973
  const staged = `${path}.${process.pid}.tmp`;
20765
- await mkdir15(dirname13(path), { recursive: true, mode: 448 });
20974
+ await mkdir16(dirname13(path), { recursive: true, mode: 448 });
20766
20975
  await writeFile12(staged, `${JSON.stringify(record2, null, 2)}
20767
20976
  `, { mode: 384 });
20768
20977
  await rename5(staged, path);
@@ -20785,9 +20994,9 @@ async function clearDaemonStartFailures(runtimeDir) {
20785
20994
  }
20786
20995
 
20787
20996
  // apps/body/dist/update-functional-probe.js
20788
- import { mkdir as mkdir16, rm as rm8 } from "node:fs/promises";
20997
+ import { mkdir as mkdir17, rm as rm8 } from "node:fs/promises";
20789
20998
  import { homedir as homedir10 } from "node:os";
20790
- import { resolve as resolve24 } from "node:path";
20999
+ import { resolve as resolve25 } from "node:path";
20791
21000
  var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
20792
21001
  var UPDATE_PROBE_SESSION_OPEN_TIMEOUT_MS = 2e4;
20793
21002
  var UPDATE_PROBE_TURN_TIMEOUT_MS = 45e3;
@@ -20833,11 +21042,11 @@ async function runUpdateFunctionalProbe(input) {
20833
21042
  if (input.sandboxRequired && !input.config.bwrapPath) {
20834
21043
  throw new UpdateFunctionalProbeError("sandbox-unavailable", "the configured bubblewrap boundary did not pass its startup self-test");
20835
21044
  }
20836
- const root = input.probeRoot ?? resolve24(input.runtimeDir, "update-functional-probe");
20837
- const cwd = resolve24(root, "checkout");
20838
- const homeRoot = resolve24(root, "agent-home");
21045
+ const root = input.probeRoot ?? resolve25(input.runtimeDir, "update-functional-probe");
21046
+ const cwd = resolve25(root, "checkout");
21047
+ const homeRoot = resolve25(root, "agent-home");
20839
21048
  await rm8(root, { recursive: true, force: true });
20840
- await mkdir16(cwd, { recursive: true, mode: 448 });
21049
+ await mkdir17(cwd, { recursive: true, mode: 448 });
20841
21050
  let client;
20842
21051
  try {
20843
21052
  const agentEnv = {
@@ -20866,7 +21075,7 @@ async function runUpdateFunctionalProbe(input) {
20866
21075
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
20867
21076
  const operatorHome = input.config.operatorHome ?? homedir10();
20868
21077
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
20869
- await Promise.all(homeStateDirs.map((dir) => mkdir16(dir, { recursive: true })));
21078
+ await Promise.all(homeStateDirs.map((dir) => mkdir17(dir, { recursive: true })));
20870
21079
  spawnCommand = wrapAgentCommand({
20871
21080
  bwrapPath: input.config.bwrapPath,
20872
21081
  spec: {
@@ -21002,7 +21211,7 @@ async function probeReleaseInSubprocess(input) {
21002
21211
  return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
21003
21212
  }
21004
21213
  const timeoutMs = input.timeoutMs ?? CURRENT_RELEASE_PROBE_TIMEOUT_MS;
21005
- return new Promise((resolve27) => {
21214
+ return new Promise((resolve28) => {
21006
21215
  const child = spawn7(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
21007
21216
  let stdout6 = "";
21008
21217
  let stderr = "";
@@ -21012,7 +21221,7 @@ async function probeReleaseInSubprocess(input) {
21012
21221
  return;
21013
21222
  settled = true;
21014
21223
  clearTimeout(timer);
21015
- resolve27(outcome);
21224
+ resolve28(outcome);
21016
21225
  };
21017
21226
  const timer = setTimeout(() => {
21018
21227
  child.kill("SIGKILL");
@@ -21092,7 +21301,7 @@ async function runUpdateProbeCommand(args, options = {}) {
21092
21301
 
21093
21302
  // apps/body/dist/release-status.js
21094
21303
  import { readFile as readFile13, readdir as readdir5, rename as rename6, writeFile as writeFile13 } from "node:fs/promises";
21095
- import { resolve as resolve25 } from "node:path";
21304
+ import { resolve as resolve26 } from "node:path";
21096
21305
  var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
21097
21306
  var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
21098
21307
  var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
@@ -21109,7 +21318,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
21109
21318
  pid: options.pid ?? process.pid,
21110
21319
  readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
21111
21320
  };
21112
- const target = resolve25(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
21321
+ const target = resolve26(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
21113
21322
  const temporary = `${target}.${status.pid}.tmp`;
21114
21323
  await writeFile13(temporary, `${JSON.stringify(status, null, 2)}
21115
21324
  `, { mode: 384 });
@@ -21169,7 +21378,7 @@ async function runStoredDaemon(pathOrPointer) {
21169
21378
  runtime = activated.runtime;
21170
21379
  const daemonApi = activated.client;
21171
21380
  const agent = runtimeAgentCommand(runtime);
21172
- await writeFile14(resolve26(dirname15(configPath), "daemon.pid"), `${process.pid}
21381
+ await writeFile14(resolve27(dirname15(configPath), "daemon.pid"), `${process.pid}
21173
21382
  `, { mode: 384 });
21174
21383
  const env = {
21175
21384
  ...process.env,
@@ -21177,7 +21386,7 @@ async function runStoredDaemon(pathOrPointer) {
21177
21386
  BUZZ_DEV_MCP_BIN: runtime.mcpBinary
21178
21387
  };
21179
21388
  const config = loadBodyConfig({
21180
- workspaceRoot: resolve26(dirname15(configPath), "workspace"),
21389
+ workspaceRoot: resolve27(dirname15(configPath), "workspace"),
21181
21390
  llmEnvFile: runtime.llmEnvFile,
21182
21391
  env,
21183
21392
  agent
@@ -21347,7 +21556,7 @@ async function runStoredDaemon(pathOrPointer) {
21347
21556
  throw error;
21348
21557
  } finally {
21349
21558
  await notifier.stopping(stoppingStatus).catch(() => void 0);
21350
- const pidPath = resolve26(dirname15(configPath), "daemon.pid");
21559
+ const pidPath = resolve27(dirname15(configPath), "daemon.pid");
21351
21560
  const recorded = Number((await readFile14(pidPath, "utf8").catch(() => "")).trim());
21352
21561
  if (recorded === process.pid) {
21353
21562
  await unlink3(pidPath).catch(() => void 0);
@@ -21422,7 +21631,7 @@ async function main() {
21422
21631
  }
21423
21632
  if (!configPath)
21424
21633
  throw new Error("daemon requires --config <runtime.json> or --agent <pubkey>");
21425
- await runStoredDaemon(resolve26(configPath));
21634
+ await runStoredDaemon(resolve27(configPath));
21426
21635
  return;
21427
21636
  }
21428
21637
  if (command === "update") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usebeeline",
3
- "version": "0.0.48",
3
+ "version": "0.0.49",
4
4
  "description": "Connect an AI coding agent to Beeline with one command.",
5
5
  "homepage": "https://usebeeline.app",
6
6
  "bugs": {