usebeeline 0.1.136 → 0.1.138

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 +173 -94
  2. package/package.json +1 -1
@@ -1311,6 +1311,136 @@ var init_managed_update = __esm({
1311
1311
  }
1312
1312
  });
1313
1313
 
1314
+ // apps/body/dist/adapter-store.js
1315
+ var init_adapter_store = __esm({
1316
+ "apps/body/dist/adapter-store.js"() {
1317
+ "use strict";
1318
+ }
1319
+ });
1320
+
1321
+ // apps/body/dist/agent-command.js
1322
+ import { execFile as execFile2, spawn as spawn4 } from "node:child_process";
1323
+ import { promisify as promisify2 } from "node:util";
1324
+ function sessionAgentBehavior(agent) {
1325
+ return agent ? SESSION_AGENT_BEHAVIORS[agent] : {};
1326
+ }
1327
+ var CURSOR_ACP_BRIDGE_LABEL, AGENT_BEHAVIORS, SESSION_AGENT_BEHAVIORS, SESSION_CLIENT_ORDER, SHARED_CREDENTIALS, execFileAsync;
1328
+ var init_agent_command = __esm({
1329
+ "apps/body/dist/agent-command.js"() {
1330
+ "use strict";
1331
+ init_adapter_store();
1332
+ CURSOR_ACP_BRIDGE_LABEL = "cursor-acp-bridge";
1333
+ AGENT_BEHAVIORS = {
1334
+ codex: {
1335
+ label: "Codex",
1336
+ cliSignIn: "codex",
1337
+ roomTomlDefaults: true,
1338
+ codexCacheBindings: true,
1339
+ fastMode: true,
1340
+ quotaCredential: { homeEnv: "CODEX_HOME", directory: ".codex", file: "auth.json" },
1341
+ importedMcp: { format: "toml", source: ".codex/config.toml", homeEnv: "CODEX_HOME", file: "config.toml" },
1342
+ session: {
1343
+ delivery: "queue",
1344
+ processNames: ["codex", "codex-tui"],
1345
+ clientNames: ["codex"],
1346
+ hookOutput: { start: "SessionStart", prompt: "UserPromptSubmit", tool: "PostToolUse", stop: "block" }
1347
+ }
1348
+ },
1349
+ claude: {
1350
+ label: "Claude",
1351
+ sharedLoginWriteBack: true,
1352
+ quotaCredential: { homeEnv: "CLAUDE_CONFIG_DIR", directory: ".claude", file: ".credentials.json" },
1353
+ importedMcp: { format: "json", source: ".claude.json", homeEnv: "CLAUDE_CONFIG_DIR", file: ".claude.json" },
1354
+ session: {
1355
+ delivery: "socket",
1356
+ processNames: ["claude"],
1357
+ clientNames: ["claude-code", "claude code"],
1358
+ clientExactNames: ["claude"],
1359
+ hookOutput: { start: "SessionStart", prompt: "UserPromptSubmit", stop: "block" }
1360
+ }
1361
+ },
1362
+ goose: {
1363
+ label: "Goose",
1364
+ providerKeyStore: "env",
1365
+ probeProviderRootEnv: "GOOSE_PATH_ROOT",
1366
+ modelCatalogOwnsCredentials: true,
1367
+ providerModelEnv: { provider: "GOOSE_PROVIDER", model: "GOOSE_MODEL" },
1368
+ importedMcp: { format: "extensions", source: ".config/goose/config.yaml", homeEnv: "GOOSE_PATH_ROOT", file: "config/config.yaml" }
1369
+ },
1370
+ pi: {
1371
+ label: "Pi",
1372
+ providerKeyStore: "env",
1373
+ hostedModelConfig: "model-file",
1374
+ validateHostedModelInSession: true,
1375
+ importedMcp: { format: "json", source: ".pi/agent/mcp.json", homeEnv: "PI_CODING_AGENT_DIR", file: "mcp.json" },
1376
+ session: { processNames: ["pi"], clientPrefix: "pi", mailEvents: ["poll", "post-tool-use"], pollText: true }
1377
+ },
1378
+ grok: {
1379
+ label: "Grok",
1380
+ cliSignIn: "grok",
1381
+ modelLaunch: "native-args",
1382
+ importedMcp: { format: "toml", source: ".grok/config.toml", homeEnv: "GROK_HOME", file: "config.toml" }
1383
+ },
1384
+ cursor: { nativeShellHook: { config: "hooks-file", output: "updated-input" }, label: "Cursor", cliSignIn: "cursor", resolveCommandOnStart: true, identityLabel: CURSOR_ACP_BRIDGE_LABEL, cliModelCatalog: true },
1385
+ opencode: {
1386
+ label: "OpenCode",
1387
+ providerKeyStore: "auth-file",
1388
+ modelCatalogOwnsCredentials: true,
1389
+ hostedModelConfig: "inline-provider",
1390
+ session: { processNames: ["opencode"], clientNames: ["opencode"], mailEvents: ["poll"], pollText: true }
1391
+ },
1392
+ reference: {},
1393
+ custom: { modelLaunch: "command" }
1394
+ };
1395
+ SESSION_AGENT_BEHAVIORS = {
1396
+ "claude-code": AGENT_BEHAVIORS.claude.session,
1397
+ codex: AGENT_BEHAVIORS.codex.session,
1398
+ opencode: AGENT_BEHAVIORS.opencode.session,
1399
+ pi: AGENT_BEHAVIORS.pi.session,
1400
+ antigravity: {
1401
+ processNames: ["antigravity", "agy"],
1402
+ clientNames: ["antigravity"],
1403
+ mailEvents: ["session-start", "user-prompt-submit", "stop"],
1404
+ hookOutput: { start: "inject", prompt: "inject", stop: "continue" }
1405
+ },
1406
+ gemini: {
1407
+ processNames: ["gemini"],
1408
+ clientNames: ["gemini"],
1409
+ hookOutput: { start: "SessionStart", prompt: "BeforeAgent", tool: "AfterTool", stop: "deny" }
1410
+ },
1411
+ hermes: { processNames: ["hermes"], clientNames: ["hermes"], mailEvents: ["poll"], pollText: true },
1412
+ zcode: { processNames: ["zcode"], clientPrefix: "zcode", mailEvents: ["poll"], pollText: true }
1413
+ };
1414
+ SESSION_CLIENT_ORDER = ["claude-code", "codex", "antigravity", "gemini", "opencode", "pi", "hermes", "zcode"];
1415
+ SHARED_CREDENTIALS = [
1416
+ // Claude Code relocates ~/.claude wholesale via CLAUDE_CONFIG_DIR; the OAuth
1417
+ // credentials live inside it, so an isolated dir needs them linked back.
1418
+ { dir: "claude", source: ".claude/.credentials.json", target: ".credentials.json", writeBack: AGENT_BEHAVIORS.claude.sharedLoginWriteBack },
1419
+ // Codex CLI relocates ~/.codex via CODEX_HOME; auth.json holds its login.
1420
+ { dir: "codex", source: ".codex/auth.json", target: "auth.json" },
1421
+ // Grok relocates ~/.grok via GROK_HOME; auth.json holds its login (same
1422
+ // shape as codex).
1423
+ { dir: "grok", source: ".grok/auth.json", target: "auth.json" },
1424
+ { dir: "pi", source: ".pi/agent/auth.json", target: "auth.json" },
1425
+ // Cursor CLI stores chat/MCP state under ~/.cursor/; cursor-agent reads
1426
+ // CURSOR_HOME to relocate that data directory. The login is NOT there:
1427
+ // cursor-agent reads ~/.config/cursor/auth.json (XDG config). Beeline
1428
+ // remaps HOME to the isolated user/ dir, so the login has to be linked
1429
+ // into that HOME or every Room/corner except one that was patched by
1430
+ // hand fails with "Authentication required".
1431
+ { dir: "cursor", source: ".cursor/agent-cli-state.json", target: "agent-cli-state.json" },
1432
+ { dir: "user", source: ".config/cursor/auth.json", target: ".config/cursor/auth.json" },
1433
+ // OpenCode stores provider logins under XDG data, which follows isolated HOME.
1434
+ {
1435
+ dir: "user",
1436
+ source: ".local/share/opencode/auth.json",
1437
+ target: ".local/share/opencode/auth.json"
1438
+ }
1439
+ ];
1440
+ execFileAsync = promisify2(execFile2);
1441
+ }
1442
+ });
1443
+
1314
1444
  // apps/body/dist/session-join/agents.js
