usebeeline 0.0.47 → 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 +402 -113
  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
 
@@ -2952,8 +2952,12 @@ function parseSandboxMaskEnv(env) {
2952
2952
  }
2953
2953
 
2954
2954
  // apps/body/dist/access-policy.js
2955
+ var AGENT_ACCESS_POLICIES = ["everyone", "creator", "allowlist"];
2955
2956
  var DEFAULT_ACCESS_POLICY = "creator";
2956
2957
  var LEGACY_ACCESS_POLICY = "everyone";
2958
+ function isAgentAccessPolicy(value) {
2959
+ return AGENT_ACCESS_POLICIES.includes(value);
2960
+ }
2957
2961
  var ACCESS_REFUSAL_WINDOW_MS = 60 * 60 * 1e3;
2958
2962
  function isSenderPermitted(policy, senderPubkey, ownerPubkey, allowlist = void 0) {
2959
2963
  if (!senderPubkey)
@@ -3828,7 +3832,7 @@ var AcpClient = class extends EventEmitter {
3828
3832
  const current = this.activeRunIds.get(sessionId);
3829
3833
  if (current)
3830
3834
  return Promise.resolve(current);
3831
- return new Promise((resolve27, reject) => {
3835
+ return new Promise((resolve28, reject) => {
3832
3836
  const onUpdate = (update) => {
3833
3837
  if (update.sessionId !== sessionId)
3834
3838
  return;
@@ -3836,7 +3840,7 @@ var AcpClient = class extends EventEmitter {
3836
3840
  if (!runId)
3837
3841
  return;
3838
3842
  cleanup();
3839
- resolve27(runId);
3843
+ resolve28(runId);
3840
3844
  };
3841
3845
  const timer = setTimeout(() => {
3842
3846
  cleanup();
@@ -3920,13 +3924,13 @@ var AcpClient = class extends EventEmitter {
3920
3924
  }
3921
3925
  const id = this.nextId++;
3922
3926
  const payload = { jsonrpc: "2.0", id, method, params };
3923
- return new Promise((resolve27, reject) => {
3927
+ return new Promise((resolve28, reject) => {
3924
3928
  const timer = setTimeout(() => {
3925
3929
  this.pending.delete(id);
3926
3930
  reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, Boolean(onStart), detail));
3927
3931
  }, timeoutMs);
3928
3932
  this.pending.set(id, {
3929
- resolve: resolve27,
3933
+ resolve: resolve28,
3930
3934
  reject,
3931
3935
  timer,
3932
3936
  method,
@@ -13059,7 +13063,7 @@ async function stageMonolithAgentRuntime(input) {
13059
13063
  supervisorRoot,
13060
13064
  transport: { kind: "monolith", baseUrl, exchangeToken: input.daemonExchangeToken },
13061
13065
  ...input.llmEnvFile ? { llmEnvFile: input.llmEnvFile } : {},
13062
- accessPolicy: DEFAULT_ACCESS_POLICY,
13066
+ accessPolicy: input.accessPolicy ?? DEFAULT_ACCESS_POLICY,
13063
13067
  agentBinary: input.agentBinary,
13064
13068
  agentKind: input.agentKind,
13065
13069
  agentCommand: input.agentCommand,
@@ -13279,8 +13283,8 @@ async function activateDaemonTransport(path, fetchImpl = fetch) {
13279
13283
  import { execFile as execFile4 } from "node:child_process";
13280
13284
  import { createHash as createHash4 } from "node:crypto";
13281
13285
  import { existsSync as existsSync4, mkdirSync } from "node:fs";
13282
- import { mkdir as mkdir9, rm as rm4 } from "node:fs/promises";
13283
- 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";
13284
13288
  import { promisify as promisify3 } from "node:util";
13285
13289
 
13286
13290
  // apps/body/dist/grant-runner.js
@@ -14122,7 +14126,7 @@ var GrantRunnerServer = class {
14122
14126
 
14123
14127
  // apps/body/dist/monolith-corner-turn.js
14124
14128
  import { execFile as execFile3 } from "node:child_process";
14125
- import { mkdir as mkdir7 } from "node:fs/promises";
14129
+ import { mkdir as mkdir8 } from "node:fs/promises";
14126
14130
  import { homedir as homedir6 } from "node:os";
14127
14131
  import { join as join5 } from "node:path";
14128
14132
  import { promisify as promisify2 } from "node:util";
@@ -14147,6 +14151,8 @@ var BEELINE_ROOM_CAPABILITIES = [
14147
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.",
14148
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.",
14149
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.",
14150
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.",
14151
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.",
14152
14158
  "Never claim an action or reply happened unless the prompt or a tool result proves it."
@@ -15664,8 +15670,191 @@ function sessionConfigFingerprint(input) {
15664
15670
  ]);
15665
15671
  }
15666
15672
 
15667
- // apps/body/dist/room-session.js
15673
+ // apps/body/dist/pi-mcp-bridge.js
15674
+ import { mkdir as mkdir6 } from "node:fs/promises";
15668
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";
15669
15858
 
15670
15859
  // apps/body/dist/read-only-policy.js
15671
15860
  var READ_ONLY_MCP_SERVER_NAME = "beeline-readonly-mcp";
@@ -15888,21 +16077,21 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
15888
16077
  command: config.readonlyMcpCommand,
15889
16078
  args: [...config.readonlyMcpArgs ?? []],
15890
16079
  env: [
15891
- { name: "BEELINE_READONLY_ROOT", value: resolve14(cwd) },
16080
+ { name: "BEELINE_READONLY_ROOT", value: resolve15(cwd) },
15892
16081
  ...config.agentHomeRoot ? [
15893
16082
  {
15894
16083
  name: "BEELINE_READONLY_AGENT_SKILLS_ROOT",
15895
- value: resolve14(config.agentHomeRoot, skillDir, "skills")
16084
+ value: resolve15(config.agentHomeRoot, skillDir, "skills")
15896
16085
  }
15897
16086
  ] : [],
15898
- ...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve14(agentMemoryDir) }] : []
16087
+ ...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve15(agentMemoryDir) }] : []
15899
16088
  ]
15900
16089
  };
15901
16090
  }
15902
16091
 
15903
16092
  // apps/body/dist/pi-turn-record.js
15904
16093
  import { readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
15905
- import { resolve as resolve15 } from "node:path";
16094
+ import { resolve as resolve16 } from "node:path";
15906
16095
  function summarizeProviderError(errorMessage2) {
15907
16096
  const trimmed = errorMessage2.trim();
15908
16097
  const statusMatch = /^(\d{3}):\s*([\s\S]*)$/.exec(trimmed);
@@ -15923,7 +16112,7 @@ function summarizeProviderError(errorMessage2) {
15923
16112
  }
15924
16113
  async function sessionFileFromMap(home, sessionId) {
15925
16114
  try {
15926
- 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");
15927
16116
  const map = JSON.parse(raw);
15928
16117
  const file = map.sessions?.[sessionId]?.sessionFile;
15929
16118
  return typeof file === "string" && file ? file : void 0;
@@ -15932,7 +16121,7 @@ async function sessionFileFromMap(home, sessionId) {
15932
16121
  }
15933
16122
  }
15934
16123
  async function sessionFileFromLayout(piDir, sessionId) {
15935
- const sessionsRoot = resolve15(piDir, "sessions");
16124
+ const sessionsRoot = resolve16(piDir, "sessions");
15936
16125
  const suffix = `_${sessionId}.jsonl`;
15937
16126
  let projects;
15938
16127
  try {
@@ -15941,7 +16130,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
15941
16130
  return void 0;
15942
16131
  }
15943
16132
  for (const project of projects) {
15944
- const dir = resolve15(sessionsRoot, project);
16133
+ const dir = resolve16(sessionsRoot, project);
15945
16134
  let files;
15946
16135
  try {
15947
16136
  files = await readdir3(dir);
@@ -15950,7 +16139,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
15950
16139
  }
15951
16140
  const match = files.find((file) => file.endsWith(suffix));
15952
16141
  if (match)
15953
- return resolve15(dir, match);
16142
+ return resolve16(dir, match);
15954
16143
  }
15955
16144
  return void 0;
15956
16145
  }
@@ -16145,8 +16334,8 @@ async function withTurnReceiptHeartbeat(api, receipt, task, onHeartbeatError) {
16145
16334
  }
16146
16335
 
16147
16336
  // apps/body/dist/turn-trace.js
16148
- import { appendFile, mkdir as mkdir6, readdir as readdir4, rm as rm3 } from "node:fs/promises";
16149
- 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";
16150
16339
  import { performance as performance2 } from "node:perf_hooks";
16151
16340
  var TURN_PHASES = [
16152
16341
  /** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
@@ -16376,7 +16565,7 @@ function formatTurnTraceLine(record2) {
16376
16565
  return [head, ...record2.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
16377
16566
  }
16378
16567
  function turnTraceDirectory(runtimeDir) {
16379
- return resolve16(runtimeDir, "turn-traces");
16568
+ return resolve17(runtimeDir, "turn-traces");
16380
16569
  }
16381
16570
  var TURN_TRACE_RETENTION_DAYS = 7;
16382
16571
  function traceFileName(date) {
@@ -16393,13 +16582,13 @@ var TurnTraceFile = class {
16393
16582
  this.options = options;
16394
16583
  }
16395
16584
  path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
16396
- return resolve16(this.directory, traceFileName(now2));
16585
+ return resolve17(this.directory, traceFileName(now2));
16397
16586
  }
16398
16587
  write(record2) {
16399
16588
  this.tail = this.tail.catch(() => void 0).then(async () => {
16400
16589
  const now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))();
16401
16590
  const path = this.path(now2);
16402
- await mkdir6(this.directory, { recursive: true, mode: 448 });
16591
+ await mkdir7(this.directory, { recursive: true, mode: 448 });
16403
16592
  await appendFile(path, `${JSON.stringify(record2)}
16404
16593
  `, { mode: 384 });
16405
16594
  await this.prune(now2);
@@ -16417,7 +16606,7 @@ var TurnTraceFile = class {
16417
16606
  this.prunedDay = day;
16418
16607
  const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
16419
16608
  const names = await readdir4(this.directory).catch(() => []);
16420
- 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 })));
16421
16610
  }
16422
16611
  };
16423
16612
 
@@ -16677,7 +16866,7 @@ var MonolithCornerTurnLoop = class {
16677
16866
  soul: configuration.soul ?? self?.soul,
16678
16867
  agentName: self?.name ?? this.agent.name
16679
16868
  });
16680
- await mkdir7(this.options.worktreePath, { recursive: true });
16869
+ await mkdir8(this.options.worktreePath, { recursive: true });
16681
16870
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
16682
16871
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
16683
16872
  root: this.options.config.agentHomeRoot,
@@ -16711,7 +16900,7 @@ var MonolithCornerTurnLoop = class {
16711
16900
  this.attachmentDir = tmpDir ? join5(tmpDir, "beeline-attachments") : void 0;
16712
16901
  this.sessionScratchDir = tmpDir;
16713
16902
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
16714
- await Promise.all(homeStateDirs.map((dir) => mkdir7(dir, { recursive: true })));
16903
+ await Promise.all(homeStateDirs.map((dir) => mkdir8(dir, { recursive: true })));
16715
16904
  const spawnCommand = wrapAgentCommand({
16716
16905
  bwrapPath: this.options.config.bwrapPath,
16717
16906
  spec: {
@@ -16764,6 +16953,11 @@ var MonolithCornerTurnLoop = class {
16764
16953
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
16765
16954
  })
16766
16955
  ];
16956
+ await installPiMcpBridge({
16957
+ agentCommand: command,
16958
+ piHome: agentEnv.PI_CODING_AGENT_DIR,
16959
+ servers
16960
+ });
16767
16961
  const persona = configuration.soul ?? self?.soul;
16768
16962
  const identityInstructions = `Your Beeline identity is ${self?.name ?? this.agent.name}.`;
16769
16963
  const personaInstructions = [
@@ -17117,8 +17311,16 @@ async function waitForWake(api, cornerId, signal) {
17117
17311
  try {
17118
17312
  await api.execute("waitForCornerWake", { cornerId });
17119
17313
  } catch {
17314
+ await never(signal);
17120
17315
  }
17121
17316
  }
17317
+ async function never(signal) {
17318
+ if (signal?.aborted)
17319
+ return;
17320
+ await new Promise((resolveNever) => {
17321
+ signal?.addEventListener("abort", () => resolveNever(), { once: true });
17322
+ });
17323
+ }
17122
17324
  async function wait(ms, signal) {
17123
17325
  if (signal?.aborted)
17124
17326
  return;
@@ -17134,7 +17336,7 @@ async function wait(ms, signal) {
17134
17336
  }
17135
17337
 
17136
17338
  // apps/body/dist/monolith-room-turn.js
17137
- import { mkdir as mkdir8 } from "node:fs/promises";
17339
+ import { mkdir as mkdir9 } from "node:fs/promises";
17138
17340
  import { homedir as homedir7 } from "node:os";
17139
17341
  import { join as join6 } from "node:path";
17140
17342
 
@@ -17142,6 +17344,24 @@ import { join as join6 } from "node:path";
17142
17344
  var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
17143
17345
  var SCHEDULE_RAN_VERB = "ran a schedule for";
17144
17346
 
17347
+ // packages/api-contract/dist/system-events.js
17348
+ var SERVER_EVENT_KINDS = [
17349
+ "joined",
17350
+ "schedule-ran",
17351
+ "corner-opened",
17352
+ "check-passed",
17353
+ "check-failed",
17354
+ "merged",
17355
+ "grant-decided"
17356
+ ];
17357
+ function isServerEventKind(value) {
17358
+ return SERVER_EVENT_KINDS.includes(value);
17359
+ }
17360
+ var RESUME_KINDS = ["grant-decided"];
17361
+ function isResumeKind(value) {
17362
+ return RESUME_KINDS.includes(value);
17363
+ }
17364
+
17145
17365
  // apps/body/dist/monolith-room-turn.js
17146
17366
  function isRoomMcpPermissionRequest(request, mountedServers = ROOM_MOUNTED_MCP_SERVERS) {
17147
17367
  if (isSquireMcpPermissionRequest(request))
@@ -17152,11 +17372,35 @@ function roomPrincipalMayAddressAgent(authority, humanPermitted) {
17152
17372
  return authority.member && (authority.principalKind === "agent" || authority.principalKind === "human" && humanPermitted);
17153
17373
  }
17154
17374
  function isScheduledPrompt(item, agentId) {
17155
- return item.type === "system" && item.systemEvent?.verb === SCHEDULE_RAN_VERB && item.mentionIds.includes(agentId);
17375
+ if (item.type !== "system" || !item.mentionIds.includes(agentId))
17376
+ return false;
17377
+ if (item.systemEvent?.kind)
17378
+ return item.systemEvent.kind === "schedule-ran";
17379
+ return item.systemEvent?.verb === SCHEDULE_RAN_VERB;
17380
+ }
17381
+ function inboxItemAuthorName(item, agentId, names) {
17382
+ if (isScheduledPrompt(item, agentId))
17383
+ return SCHEDULE_SCHEDULER_NAME;
17384
+ const subject = item.systemEvent?.subject;
17385
+ if (item.type === "system" && subject?.name)
17386
+ return subject.name;
17387
+ return names.get(item.authorId) ?? item.authorId.slice(0, 12);
17156
17388
  }
17157
17389
  function inboxItemPromptBody(item, agentId) {
17158
17390
  return isScheduledPrompt(item, agentId) ? item.systemEvent?.consequence ?? item.body : item.body;
17159
17391
  }
17392
+ function isSubscribedEvent(item, agentId) {
17393
+ const kind = item.systemEvent?.kind;
17394
+ return item.type === "system" && kind !== void 0 && !isResumeKind(kind) && item.mentionIds.includes(agentId);
17395
+ }
17396
+ function inboxItemSkipsSenderPolicy(item, agentId) {
17397
+ if (isGrantDecisionLine(item, agentId))
17398
+ return true;
17399
+ if (item.type !== "system" || !item.mentionIds.includes(agentId))
17400
+ return false;
17401
+ const kind = item.systemEvent?.kind;
17402
+ return kind === void 0 ? isScheduledPrompt(item, agentId) : isServerEventKind(kind);
17403
+ }
17160
17404
  function isGrantDecisionLine(item, agentId) {
17161
17405
  return item.type === "system" && item.mentionIds.includes(agentId) && parseGrantDecisionLine(item.body) !== void 0;
17162
17406
  }
@@ -17165,7 +17409,7 @@ function inboxItemTriggersTurn(item, agentId) {
17165
17409
  return false;
17166
17410
  if (!item.mentionIds.includes(agentId))
17167
17411
  return false;
17168
- return item.type === "message" || isScheduledPrompt(item, agentId) || isGrantDecisionLine(item, agentId);
17412
+ return item.type === "message" || isSubscribedEvent(item, agentId) || isScheduledPrompt(item, agentId) || isGrantDecisionLine(item, agentId);
17169
17413
  }
17170
17414
  function pendingGrantToolCall(call) {
17171
17415
  if (!/(?:^|[._:/-])request_grant$/i.test(call.title ?? ""))
@@ -17407,7 +17651,7 @@ var MonolithRoomTurnLoop = class {
17407
17651
  agentName: self?.name ?? this.agent.name
17408
17652
  });
17409
17653
  const directMessage = Array.isArray(repositoryState.directParticipants) && repositoryState.directParticipants.length === 2;
17410
- await mkdir8(this.options.cwd, { recursive: true });
17654
+ await mkdir9(this.options.cwd, { recursive: true });
17411
17655
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
17412
17656
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
17413
17657
  root: this.options.config.agentHomeRoot,
@@ -17437,7 +17681,7 @@ var MonolithRoomTurnLoop = class {
17437
17681
  this.sessionScratchDir = tmpDir;
17438
17682
  this.sessionStateDirs = stateDirs;
17439
17683
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
17440
- await Promise.all(homeStateDirs.map((dir) => mkdir8(dir, { recursive: true })));
17684
+ await Promise.all(homeStateDirs.map((dir) => mkdir9(dir, { recursive: true })));
17441
17685
  const spawnCommand = wrapAgentCommand({
17442
17686
  bwrapPath: this.options.config.bwrapPath,
17443
17687
  spec: {
@@ -17466,6 +17710,11 @@ var MonolithRoomTurnLoop = class {
17466
17710
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
17467
17711
  })
17468
17712
  ];
17713
+ await installPiMcpBridge({
17714
+ agentCommand: command,
17715
+ piHome: agentEnv.PI_CODING_AGENT_DIR,
17716
+ servers
17717
+ });
17469
17718
  const mountedServers = servers.map((server) => server.name);
17470
17719
  const clientOptions = {
17471
17720
  agentCommand: spawnCommand.command,
@@ -17657,7 +17906,7 @@ var MonolithRoomTurnLoop = class {
17657
17906
  const buildPrompt = () => [
17658
17907
  this.turnInstructionPrefix,
17659
17908
  WarmTranscript.render(this.warmTranscript.select(this.sessionId, transcriptRows), "Room conversation so far:", "New in the Room since your last turn (the earlier conversation is already in this session):"),
17660
- `Newest message from ${isScheduledPrompt(item, this.agent.publicKey) ? SCHEDULE_SCHEDULER_NAME : names.get(item.authorId) ?? item.authorId.slice(0, 12)}:`,
17909
+ `Newest message from ${inboxItemAuthorName(item, this.agent.publicKey, names)}:`,
17661
17910
  roomMessagePrompt("", inboxItemPromptBody(item, this.agent.publicKey), item.attachments, delivered, this.acceptsImages()),
17662
17911
  grantDecision ? [
17663
17912
  "This is the answer to your grant request; your paused work resumes now.",
@@ -17819,7 +18068,7 @@ var MonolithRoomTurnLoop = class {
17819
18068
  for (const item of inbox.items) {
17820
18069
  if (!inboxItemTriggersTurn(item, this.agent.publicKey))
17821
18070
  continue;
17822
- if (!isScheduledPrompt(item, this.agent.publicKey) && !isGrantDecisionLine(item, this.agent.publicKey)) {
18071
+ if (!inboxItemSkipsSenderPolicy(item, this.agent.publicKey)) {
17823
18072
  const authority = await api.execute("getRoomAuthority", {
17824
18073
  roomId,
17825
18074
  principalId: item.authorId
@@ -18481,13 +18730,13 @@ var RoomRuntimeCoordinator = class {
18481
18730
  return this.runtime.rooms.find((room) => room.channelId === roomId);
18482
18731
  }
18483
18732
  roomRoot(roomId) {
18484
- return this.roomRecord(roomId)?.root ?? resolve17(dirname6(this.configPath), "rooms", roomId);
18733
+ return this.roomRecord(roomId)?.root ?? resolve18(dirname6(this.configPath), "rooms", roomId);
18485
18734
  }
18486
18735
  roomAgentHomeRoot(workspaceRoot, required = false) {
18487
18736
  const flag = process.env.BUZZY_BODY_ROOM_HOME;
18488
18737
  if (!required && flag === "0")
18489
18738
  return void 0;
18490
- const home = resolve17(workspaceRoot, "agent-home");
18739
+ const home = resolve18(workspaceRoot, "agent-home");
18491
18740
  if (!required && flag !== "1" && !existsSync4(home) && existsSync4(workspaceRoot))
18492
18741
  return void 0;
18493
18742
  try {
@@ -18504,8 +18753,8 @@ var RoomRuntimeCoordinator = class {
18504
18753
  return {
18505
18754
  ...this.baseConfig,
18506
18755
  workspaceRoot,
18507
- agentPrivateRoot: resolve17(workspaceRoot, "agent-private"),
18508
- agentMemoryRoot: resolve17(dirname6(this.configPath), "memory"),
18756
+ agentPrivateRoot: resolve18(workspaceRoot, "agent-private"),
18757
+ agentMemoryRoot: resolve18(dirname6(this.configPath), "memory"),
18509
18758
  openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname6(this.configPath)),
18510
18759
  turnTraceDir: turnTraceDirectory(dirname6(this.configPath)),
18511
18760
  ...agentHomeRoot ? { agentHomeRoot } : {}
@@ -18574,11 +18823,11 @@ var RoomRuntimeCoordinator = class {
18574
18823
  const remote = roomCheckoutRemote(repository.remote);
18575
18824
  const targetBranch = repository.targetBranch || "main";
18576
18825
  const checkoutId = createHash4("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
18577
- const path = resolve17(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
18578
- 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 });
18579
18828
  const token = remote.startsWith("https://github.com/") ? await this.options.daemonApi.execute("getRoomGitHubToken", { roomId }) : void 0;
18580
18829
  const env = token ? githubGitEnv(token.token) : process.env;
18581
- if (!existsSync4(resolve17(path, ".git"))) {
18830
+ if (!existsSync4(resolve18(path, ".git"))) {
18582
18831
  await execFileAsync3("git", ["clone", "--no-checkout", remote, path], {
18583
18832
  env,
18584
18833
  maxBuffer: 4 * 1024 * 1024
@@ -18703,12 +18952,12 @@ var RoomRuntimeCoordinator = class {
18703
18952
  async materializeCornerWorktree(input) {
18704
18953
  const remote = githubHttpsRemote(input.remote);
18705
18954
  const repositoryHash = createHash4("sha256").update(remote).digest("hex").slice(0, 24);
18706
- const gitCommonDir = resolve17(this.runtime.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
18707
- const path = resolve17(this.runtime.supervisorRoot, "beeline", "corners", input.cornerId);
18708
- await mkdir9(dirname6(gitCommonDir), { recursive: true, mode: 448 });
18709
- 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 });
18710
18959
  const authEnv = githubGitEnv(input.token);
18711
- if (!existsSync4(resolve17(gitCommonDir, "HEAD"))) {
18960
+ if (!existsSync4(resolve18(gitCommonDir, "HEAD"))) {
18712
18961
  await execFileAsync3("git", ["clone", "--bare", remote, gitCommonDir], {
18713
18962
  env: authEnv,
18714
18963
  maxBuffer: 4 * 1024 * 1024
@@ -18721,7 +18970,7 @@ var RoomRuntimeCoordinator = class {
18721
18970
  "origin",
18722
18971
  `+refs/heads/${input.targetBranch}:refs/remotes/origin/${input.targetBranch}`
18723
18972
  ], { env: authEnv, maxBuffer: 4 * 1024 * 1024 });
18724
- if (!existsSync4(resolve17(path, ".git"))) {
18973
+ if (!existsSync4(resolve18(path, ".git"))) {
18725
18974
  await rm4(path, { recursive: true, force: true });
18726
18975
  await execFileAsync3("git", [
18727
18976
  `--git-dir=${gitCommonDir}`,
@@ -18758,7 +19007,7 @@ var RoomRuntimeCoordinator = class {
18758
19007
  `${this.agent.publicKey.slice(0, 16)}@users.noreply.github.com`
18759
19008
  ]);
18760
19009
  const top = await execFileAsync3("git", ["-C", path, "rev-parse", "--show-toplevel"]);
18761
- if (resolve17(top.stdout.trim()) !== resolve17(path)) {
19010
+ if (resolve18(top.stdout.trim()) !== resolve18(path)) {
18762
19011
  throw new Error(`corner worktree escaped its isolated root: ${top.stdout.trim()}`);
18763
19012
  }
18764
19013
  return { path, gitCommonDir };
@@ -18936,9 +19185,9 @@ var ThinDaemonCore = class {
18936
19185
 
18937
19186
  // apps/body/dist/systemd.js
18938
19187
  import { execFile as execFile5 } from "node:child_process";
18939
- 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";
18940
19189
  import { homedir as homedir8 } from "node:os";
18941
- import { dirname as dirname7, resolve as resolve18 } from "node:path";
19190
+ import { dirname as dirname7, resolve as resolve19 } from "node:path";
18942
19191
  import { setTimeout as sleep } from "node:timers/promises";
18943
19192
  import { promisify as promisify4 } from "node:util";
18944
19193
  var execFileAsync4 = promisify4(execFile5);
@@ -18980,9 +19229,9 @@ WantedBy=default.target
18980
19229
  }
18981
19230
  function isCanonicalInstalledLauncher(env = process.env, invocationPath = process.argv[1]) {
18982
19231
  const home = env.HOME?.trim() || homedir8();
18983
- const expectedLibDir = resolve18(home, ".local", "lib", "beeline");
19232
+ const expectedLibDir = resolve19(home, ".local", "lib", "beeline");
18984
19233
  const expectedPrefix = `${expectedLibDir}/`;
18985
- 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);
18986
19235
  }
18987
19236
  function assertCanonicalInstalledLauncher(env, invocationPath) {
18988
19237
  if (isCanonicalInstalledLauncher(env, invocationPath))
@@ -18990,8 +19239,8 @@ function assertCanonicalInstalledLauncher(env, invocationPath) {
18990
19239
  throw new Error("refusing to modify the shared Beeline systemd unit outside the canonical ~/.local/bin/beeline launcher");
18991
19240
  }
18992
19241
  function systemdUserUnitPath(env = process.env) {
18993
- const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve18(homedir8(), ".config");
18994
- 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);
18995
19244
  }
18996
19245
  var runSystemctl = async (args) => {
18997
19246
  const result = await execFileAsync4("systemctl", ["--user", ...args], {
@@ -19009,7 +19258,7 @@ async function installAgentService(publicKey, options = {}) {
19009
19258
  const content = agentServiceUnit();
19010
19259
  const existing = await readFile8(path, "utf8").catch(() => "");
19011
19260
  if (existing !== content) {
19012
- await mkdir10(dirname7(path), { recursive: true, mode: 448 });
19261
+ await mkdir11(dirname7(path), { recursive: true, mode: 448 });
19013
19262
  await writeFile7(path, content, { mode: 384 });
19014
19263
  }
19015
19264
  const run2 = options.run ?? runSystemctl;
@@ -19182,8 +19431,8 @@ async function runStartCommand(args, interactiveUi) {
19182
19431
  // apps/body/dist/connect-command.js
19183
19432
  import { spawn as spawn5 } from "node:child_process";
19184
19433
  import { createHash as createHash6 } from "node:crypto";
19185
- import { chmod as chmod4, mkdir as mkdir12, readFile as readFile10, unlink as unlink2, writeFile as writeFile9 } from "node:fs/promises";
19186
- 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";
19187
19436
  import { stdin as stdin3, stdout as stdout4 } from "node:process";
19188
19437
 
19189
19438
  // packages/api-contract/dist/agent-pairing-code.js
@@ -19476,6 +19725,7 @@ async function pairDevice(grant, options = {}) {
19476
19725
  agentCommand: selectedAgent.command,
19477
19726
  agentArgs: selectedAgent.args,
19478
19727
  modelSelection: { model: grant.model },
19728
+ ...grant.accessPolicy ? { accessPolicy: grant.accessPolicy } : {},
19479
19729
  mcpBinary: localConfig.mcpBinary,
19480
19730
  agentIdentity,
19481
19731
  bodyIdentity: identityFromKey(grant.bodySecretKey, DEFAULT_BODY_IDENTITY_NAME2),
@@ -19760,6 +20010,11 @@ async function jsonRequest(url, body, fetchImpl) {
19760
20010
  }
19761
20011
  return response.json();
19762
20012
  }
20013
+ function parseConnectSubscriptions(value) {
20014
+ return [
20015
+ ...new Set((value ?? "").split(",").map((entry) => entry.trim().toLowerCase()).filter(Boolean))
20016
+ ];
20017
+ }
19763
20018
  function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl) {
19764
20019
  const normalizedPairingCode = normalizeAgentPairingCode(pairingCode);
19765
20020
  if (!normalizedPairingCode)
@@ -19770,7 +20025,11 @@ function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl) {
19770
20025
  harness: selection.harness,
19771
20026
  ...selection.provider ? { provider: selection.provider } : {},
19772
20027
  model: selection.model,
19773
- avatar_seed: avatarSeed
20028
+ avatar_seed: avatarSeed,
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
19774
20033
  }, fetchImpl);
19775
20034
  }
19776
20035
  async function renameConnectedAgent(baseUrl, pairingCode, name, fetchImpl) {
@@ -19780,6 +20039,16 @@ async function renameConnectedAgent(baseUrl, pairingCode, name, fetchImpl) {
19780
20039
  const renamed = await jsonRequest(`${baseUrl}/auth/agent/connect/name`, { pairing_code: normalizedPairingCode, agent_name: name.trim().replace(/\s+/g, " ") }, fetchImpl);
19781
20040
  return renamed.agent_name;
19782
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
+ }
19783
20052
  function seededIdentityLine(grant) {
19784
20053
  return grant.agent_face ? `${grant.agent_name} the ${grant.agent_face}` : grant.agent_name;
19785
20054
  }
@@ -19797,7 +20066,7 @@ async function installCurrentRelease(fetchImpl) {
19797
20066
  });
19798
20067
  await activateRelease(layout, releaseId);
19799
20068
  return {
19800
- binary: resolve20(layout.binDir, "beeline"),
20069
+ binary: resolve21(layout.binDir, "beeline"),
19801
20070
  version: published.version ?? releaseId
19802
20071
  };
19803
20072
  }
@@ -19820,7 +20089,7 @@ function providerEnvironment(selection) {
19820
20089
  };
19821
20090
  }
19822
20091
  async function writePrivateJson(path, value) {
19823
- await mkdir12(dirname10(path), { recursive: true, mode: 448 });
20092
+ await mkdir13(dirname10(path), { recursive: true, mode: 448 });
19824
20093
  await writeFile9(path, `${JSON.stringify(value, null, 2)}
19825
20094
  `, { mode: 384 });
19826
20095
  await chmod4(path, 384);
@@ -19829,8 +20098,8 @@ async function writeProviderEnv(selection, agentPubkey) {
19829
20098
  const values = providerEnvironment(selection);
19830
20099
  if (Object.keys(values).length === 0)
19831
20100
  return void 0;
19832
- const path = resolve20(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
19833
- 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 });
19834
20103
  const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
19835
20104
  await writeFile9(path, `${contents}
19836
20105
  `, { mode: 384 });
@@ -19877,12 +20146,12 @@ async function runConnectCommand(code, options = {}) {
19877
20146
  }
19878
20147
  const restoreRails = paintWizardBrass();
19879
20148
  try {
19880
- await runConnectWizard(code, options.fetchImpl ?? fetch);
20149
+ await runConnectWizard(code, options.fetchImpl ?? fetch, options.subscribe ?? [], options.accessPolicy);
19881
20150
  } finally {
19882
20151
  restoreRails();
19883
20152
  }
19884
20153
  }
19885
- async function runConnectWizard(code, fetchImpl) {
20154
+ async function runConnectWizard(code, fetchImpl, eventSubscriptions, accessPolicy) {
19886
20155
  intro(brass("Beeline connect"));
19887
20156
  const pairingCode = code?.trim() || await clackPrompts.text({
19888
20157
  message: brass("Pairing code from the app"),
@@ -19892,9 +20161,10 @@ async function runConnectWizard(code, fetchImpl) {
19892
20161
  const baseUrl = (process.env.BEELINE_AUTH_URL ?? "https://server.usebeeline.app").replace(/\/$/, "");
19893
20162
  const claimed = await brassSpinner("Connecting to your Beeline Workspace\u2026", () => requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl), (connectedGrant) => `Connected to ${connectedGrant.workspace_name}`);
19894
20163
  const grant = { ...claimed, agent_name: await confirmSeededName(baseUrl, pairingCode, claimed, fetchImpl) };
20164
+ await finishConnectedAgentPairing(baseUrl, pairingCode, grant.workspace_joined, eventSubscriptions, fetchImpl);
19895
20165
  const installedRelease = await brassSpinner("Installing the Beeline daemon\u2026", () => installCurrentRelease(fetchImpl), (release) => `Installed Beeline helper ${release.version}`);
19896
20166
  const llmEnvFile = await writeProviderEnv(selection, grant.agent_pubkey);
19897
- 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`);
19898
20168
  await writePrivateJson(grantPath, {
19899
20169
  agentSecretKey: grant.agent_secret_key,
19900
20170
  bodySecretKey: grant.body_secret_key,
@@ -19907,7 +20177,8 @@ async function runConnectWizard(code, fetchImpl) {
19907
20177
  pairedBy: grant.paired_by,
19908
20178
  monolithBaseUrl: baseUrl,
19909
20179
  daemonExchangeToken: grant.daemon_exchange_token,
19910
- ...llmEnvFile ? { llmEnvFile } : {}
20180
+ ...llmEnvFile ? { llmEnvFile } : {},
20181
+ ...accessPolicy ? { accessPolicy } : {}
19911
20182
  });
19912
20183
  await brassSpinner("Starting your agent\u2026", () => runInstalledFinish(installedRelease.binary, grantPath), () => `Started ${grant.agent_name}`);
19913
20184
  console.log("");
@@ -19947,6 +20218,8 @@ function isDevicePairingGrant(value) {
19947
20218
  if (!value || typeof value !== "object")
19948
20219
  return false;
19949
20220
  const grant = value;
20221
+ if (grant.accessPolicy !== void 0 && !isAgentAccessPolicy(grant.accessPolicy))
20222
+ return false;
19950
20223
  let monolithOrigin = "";
19951
20224
  try {
19952
20225
  monolithOrigin = new URL(grant.monolithBaseUrl ?? "").origin;
@@ -19973,11 +20246,11 @@ async function runConnectFinishCommand(path) {
19973
20246
  throw new Error("connect-finish may run only from the canonical installed Beeline launcher");
19974
20247
  }
19975
20248
  try {
19976
- const grant = JSON.parse(await readFile10(resolve20(path), "utf8"));
20249
+ const grant = JSON.parse(await readFile10(resolve21(path), "utf8"));
19977
20250
  if (!isDevicePairingGrant(grant))
19978
20251
  throw new Error("device connection grant is invalid");
19979
20252
  const connected = await completeDevicePairing(grant);
19980
- await unlink2(resolve20(path));
20253
+ await unlink2(resolve21(path));
19981
20254
  const providerEnv = grant.llmEnvFile ? await readFile10(grant.llmEnvFile, "utf8").catch(() => "") : "";
19982
20255
  const apiKey = (/^OPENROUTER_API_KEY=(\S+)/m.exec(providerEnv)?.[1] ?? "").replace(/^["']|["']$/g, "");
19983
20256
  const model = openRouterModelId(grant.model, { OPENROUTER_API_KEY: apiKey });
@@ -20006,19 +20279,19 @@ init_self_update_manifest();
20006
20279
  // apps/body/dist/managed-update.js
20007
20280
  init_self_update();
20008
20281
  import { spawn as spawn6 } from "node:child_process";
20009
- import { mkdir as mkdir14, rm as rm6, stat as stat2, writeFile as writeFile11 } from "node:fs/promises";
20010
- 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";
20011
20284
 
20012
20285
  // apps/body/dist/update-rollback-alert.js
20013
- import { mkdir as mkdir13, readFile as readFile11, rename as rename4, writeFile as writeFile10 } from "node:fs/promises";
20014
- 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";
20015
20288
  function updateRollbackAlertPath(runtimeDir) {
20016
- return resolve21(runtimeDir, "update-rollback-alert.json");
20289
+ return resolve22(runtimeDir, "update-rollback-alert.json");
20017
20290
  }
20018
20291
  async function writeAlert(runtimeDir, alert) {
20019
20292
  const path = updateRollbackAlertPath(runtimeDir);
20020
20293
  const staged = `${path}.${process.pid}.tmp`;
20021
- await mkdir13(dirname11(path), { recursive: true });
20294
+ await mkdir14(dirname11(path), { recursive: true });
20022
20295
  await writeFile10(staged, `${JSON.stringify(alert, null, 2)}
20023
20296
  `, { mode: 384 });
20024
20297
  await rename4(staged, path);
@@ -20056,13 +20329,13 @@ var LOCK_STALE_MS = UPDATE_WORKER_DEADLINE_MS + 5 * 6e4;
20056
20329
  var DEFAULT_UPDATE_INITIAL_DELAY_MS = 0;
20057
20330
  async function withInstallLock(layout, work, options = {}) {
20058
20331
  const now2 = options.now ?? Date.now;
20059
- const lock = resolve22(layout.releasesRoot, ".state", "install.lock");
20332
+ const lock = resolve23(layout.releasesRoot, ".state", "install.lock");
20060
20333
  const deadline = now2() + (options.waitMs ?? 1e4);
20061
- await mkdir14(dirname12(lock), { recursive: true });
20334
+ await mkdir15(dirname12(lock), { recursive: true });
20062
20335
  for (; ; ) {
20063
20336
  try {
20064
- await mkdir14(lock);
20065
- await writeFile11(resolve22(lock, "owner"), `${process.pid}
20337
+ await mkdir15(lock);
20338
+ await writeFile11(resolve23(lock, "owner"), `${process.pid}
20066
20339
  ${now2()}
20067
20340
  `, "utf8");
20068
20341
  break;
@@ -20185,7 +20458,7 @@ var ManagedUpdateHandoff = class _ManagedUpdateHandoff {
20185
20458
  if (!attempt || attempt.releaseId !== desiredRelease || attempt.status !== "pending") {
20186
20459
  const from = await readInstalledBundleIdentity({
20187
20460
  ...this.#layout,
20188
- libDir: resolve22(this.#layout.releasesRoot, this.#loadedRelease)
20461
+ libDir: resolve23(this.#layout.releasesRoot, this.#loadedRelease)
20189
20462
  }).catch(() => void 0) ?? {};
20190
20463
  const to = await readInstalledBundleIdentity(this.#layout).catch(() => void 0) ?? {};
20191
20464
  const record2 = {
@@ -20472,7 +20745,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
20472
20745
  });
20473
20746
  if (!accepted)
20474
20747
  return false;
20475
- await writeFile11(resolve22(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
20748
+ await writeFile11(resolve23(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
20476
20749
  readyAt: (options.now ?? Date.now)(),
20477
20750
  loadedRelease,
20478
20751
  functionalProof: options.functionalProof
@@ -20677,12 +20950,12 @@ async function runUpdateCommand(args) {
20677
20950
  init_self_update();
20678
20951
 
20679
20952
  // apps/body/dist/daemon-failure.js
20680
- import { mkdir as mkdir15, readFile as readFile12, rename as rename5, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
20681
- 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";
20682
20955
  var DAEMON_FAILURE_LIMIT = 3;
20683
20956
  var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
20684
20957
  function daemonFailurePath(runtimeDir) {
20685
- return resolve23(runtimeDir, "daemon-distress.json");
20958
+ return resolve24(runtimeDir, "daemon-distress.json");
20686
20959
  }
20687
20960
  async function readFailureRecord(runtimeDir) {
20688
20961
  try {
@@ -20698,7 +20971,7 @@ async function readFailureRecord(runtimeDir) {
20698
20971
  async function writeFailureRecord(runtimeDir, record2) {
20699
20972
  const path = daemonFailurePath(runtimeDir);
20700
20973
  const staged = `${path}.${process.pid}.tmp`;
20701
- await mkdir15(dirname13(path), { recursive: true, mode: 448 });
20974
+ await mkdir16(dirname13(path), { recursive: true, mode: 448 });
20702
20975
  await writeFile12(staged, `${JSON.stringify(record2, null, 2)}
20703
20976
  `, { mode: 384 });
20704
20977
  await rename5(staged, path);
@@ -20721,9 +20994,9 @@ async function clearDaemonStartFailures(runtimeDir) {
20721
20994
  }
20722
20995
 
20723
20996
  // apps/body/dist/update-functional-probe.js
20724
- import { mkdir as mkdir16, rm as rm8 } from "node:fs/promises";
20997
+ import { mkdir as mkdir17, rm as rm8 } from "node:fs/promises";
20725
20998
  import { homedir as homedir10 } from "node:os";
20726
- import { resolve as resolve24 } from "node:path";
20999
+ import { resolve as resolve25 } from "node:path";
20727
21000
  var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
20728
21001
  var UPDATE_PROBE_SESSION_OPEN_TIMEOUT_MS = 2e4;
20729
21002
  var UPDATE_PROBE_TURN_TIMEOUT_MS = 45e3;
@@ -20769,11 +21042,11 @@ async function runUpdateFunctionalProbe(input) {
20769
21042
  if (input.sandboxRequired && !input.config.bwrapPath) {
20770
21043
  throw new UpdateFunctionalProbeError("sandbox-unavailable", "the configured bubblewrap boundary did not pass its startup self-test");
20771
21044
  }
20772
- const root = input.probeRoot ?? resolve24(input.runtimeDir, "update-functional-probe");
20773
- const cwd = resolve24(root, "checkout");
20774
- 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");
20775
21048
  await rm8(root, { recursive: true, force: true });
20776
- await mkdir16(cwd, { recursive: true, mode: 448 });
21049
+ await mkdir17(cwd, { recursive: true, mode: 448 });
20777
21050
  let client;
20778
21051
  try {
20779
21052
  const agentEnv = {
@@ -20802,7 +21075,7 @@ async function runUpdateFunctionalProbe(input) {
20802
21075
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
20803
21076
  const operatorHome = input.config.operatorHome ?? homedir10();
20804
21077
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
20805
- await Promise.all(homeStateDirs.map((dir) => mkdir16(dir, { recursive: true })));
21078
+ await Promise.all(homeStateDirs.map((dir) => mkdir17(dir, { recursive: true })));
20806
21079
  spawnCommand = wrapAgentCommand({
20807
21080
  bwrapPath: input.config.bwrapPath,
20808
21081
  spec: {
@@ -20938,7 +21211,7 @@ async function probeReleaseInSubprocess(input) {
20938
21211
  return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
20939
21212
  }
20940
21213
  const timeoutMs = input.timeoutMs ?? CURRENT_RELEASE_PROBE_TIMEOUT_MS;
20941
- return new Promise((resolve27) => {
21214
+ return new Promise((resolve28) => {
20942
21215
  const child = spawn7(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
20943
21216
  let stdout6 = "";
20944
21217
  let stderr = "";
@@ -20948,7 +21221,7 @@ async function probeReleaseInSubprocess(input) {
20948
21221
  return;
20949
21222
  settled = true;
20950
21223
  clearTimeout(timer);
20951
- resolve27(outcome);
21224
+ resolve28(outcome);
20952
21225
  };
20953
21226
  const timer = setTimeout(() => {
20954
21227
  child.kill("SIGKILL");
@@ -21028,7 +21301,7 @@ async function runUpdateProbeCommand(args, options = {}) {
21028
21301
 
21029
21302
  // apps/body/dist/release-status.js
21030
21303
  import { readFile as readFile13, readdir as readdir5, rename as rename6, writeFile as writeFile13 } from "node:fs/promises";
21031
- import { resolve as resolve25 } from "node:path";
21304
+ import { resolve as resolve26 } from "node:path";
21032
21305
  var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
21033
21306
  var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
21034
21307
  var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
@@ -21045,7 +21318,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
21045
21318
  pid: options.pid ?? process.pid,
21046
21319
  readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
21047
21320
  };
21048
- const target = resolve25(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
21321
+ const target = resolve26(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
21049
21322
  const temporary = `${target}.${status.pid}.tmp`;
21050
21323
  await writeFile13(temporary, `${JSON.stringify(status, null, 2)}
21051
21324
  `, { mode: 384 });
@@ -21059,7 +21332,12 @@ function usage(exitCode = 1) {
21059
21332
  ${import_picocolors3.default.bold("Beeline \u2014 thin Room agent.")}
21060
21333
 
21061
21334
  ${import_picocolors3.default.dim("Usage:")}
21062
- beeline connect [XXXXXXXX-XXXXXXXX] Install and connect an app-authorized agent
21335
+ beeline connect [XXXXXXXX-XXXXXXXX] [--subscribe <kinds>] [--access <policy>]
21336
+ Install and connect an app-authorized agent;
21337
+ --subscribe takes a comma-separated list of
21338
+ event kinds it reacts to (e.g. joined);
21339
+ --access is everyone|creator|allowlist
21340
+ (default creator)
21063
21341
  beeline start [agent-pubkey] Start \u2014 or RESTART when already running,
21064
21342
  stopping cleanly after in-flight work \u2014
21065
21343
  this repo's (or, outside a repo, this
@@ -21100,7 +21378,7 @@ async function runStoredDaemon(pathOrPointer) {
21100
21378
  runtime = activated.runtime;
21101
21379
  const daemonApi = activated.client;
21102
21380
  const agent = runtimeAgentCommand(runtime);
21103
- await writeFile14(resolve26(dirname15(configPath), "daemon.pid"), `${process.pid}
21381
+ await writeFile14(resolve27(dirname15(configPath), "daemon.pid"), `${process.pid}
21104
21382
  `, { mode: 384 });
21105
21383
  const env = {
21106
21384
  ...process.env,
@@ -21108,7 +21386,7 @@ async function runStoredDaemon(pathOrPointer) {
21108
21386
  BUZZ_DEV_MCP_BIN: runtime.mcpBinary
21109
21387
  };
21110
21388
  const config = loadBodyConfig({
21111
- workspaceRoot: resolve26(dirname15(configPath), "workspace"),
21389
+ workspaceRoot: resolve27(dirname15(configPath), "workspace"),
21112
21390
  llmEnvFile: runtime.llmEnvFile,
21113
21391
  env,
21114
21392
  agent
@@ -21278,7 +21556,7 @@ async function runStoredDaemon(pathOrPointer) {
21278
21556
  throw error;
21279
21557
  } finally {
21280
21558
  await notifier.stopping(stoppingStatus).catch(() => void 0);
21281
- const pidPath = resolve26(dirname15(configPath), "daemon.pid");
21559
+ const pidPath = resolve27(dirname15(configPath), "daemon.pid");
21282
21560
  const recorded = Number((await readFile14(pidPath, "utf8").catch(() => "")).trim());
21283
21561
  if (recorded === process.pid) {
21284
21562
  await unlink3(pidPath).catch(() => void 0);
@@ -21300,7 +21578,18 @@ async function main() {
21300
21578
  return;
21301
21579
  }
21302
21580
  if (command === "connect") {
21303
- await runConnectCommand(args[1]);
21581
+ const subscribeFlag = args.indexOf("--subscribe");
21582
+ const subscribe = subscribeFlag >= 0 ? parseConnectSubscriptions(args[subscribeFlag + 1]) : [];
21583
+ const accessFlag = args.indexOf("--access");
21584
+ const accessPolicy = accessFlag >= 0 ? args[accessFlag + 1] : void 0;
21585
+ if (accessFlag >= 0 && !isAgentAccessPolicy(accessPolicy)) {
21586
+ throw new Error(`--access must be one of ${AGENT_ACCESS_POLICIES.join(", ")}`);
21587
+ }
21588
+ const code = args[1] && !args[1].startsWith("--") ? args[1] : void 0;
21589
+ await runConnectCommand(code, {
21590
+ ...subscribe.length ? { subscribe } : {},
21591
+ ...isAgentAccessPolicy(accessPolicy) ? { accessPolicy } : {}
21592
+ });
21304
21593
  return;
21305
21594
  }
21306
21595
  if (command === "connect-finish") {
@@ -21342,7 +21631,7 @@ async function main() {
21342
21631
  }
21343
21632
  if (!configPath)
21344
21633
  throw new Error("daemon requires --config <runtime.json> or --agent <pubkey>");
21345
- await runStoredDaemon(resolve26(configPath));
21634
+ await runStoredDaemon(resolve27(configPath));
21346
21635
  return;
21347
21636
  }
21348
21637
  if (command === "update") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usebeeline",
3
- "version": "0.0.47",
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": {