1315
1445
  import { readFileSync as readFileSync2 } from "node:fs";
1316
1446
  import { basename as basename2 } from "node:path";
@@ -1345,44 +1475,16 @@ function detectEnv(env = process.env) {
1345
1475
  }
1346
1476
  function fromClientName(name) {
1347
1477
  const n = name.toLowerCase();
1348
- const has = (part) => n.includes(part);
1349
- if (has("claude-code") || has("claude code") || n === "claude")
1350
- return "claude-code";
1351
- if (has("codex"))
1352
- return "codex";
1353
- if (has("antigravity"))
1354
- return "antigravity";
1355
- if (has("gemini"))
1356
- return "gemini";
1357
- if (has("opencode"))
1358
- return "opencode";
1359
- if (n === "pi" || n.startsWith("pi-") || n.startsWith("pi "))
1360
- return "pi";
1361
- if (has("hermes"))
1362
- return "hermes";
1363
- if (n === "zcode" || n.startsWith("zcode-") || n.startsWith("zcode "))
1364
- return "zcode";
1478
+ for (const agent of SESSION_CLIENT_ORDER) {
1479
+ const policy = sessionAgentBehavior(agent);
1480
+ if (policy.clientNames?.some((part) => n.includes(part)) || policy.clientExactNames?.includes(n) || policy.clientPrefix && (n === policy.clientPrefix || n.startsWith(`${policy.clientPrefix}-`) || n.startsWith(`${policy.clientPrefix} `)))
1481
+ return agent;
1482
+ }
1365
1483
  return void 0;
1366
1484
  }
1367
1485
  function fromProcessName(command2) {
1368
1486
  const name = basename2(command2.split(/\s+/)[0] ?? "").toLowerCase().replace(/\.(exe|js|mjs|cjs)$/, "");
1369
- if (name === "claude")
1370
- return "claude-code";
1371
- if (name === "codex" || name === "codex-tui")
1372
- return "codex";
1373
- if (name === "opencode")
1374
- return "opencode";
1375
- if (name === "pi")
1376
- return "pi";
1377
- if (name === "gemini")
1378
- return "gemini";
1379
- if (name === "antigravity" || name === "agy")
1380
- return "antigravity";
1381
- if (name === "hermes")
1382
- return "hermes";
1383
- if (name === "zcode")
1384
- return "zcode";
1385
- return void 0;
1487
+ return AGENTS.find((agent) => SESSION_AGENT_BEHAVIORS[agent].processNames?.includes(name));
1386
1488
  }
1387
1489
  function statParent(stat3) {
1388
1490
  const rest = stat3.slice(stat3.lastIndexOf(")") + 1).trim().split(/\s+/);
@@ -1465,6 +1567,7 @@ var AGENTS, LABELS;
1465
1567
  var init_agents = __esm({
1466
1568
  "apps/body/dist/session-join/agents.js"() {
1467
1569
  "use strict";
1570
+ init_agent_command();
1468
1571
  AGENTS = ["claude-code", "codex", "opencode", "pi", "antigravity", "gemini", "hermes", "zcode"];
1469
1572
  LABELS = {
1470
1573
  "claude-code": "Claude Code",
@@ -4760,7 +4863,7 @@ var init_phone = __esm({
4760
4863
  });
4761
4864
 
4762
4865
  // apps/body/dist/session-join/codex.js
4763
- import { execFile as execFile2 } from "node:child_process";
4866
+ import { execFile as execFile3 } from "node:child_process";
4764
4867
  import { closeSync, fstatSync, openSync, readSync, readdirSync as readdirSync2, readlinkSync, statSync as statSync2 } from "node:fs";
4765
4868
  import { homedir as homedir5 } from "node:os";
4766
4869
  import { basename as basename3, join as join3 } from "node:path";
@@ -4825,7 +4928,7 @@ function scanCodex(proc = "/proc") {
4825
4928
  for (const name of pids) {
4826
4929
  const pid = Number(name);
4827
4930
  const command2 = proc === "/proc" ? processCommand(pid) : void 0;
4828
- if (proc === "/proc" && (!command2 || fromProcessName(command2) !== "codex"))
4931
+ if (proc === "/proc" && (!command2 || sessionAgentBehavior(fromProcessName(command2)).delivery !== "queue"))
4829
4932
  continue;
4830
4933
  let fds;
4831
4934
  try {
@@ -4856,7 +4959,7 @@ function scanCodex(proc = "/proc") {
4856
4959
  }
4857
4960
  function codexQueue(threadId, text, bin = "codex", timeoutMs = 3e4) {
4858
4961
  return new Promise((resolve11, reject) => {
4859
- execFile2(bin, ["queue", "--thread", threadId, "--message", text], { timeout: timeoutMs }, (error, _stdout, stderr) => {
4962
+ execFile3(bin, ["queue", "--thread", threadId, "--message", text], { timeout: timeoutMs }, (error, _stdout, stderr) => {
4860
4963
  if (error)
4861
4964
  reject(new Error(String(stderr).trim() || error.message));
4862
4965
  else
@@ -4868,6 +4971,7 @@ var seen;
4868
4971
  var init_codex = __esm({
4869
4972
  "apps/body/dist/session-join/codex.js"() {
4870
4973
  "use strict";
4974
+ init_agent_command();
4871
4975
  init_agents();
4872
4976
  seen = /* @__PURE__ */ new Map();
4873
4977
  }
@@ -5121,7 +5225,7 @@ function liveSessions(sources) {
5121
5225
  cwd: h.cwd,
5122
5226
  pid: h.pid,
5123
5227
  state: h.state,
5124
- ...h.agent === "codex" && h.transcript ? { rollout: h.transcript } : {}
5228
+ ...sessionAgentBehavior(h.agent).delivery === "queue" && h.transcript ? { rollout: h.transcript } : {}
5125
5229
  });
5126
5230
  }
5127
5231
  return found;
@@ -5136,6 +5240,7 @@ function findSession(joined2, live, others = []) {
5136
5240
  var init_sessions = __esm({
5137
5241
  "apps/body/dist/session-join/sessions.js"() {
5138
5242
  "use strict";
5243
+ init_agent_command();
5139
5244
  init_claude();
5140
5245
  init_codex();
5141
5246
  init_store();
@@ -5143,7 +5248,7 @@ var init_sessions = __esm({
5143
5248
  });
5144
5249
 
5145
5250
  // apps/body/dist/session-join/bridge.js
5146
- import { spawn as spawn4 } from "node:child_process";
5251
+ import { spawn as spawn5 } from "node:child_process";
5147
5252
  import { chmodSync as chmodSync2, closeSync as closeSync3, existsSync as existsSync2, mkdirSync as mkdirSync3, openSync as openSync3, readFileSync as readFileSync6, readdirSync as readdirSync5, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
5148
5253
  import { createConnection as createConnection4, createServer as createServer3 } from "node:net";
5149
5254
  import { join as join6 } from "node:path";
@@ -5192,7 +5297,7 @@ function renderWake(w, joined2, runner2) {
5192
5297
  ].join("\n");
5193
5298
  }
5194
5299
  async function deliver(dir, joined2, session2, deps = realDeps) {
5195
- if (joined2.agent !== "claude-code" && joined2.agent !== "codex")
5300
+ if (!sessionAgentBehavior(joined2.agent).delivery)
5196
5301
  return "waiting for the app to collect it";
5197
5302
  if (!session2)
5198
5303
  return "waiting for the session to open";
@@ -5468,7 +5573,7 @@ function ensureBridge(dir, runner2, env = process.env) {
5468
5573
  if (bridgeRunning(dir))
5469
5574
  return;
5470
5575
  const out = openSync3(join6(dir, "bridge.log"), "a", 384);
5471
- const child = spawn4(runner2.node, [runner2.bundle, "session", "bridge"], { detached: true, stdio: ["ignore", out, out], env });
5576
+ const child = spawn5(runner2.node, [runner2.bundle, "session", "bridge"], { detached: true, stdio: ["ignore", out, out], env });
5472
5577
  child.unref();
5473
5578
  closeSync3(out);
5474
5579
  }
@@ -5476,6 +5581,7 @@ var realDeps, WAKE_REDELIVERY_MINUTES;
5476
5581
  var init_bridge = __esm({
5477
5582
  "apps/body/dist/session-join/bridge.js"() {
5478
5583
  "use strict";
5584
+ init_agent_command();
5479
5585
  init_phone();
5480
5586
  init_beeline_api();
5481
5587
  init_codex();
@@ -6088,7 +6194,7 @@ var init_claude_inbound = __esm({
6088
6194
  });
6089
6195
 
6090
6196
  // apps/body/dist/session-join/codex-trust.js
6091
- import { spawn as spawn5 } from "node:child_process";
6197
+ import { spawn as spawn6 } from "node:child_process";
6092
6198
  import { join as join9 } from "node:path";
6093
6199
  function beelineTrustEdits(hooks, context) {
6094
6200
  const path = join9(codexHome(context.env), "hooks.json");
@@ -6100,7 +6206,7 @@ function beelineTrustEdits(hooks, context) {
6100
6206
  return [{ keyPath: `hooks.state.${JSON.stringify(hook.key)}.trusted_hash`, value: hook.currentHash, mergeStrategy: "replace" }];
6101
6207
  }
6102
6208
  async function trustCodexHook(context, bin, cwd) {
6103
- const child = spawn5(bin, ["app-server", "--stdio"], { env: context.env, cwd, stdio: ["pipe", "pipe", "ignore"] });
6209
+ const child = spawn6(bin, ["app-server", "--stdio"], { env: context.env, cwd, stdio: ["pipe", "pipe", "ignore"] });
6104
6210
  let id = 0, buffer = "";
6105
6211
  const pending = /* @__PURE__ */ new Map();
6106
6212
  const fail = () => {
@@ -6189,50 +6295,21 @@ function normalizeEvent(event, state) {
6189
6295
  return void 0;
6190
6296
  }
6191
6297
  function takesMail(agent, event) {
6192
- if (agent === "antigravity")
6193
- return ["session-start", "user-prompt-submit", "stop"].includes(event);
6194
- if (agent === "opencode" || agent === "hermes" || agent === "zcode")
6195
- return event === "poll";
6196
- if (agent === "pi")
6197
- return event === "poll" || event === "post-tool-use";
6198
- return ["session-start", "user-prompt-submit", "post-tool-use", "stop"].includes(event);
6298
+ return (sessionAgentBehavior(agent).mailEvents ?? ["session-start", "user-prompt-submit", "post-tool-use", "stop"]).includes(event);
6199
6299
  }
6200
6300
  function formatFor(agent, event, text) {
6201
6301
  const ev = normalizeEvent(event);
6202
- const specific = (name) => ({ hookSpecificOutput: { hookEventName: name, additionalContext: text } });
6203
- const block = { decision: "block", reason: text };
6204
- let out;
6205
- if (agent === "antigravity" && (ev === "start" || ev === "prompt"))
6206
- out = { injectSteps: [{ userMessage: text }] };
6207
- else if (agent === "antigravity" && ev === "stop")
6208
- out = { decision: "continue", reason: text };
6209
- else if ((agent === "opencode" || agent === "pi" || agent === "hermes" || agent === "zcode") && event === "poll")
6302
+ const policy = sessionAgentBehavior(agent);
6303
+ if (policy.pollText && event === "poll")
6210
6304
  return text;
6211
- else if (agent === "claude-code" && ev === "start")
6212
- out = specific("SessionStart");
6213
- else if (agent === "claude-code" && ev === "prompt")
6214
- out = specific("UserPromptSubmit");
6215
- else if (agent === "claude-code" && ev === "stop")
6216
- out = block;
6217
- else if (agent === "codex" && ev === "start")
6218
- out = specific("SessionStart");
6219
- else if (agent === "codex" && ev === "prompt")
6220
- out = specific("UserPromptSubmit");
6221
- else if (agent === "codex" && ev === "tool")
6222
- out = specific("PostToolUse");
6223
- else if (agent === "codex" && ev === "stop")
6224
- out = block;
6225
- else if (agent === "gemini" && ev === "start")
6226
- out = specific("SessionStart");
6227
- else if (agent === "gemini" && ev === "prompt")
6228
- out = specific("BeforeAgent");
6229
- else if (agent === "gemini" && ev === "tool")
6230
- out = specific("AfterTool");
6231
- else if (agent === "gemini" && ev === "stop")
6232
- out = { decision: "deny", reason: text };
6233
- else
6305
+ const shape = ev && policy.hookOutput?.[ev];
6306
+ if (!shape)
6234
6307
  return text;
6235
- return JSON.stringify(out);
6308
+ if (shape === "inject")
6309
+ return JSON.stringify({ injectSteps: [{ userMessage: text }] });
6310
+ if (shape === "block" || shape === "continue" || shape === "deny")
6311
+ return JSON.stringify({ decision: shape, reason: text });
6312
+ return JSON.stringify({ hookSpecificOutput: { hookEventName: shape, additionalContext: text } });
6236
6313
  }
6237
6314
  function joinedFor(sessions, agent, sessionId, cwd) {
6238
6315
  return sessions.find((s) => s.agent === agent && s.sessionId === sessionId) ?? sessions.find((s) => s.agent === agent && s.cwd === cwd);
@@ -6273,12 +6350,13 @@ function runHook(dir, input, now = Date.now()) {
6273
6350
  var init_hook = __esm({
6274
6351
  "apps/body/dist/session-join/hook.js"() {
6275
6352
  "use strict";
6353
+ init_agent_command();
6276
6354
  init_store();
6277
6355
  }
6278
6356
  });
6279
6357
 
6280
6358
  // apps/body/dist/session-join/pull-apps.js
6281
- import { execFile as execFile3 } from "node:child_process";
6359
+ import { execFile as execFile4 } from "node:child_process";
6282
6360
  import { createInterface as createInterface2 } from "node:readline";
6283
6361
  function zcodeKey(dir, cwd) {
6284
6362
  return readState(dir).sessions.find((s) => s.agent === "zcode" && s.cwd === cwd)?.key;
@@ -6353,7 +6431,7 @@ var init_pull_apps = __esm({
6353
6431
  "use strict";
6354
6432
  init_store();
6355
6433
  init_beeline_api();
6356
- agentapi = (sessionId, text) => new Promise((resolve11, reject) => execFile3("agentapi", ["send-message", sessionId, text], { timeout: 3e4 }, (error) => error ? reject(error) : resolve11()));
6434
+ agentapi = (sessionId, text) => new Promise((resolve11, reject) => execFile4("agentapi", ["send-message", sessionId, text], { timeout: 3e4 }, (error) => error ? reject(error) : resolve11()));
6357
6435
  }
6358
6436
  });
6359
6437
 
@@ -6363,7 +6441,7 @@ __export(command_exports, {
6363
6441
  findOwnSession: () => findOwnSession,
6364
6442
  runSessionCommand: () => runSessionCommand
6365
6443
  });
6366
- import { spawn as spawn6, spawnSync as spawnSync2 } from "node:child_process";
6444
+ import { spawn as spawn7, spawnSync as spawnSync2 } from "node:child_process";
6367
6445
  import { copyFileSync as copyFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync9, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "node:fs";
6368
6446
  import { delimiter, join as join10, resolve as resolve9 } from "node:path";
6369
6447
  import { createHash as createHash6, randomUUID } from "node:crypto";
@@ -6424,7 +6502,7 @@ function findOwnSession(env, dir) {
6424
6502
  claudeInboundFallback: held && !hasClaudeMcp(dir, own2?.pid ?? detected.pid)
6425
6503
  };
6426
6504
  }
6427
- if (detected.agent === "codex") {
6505
+ if (sessionAgentBehavior(detected.agent).delivery === "queue") {
6428
6506
  const thread = env.CODEX_THREAD_ID ?? env.CODEX_SESSION_ID;
6429
6507
  const live = scanCodex();
6430
6508
  const own2 = thread ? live.find((s) => s.threadId === thread) : live.find((s) => detected.pid !== void 0 && s.pid === detected.pid);
@@ -6474,7 +6552,7 @@ async function joinCommand(args, env) {
6474
6552
  name,
6475
6553
  sessionId: own2.sessionId,
6476
6554
  pid: own2.pid,
6477
- agentBin: own2.agent === "codex" ? which("codex", env) : void 0,
6555
+ agentBin: sessionAgentBehavior(own2.agent).delivery === "queue" ? which("codex", env) : void 0,
6478
6556
  startedAt: Date.now(),
6479
6557
  claudeInboundFallback: own2.claudeInboundFallback
6480
6558
  };
@@ -6482,7 +6560,7 @@ async function joinCommand(args, env) {
6482
6560
  const file = join10(dir, "pending", `${createHash6("sha256").update(signIn.state).digest("hex").slice(0, 24)}.json`);
6483
6561
  writeFileSync5(file, JSON.stringify(pending), { mode: 384 });
6484
6562
  const out = join10(dir, "bridge.log");
6485
- const child = spawn6(run2.node, [run2.bundle, "session", "finish-join", file], { detached: true, stdio: "ignore", env: { ...env, BEELINE_SESSION_BUNDLE: run2.bundle } });
6563
+ const child = spawn7(run2.node, [run2.bundle, "session", "finish-join", file], { detached: true, stdio: "ignore", env: { ...env, BEELINE_SESSION_BUNDLE: run2.bundle } });
6486
6564
  child.unref();
6487
6565
  console.log([
6488
6566
  `Show your person this link. They open it on any device (a phone works) and sign in with GitHub or Google:`,
@@ -6544,7 +6622,7 @@ async function finishJoin(file, env) {
6544
6622
  queueInbox(dir, key, waiting.join("\n\n"));
6545
6623
  });
6546
6624
  const changes = setupAgent(pending.agent, { env, node: run2.node, bundle: run2.bundle });
6547
- if (pending.agent === "codex" && await trustCodexHook({ env, node: run2.node, bundle: run2.bundle }, pending.agentBin ?? "codex", pending.cwd)) {
6625
+ if (sessionAgentBehavior(pending.agent).delivery === "queue" && await trustCodexHook({ env, node: run2.node, bundle: run2.bundle }, pending.agentBin ?? "codex", pending.cwd)) {
6548
6626
  const prompt = changes.findIndex((line) => line.startsWith("Codex asks once"));
6549
6627
  if (prompt >= 0)
6550
6628
  changes.splice(prompt, 1);
@@ -6573,7 +6651,7 @@ async function announce(joined2, text, dir) {
6573
6651
  return;
6574
6652
  }
6575
6653
  }
6576
- if (joined2.agent === "codex" && joined2.sessionId) {
6654
+ if (sessionAgentBehavior(joined2.agent).delivery === "queue" && joined2.sessionId) {
6577
6655
  await codexQueue(joined2.sessionId, text, joined2.agentBin ?? "codex").catch(() => void 0);
6578
6656
  return;
6579
6657
  }
@@ -6724,7 +6802,7 @@ async function runSessionCommand(args, env = process.env) {
6724
6802
  const failure = error;
6725
6803
  const cause = failure?.cause;
6726
6804
  const denied = [failure, cause].some((e) => e && (["EACCES", "EPERM", "EROFS"].includes(e.code ?? "") || e.code === "ENOENT" && e.syscall === "mkdir"));
6727
- if (detectAgent(env)?.agent === "codex" && denied) {
6805
+ if (sessionAgentBehavior(detectAgent(env)?.agent).delivery === "queue" && denied) {
6728
6806
  throw new Error('Codex blocked access needed to join Beeline. Run /permissions, pick "Ask for approval", then run Join again. Choose "Yes, proceed" for the Join command once; no permanent allowance or Full Access is needed.', { cause: error });
6729
6807
  }
6730
6808
  throw error;
@@ -6736,6 +6814,7 @@ var VALUED;
6736
6814
  var init_command = __esm({
6737
6815
  "apps/body/dist/session-join/command.js"() {
6738
6816
  "use strict";
6817
+ init_agent_command();
6739
6818
  init_agents();
6740
6819
  init_beeline_api();
6741
6820
  init_bridge();
@@ -6753,7 +6832,7 @@ var init_command = __esm({
6753
6832
  });
6754
6833
 
6755
6834
  // apps/body/dist/recovery-cli.js
6756
- import { spawn as spawn7 } from "node:child_process";
6835
+ import { spawn as spawn8 } from "node:child_process";
6757
6836
  import { readFile as readFile4, readdir as readdir5, stat as stat2, unlink } from "node:fs/promises";
6758
6837
  import { resolve as resolve10 } from "node:path";
6759
6838
 
@@ -7382,7 +7461,7 @@ async function main() {
7382
7461
  const entry = await resolveBundleEntrypoint(layout.libDir);
7383
7462
  if (!entry)
7384
7463
  throw new Error("no installed Beeline body; run npx usebeeline connect");
7385
- const child = spawn7(process.execPath, [entry, ...args], {
7464
+ const child = spawn8(process.execPath, [entry, ...args], {
7386
7465
  env: {
7387
7466
  ...process.env,
7388
7467
  BEELINE_LIB_DIR: layout.libDir,
@@ -7400,7 +7479,7 @@ async function convergeDependencies(layout, deadlineAt) {
7400
7479
  if (!entry)
7401
7480
  throw new Error("dependency phase has no selected body");
7402
7481
  await new Promise((done, reject) => {
7403
- const child = spawn7(process.execPath, [entry, "converge-dependencies"], {
7482
+ const child = spawn8(process.execPath, [entry, "converge-dependencies"], {
7404
7483
  env: { ...process.env, BEELINE_LIB_DIR: layout.libDir, BEELINE_INTERNAL_RECOVERY: "1" },
7405
7484
  stdio: "inherit"
7406
7485
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "usebeeline",
3
- "version": "0.1.136",
3
+ "version": "0.1.138",
4
4
  "description": "Connect an AI coding agent to Beeline with one command.",
5
5
  "homepage": "https://usebeeline.app",
6
6
  "bugs": {