codeam-cli 2.62.2 → 2.63.1

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 (3) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/index.js +663 -311
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -271,8 +271,8 @@ var init_stdio_proxy = __esm({
271
271
  }
272
272
  async spawnChild(stdout, preResolved) {
273
273
  const spec = preResolved ?? await this.opts.spawnSpec();
274
- const spawn45 = this.opts.spawnImpl ?? import_node_child_process33.spawn;
275
- const child = spawn45(spec.command, spec.args, {
274
+ const spawn46 = this.opts.spawnImpl ?? import_node_child_process33.spawn;
275
+ const child = spawn46(spec.command, spec.args, {
276
276
  env: { ...process.env, ...spec.env },
277
277
  // env only — never argv
278
278
  stdio: ["pipe", "pipe", "inherit"]
@@ -2916,6 +2916,11 @@ var USER_EVENTS = {
2916
2916
  CODERABBIT_PROGRESS: "coderabbit_progress",
2917
2917
  CODERABBIT_STATUS: "coderabbit_status",
2918
2918
  CODERABBIT_REVIEW: "coderabbit_review",
2919
+ // Session agent switch — the CLI posts these to /api/agent-switch/events
2920
+ // while a `switch_agent` relay command swaps the session's agent in-process;
2921
+ // the backend re-publishes them on the per-user SSE bus (mirrored in repo A).
2922
+ SWITCH_AGENT_PROGRESS: "switch_agent_progress",
2923
+ SWITCH_AGENT_STATUS: "switch_agent_status",
2919
2924
  // VCS / PR Command Center — the backend publishes this after an agent finishes
2920
2925
  // reviewing a PR (verdict + comment count + findings), driving the mobile
2921
2926
  // completion screen + push. Mirrored in repo A's app-shared events.ts.
@@ -3231,6 +3236,13 @@ function makeConfig(baseDir) {
3231
3236
  s.disable1mContext = value;
3232
3237
  save(c2);
3233
3238
  }
3239
+ function setSessionAgent2(pluginId, agent) {
3240
+ const c2 = load();
3241
+ const s = c2.sessions.find((x) => x.pluginId === pluginId);
3242
+ if (!s) return;
3243
+ s.agent = agent;
3244
+ save(c2);
3245
+ }
3234
3246
  function clearAll2() {
3235
3247
  try {
3236
3248
  fs3.unlinkSync(file);
@@ -3243,7 +3255,7 @@ function makeConfig(baseDir) {
3243
3255
  function loadCliConfig2() {
3244
3256
  return load();
3245
3257
  }
3246
- return { getConfig: getConfig2, ensurePluginId: ensurePluginId2, addSession: addSession2, removeSession: removeSession2, setActiveSession: setActiveSession2, getActiveSession: getActiveSession2, getActiveSessionForAgent: getActiveSessionForAgent2, setDisable1mContext: setDisable1mContext2, clearAll: clearAll2, saveCliConfig: saveCliConfig2, loadCliConfig: loadCliConfig2 };
3258
+ return { getConfig: getConfig2, ensurePluginId: ensurePluginId2, addSession: addSession2, removeSession: removeSession2, setActiveSession: setActiveSession2, getActiveSession: getActiveSession2, getActiveSessionForAgent: getActiveSessionForAgent2, setDisable1mContext: setDisable1mContext2, setSessionAgent: setSessionAgent2, clearAll: clearAll2, saveCliConfig: saveCliConfig2, loadCliConfig: loadCliConfig2 };
3247
3259
  }
3248
3260
  var CODESPACE_ENV_KEYS = [
3249
3261
  "PREVIEW_TUNNEL_TOKEN",
@@ -3267,11 +3279,11 @@ function loadCodespaceEnv() {
3267
3279
  }
3268
3280
  }
3269
3281
  var _default = makeConfig();
3270
- var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
3282
+ var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, setSessionAgent, clearAll, saveCliConfig, loadCliConfig } = _default;
3271
3283
 
3272
3284
  // src/commands/pair-auto.ts
3273
3285
  var fs63 = __toESM(require("fs"));
3274
- var os52 = __toESM(require("os"));
3286
+ var os53 = __toESM(require("os"));
3275
3287
  var path68 = __toESM(require("path"));
3276
3288
  var import_crypto4 = require("crypto");
3277
3289
 
@@ -8022,7 +8034,7 @@ function readAnonId() {
8022
8034
  }
8023
8035
  function superProperties() {
8024
8036
  return {
8025
- cliVersion: true ? "2.62.2" : "0.0.0-dev",
8037
+ cliVersion: true ? "2.63.1" : "0.0.0-dev",
8026
8038
  nodeVersion: process.version,
8027
8039
  platform: process.platform,
8028
8040
  arch: process.arch,
@@ -8203,7 +8215,7 @@ var os4 = __toESM(require("os"));
8203
8215
  // package.json
8204
8216
  var package_default = {
8205
8217
  name: "codeam-cli",
8206
- version: "2.62.2",
8218
+ version: "2.63.1",
8207
8219
  description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
8208
8220
  type: "commonjs",
8209
8221
  main: "dist/index.js",
@@ -8579,18 +8591,48 @@ async function fetchProvisionCredential(input) {
8579
8591
  try {
8580
8592
  const res = await _transport.postJsonAuthed(
8581
8593
  `${API_BASE}/api/plugin/agents/${input.agentId}/provision-credential`,
8582
- { sessionId: input.sessionId, pluginId: input.pluginId },
8594
+ {
8595
+ sessionId: input.sessionId,
8596
+ pluginId: input.pluginId,
8597
+ ...input.includeInstallScript ? { includeInstallScript: true } : {}
8598
+ },
8583
8599
  input.pluginAuthToken
8584
8600
  );
8585
8601
  const data = res?.data;
8586
8602
  if (data && (data.method === "api_key" || data.method === "oauth") && typeof data.credential === "string" && data.credential.length > 0) {
8587
- return { method: data.method, credential: data.credential };
8603
+ return {
8604
+ method: data.method,
8605
+ credential: data.credential,
8606
+ ...typeof data.installScript === "string" && data.installScript.length > 0 ? { installScript: data.installScript } : {}
8607
+ };
8588
8608
  }
8589
8609
  return null;
8590
8610
  } catch {
8591
8611
  return null;
8592
8612
  }
8593
8613
  }
8614
+ async function postAgentSwitchEvent(input) {
8615
+ try {
8616
+ await _transport.postJsonAuthed(
8617
+ `${API_BASE}/api/agent-switch/events`,
8618
+ {
8619
+ sessionId: input.sessionId,
8620
+ pluginId: input.pluginId,
8621
+ type: input.type,
8622
+ payload: input.payload ?? {}
8623
+ },
8624
+ input.pluginAuthToken
8625
+ );
8626
+ return { ok: true };
8627
+ } catch (err) {
8628
+ const e = err;
8629
+ return {
8630
+ ok: false,
8631
+ status: typeof e.statusCode === "number" ? e.statusCode : 0,
8632
+ message: e.message || "unknown"
8633
+ };
8634
+ }
8635
+ }
8594
8636
  async function postAgentReviewReport(input) {
8595
8637
  try {
8596
8638
  await _transport.postJsonAuthed(
@@ -9613,7 +9655,7 @@ var CommandRelayService = class _CommandRelayService {
9613
9655
  // fresh + clear the "CLI update available" banner after a self-update
9614
9656
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9615
9657
  // pair/reconnect). Older backends ignore the extra field.
9616
- ..."2.62.2" ? { ideVersion: "2.62.2" } : {}
9658
+ ..."2.63.1" ? { ideVersion: "2.63.1" } : {}
9617
9659
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9618
9660
  }
9619
9661
  /**
@@ -9644,6 +9686,23 @@ var CommandRelayService = class _CommandRelayService {
9644
9686
  }).catch(() => {
9645
9687
  });
9646
9688
  }
9689
+ /**
9690
+ * Swap the agent this relay reports for the session (in-session agent
9691
+ * switch). Heartbeats pick the new id up on their next tick; call
9692
+ * {@link reannounceAgents} to push the new `/api/plugin/agents` entry.
9693
+ */
9694
+ setAgentMeta(meta) {
9695
+ this.agentMeta = meta;
9696
+ }
9697
+ /**
9698
+ * Re-register the (possibly swapped) agent with the backend. Resets
9699
+ * `agentsRegistered` so the 5 s retry timer keeps trying until a POST
9700
+ * lands — same at-least-once semantics as the initial registration.
9701
+ */
9702
+ reannounceAgents() {
9703
+ this.agentsRegistered = false;
9704
+ this.reportAgents();
9705
+ }
9647
9706
  // ─── Lifecycle ───────────────────────────────────────────────────
9648
9707
  cleanup() {
9649
9708
  if (this.pollTimer) {
@@ -9840,10 +9899,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
9840
9899
  /[\\/]Start Menu([\\/]|$)/i,
9841
9900
  /[\\/]Templates([\\/]|$)/i
9842
9901
  ];
9843
- function isUnsafeWindowsWatchRoot(dir, homedir51) {
9902
+ function isUnsafeWindowsWatchRoot(dir, homedir52) {
9844
9903
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
9845
9904
  const cwd = norm(dir);
9846
- const home = norm(homedir51);
9905
+ const home = norm(homedir52);
9847
9906
  if (cwd === home) return true;
9848
9907
  if (/^[a-z]:$/.test(cwd)) return true;
9849
9908
  const sysRoots = [
@@ -10988,10 +11047,10 @@ function closeAllTerminals() {
10988
11047
 
10989
11048
  // src/commands/start/handlers.ts
10990
11049
  var fs62 = __toESM(require("fs"));
10991
- var os51 = __toESM(require("os"));
11050
+ var os52 = __toESM(require("os"));
10992
11051
  var path67 = __toESM(require("path"));
10993
11052
  var import_crypto3 = require("crypto");
10994
- var import_child_process24 = require("child_process");
11053
+ var import_child_process25 = require("child_process");
10995
11054
 
10996
11055
  // src/lib/payload.ts
10997
11056
  var import_zod = require("zod");
@@ -14499,10 +14558,10 @@ function buildForPlatform(platform3) {
14499
14558
  var import_node_crypto4 = require("crypto");
14500
14559
 
14501
14560
  // src/agents/claude/resolver.ts
14502
- function buildClaudeLaunch(extraArgs = [], os64 = createOsStrategy()) {
14503
- const found = os64.findInPath("claude") ?? os64.findInPath("claude-code");
14561
+ function buildClaudeLaunch(extraArgs = [], os65 = createOsStrategy()) {
14562
+ const found = os65.findInPath("claude") ?? os65.findInPath("claude-code");
14504
14563
  if (!found) return null;
14505
- return os64.buildLaunch(found, extraArgs);
14564
+ return os65.buildLaunch(found, extraArgs);
14506
14565
  }
14507
14566
 
14508
14567
  // src/agents/claude/installer.ts
@@ -15092,8 +15151,8 @@ var ClaudeRuntimeStrategy = class {
15092
15151
  meta = getAgent("claude");
15093
15152
  mode = "interactive";
15094
15153
  os;
15095
- constructor(os64) {
15096
- this.os = os64;
15154
+ constructor(os65) {
15155
+ this.os = os65;
15097
15156
  }
15098
15157
  /**
15099
15158
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -15873,8 +15932,8 @@ function codexCredentialLocator() {
15873
15932
  function codexLoginLauncher() {
15874
15933
  return {
15875
15934
  async ensureInstalled() {
15876
- const os64 = createOsStrategy();
15877
- return os64.findInPath("codex") !== null;
15935
+ const os65 = createOsStrategy();
15936
+ return os65.findInPath("codex") !== null;
15878
15937
  },
15879
15938
  launch() {
15880
15939
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -15897,8 +15956,8 @@ var CodexRuntimeStrategy = class {
15897
15956
  meta = getAgent("codex");
15898
15957
  mode = "interactive";
15899
15958
  os;
15900
- constructor(os64) {
15901
- this.os = os64;
15959
+ constructor(os65) {
15960
+ this.os = os65;
15902
15961
  }
15903
15962
  async prepareLaunch() {
15904
15963
  let binary = this.os.findInPath("codex");
@@ -16007,12 +16066,12 @@ var CodexRuntimeStrategy = class {
16007
16066
  });
16008
16067
  }
16009
16068
  };
16010
- function resolveNpm(os64) {
16011
- return os64.id === "win32" ? "npm.cmd" : "npm";
16069
+ function resolveNpm(os65) {
16070
+ return os65.id === "win32" ? "npm.cmd" : "npm";
16012
16071
  }
16013
- async function installCodexViaNpm(os64) {
16072
+ async function installCodexViaNpm(os65) {
16014
16073
  return new Promise((resolve9, reject) => {
16015
- const proc = (0, import_node_child_process5.spawn)(resolveNpm(os64), ["install", "-g", "@openai/codex"], {
16074
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os65), ["install", "-g", "@openai/codex"], {
16016
16075
  stdio: "inherit"
16017
16076
  });
16018
16077
  proc.on("close", (code) => {
@@ -16029,16 +16088,16 @@ async function installCodexViaNpm(os64) {
16029
16088
  });
16030
16089
  });
16031
16090
  }
16032
- function augmentNpmGlobalBin(os64) {
16091
+ function augmentNpmGlobalBin(os65) {
16033
16092
  try {
16034
- const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os64), ["prefix", "-g"], {
16093
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os65), ["prefix", "-g"], {
16035
16094
  stdio: ["ignore", "pipe", "ignore"]
16036
16095
  });
16037
16096
  if (result.status !== 0) return;
16038
16097
  const prefix = result.stdout.toString().trim();
16039
16098
  if (!prefix) return;
16040
- const binDir = os64.id === "win32" ? prefix : path25.join(prefix, "bin");
16041
- os64.augmentPath([binDir]);
16099
+ const binDir = os65.id === "win32" ? prefix : path25.join(prefix, "bin");
16100
+ os65.augmentPath([binDir]);
16042
16101
  } catch {
16043
16102
  }
16044
16103
  }
@@ -16437,10 +16496,10 @@ function manualInstallHint(runner, tools) {
16437
16496
  const argv = osPackageInstallArgv(detectPackageManager(runner), [...tools]);
16438
16497
  return argv ? `\`sudo ${argv.join(" ")}\`` : `your package manager (e.g. \`${pkgs}\`)`;
16439
16498
  }
16440
- function writeUnzipShim(os64, runner) {
16499
+ function writeUnzipShim(os65, runner) {
16441
16500
  const python = ["python3", "python"].find((p2) => runner.which(p2));
16442
16501
  if (!python) return null;
16443
- const dir = os64.scratchPath("codeam-cr-prereq");
16502
+ const dir = os65.scratchPath("codeam-cr-prereq");
16444
16503
  const shim = path27.join(dir, "unzip");
16445
16504
  const script = `#!/bin/sh
16446
16505
  set -e
@@ -16462,9 +16521,9 @@ exec ${python} -m zipfile -e "$archive" "$dest"
16462
16521
  (0, import_node_fs5.chmodSync)(shim, 448);
16463
16522
  return dir;
16464
16523
  }
16465
- async function ensureInstallPrerequisites(os64, deps = {}) {
16524
+ async function ensureInstallPrerequisites(os65, deps = {}) {
16466
16525
  const runner = deps.runner ?? defaultHeadroomRunner;
16467
- const missing = REQUIRED_TOOLS.filter((t2) => os64.findInPath(t2) === null);
16526
+ const missing = REQUIRED_TOOLS.filter((t2) => os65.findInPath(t2) === null);
16468
16527
  if (missing.length === 0) return { ok: true, extraPath: [] };
16469
16528
  log.info(
16470
16529
  "coderabbit",
@@ -16483,10 +16542,10 @@ async function ensureInstallPrerequisites(os64, deps = {}) {
16483
16542
  );
16484
16543
  }
16485
16544
  }
16486
- const stillMissing = REQUIRED_TOOLS.filter((t2) => os64.findInPath(t2) === null);
16545
+ const stillMissing = REQUIRED_TOOLS.filter((t2) => os65.findInPath(t2) === null);
16487
16546
  if (stillMissing.length === 0) return { ok: true, extraPath: [] };
16488
16547
  if (stillMissing.length === 1 && stillMissing[0] === "unzip") {
16489
- const shimDir = writeUnzipShim(os64, runner);
16548
+ const shimDir = writeUnzipShim(os65, runner);
16490
16549
  if (shimDir) {
16491
16550
  log.info("coderabbit", "unzip is unavailable \u2014 using a scoped python zipfile shim");
16492
16551
  return { ok: true, extraPath: [shimDir] };
@@ -16549,15 +16608,15 @@ function summarizeInstallFailure(output) {
16549
16608
  }
16550
16609
  return lines.length > 0 ? lines[lines.length - 1] : null;
16551
16610
  }
16552
- async function ensureCoderabbitInstalled(os64, deps = {}) {
16553
- if (os64.findInPath("coderabbit")) return { ok: true };
16554
- if (os64.id === "win32") {
16611
+ async function ensureCoderabbitInstalled(os65, deps = {}) {
16612
+ if (os65.findInPath("coderabbit")) return { ok: true };
16613
+ if (os65.id === "win32") {
16555
16614
  return {
16556
16615
  ok: false,
16557
16616
  error: "CodeRabbit on Windows requires WSL. Install the CLI inside your WSL distribution (curl -fsSL https://cli.coderabbit.ai/install.sh | sh), then try again."
16558
16617
  };
16559
16618
  }
16560
- const prereq = await ensureInstallPrerequisites(os64, deps);
16619
+ const prereq = await ensureInstallPrerequisites(os65, deps);
16561
16620
  if (!prereq.ok) return { ok: false, error: prereq.error };
16562
16621
  const env = { ...process.env };
16563
16622
  if (prereq.extraPath.length > 0) {
@@ -16573,8 +16632,8 @@ async function ensureCoderabbitInstalled(os64, deps = {}) {
16573
16632
  error: detail ? `CodeRabbit CLI install failed: ${detail}` : "CodeRabbit CLI install failed \u2014 check this machine's network egress and try again."
16574
16633
  };
16575
16634
  }
16576
- os64.augmentPath([`${os64.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
16577
- if (os64.findInPath("coderabbit") === null) {
16635
+ os65.augmentPath([`${os65.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
16636
+ if (os65.findInPath("coderabbit") === null) {
16578
16637
  const detail = summarizeInstallFailure(output);
16579
16638
  return {
16580
16639
  ok: false,
@@ -16616,10 +16675,10 @@ function coderabbitCredentialLocator() {
16616
16675
  validate: validateNonEmptyCredential
16617
16676
  };
16618
16677
  }
16619
- function coderabbitLoginLauncher(os64) {
16678
+ function coderabbitLoginLauncher(os65) {
16620
16679
  return {
16621
16680
  async ensureInstalled() {
16622
- const result = await ensureCoderabbitInstalled(os64);
16681
+ const result = await ensureCoderabbitInstalled(os65);
16623
16682
  if (!result.ok && result.error) console.error(`
16624
16683
  \u2717 ${result.error}
16625
16684
  `);
@@ -16843,8 +16902,8 @@ var CoderabbitRuntimeStrategy = class {
16843
16902
  meta = getAgent("coderabbit");
16844
16903
  mode = "batch";
16845
16904
  os;
16846
- constructor(os64) {
16847
- this.os = os64;
16905
+ constructor(os65) {
16906
+ this.os = os65;
16848
16907
  }
16849
16908
  getDefaultArgs() {
16850
16909
  return ["review", "--agent"];
@@ -17115,10 +17174,10 @@ function cursorCredentialLocator() {
17115
17174
  validate: validateNonEmptyCredential
17116
17175
  };
17117
17176
  }
17118
- function cursorLoginLauncher(os64) {
17177
+ function cursorLoginLauncher(os65) {
17119
17178
  return {
17120
17179
  async ensureInstalled() {
17121
- if (os64.findInPath("cursor-agent")) return true;
17180
+ if (os65.findInPath("cursor-agent")) return true;
17122
17181
  console.error(
17123
17182
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
17124
17183
  );
@@ -17182,8 +17241,8 @@ var CursorRuntimeStrategy = class {
17182
17241
  meta = getAgent("cursor");
17183
17242
  mode = "interactive";
17184
17243
  os;
17185
- constructor(os64) {
17186
- this.os = os64;
17244
+ constructor(os65) {
17245
+ this.os = os65;
17187
17246
  }
17188
17247
  async prepareLaunch() {
17189
17248
  const binary = this.os.findInPath("cursor-agent");
@@ -17399,10 +17458,10 @@ function aiderCredentialLocator() {
17399
17458
  validate: validateNonEmptyCredential
17400
17459
  };
17401
17460
  }
17402
- function aiderLoginLauncher(os64) {
17461
+ function aiderLoginLauncher(os65) {
17403
17462
  return {
17404
17463
  async ensureInstalled() {
17405
- if (os64.findInPath("aider")) return true;
17464
+ if (os65.findInPath("aider")) return true;
17406
17465
  console.error(
17407
17466
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
17408
17467
  );
@@ -17412,7 +17471,7 @@ function aiderLoginLauncher(os64) {
17412
17471
  console.error(
17413
17472
  "\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
17414
17473
  );
17415
- return (0, import_node_child_process12.spawn)(os64.id === "win32" ? "cmd.exe" : "sh", os64.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
17474
+ return (0, import_node_child_process12.spawn)(os65.id === "win32" ? "cmd.exe" : "sh", os65.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
17416
17475
  stdio: "ignore"
17417
17476
  });
17418
17477
  }
@@ -17484,8 +17543,8 @@ var AiderRuntimeStrategy = class {
17484
17543
  meta = getAgent("aider");
17485
17544
  mode = "interactive";
17486
17545
  os;
17487
- constructor(os64) {
17488
- this.os = os64;
17546
+ constructor(os65) {
17547
+ this.os = os65;
17489
17548
  }
17490
17549
  async prepareLaunch() {
17491
17550
  const binary = this.os.findInPath("aider");
@@ -17617,8 +17676,8 @@ function geminiCredentialLocator() {
17617
17676
  function geminiLoginLauncher() {
17618
17677
  return {
17619
17678
  async ensureInstalled() {
17620
- const os64 = createOsStrategy();
17621
- return os64.findInPath("gemini") !== null;
17679
+ const os65 = createOsStrategy();
17680
+ return os65.findInPath("gemini") !== null;
17622
17681
  },
17623
17682
  launch() {
17624
17683
  return (0, import_node_child_process13.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -17808,8 +17867,8 @@ var GeminiRuntimeStrategy = class {
17808
17867
  meta = getAgent("gemini");
17809
17868
  mode = "interactive";
17810
17869
  os;
17811
- constructor(os64) {
17812
- this.os = os64;
17870
+ constructor(os65) {
17871
+ this.os = os65;
17813
17872
  }
17814
17873
  async prepareLaunch() {
17815
17874
  const binary = this.os.findInPath("gemini");
@@ -18100,8 +18159,8 @@ var KimiRuntimeStrategy = class {
18100
18159
  meta = getAgent("kimi");
18101
18160
  mode = "interactive";
18102
18161
  os;
18103
- constructor(os64) {
18104
- this.os = os64;
18162
+ constructor(os65) {
18163
+ this.os = os65;
18105
18164
  }
18106
18165
  async prepareLaunch() {
18107
18166
  const binary = this.os.findInPath("kimi");
@@ -18243,8 +18302,8 @@ var OpencodeRuntimeStrategy = class {
18243
18302
  meta = getAgent("opencode");
18244
18303
  mode = "interactive";
18245
18304
  os;
18246
- constructor(os64) {
18247
- this.os = os64;
18305
+ constructor(os65) {
18306
+ this.os = os65;
18248
18307
  }
18249
18308
  async prepareLaunch() {
18250
18309
  const binary = this.os.findInPath("opencode");
@@ -18328,20 +18387,20 @@ var OpencodeRuntimeStrategy = class {
18328
18387
 
18329
18388
  // src/agents/registry.ts
18330
18389
  var runtimeBuilders = {
18331
- claude: (os64) => new ClaudeRuntimeStrategy(os64),
18332
- codex: (os64) => new CodexRuntimeStrategy(os64),
18333
- coderabbit: (os64) => new CoderabbitRuntimeStrategy(os64),
18334
- cursor: (os64) => new CursorRuntimeStrategy(os64),
18335
- aider: (os64) => new AiderRuntimeStrategy(os64),
18336
- gemini: (os64) => new GeminiRuntimeStrategy(os64),
18337
- kimi: (os64) => new KimiRuntimeStrategy(os64),
18338
- opencode: (os64) => new OpencodeRuntimeStrategy(os64)
18390
+ claude: (os65) => new ClaudeRuntimeStrategy(os65),
18391
+ codex: (os65) => new CodexRuntimeStrategy(os65),
18392
+ coderabbit: (os65) => new CoderabbitRuntimeStrategy(os65),
18393
+ cursor: (os65) => new CursorRuntimeStrategy(os65),
18394
+ aider: (os65) => new AiderRuntimeStrategy(os65),
18395
+ gemini: (os65) => new GeminiRuntimeStrategy(os65),
18396
+ kimi: (os65) => new KimiRuntimeStrategy(os65),
18397
+ opencode: (os65) => new OpencodeRuntimeStrategy(os65)
18339
18398
  };
18340
18399
  var deployBuilders = {
18341
18400
  claude: () => new ClaudeDeployStrategy(),
18342
18401
  codex: () => new CodexDeployStrategy()
18343
18402
  };
18344
- function createAgentStrategy(agent, os64 = createOsStrategy()) {
18403
+ function createAgentStrategy(agent, os65 = createOsStrategy()) {
18345
18404
  if (!AGENT_REGISTRY[agent]?.enabled) {
18346
18405
  throw new Error(
18347
18406
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -18351,10 +18410,10 @@ function createAgentStrategy(agent, os64 = createOsStrategy()) {
18351
18410
  if (!build) {
18352
18411
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
18353
18412
  }
18354
- return build(os64);
18413
+ return build(os65);
18355
18414
  }
18356
- function createInteractiveAgentStrategy(agent, os64 = createOsStrategy()) {
18357
- const s = createAgentStrategy(agent, os64);
18415
+ function createInteractiveAgentStrategy(agent, os65 = createOsStrategy()) {
18416
+ const s = createAgentStrategy(agent, os65);
18358
18417
  if (s.mode !== "interactive") {
18359
18418
  throw new Error(
18360
18419
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -19032,8 +19091,8 @@ function collectChangedFiles(cwd) {
19032
19091
  }
19033
19092
  return [...byPath.values()];
19034
19093
  }
19035
- function restoreCoderabbitOauthBlob(os64, value) {
19036
- const dir = path38.join(os64.homeDir(), ".coderabbit");
19094
+ function restoreCoderabbitOauthBlob(os65, value) {
19095
+ const dir = path38.join(os65.homeDir(), ".coderabbit");
19037
19096
  (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
19038
19097
  let file = "auth.json";
19039
19098
  let contents = value.trim();
@@ -19053,26 +19112,26 @@ function installFailureMessage(result) {
19053
19112
  return result.error ?? "CodeRabbit CLI could not be installed";
19054
19113
  }
19055
19114
  async function configureCoderabbit(input, deps = {}) {
19056
- const os64 = deps.os ?? createOsStrategy();
19115
+ const os65 = deps.os ?? createOsStrategy();
19057
19116
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
19058
19117
  const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
19059
19118
  const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
19060
19119
  const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
19061
19120
  const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
19062
19121
  const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
19063
- const home = os64.homeDir();
19064
- os64.augmentPath(
19065
- os64.id === "win32" ? [
19122
+ const home = os65.homeDir();
19123
+ os65.augmentPath(
19124
+ os65.id === "win32" ? [
19066
19125
  path38.join(home, ".local", "bin"),
19067
19126
  path38.join(process.env.APPDATA ?? path38.join(home, "AppData", "Roaming"), "npm"),
19068
19127
  path38.join(home, "scoop", "shims")
19069
19128
  ] : [path38.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
19070
19129
  );
19071
- const installed2 = os64.findInPath("coderabbit") !== null;
19130
+ const installed2 = os65.findInPath("coderabbit") !== null;
19072
19131
  const base = () => ({
19073
19132
  action: input.action,
19074
19133
  supported: true,
19075
- installed: os64.findInPath("coderabbit") !== null,
19134
+ installed: os65.findInPath("coderabbit") !== null,
19076
19135
  loggedIn: false
19077
19136
  });
19078
19137
  if (input.action === "status") {
@@ -19086,7 +19145,7 @@ async function configureCoderabbit(input, deps = {}) {
19086
19145
  const key = (input.apiKey ?? "").trim();
19087
19146
  if (!key) return { ...res2, error: "No API key provided" };
19088
19147
  if (!res2.installed) {
19089
- const inst = await ensureInstalled(os64);
19148
+ const inst = await ensureInstalled(os65);
19090
19149
  res2.installed = inst.ok;
19091
19150
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
19092
19151
  }
@@ -19110,7 +19169,7 @@ async function configureCoderabbit(input, deps = {}) {
19110
19169
  }
19111
19170
  if (!res2.installed) {
19112
19171
  deps.onEvent?.({ kind: "installing" });
19113
- const inst = await ensureInstalled(os64);
19172
+ const inst = await ensureInstalled(os65);
19114
19173
  res2.installed = inst.ok;
19115
19174
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
19116
19175
  }
@@ -19127,7 +19186,7 @@ async function configureCoderabbit(input, deps = {}) {
19127
19186
  return { ...res2, loggedIn: true, linked: true };
19128
19187
  }
19129
19188
  try {
19130
- restoreCoderabbitOauthBlob(os64, cred.credential);
19189
+ restoreCoderabbitOauthBlob(os65, cred.credential);
19131
19190
  } catch (err) {
19132
19191
  return {
19133
19192
  ...res2,
@@ -19151,7 +19210,7 @@ async function configureCoderabbit(input, deps = {}) {
19151
19210
  const res2 = base();
19152
19211
  if (!installed2) {
19153
19212
  deps.onEvent?.({ kind: "installing" });
19154
- const inst = await ensureInstalled(os64);
19213
+ const inst = await ensureInstalled(os65);
19155
19214
  res2.installed = inst.ok;
19156
19215
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
19157
19216
  }
@@ -19191,7 +19250,7 @@ async function configureCoderabbit(input, deps = {}) {
19191
19250
  }
19192
19251
  const res = base();
19193
19252
  if (!res.installed) {
19194
- const inst = await ensureInstalled(os64);
19253
+ const inst = await ensureInstalled(os65);
19195
19254
  res.installed = inst.ok;
19196
19255
  if (!inst.ok) return { ...res, error: installFailureMessage(inst) };
19197
19256
  }
@@ -19375,7 +19434,7 @@ function defaultRunGh(args2) {
19375
19434
 
19376
19435
  // src/commands/host-agent.ts
19377
19436
  var import_node_child_process25 = require("child_process");
19378
- var os40 = __toESM(require("os"));
19437
+ var os41 = __toESM(require("os"));
19379
19438
  var fs45 = __toESM(require("fs"));
19380
19439
  var path49 = __toESM(require("path"));
19381
19440
 
@@ -19499,6 +19558,55 @@ function persistOrClearSkillsFromPayload(skills) {
19499
19558
  else clearSkillsManifest();
19500
19559
  }
19501
19560
 
19561
+ // src/commands/host/agent-install.ts
19562
+ var import_child_process13 = require("child_process");
19563
+ var os32 = __toESM(require("os"));
19564
+ function runAgentInstallScript(script, opts = {}) {
19565
+ const timeoutMs = opts.timeoutMs ?? 18e4;
19566
+ const scope = opts.logScope ?? "agent-install";
19567
+ return new Promise((resolve9) => {
19568
+ const home = process.env.HOME || os32.homedir();
19569
+ const child = (0, import_child_process13.spawn)("sh", ["-c", script], {
19570
+ env: { ...process.env, HOME: home },
19571
+ stdio: ["ignore", "pipe", "pipe"]
19572
+ });
19573
+ const onData = (b) => {
19574
+ const line = b.toString().replace(/\n+$/g, "");
19575
+ if (line) log.info(scope, `agent-install: ${line}`);
19576
+ };
19577
+ child.stdout?.on("data", onData);
19578
+ child.stderr?.on("data", onData);
19579
+ let settled = false;
19580
+ const done = (result) => {
19581
+ if (settled) return;
19582
+ settled = true;
19583
+ resolve9(result);
19584
+ };
19585
+ const timer = setTimeout(() => {
19586
+ log.warn(scope, `agent install timed out (${Math.round(timeoutMs / 1e3)}s)`);
19587
+ try {
19588
+ child.kill("SIGTERM");
19589
+ } catch {
19590
+ }
19591
+ done({ ok: false, code: null, timedOut: true });
19592
+ }, timeoutMs);
19593
+ child.once("exit", (code) => {
19594
+ clearTimeout(timer);
19595
+ if (code !== 0) {
19596
+ log.warn(scope, `agent install exited code=${code}`);
19597
+ } else {
19598
+ log.info(scope, "agent CLI installed");
19599
+ }
19600
+ done({ ok: code === 0, code: code ?? null, timedOut: false });
19601
+ });
19602
+ child.once("error", (e) => {
19603
+ clearTimeout(timer);
19604
+ log.warn(scope, `agent install spawn error: ${e.message}`);
19605
+ done({ ok: false, code: null, timedOut: false });
19606
+ });
19607
+ });
19608
+ }
19609
+
19502
19610
  // src/lib/process-guards.ts
19503
19611
  var installed = false;
19504
19612
  function installRelayCrashGuards() {
@@ -19524,13 +19632,13 @@ function describeReason(reason) {
19524
19632
 
19525
19633
  // src/commands/host/host-client.ts
19526
19634
  var fs36 = __toESM(require("fs"));
19527
- var os32 = __toESM(require("os"));
19635
+ var os33 = __toESM(require("os"));
19528
19636
  var path41 = __toESM(require("path"));
19529
19637
  var import_node_crypto9 = require("crypto");
19530
19638
  function sampleCpuTimes() {
19531
19639
  let idle = 0;
19532
19640
  let total = 0;
19533
- for (const cpu of os32.cpus()) {
19641
+ for (const cpu of os33.cpus()) {
19534
19642
  const t2 = cpu.times;
19535
19643
  idle += t2.idle;
19536
19644
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -19549,8 +19657,8 @@ var MetricsCollector = class {
19549
19657
  const prev = this.prevCpu;
19550
19658
  this.prevCpu = current2;
19551
19659
  if (!prev) {
19552
- const cores = os32.cpus().length || 1;
19553
- const proxy = os32.loadavg()[0] / cores * 100;
19660
+ const cores = os33.cpus().length || 1;
19661
+ const proxy = os33.loadavg()[0] / cores * 100;
19554
19662
  return Math.min(100, Math.max(0, Math.round(proxy)));
19555
19663
  }
19556
19664
  const idleDelta = current2.idle - prev.idle;
@@ -19563,8 +19671,8 @@ var MetricsCollector = class {
19563
19671
  collect() {
19564
19672
  return {
19565
19673
  cpuPct: this.cpuPct(),
19566
- ramUsedMb: Math.round((os32.totalmem() - os32.freemem()) / 1048576),
19567
- ramTotalMb: Math.round(os32.totalmem() / 1048576),
19674
+ ramUsedMb: Math.round((os33.totalmem() - os33.freemem()) / 1048576),
19675
+ ramTotalMb: Math.round(os33.totalmem() / 1048576),
19568
19676
  latencyMs: this.lastLatencyMs
19569
19677
  };
19570
19678
  }
@@ -19573,13 +19681,13 @@ function apiBase() {
19573
19681
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
19574
19682
  }
19575
19683
  function hostIdentityPath() {
19576
- return path41.join(os32.homedir(), ".codeam", "host-agent.json");
19684
+ return path41.join(os33.homedir(), ".codeam", "host-agent.json");
19577
19685
  }
19578
19686
  function collectOsInfo() {
19579
19687
  return {
19580
- distro: os32.platform(),
19581
- arch: os32.arch(),
19582
- kernel: os32.release(),
19688
+ distro: os33.platform(),
19689
+ arch: os33.arch(),
19690
+ kernel: os33.release(),
19583
19691
  nodeVersion: process.versions.node
19584
19692
  };
19585
19693
  }
@@ -19674,7 +19782,7 @@ async function postJson(pathname, body) {
19674
19782
  function resolveHostLabel(label) {
19675
19783
  const explicit = label?.trim();
19676
19784
  const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
19677
- const resolved = explicit || envLabel || os32.hostname();
19785
+ const resolved = explicit || envLabel || os33.hostname();
19678
19786
  return resolved.slice(0, 80);
19679
19787
  }
19680
19788
  async function redeemEnrollToken(token, label) {
@@ -19786,7 +19894,7 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
19786
19894
 
19787
19895
  // src/commands/host/workspace.ts
19788
19896
  var fs37 = __toESM(require("fs"));
19789
- var os33 = __toESM(require("os"));
19897
+ var os34 = __toESM(require("os"));
19790
19898
  var path42 = __toESM(require("path"));
19791
19899
  var import_node_child_process20 = require("child_process");
19792
19900
  var import_node_util4 = require("util");
@@ -19795,7 +19903,7 @@ function isAbsolutePathTarget(target) {
19795
19903
  return path42.isAbsolute(target);
19796
19904
  }
19797
19905
  function selfHostedWorkspaceRoot() {
19798
- return path42.join(os33.homedir(), ".codeam", "self-hosted");
19906
+ return path42.join(os34.homedir(), ".codeam", "self-hosted");
19799
19907
  }
19800
19908
  function nonInteractiveGitEnv() {
19801
19909
  return {
@@ -19935,7 +20043,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
19935
20043
 
19936
20044
  // src/commands/host/agent-provisioning.ts
19937
20045
  var fs38 = __toESM(require("fs"));
19938
- var os34 = __toESM(require("os"));
20046
+ var os35 = __toESM(require("os"));
19939
20047
  var path43 = __toESM(require("path"));
19940
20048
  var PUBLIC_TO_INTERNAL_AGENT = {
19941
20049
  claude_code: "claude",
@@ -20120,7 +20228,7 @@ var UnsupportedAgentError = class extends Error {
20120
20228
  this.agentId = agentId;
20121
20229
  }
20122
20230
  };
20123
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os34.homedir()) {
20231
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os35.homedir()) {
20124
20232
  const internal = toInternalAgentId(publicAgentId);
20125
20233
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
20126
20234
  const provisioner = PROVISIONERS[internal];
@@ -20131,10 +20239,10 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os34.homedir(
20131
20239
  // src/commands/host/git-tooling.ts
20132
20240
  var import_node_child_process21 = require("child_process");
20133
20241
  var fs39 = __toESM(require("fs"));
20134
- var os35 = __toESM(require("os"));
20242
+ var os36 = __toESM(require("os"));
20135
20243
  var path44 = __toESM(require("path"));
20136
20244
  function codeamBinDir() {
20137
- return process.env.CODEAM_BIN_DIR ?? path44.join(os35.homedir(), ".codeam", "bin");
20245
+ return process.env.CODEAM_BIN_DIR ?? path44.join(os36.homedir(), ".codeam", "bin");
20138
20246
  }
20139
20247
  var FALLBACK_GH_VERSION = "2.62.0";
20140
20248
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -20189,7 +20297,7 @@ async function ensureGhCli(runner, token, deps = {}) {
20189
20297
  const version3 = await resolveVersionFn(token);
20190
20298
  const asset = `gh_${version3}_${osToken}_${arch2}`;
20191
20299
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
20192
- const tmpRoot = fs39.mkdtempSync(path44.join(os35.tmpdir(), "codeam-gh-"));
20300
+ const tmpRoot = fs39.mkdtempSync(path44.join(os36.tmpdir(), "codeam-gh-"));
20193
20301
  const archive = path44.join(tmpRoot, `${asset}.${ext}`);
20194
20302
  if (!await downloadFn(url2, archive)) {
20195
20303
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
@@ -20269,7 +20377,7 @@ async function ensureGlabCli(runner, deps = {}) {
20269
20377
  const version3 = await resolveLatestGlabVersion();
20270
20378
  const asset = `glab_${version3}_${osToken}_${arch2}`;
20271
20379
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
20272
- const tmpRoot = fs39.mkdtempSync(path44.join(os35.tmpdir(), "codeam-glab-"));
20380
+ const tmpRoot = fs39.mkdtempSync(path44.join(os36.tmpdir(), "codeam-glab-"));
20273
20381
  const archive = path44.join(tmpRoot, `${asset}.${ext}`);
20274
20382
  if (!await downloadFn(url2, archive)) {
20275
20383
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
@@ -20493,14 +20601,14 @@ var HeadroomStatsReporter = class {
20493
20601
  // src/commands/host/headroom-bootstrap.ts
20494
20602
  var fs41 = __toESM(require("fs"));
20495
20603
  var path46 = __toESM(require("path"));
20496
- var os37 = __toESM(require("os"));
20604
+ var os38 = __toESM(require("os"));
20497
20605
 
20498
20606
  // src/commands/host/headroom-config.ts
20499
20607
  var fs40 = __toESM(require("fs"));
20500
- var os36 = __toESM(require("os"));
20608
+ var os37 = __toESM(require("os"));
20501
20609
  var path45 = __toESM(require("path"));
20502
20610
  function headroomConfigPath() {
20503
- return path45.join(os36.homedir(), ".codeam", "headroom-config.json");
20611
+ return path45.join(os37.homedir(), ".codeam", "headroom-config.json");
20504
20612
  }
20505
20613
  function persistHeadroomConfig(config) {
20506
20614
  try {
@@ -20518,7 +20626,7 @@ function persistHeadroomConfig(config) {
20518
20626
  }
20519
20627
  }
20520
20628
  function agentSettingsPath(kind) {
20521
- const home = os36.homedir();
20629
+ const home = os37.homedir();
20522
20630
  if (kind === "claude") return path45.join(home, ".claude", "settings.json");
20523
20631
  if (kind === "codex") return path45.join(home, ".codex", "auth.json");
20524
20632
  if (kind === "copilot") return path45.join(home, ".config", "github-copilot", "hosts.json");
@@ -20529,7 +20637,7 @@ function backupAgentHeadroomConfig(kind) {
20529
20637
  if (!src) return;
20530
20638
  try {
20531
20639
  if (!fs40.existsSync(src)) return;
20532
- const dest = path45.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20640
+ const dest = path45.join(os37.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20533
20641
  fs40.mkdirSync(path45.dirname(dest), { recursive: true, mode: 448 });
20534
20642
  fs40.copyFileSync(src, dest);
20535
20643
  fs40.chmodSync(dest, 384);
@@ -20544,7 +20652,7 @@ function backupAgentHeadroomConfig(kind) {
20544
20652
  function restoreAgentHeadroomConfig(kind) {
20545
20653
  const dest = agentSettingsPath(kind);
20546
20654
  if (!dest) return false;
20547
- const src = path45.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20655
+ const src = path45.join(os37.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20548
20656
  if (!fs40.existsSync(src)) return false;
20549
20657
  try {
20550
20658
  fs40.mkdirSync(path45.dirname(dest), { recursive: true, mode: 448 });
@@ -20636,7 +20744,7 @@ async function getFreeDiskBytes(dir) {
20636
20744
  }
20637
20745
  function headroomModelsCached() {
20638
20746
  const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path46.join(
20639
- process.env.HF_HOME || path46.join(os37.homedir(), ".cache", "huggingface"),
20747
+ process.env.HF_HOME || path46.join(os38.homedir(), ".cache", "huggingface"),
20640
20748
  "hub"
20641
20749
  );
20642
20750
  return HEADROOM_MODELS.every(
@@ -20747,10 +20855,10 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
20747
20855
 
20748
20856
  // src/commands/host/house-proxy-config.ts
20749
20857
  var fs42 = __toESM(require("fs"));
20750
- var os38 = __toESM(require("os"));
20858
+ var os39 = __toESM(require("os"));
20751
20859
  var path47 = __toESM(require("path"));
20752
20860
  function houseProxyConfigPath() {
20753
- return path47.join(os38.homedir(), ".codeam", "house-proxy.json");
20861
+ return path47.join(os39.homedir(), ".codeam", "house-proxy.json");
20754
20862
  }
20755
20863
  function persistHouseProxyConfig(config) {
20756
20864
  try {
@@ -20809,7 +20917,7 @@ var import_node_child_process23 = require("child_process");
20809
20917
 
20810
20918
  // src/lib/updateNotifier.ts
20811
20919
  var fs43 = __toESM(require("fs"));
20812
- var os39 = __toESM(require("os"));
20920
+ var os40 = __toESM(require("os"));
20813
20921
  var path48 = __toESM(require("path"));
20814
20922
  var https6 = __toESM(require("https"));
20815
20923
  var import_node_child_process22 = require("child_process");
@@ -20819,7 +20927,7 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
20819
20927
  var TTL_MS = 24 * 60 * 60 * 1e3;
20820
20928
  var REQUEST_TIMEOUT_MS = 1500;
20821
20929
  function cachePath() {
20822
- const dir = path48.join(os39.homedir(), ".codeam");
20930
+ const dir = path48.join(os40.homedir(), ".codeam");
20823
20931
  return path48.join(dir, "update-check.json");
20824
20932
  }
20825
20933
  function readCache() {
@@ -20965,7 +21073,7 @@ async function autoUpgradeBeforeCriticalCommand() {
20965
21073
  if (process.env.NODE_ENV === "test") return;
20966
21074
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20967
21075
  if (process.env.CI) return;
20968
- const current2 = true ? "2.62.2" : null;
21076
+ const current2 = true ? "2.63.1" : null;
20969
21077
  if (!current2) return;
20970
21078
  const cache = readCache();
20971
21079
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -20982,7 +21090,7 @@ function checkForUpdates() {
20982
21090
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20983
21091
  if (process.env.CI) return;
20984
21092
  if (!process.stdout.isTTY) return;
20985
- const current2 = true ? "2.62.2" : null;
21093
+ const current2 = true ? "2.63.1" : null;
20986
21094
  if (!current2) return;
20987
21095
  const cache = readCache();
20988
21096
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -21002,7 +21110,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
21002
21110
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
21003
21111
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
21004
21112
  function currentCliVersion() {
21005
- return true ? "2.62.2" : null;
21113
+ return true ? "2.63.1" : null;
21006
21114
  }
21007
21115
  function runCmd(cmd, args2, timeoutMs) {
21008
21116
  return new Promise((resolve9) => {
@@ -21734,7 +21842,7 @@ var HostAgentSupervisor = class {
21734
21842
  const relay = this.relay;
21735
21843
  if (!relay) return;
21736
21844
  const raw = cmd.payload?.path;
21737
- const target = typeof raw === "string" && raw.trim() ? path49.resolve(raw.trim()) : os40.homedir();
21845
+ const target = typeof raw === "string" && raw.trim() ? path49.resolve(raw.trim()) : os41.homedir();
21738
21846
  try {
21739
21847
  const dirents = await fs45.promises.readdir(target, { withFileTypes: true });
21740
21848
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
@@ -21974,7 +22082,7 @@ var HostAgentSupervisor = class {
21974
22082
  CODEAM_AUTO_TOKEN: payload.autoPairToken
21975
22083
  };
21976
22084
  const houseConfigDir = path49.join(
21977
- os40.homedir(),
22085
+ os41.homedir(),
21978
22086
  ".codeam",
21979
22087
  "house-claude",
21980
22088
  payload.deployId
@@ -22006,7 +22114,7 @@ var HostAgentSupervisor = class {
22006
22114
  report("installing", "installing agent CLI");
22007
22115
  await this.runAgentInstall(payload.agentInstallScript);
22008
22116
  }
22009
- const home = process.env.HOME || os40.homedir();
22117
+ const home = process.env.HOME || os41.homedir();
22010
22118
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
22011
22119
  if (payload.cloneToken) {
22012
22120
  try {
@@ -22040,7 +22148,7 @@ var HostAgentSupervisor = class {
22040
22148
  }
22041
22149
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
22042
22150
  report("headroom", "setting up Headroom proxy");
22043
- const freeBytes = await this.getFreeDisk(os40.homedir());
22151
+ const freeBytes = await this.getFreeDisk(os41.homedir());
22044
22152
  const alreadyInstalled = this.isHeadroomInstalled();
22045
22153
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
22046
22154
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -22099,7 +22207,7 @@ var HostAgentSupervisor = class {
22099
22207
  );
22100
22208
  if (!payload.suppressOnboardingWelcome) {
22101
22209
  try {
22102
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path49.join(os40.homedir(), ".claude");
22210
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path49.join(os41.homedir(), ".claude");
22103
22211
  const projectDir = path49.join(cfgDir, "projects", encodeCwd(cwd));
22104
22212
  const hasPriorConversation = fs45.existsSync(projectDir) && fs45.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
22105
22213
  if (hasPriorConversation) {
@@ -22247,54 +22355,14 @@ var HostAgentSupervisor = class {
22247
22355
  * HOME is forced so the installer's `~/.local/bin` resolves on a detached
22248
22356
  * host-agent whose env may lack it.
22249
22357
  */
22250
- runAgentInstall(script) {
22251
- return new Promise((resolve9) => {
22252
- const home = process.env.HOME || os40.homedir();
22253
- const child = (0, import_node_child_process25.spawn)("sh", ["-c", script], {
22254
- env: { ...process.env, HOME: home },
22255
- stdio: ["ignore", "pipe", "pipe"]
22256
- });
22257
- const onData = (b) => {
22258
- const line = b.toString().replace(/\n+$/g, "");
22259
- if (line) log.info("host-agent", `agent-install: ${line}`);
22260
- };
22261
- child.stdout?.on("data", onData);
22262
- child.stderr?.on("data", onData);
22263
- let settled = false;
22264
- const done = () => {
22265
- if (settled) return;
22266
- settled = true;
22267
- resolve9();
22268
- };
22269
- const timer = setTimeout(() => {
22270
- log.warn(
22271
- "host-agent",
22272
- "agent install timed out (180s) \u2014 preview detection may be unavailable"
22273
- );
22274
- try {
22275
- child.kill("SIGTERM");
22276
- } catch {
22277
- }
22278
- done();
22279
- }, 18e4);
22280
- child.once("exit", (code) => {
22281
- clearTimeout(timer);
22282
- if (code !== 0) {
22283
- log.warn(
22284
- "host-agent",
22285
- `agent install exited code=${code} \u2014 preview detection may be unavailable; agent still runs`
22286
- );
22287
- } else {
22288
- log.info("host-agent", "agent CLI installed");
22289
- }
22290
- done();
22291
- });
22292
- child.once("error", (e) => {
22293
- clearTimeout(timer);
22294
- log.warn("host-agent", `agent install spawn error: ${e.message}`);
22295
- done();
22296
- });
22297
- });
22358
+ async runAgentInstall(script) {
22359
+ const res = await runAgentInstallScript(script, { logScope: "host-agent" });
22360
+ if (!res.ok) {
22361
+ log.warn(
22362
+ "host-agent",
22363
+ "agent install failed \u2014 preview detection may be unavailable; agent still runs"
22364
+ );
22365
+ }
22298
22366
  }
22299
22367
  /**
22300
22368
  * Kill the child for the given id. The backend correlates the session it
@@ -22338,7 +22406,7 @@ var HostAgentSupervisor = class {
22338
22406
  }
22339
22407
  const dirs = [
22340
22408
  path49.join(selfHostedWorkspaceRoot(), deployId),
22341
- path49.join(os40.homedir(), ".codeam", "house-claude", deployId)
22409
+ path49.join(os41.homedir(), ".codeam", "house-claude", deployId)
22342
22410
  ];
22343
22411
  for (const dir of dirs) {
22344
22412
  try {
@@ -22480,9 +22548,9 @@ async function configureHeadroom(action, ctx, deps) {
22480
22548
 
22481
22549
  // src/services/headroom/budget-relaunch.ts
22482
22550
  var fs46 = __toESM(require("fs"));
22483
- var os41 = __toESM(require("os"));
22551
+ var os42 = __toESM(require("os"));
22484
22552
  var path50 = __toESM(require("path"));
22485
- var import_child_process13 = require("child_process");
22553
+ var import_child_process14 = require("child_process");
22486
22554
  function amendDeploymentManifestBudget(manifest, budget) {
22487
22555
  const rawArgs = manifest.proxy_args ?? [];
22488
22556
  const strippedArgs = [];
@@ -22561,7 +22629,7 @@ function writeManifestReal(manifestPath, manifest) {
22561
22629
  }
22562
22630
  function restartDeploymentReal(profile) {
22563
22631
  try {
22564
- const proc = (0, import_child_process13.spawn)("headroom", ["install", "restart", "--profile", profile], {
22632
+ const proc = (0, import_child_process14.spawn)("headroom", ["install", "restart", "--profile", profile], {
22565
22633
  detached: true,
22566
22634
  stdio: "ignore"
22567
22635
  });
@@ -22592,7 +22660,7 @@ function spawnProxyReal2(_budget) {
22592
22660
  );
22593
22661
  }
22594
22662
  function makeRealApplyBudgetDeps() {
22595
- const homeDir2 = os41.homedir();
22663
+ const homeDir2 = os42.homedir();
22596
22664
  return {
22597
22665
  findDeployments: () => findHeadroomDeployments(homeDir2, {
22598
22666
  readDir: (dir) => fs46.readdirSync(dir),
@@ -22731,12 +22799,12 @@ async function readUsageReport(deps = {}) {
22731
22799
  // src/agents/acp/guardrail-config.ts
22732
22800
  var fs47 = __toESM(require("fs"));
22733
22801
  var path51 = __toESM(require("path"));
22734
- var os42 = __toESM(require("os"));
22802
+ var os43 = __toESM(require("os"));
22735
22803
  var current = null;
22736
- function guardrailConfigPath(homeDir2 = os42.homedir()) {
22804
+ function guardrailConfigPath(homeDir2 = os43.homedir()) {
22737
22805
  return path51.join(homeDir2, ".codeam", "guardrails.json");
22738
22806
  }
22739
- function loadGuardrailPolicy(homeDir2 = os42.homedir()) {
22807
+ function loadGuardrailPolicy(homeDir2 = os43.homedir()) {
22740
22808
  try {
22741
22809
  current = normalizeGuardrailPolicy(JSON.parse(fs47.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
22742
22810
  } catch {
@@ -22744,10 +22812,10 @@ function loadGuardrailPolicy(homeDir2 = os42.homedir()) {
22744
22812
  }
22745
22813
  return current;
22746
22814
  }
22747
- function getGuardrailPolicy(homeDir2 = os42.homedir()) {
22815
+ function getGuardrailPolicy(homeDir2 = os43.homedir()) {
22748
22816
  return current ?? loadGuardrailPolicy(homeDir2);
22749
22817
  }
22750
- function setGuardrailPolicy(raw, homeDir2 = os42.homedir()) {
22818
+ function setGuardrailPolicy(raw, homeDir2 = os43.homedir()) {
22751
22819
  const next = normalizeGuardrailPolicy(raw);
22752
22820
  current = next;
22753
22821
  try {
@@ -22761,11 +22829,11 @@ function setGuardrailPolicy(raw, homeDir2 = os42.homedir()) {
22761
22829
 
22762
22830
  // src/services/preview/port-registry.ts
22763
22831
  var fs48 = __toESM(require("fs"));
22764
- var os43 = __toESM(require("os"));
22832
+ var os44 = __toESM(require("os"));
22765
22833
  var path52 = __toESM(require("path"));
22766
- var import_child_process14 = require("child_process");
22834
+ var import_child_process15 = require("child_process");
22767
22835
  function registryPath() {
22768
- return path52.join(os43.homedir(), ".codeam", "preview-ports.json");
22836
+ return path52.join(os44.homedir(), ".codeam", "preview-ports.json");
22769
22837
  }
22770
22838
  function readRegistry() {
22771
22839
  try {
@@ -22810,7 +22878,7 @@ function groupAlive(pgid) {
22810
22878
  }
22811
22879
  function killGroup(pgid) {
22812
22880
  if (process.platform === "win32") {
22813
- (0, import_child_process14.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pgid)], { stdio: "ignore" });
22881
+ (0, import_child_process15.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pgid)], { stdio: "ignore" });
22814
22882
  return;
22815
22883
  }
22816
22884
  try {
@@ -23051,7 +23119,7 @@ async function applyPreviewHostAllow(cwd) {
23051
23119
  }
23052
23120
 
23053
23121
  // src/services/preview/cloudflared.ts
23054
- var import_child_process15 = require("child_process");
23122
+ var import_child_process16 = require("child_process");
23055
23123
  var import_fs2 = require("fs");
23056
23124
  var import_promises = __toESM(require("fs/promises"));
23057
23125
  var import_os9 = __toESM(require("os"));
@@ -23128,7 +23196,7 @@ async function isExecutableBinary(p2) {
23128
23196
  }
23129
23197
  function extractTgz(tgzPath, destDir) {
23130
23198
  return new Promise((resolve9, reject) => {
23131
- const child = (0, import_child_process15.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
23199
+ const child = (0, import_child_process16.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
23132
23200
  child.on("error", (err) => reject(err));
23133
23201
  child.on(
23134
23202
  "exit",
@@ -23162,7 +23230,7 @@ async function spawnNamedTunnel(bin, token, port) {
23162
23230
  await import_promises.default.mkdir(credDir, { recursive: true });
23163
23231
  const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
23164
23232
  await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
23165
- return (0, import_child_process15.spawn)(
23233
+ return (0, import_child_process16.spawn)(
23166
23234
  bin,
23167
23235
  [
23168
23236
  "tunnel",
@@ -23178,9 +23246,9 @@ async function spawnNamedTunnel(bin, token, port) {
23178
23246
  }
23179
23247
 
23180
23248
  // src/services/preview/codespace.ts
23181
- var import_child_process16 = require("child_process");
23249
+ var import_child_process17 = require("child_process");
23182
23250
  var import_util3 = require("util");
23183
- var execFileP5 = (0, import_util3.promisify)(import_child_process16.execFile);
23251
+ var execFileP5 = (0, import_util3.promisify)(import_child_process17.execFile);
23184
23252
 
23185
23253
  // src/services/preview/config-file.ts
23186
23254
  var import_promises3 = __toESM(require("fs/promises"));
@@ -23375,10 +23443,10 @@ var import_fs3 = require("fs");
23375
23443
  var import_path6 = __toESM(require("path"));
23376
23444
 
23377
23445
  // src/services/preview/run-setup.ts
23378
- var import_child_process17 = require("child_process");
23446
+ var import_child_process18 = require("child_process");
23379
23447
  function runSetupCommand(cmd, args2, cwd, env, opts) {
23380
23448
  return new Promise((resolve9) => {
23381
- const child = (0, import_child_process17.spawn)(cmd, args2, {
23449
+ const child = (0, import_child_process18.spawn)(cmd, args2, {
23382
23450
  cwd,
23383
23451
  env: { ...process.env, ...env ?? {} },
23384
23452
  stdio: ["ignore", "pipe", "pipe"]
@@ -23722,7 +23790,7 @@ function activePreviewSessionIds() {
23722
23790
  }
23723
23791
 
23724
23792
  // src/services/preview/start-orchestrator.ts
23725
- var import_child_process19 = require("child_process");
23793
+ var import_child_process20 = require("child_process");
23726
23794
  var fs56 = __toESM(require("fs"));
23727
23795
  var path60 = __toESM(require("path"));
23728
23796
  var import_which2 = __toESM(require("which"));
@@ -23732,7 +23800,7 @@ var import_fs5 = require("fs");
23732
23800
  var path59 = __toESM(require("path"));
23733
23801
 
23734
23802
  // src/beads/project-key.ts
23735
- var import_child_process18 = require("child_process");
23803
+ var import_child_process19 = require("child_process");
23736
23804
  var crypto2 = __toESM(require("crypto"));
23737
23805
  var fs54 = __toESM(require("fs"));
23738
23806
  var path58 = __toESM(require("path"));
@@ -23779,7 +23847,7 @@ function findRepoRoot(cwd) {
23779
23847
  }
23780
23848
  var _execSeam2 = {
23781
23849
  exec: (file, args2, opts) => {
23782
- const out2 = (0, import_child_process18.execFileSync)(file, args2, opts);
23850
+ const out2 = (0, import_child_process19.execFileSync)(file, args2, opts);
23783
23851
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
23784
23852
  },
23785
23853
  realpath: (p2) => fs54.realpathSync(p2)
@@ -24151,7 +24219,7 @@ async function startDevServer(ctx) {
24151
24219
  await applyPreviewHostAllow(cwd);
24152
24220
  const spawnable = normalizeDetectionForSpawn(detection, cwd);
24153
24221
  emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
24154
- const devServer = (0, import_child_process19.spawn)(spawnable.command, spawnable.args, {
24222
+ const devServer = (0, import_child_process20.spawn)(spawnable.command, spawnable.args, {
24155
24223
  cwd,
24156
24224
  env: { ...process.env, ...spawnable.env ?? {} },
24157
24225
  stdio: ["ignore", "pipe", "pipe"],
@@ -24276,7 +24344,7 @@ async function establishTunnel(ctx, dev) {
24276
24344
  `cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
24277
24345
  );
24278
24346
  }
24279
- const candidate = (0, import_child_process19.spawn)(
24347
+ const candidate = (0, import_child_process20.spawn)(
24280
24348
  bin,
24281
24349
  ["tunnel", "--url", `http://localhost:${detection.port}`],
24282
24350
  { stdio: ["ignore", "pipe", "pipe"] }
@@ -24307,9 +24375,9 @@ async function establishTunnel(ctx, dev) {
24307
24375
  }
24308
24376
 
24309
24377
  // src/beads/bd-adapter.ts
24310
- var import_child_process20 = require("child_process");
24378
+ var import_child_process21 = require("child_process");
24311
24379
  var fs57 = __toESM(require("fs"));
24312
- var os45 = __toESM(require("os"));
24380
+ var os46 = __toESM(require("os"));
24313
24381
  var path61 = __toESM(require("path"));
24314
24382
  var BD_PACKAGE = "@beads/bd";
24315
24383
  function resolveBundledBdBinary() {
@@ -24361,7 +24429,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
24361
24429
  return new Promise((resolve9) => {
24362
24430
  let proc;
24363
24431
  try {
24364
- proc = (0, import_child_process20.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
24432
+ proc = (0, import_child_process21.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
24365
24433
  } catch (err) {
24366
24434
  resolve9({ code: -1, stdout: "", stderr: err.message });
24367
24435
  return;
@@ -24427,7 +24495,7 @@ var BdAdapter = class {
24427
24495
  const env = { ...process.env };
24428
24496
  if (!env.HOME) {
24429
24497
  try {
24430
- const home = os45.homedir();
24498
+ const home = os46.homedir();
24431
24499
  if (home) env.HOME = home;
24432
24500
  } catch {
24433
24501
  }
@@ -24518,13 +24586,13 @@ function coerceIssue(row, projectKey) {
24518
24586
  }
24519
24587
 
24520
24588
  // src/beads/provisioner.ts
24521
- var import_child_process23 = require("child_process");
24589
+ var import_child_process24 = require("child_process");
24522
24590
  var fs59 = __toESM(require("fs"));
24523
- var os47 = __toESM(require("os"));
24591
+ var os48 = __toESM(require("os"));
24524
24592
  var path63 = __toESM(require("path"));
24525
24593
 
24526
24594
  // src/beads/install-bd.ts
24527
- var import_child_process21 = require("child_process");
24595
+ var import_child_process22 = require("child_process");
24528
24596
  var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
24529
24597
  var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
24530
24598
  function resolveInstallStrategy(platform3) {
@@ -24555,7 +24623,7 @@ function _defaultInstallSpawn(strategy) {
24555
24623
  return new Promise((resolve9) => {
24556
24624
  let proc;
24557
24625
  try {
24558
- proc = (0, import_child_process21.spawn)(strategy.command, strategy.args, { env: process.env });
24626
+ proc = (0, import_child_process22.spawn)(strategy.command, strategy.args, { env: process.env });
24559
24627
  } catch (err) {
24560
24628
  resolve9({ ok: false, code: -1, stderr: err.message });
24561
24629
  return;
@@ -24585,9 +24653,9 @@ async function installBd(platform3 = process.platform) {
24585
24653
  }
24586
24654
 
24587
24655
  // src/beads/install-dolt.ts
24588
- var import_child_process22 = require("child_process");
24656
+ var import_child_process23 = require("child_process");
24589
24657
  var fs58 = __toESM(require("fs"));
24590
- var os46 = __toESM(require("os"));
24658
+ var os47 = __toESM(require("os"));
24591
24659
  var path62 = __toESM(require("path"));
24592
24660
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
24593
24661
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
@@ -24628,11 +24696,11 @@ function resolveDoltInstallStrategy(platform3) {
24628
24696
  }
24629
24697
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
24630
24698
  function doltPlatformTuple(platform3, arch2) {
24631
- const os64 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
24699
+ const os65 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
24632
24700
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
24633
24701
  if (!a) return null;
24634
- if (os64 === "windows" && a !== "amd64") return null;
24635
- return `${os64}-${a}`;
24702
+ if (os65 === "windows" && a !== "amd64") return null;
24703
+ return `${os65}-${a}`;
24636
24704
  }
24637
24705
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
24638
24706
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -24677,7 +24745,7 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
24677
24745
  return result;
24678
24746
  }
24679
24747
  var _doltPathSeam = {
24680
- homedir: () => os46.homedir(),
24748
+ homedir: () => os47.homedir(),
24681
24749
  getPath: () => process.env.PATH ?? "",
24682
24750
  setPath: (p2) => {
24683
24751
  process.env.PATH = p2;
@@ -24747,7 +24815,7 @@ function _defaultDoltInstallSpawn(strategy) {
24747
24815
  };
24748
24816
  let proc;
24749
24817
  try {
24750
- proc = (0, import_child_process22.spawn)(strategy.command, strategy.args, {
24818
+ proc = (0, import_child_process23.spawn)(strategy.command, strategy.args, {
24751
24819
  env: process.env,
24752
24820
  stdio: ["ignore", "pipe", "pipe"]
24753
24821
  });
@@ -24888,7 +24956,7 @@ var _provisionSeam = {
24888
24956
  };
24889
24957
  var _linkSeam = {
24890
24958
  platform: () => process.platform,
24891
- homedir: () => os47.homedir(),
24959
+ homedir: () => os48.homedir(),
24892
24960
  isWritableDir: (dir) => {
24893
24961
  try {
24894
24962
  fs59.accessSync(dir, fs59.constants.W_OK);
@@ -24974,7 +25042,7 @@ function linkBdOntoPath(binaryPath) {
24974
25042
  log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
24975
25043
  }
24976
25044
  function setGitBeadsRole() {
24977
- (0, import_child_process23.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
25045
+ (0, import_child_process24.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
24978
25046
  stdio: "ignore"
24979
25047
  });
24980
25048
  }
@@ -25683,7 +25751,7 @@ function cleanupAttachmentTempFiles() {
25683
25751
  function saveFilesTemp(files) {
25684
25752
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
25685
25753
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
25686
- const tmpPath = path67.join(os51.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
25754
+ const tmpPath = path67.join(os52.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
25687
25755
  fs62.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
25688
25756
  pendingAttachmentFiles.add(tmpPath);
25689
25757
  return tmpPath;
@@ -25823,7 +25891,7 @@ var sessionTerminated = async (ctx, cmd) => {
25823
25891
  }
25824
25892
  quiet(() => ctx.agent.kill());
25825
25893
  try {
25826
- const proc = (0, import_child_process24.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
25894
+ const proc = (0, import_child_process25.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
25827
25895
  detached: true,
25828
25896
  stdio: "ignore"
25829
25897
  });
@@ -25842,7 +25910,7 @@ var shutdownSession = async (ctx, cmd) => {
25842
25910
  quiet(() => ctx.agent.kill());
25843
25911
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
25844
25912
  try {
25845
- const stopProc = (0, import_child_process24.spawn)(
25913
+ const stopProc = (0, import_child_process25.spawn)(
25846
25914
  "bash",
25847
25915
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
25848
25916
  { detached: true, stdio: "ignore" }
@@ -25852,7 +25920,7 @@ var shutdownSession = async (ctx, cmd) => {
25852
25920
  }
25853
25921
  }
25854
25922
  try {
25855
- const proc = (0, import_child_process24.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
25923
+ const proc = (0, import_child_process25.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
25856
25924
  detached: true,
25857
25925
  stdio: "ignore"
25858
25926
  });
@@ -26278,7 +26346,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
26278
26346
  });
26279
26347
  const token = ctx.pluginAuthToken;
26280
26348
  void (async () => {
26281
- const os64 = createOsStrategy();
26349
+ const os65 = createOsStrategy();
26282
26350
  try {
26283
26351
  const report = await reviewPullRequest(
26284
26352
  {
@@ -26287,7 +26355,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
26287
26355
  baseBranch: parsed.baseBranch
26288
26356
  },
26289
26357
  {
26290
- runReview: (input) => new CoderabbitRuntimeStrategy(os64).runOneShot(input),
26358
+ runReview: (input) => new CoderabbitRuntimeStrategy(os65).runOneShot(input),
26291
26359
  runGh: (args2) => defaultRunGh(args2),
26292
26360
  postReport: async (r) => {
26293
26361
  if (!token) return;
@@ -26457,7 +26525,7 @@ var defaultCliUpdateDeps = {
26457
26525
  // Only a truly local `codeam start` (neither marker) re-execs in place below.
26458
26526
  isSupervised: () => process.env["CODEAM_AUTO_APPROVE"] === "1" || process.env["CODESPACES"] === "true",
26459
26527
  relaunch: (args2) => {
26460
- const child = (0, import_child_process24.spawnSync)("codeam", args2, { stdio: "inherit", env: process.env });
26528
+ const child = (0, import_child_process25.spawnSync)("codeam", args2, { stdio: "inherit", env: process.env });
26461
26529
  process.exit(child.status ?? 0);
26462
26530
  }
26463
26531
  };
@@ -26538,7 +26606,7 @@ async function runNpmInstallLatest() {
26538
26606
  const useShell = process.platform === "win32";
26539
26607
  const command2 = useShell && invocation.command.includes(" ") ? `"${invocation.command}"` : invocation.command;
26540
26608
  const result = await new Promise((resolve9) => {
26541
- (0, import_child_process24.execFile)(
26609
+ (0, import_child_process25.execFile)(
26542
26610
  command2,
26543
26611
  invocation.args,
26544
26612
  { timeout: CLI_UPDATE_INSTALL_TIMEOUT_MS, shell: useShell },
@@ -27152,13 +27220,13 @@ async function dispatchCommand(ctx, cmd) {
27152
27220
  }
27153
27221
 
27154
27222
  // src/commands/start/keep-alive.ts
27155
- var import_child_process25 = require("child_process");
27223
+ var import_child_process26 = require("child_process");
27156
27224
  function buildKeepAlive(ctx) {
27157
27225
  let timer = null;
27158
27226
  async function setIdleTimeout(minutes) {
27159
27227
  if (!ctx.inCodespace || !ctx.codespaceName) return;
27160
27228
  await new Promise((resolve9) => {
27161
- const proc = (0, import_child_process25.spawn)(
27229
+ const proc = (0, import_child_process26.spawn)(
27162
27230
  "gh",
27163
27231
  [
27164
27232
  "api",
@@ -27423,7 +27491,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
27423
27491
  pluginId,
27424
27492
  ideName: "codeam-cli (codespace)",
27425
27493
  ideVersion: process.env.npm_package_version ?? "unknown",
27426
- hostname: os52.hostname(),
27494
+ hostname: os53.hostname(),
27427
27495
  codespaceName: process.env.CODESPACE_NAME ?? "",
27428
27496
  // Current git branch of the codespace's working directory, so the
27429
27497
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -27484,7 +27552,7 @@ async function claim(token, pluginId, pluginSecretHash) {
27484
27552
  }
27485
27553
  }
27486
27554
  function pairAutoLockPath() {
27487
- return path68.join(os52.homedir(), ".codeam", "pair-auto.lock");
27555
+ return path68.join(os53.homedir(), ".codeam", "pair-auto.lock");
27488
27556
  }
27489
27557
  function isLivePairAuto(pid) {
27490
27558
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -27504,7 +27572,7 @@ function isLiveCodeam(pid) {
27504
27572
  }
27505
27573
  function daemonLockPath(sessionId) {
27506
27574
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
27507
- return path68.join(os52.homedir(), ".codeam", `daemon-${safe}.lock`);
27575
+ return path68.join(os53.homedir(), ".codeam", `daemon-${safe}.lock`);
27508
27576
  }
27509
27577
  function acquireDaemonLock(sessionId) {
27510
27578
  const lockPath = daemonLockPath(sessionId);
@@ -28013,7 +28081,7 @@ var path70 = __toESM(require("path"));
28013
28081
  var import_fs6 = __toESM(require("fs"));
28014
28082
  var import_os11 = __toESM(require("os"));
28015
28083
  var import_path8 = __toESM(require("path"));
28016
- var import_child_process26 = require("child_process");
28084
+ var import_child_process27 = require("child_process");
28017
28085
  function currentPlatformKey() {
28018
28086
  return `${process.platform}-${process.arch}`;
28019
28087
  }
@@ -28076,7 +28144,7 @@ function isCommandOnPath(cmd, probe = defaultWhich) {
28076
28144
  function defaultWhich(cmd) {
28077
28145
  const finder = process.platform === "win32" ? "where" : "which";
28078
28146
  try {
28079
- const res = (0, import_child_process26.spawnSync)(finder, [cmd], { stdio: "ignore" });
28147
+ const res = (0, import_child_process27.spawnSync)(finder, [cmd], { stdio: "ignore" });
28080
28148
  return res.status === 0;
28081
28149
  } catch {
28082
28150
  return false;
@@ -28129,7 +28197,7 @@ var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_
28129
28197
  var PERMANENT_ADAPTER_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
28130
28198
  function probeAdapterModuleGraph(command2, args2, opts = {}) {
28131
28199
  const livenessMs = opts.livenessMs ?? 400;
28132
- const spawnFn = opts.spawnFn ?? import_child_process26.spawn;
28200
+ const spawnFn = opts.spawnFn ?? import_child_process27.spawn;
28133
28201
  return new Promise((resolve9) => {
28134
28202
  let settled = false;
28135
28203
  let stderr = "";
@@ -28193,11 +28261,12 @@ function kimiRuns() {
28193
28261
  const r = (0, import_node_child_process27.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
28194
28262
  return !r.error && r.status === 0;
28195
28263
  }
28196
- function augmentPath2() {
28264
+ function augmentKimiPath() {
28197
28265
  const dir = kimiBinDir();
28198
28266
  const parts = (process.env.PATH ?? "").split(":");
28199
28267
  if (!parts.includes(dir)) process.env.PATH = `${dir}:${process.env.PATH ?? ""}`;
28200
28268
  }
28269
+ var augmentPath2 = augmentKimiPath;
28201
28270
  async function runInstaller2() {
28202
28271
  return new Promise((resolve9) => {
28203
28272
  const proc = (0, import_node_child_process27.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
@@ -28245,11 +28314,12 @@ function opencodeRuns() {
28245
28314
  const r = (0, import_node_child_process28.spawnSync)("opencode", ["--version"], { stdio: "ignore", timeout: 15e3 });
28246
28315
  return !r.error && r.status === 0;
28247
28316
  }
28248
- function augmentPath3() {
28317
+ function augmentOpencodePath() {
28249
28318
  const dir = opencodeBinDir();
28250
28319
  const parts = (process.env.PATH ?? "").split(":");
28251
28320
  if (!parts.includes(dir)) process.env.PATH = `${dir}:${process.env.PATH ?? ""}`;
28252
28321
  }
28322
+ var augmentPath3 = augmentOpencodePath;
28253
28323
  async function runInstaller3() {
28254
28324
  return new Promise((resolve9) => {
28255
28325
  const proc = (0, import_node_child_process28.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL3} | bash`], { stdio: "inherit" });
@@ -28391,6 +28461,7 @@ var REGISTRY = {
28391
28461
  // provisions it, so there we just wait for the binary to appear.
28392
28462
  waitForBinary: async (o) => {
28393
28463
  if (isLocalSession()) await ensureKimiInstalled();
28464
+ augmentKimiPath();
28394
28465
  return waitForCommandOnPath("kimi", o);
28395
28466
  }
28396
28467
  }),
@@ -28406,6 +28477,7 @@ var REGISTRY = {
28406
28477
  requiresAgentBinary: "opencode",
28407
28478
  waitForBinary: async (o) => {
28408
28479
  if (isLocalSession()) await ensureOpencodeInstalled();
28480
+ augmentOpencodePath();
28409
28481
  return waitForCommandOnPath("opencode", o);
28410
28482
  }
28411
28483
  })
@@ -28455,7 +28527,7 @@ var import_node_crypto11 = require("crypto");
28455
28527
  // src/services/history.service.ts
28456
28528
  var fs65 = __toESM(require("fs"));
28457
28529
  var path71 = __toESM(require("path"));
28458
- var os54 = __toESM(require("os"));
28530
+ var os55 = __toESM(require("os"));
28459
28531
  var https7 = __toESM(require("https"));
28460
28532
  var http6 = __toESM(require("http"));
28461
28533
  var import_zod2 = require("zod");
@@ -28623,7 +28695,7 @@ var HistoryService = class _HistoryService {
28623
28695
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
28624
28696
  }
28625
28697
  get projectDir() {
28626
- return this.runtime.resolveHistoryDir(this.cwd) ?? path71.join(os54.homedir(), ".claude", "projects", encodeCwd(this.cwd));
28698
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path71.join(os55.homedir(), ".claude", "projects", encodeCwd(this.cwd));
28627
28699
  }
28628
28700
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
28629
28701
  setCurrentConversationId(id) {
@@ -29051,7 +29123,7 @@ var HistoryService = class _HistoryService {
29051
29123
  var import_node_child_process29 = require("child_process");
29052
29124
  var fs66 = __toESM(require("fs/promises"));
29053
29125
  var fsSync = __toESM(require("fs"));
29054
- var os56 = __toESM(require("os"));
29126
+ var os57 = __toESM(require("os"));
29055
29127
  var path73 = __toESM(require("path"));
29056
29128
  var import_node_stream = require("stream");
29057
29129
 
@@ -33079,7 +33151,7 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
33079
33151
 
33080
33152
  // src/agents/acp/internal-paths.ts
33081
33153
  var path72 = __toESM(require("path"));
33082
- var os55 = __toESM(require("os"));
33154
+ var os56 = __toESM(require("os"));
33083
33155
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
33084
33156
  var SELF_HOSTED_WORKSPACE_RE = /\.codeam[/\\]self-hosted/gi;
33085
33157
  function textReferencesInternal(text) {
@@ -33087,7 +33159,7 @@ function textReferencesInternal(text) {
33087
33159
  const scrubbed = text.replace(SELF_HOSTED_WORKSPACE_RE, " ");
33088
33160
  return INTERNAL_TOKENS.some((t2) => scrubbed.includes(t2));
33089
33161
  }
33090
- function pathIsInternal(p2, homeDir2 = os55.homedir()) {
33162
+ function pathIsInternal(p2, homeDir2 = os56.homedir()) {
33091
33163
  if (!p2) return false;
33092
33164
  const abs = path72.resolve(p2);
33093
33165
  const home = path72.resolve(homeDir2);
@@ -34135,7 +34207,7 @@ function applyLineRange(content, line, limit) {
34135
34207
  return { content: lines.slice(start2, end).join("\n") };
34136
34208
  }
34137
34209
  function knownAgentBinaryDirs() {
34138
- const home = os56.homedir();
34210
+ const home = os57.homedir();
34139
34211
  const out2 = [];
34140
34212
  out2.push("/tmp/codeam-node20/bin");
34141
34213
  for (const root of [
@@ -34190,12 +34262,12 @@ function buildRelaunchProxyEnv(baseEnv) {
34190
34262
  return env;
34191
34263
  }
34192
34264
  var relaunchProxyWithoutBudget = async () => {
34193
- const { spawn: spawn45 } = await import("child_process");
34265
+ const { spawn: spawn46 } = await import("child_process");
34194
34266
  killHeadroomProxy();
34195
34267
  await new Promise((r) => setTimeout(r, 500));
34196
34268
  const proxyEnv = buildRelaunchProxyEnv(process.env);
34197
34269
  try {
34198
- const proxy = spawn45(
34270
+ const proxy = spawn46(
34199
34271
  "headroom",
34200
34272
  ["proxy", "--port", "8787"],
34201
34273
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -34214,6 +34286,148 @@ var relaunchProxyWithoutBudget = async () => {
34214
34286
  await new Promise((r) => setTimeout(r, 3e3));
34215
34287
  };
34216
34288
 
34289
+ // src/agents/acp/switch-agent.ts
34290
+ var NON_SWITCHABLE = /* @__PURE__ */ new Set([
34291
+ // Review-only reviewer — added to a session, never the primary agent.
34292
+ "coderabbit"
34293
+ ]);
34294
+ function displayName(id) {
34295
+ return isKnownAgentId(id) ? AGENT_REGISTRY[id]?.displayName ?? id : id;
34296
+ }
34297
+ function resolveSwitchTarget(raw, currentAgent) {
34298
+ if (typeof raw !== "string" || raw.length === 0) {
34299
+ return { ok: false, error: "switch_agent: missing agentId" };
34300
+ }
34301
+ if (!isKnownAgentId(raw)) {
34302
+ return { ok: false, error: `Unknown agent "${raw}".` };
34303
+ }
34304
+ if (NON_SWITCHABLE.has(raw)) {
34305
+ return { ok: false, error: `${displayName(raw)} is a reviewer \u2014 it can't drive a session.` };
34306
+ }
34307
+ if (!requiresAcp(raw)) {
34308
+ return {
34309
+ ok: false,
34310
+ error: `${displayName(raw)} can't be switched to in a live session yet.`
34311
+ };
34312
+ }
34313
+ if (raw === currentAgent) {
34314
+ return { ok: false, error: `${displayName(raw)} is already this session's agent.` };
34315
+ }
34316
+ return { ok: true, agentId: raw };
34317
+ }
34318
+ function toAgentAuth(method, credential) {
34319
+ return { kind: method === "api_key" ? "api_key" : "oauth_token", value: credential };
34320
+ }
34321
+ async function ensureAgentBinaryForSwitch(agentId, installScript, deps = {}) {
34322
+ const resolveAdapter = deps.resolveAdapter ?? getAcpAdapter;
34323
+ const runInstall = deps.runInstall ?? runAgentInstallScript;
34324
+ const spec = resolveAdapter(agentId);
34325
+ if (!spec) {
34326
+ return { ok: false, error: `${displayName(agentId)} ACP adapter is unavailable on this CLI.` };
34327
+ }
34328
+ if (await spec.waitForBinary({ timeoutMs: 2e3 })) return { ok: true };
34329
+ if (!installScript) {
34330
+ return {
34331
+ ok: false,
34332
+ error: `${displayName(agentId)} CLI is not installed on this machine.`
34333
+ };
34334
+ }
34335
+ log.info("switchAgent", `installing ${agentId} binary (missing on PATH)`);
34336
+ const res = await runInstall(installScript, { logScope: "switchAgent" });
34337
+ if (!res.ok) {
34338
+ return {
34339
+ ok: false,
34340
+ error: res.timedOut ? `${displayName(agentId)} install timed out.` : `${displayName(agentId)} install failed.`
34341
+ };
34342
+ }
34343
+ if (await spec.waitForBinary({ timeoutMs: 3e4 })) return { ok: true };
34344
+ return {
34345
+ ok: false,
34346
+ error: `${displayName(agentId)} installed but its binary never appeared on PATH.`
34347
+ };
34348
+ }
34349
+ function buildHandoffPreamble(fromAgent, toAgent, transcript) {
34350
+ const trimmed = transcript.trim();
34351
+ if (trimmed.length === 0) return null;
34352
+ const takeover = fromAgent === toAgent ? `[Session handoff] You (${displayName(toAgent)}) are resuming a live coding session after a restart. ` : `[Session handoff] You (${displayName(toAgent)}) are taking over a live coding session previously driven by ${displayName(fromAgent)}. `;
34353
+ return [
34354
+ takeover,
34355
+ `The conversation below is context from that session \u2014 continue the work seamlessly from where it left off. `,
34356
+ `Do not re-introduce yourself or re-do completed work.
34357
+
34358
+ `,
34359
+ `--- Recent conversation with ${displayName(fromAgent)} ---
34360
+ `,
34361
+ `${trimmed}
34362
+ `,
34363
+ `--- End of handoff context ---`
34364
+ ].join("");
34365
+ }
34366
+ function makeSerializedSwitchEmitter(post2) {
34367
+ let chain = Promise.resolve();
34368
+ return (type, payload) => {
34369
+ chain = chain.then(() => post2(type, payload)).catch(() => void 0);
34370
+ return chain;
34371
+ };
34372
+ }
34373
+ async function performAgentSwitch(deps, rawAgentId) {
34374
+ const from = deps.currentAgent();
34375
+ const target = resolveSwitchTarget(rawAgentId, from);
34376
+ if (!target.ok) {
34377
+ return { ok: false, agentId: typeof rawAgentId === "string" ? rawAgentId : "", error: target.error };
34378
+ }
34379
+ const agentId = target.agentId;
34380
+ const emitStatus = (status2) => deps.postEvent("switch_agent_status", { ...status2 });
34381
+ const emitStep = (step) => deps.postEvent("switch_agent_progress", { step, agentId });
34382
+ const fail2 = (error) => {
34383
+ log.warn("switchAgent", `switch ${from} \u2192 ${agentId} failed: ${error}`);
34384
+ void emitStatus({ state: "error", agentId, fromAgentId: from, error });
34385
+ return { ok: false, agentId, error };
34386
+ };
34387
+ log.info("switchAgent", `switch requested ${from} \u2192 ${agentId}`);
34388
+ void emitStatus({ state: "switching", agentId, fromAgentId: from });
34389
+ void emitStep("credential");
34390
+ const cred = await deps.fetchCredential(agentId);
34391
+ if (!cred) {
34392
+ return fail2(
34393
+ `No linked credential for ${displayName(agentId)}. Link it in Profile \u203A Agents first.`
34394
+ );
34395
+ }
34396
+ try {
34397
+ deps.provisionCredential(agentId, toAgentAuth(cred.method, cred.credential));
34398
+ } catch (err) {
34399
+ log.warn("switchAgent", `credential provisioning failed: ${err.message}`);
34400
+ return fail2(`Couldn't write the ${displayName(agentId)} credential on this machine.`);
34401
+ }
34402
+ void emitStep("install");
34403
+ const bin = await deps.ensureBinary(agentId, cred.installScript);
34404
+ if (!bin.ok) return fail2(bin.error);
34405
+ void emitStep("restart");
34406
+ try {
34407
+ await deps.swapRuntime(agentId);
34408
+ } catch (err) {
34409
+ log.warn("switchAgent", `swap failed, reverting to ${from}: ${err.message}`);
34410
+ try {
34411
+ await deps.revertRuntime(from);
34412
+ } catch (revertErr) {
34413
+ log.warn("switchAgent", `revert failed: ${revertErr.message}`);
34414
+ return fail2(
34415
+ `Switching to ${displayName(agentId)} failed and ${displayName(from)} couldn't be restored \u2014 restart the session.`
34416
+ );
34417
+ }
34418
+ return fail2(`Couldn't start ${displayName(agentId)} \u2014 the session stays on ${displayName(from)}.`);
34419
+ }
34420
+ try {
34421
+ deps.persistAgent(agentId);
34422
+ } catch (err) {
34423
+ log.warn("switchAgent", `persist failed (non-fatal): ${err.message}`);
34424
+ }
34425
+ deps.reannounce(agentId);
34426
+ await emitStatus({ state: "ready", agentId, fromAgentId: from });
34427
+ log.info("switchAgent", `switch complete ${from} \u2192 ${agentId}`);
34428
+ return { ok: true, agentId };
34429
+ }
34430
+
34217
34431
  // src/services/streaming/transport.ts
34218
34432
  var http7 = __toESM(require("http"));
34219
34433
  var https8 = __toESM(require("https"));
@@ -34660,12 +34874,12 @@ function commonPrefixLength(a, b) {
34660
34874
  }
34661
34875
 
34662
34876
  // src/agents/acp/onboarding.ts
34663
- var import_child_process27 = require("child_process");
34877
+ var import_child_process28 = require("child_process");
34664
34878
  var fs67 = __toESM(require("fs"));
34665
- var os57 = __toESM(require("os"));
34879
+ var os58 = __toESM(require("os"));
34666
34880
  var path74 = __toESM(require("path"));
34667
34881
  var _onboardingSeam = {
34668
- markerPath: (sessionId) => path74.join(os57.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34882
+ markerPath: (sessionId) => path74.join(os58.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34669
34883
  exists: (p2) => fs67.existsSync(p2),
34670
34884
  write: (p2) => {
34671
34885
  fs67.mkdirSync(path74.dirname(p2), { recursive: true });
@@ -34681,7 +34895,7 @@ var _onboardingSeam = {
34681
34895
  */
34682
34896
  gitRemoteUrl: (cwd) => {
34683
34897
  try {
34684
- return (0, import_child_process27.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
34898
+ return (0, import_child_process28.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
34685
34899
  encoding: "utf8",
34686
34900
  stdio: ["ignore", "pipe", "ignore"],
34687
34901
  timeout: 2e3
@@ -34963,7 +35177,7 @@ function extractSelectPrompt(text) {
34963
35177
  var import_crypto5 = require("crypto");
34964
35178
 
34965
35179
  // src/services/turn-files/git-changeset.ts
34966
- var import_child_process28 = require("child_process");
35180
+ var import_child_process29 = require("child_process");
34967
35181
  var fs69 = __toESM(require("fs/promises"));
34968
35182
  var path76 = __toESM(require("path"));
34969
35183
 
@@ -35149,7 +35363,7 @@ function defaultRunGit(cwd, args2) {
35149
35363
  return new Promise((resolve9) => {
35150
35364
  let proc;
35151
35365
  try {
35152
- proc = (0, import_child_process28.spawn)("git", args2, { cwd, env: process.env });
35366
+ proc = (0, import_child_process29.spawn)("git", args2, { cwd, env: process.env });
35153
35367
  } catch {
35154
35368
  resolve9(null);
35155
35369
  return;
@@ -36539,8 +36753,8 @@ function buildAcpPromptBlocks(payload) {
36539
36753
  // src/agents/agent-standard.ts
36540
36754
  var fs74 = __toESM(require("fs"));
36541
36755
  var path81 = __toESM(require("path"));
36542
- var os58 = __toESM(require("os"));
36543
- function ensureAgentStandard(homeDir2 = os58.homedir()) {
36756
+ var os59 = __toESM(require("os"));
36757
+ function ensureAgentStandard(homeDir2 = os59.homedir()) {
36544
36758
  try {
36545
36759
  const file = path81.join(homeDir2, ".claude", "CLAUDE.md");
36546
36760
  let existing = "";
@@ -36561,7 +36775,7 @@ ${AGENT_STANDARD_BLOCK}
36561
36775
  }
36562
36776
  var _agentStandardSeam = {
36563
36777
  isLocalSession: () => isLocalSession(),
36564
- markerPath: (sessionId) => path81.join(os58.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36778
+ markerPath: (sessionId) => path81.join(os59.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36565
36779
  exists: (p2) => fs74.existsSync(p2),
36566
36780
  write: (p2) => {
36567
36781
  fs74.mkdirSync(path81.dirname(p2), { recursive: true });
@@ -36703,6 +36917,10 @@ async function startTaskH(ctx) {
36703
36917
  await streaming.beginTurn();
36704
36918
  history.appendUserPrompt(promptText);
36705
36919
  maybePrefaceAgentStandard(blocks, opts.agent, opts.sessionId);
36920
+ if (ctx.pendingHandoff?.current) {
36921
+ blocks.unshift({ type: "text", text: ctx.pendingHandoff.current });
36922
+ ctx.pendingHandoff.current = null;
36923
+ }
36706
36924
  let turnClosed = false;
36707
36925
  try {
36708
36926
  const reply = await client3.prompt(blocks);
@@ -37246,6 +37464,27 @@ async function integrationsDetectH(ctx) {
37246
37464
  });
37247
37465
  }
37248
37466
  }
37467
+ async function switchAgentH(ctx) {
37468
+ const { cmd, relay } = ctx;
37469
+ if (!ctx.switchAgent) {
37470
+ await relay.sendResult(cmd.id, "failed", {
37471
+ error: "Switching agents is not supported on this session."
37472
+ });
37473
+ return;
37474
+ }
37475
+ const rawAgentId = cmd.payload?.agentId;
37476
+ try {
37477
+ const result = await ctx.switchAgent(rawAgentId);
37478
+ await relay.sendResult(
37479
+ cmd.id,
37480
+ result.ok ? "completed" : "failed",
37481
+ result
37482
+ );
37483
+ } catch (err) {
37484
+ log.warn("acpRunner", `switch_agent failed: ${describeError(err)}`);
37485
+ await relay.sendResult(cmd.id, "failed", { error: describeError(err) });
37486
+ }
37487
+ }
37249
37488
  var ACP_COMMAND_HANDLERS = {
37250
37489
  integrations_sync: integrationsSyncH,
37251
37490
  integrations_detect: integrationsDetectH,
@@ -37263,6 +37502,7 @@ var ACP_COMMAND_HANDLERS = {
37263
37502
  select_option: selectOptionH,
37264
37503
  provide_input: provideInputH,
37265
37504
  resume_session: resumeSessionH,
37505
+ switch_agent: switchAgentH,
37266
37506
  change_model: changeModelH,
37267
37507
  summarize: summarizeH,
37268
37508
  session_terminated: sessionShutdownH,
@@ -37712,6 +37952,27 @@ var AcpHistory = class {
37712
37952
  this.messages.length = 0;
37713
37953
  this.summary = null;
37714
37954
  }
37955
+ /**
37956
+ * Render the TAIL of the buffered conversation as plain text, bounded to
37957
+ * `maxChars` — the in-session agent switch captures this right before the
37958
+ * old client stops and prefixes it to the first post-switch prompt, so the
37959
+ * NEW agent inherits the session's context (a cross-agent `session/load`
37960
+ * is impossible; this handoff is the continuity mechanism). Walks newest →
37961
+ * oldest so the most recent turns always survive the cap, then restores
37962
+ * chronological order.
37963
+ */
37964
+ recentTranscript(maxChars) {
37965
+ const lines = [];
37966
+ let used = 0;
37967
+ for (let i = this.messages.length - 1; i >= 0; i--) {
37968
+ const m = this.messages[i];
37969
+ const line = `${m.role === "user" ? "User" : "Agent"}: ${m.text.trim()}`;
37970
+ if (used + line.length > maxChars) break;
37971
+ lines.push(line);
37972
+ used += line.length + 2;
37973
+ }
37974
+ return lines.reverse().join("\n\n");
37975
+ }
37715
37976
  appendUserPrompt(text) {
37716
37977
  if (this.summary === null) {
37717
37978
  const trimmed = text.trim().replace(/\s+/g, " ");
@@ -37953,9 +38214,9 @@ async function runAcpSession(opts) {
37953
38214
  })();
37954
38215
  }
37955
38216
  };
37956
- const client3 = new AcpClient(clientOptions);
38217
+ let client3 = new AcpClient(clientOptions);
37957
38218
  let _budgetReachedPosted = false;
37958
- const budgetRecovery = createBudgetRecovery({
38219
+ const makeBudgetRecovery = () => createBudgetRecovery({
37959
38220
  publishText: (text) => publisher.publishOutput({ type: "text", content: text, done: true }),
37960
38221
  publishSelectPrompt: (question, options) => publisher.publishOutput({
37961
38222
  type: "select_prompt",
@@ -37974,6 +38235,7 @@ async function runAcpSession(opts) {
37974
38235
  agentId: opts.agent,
37975
38236
  log: (msg) => log.info("acpRunner", msg)
37976
38237
  });
38238
+ let budgetRecovery = makeBudgetRecovery();
37977
38239
  showInfo(`Starting ${opts.agent} via ACP adapter (${opts.adapter.requiresAgentBinary})\u2026`);
37978
38240
  let handshake;
37979
38241
  try {
@@ -37992,6 +38254,7 @@ async function runAcpSession(opts) {
37992
38254
  }
37993
38255
  let acpSessionId = handshake.sessionId;
37994
38256
  const { initialize, model: handshakeModel, tier: handshakeTier } = handshake;
38257
+ let agentCaps = initialize.agentCapabilities;
37995
38258
  log.trace(
37996
38259
  "acpRunner",
37997
38260
  `adapter handshake ok protocolVersion=${initialize.protocolVersion} sessionId=${acpSessionId.slice(0, 8)}`
@@ -38027,8 +38290,8 @@ async function runAcpSession(opts) {
38027
38290
  path: opts.cwd,
38028
38291
  done: true
38029
38292
  });
38030
- const runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
38031
- const history = new AcpHistory(publisher, {
38293
+ let runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
38294
+ let history = new AcpHistory(publisher, {
38032
38295
  agent: opts.agent,
38033
38296
  acpSessionId,
38034
38297
  // Agent-agnostic RECENT list: enumerate via the ACP session/list RPC (any
@@ -38036,7 +38299,7 @@ async function runAcpSession(opts) {
38036
38299
  // agents → flush() falls back to the current session only.
38037
38300
  listSessions: () => client3.listSessions()
38038
38301
  });
38039
- const jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
38302
+ let jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
38040
38303
  pluginAuthToken: opts.pluginAuthToken
38041
38304
  });
38042
38305
  void (async () => {
@@ -38107,7 +38370,7 @@ async function runAcpSession(opts) {
38107
38370
  opts,
38108
38371
  history,
38109
38372
  jsonlHistory,
38110
- initialize.agentCapabilities,
38373
+ agentCaps,
38111
38374
  turnFiles,
38112
38375
  getBeads,
38113
38376
  publisher,
@@ -38123,11 +38386,98 @@ async function runAcpSession(opts) {
38123
38386
  // conversation" fix).
38124
38387
  (id) => {
38125
38388
  acpSessionId = id;
38126
- }
38389
+ },
38390
+ switchAgentForSession,
38391
+ pendingHandoff
38127
38392
  );
38128
38393
  },
38129
38394
  { id: opts.agent, name: opts.agent, displayName: opts.agent }
38130
38395
  );
38396
+ const HANDOFF_MAX_CHARS = 16e3;
38397
+ const pendingHandoff = { current: null };
38398
+ let switchCredentialEnv = {};
38399
+ const relaunchWith = async (nextAgent) => {
38400
+ try {
38401
+ await client3.cancel();
38402
+ } catch {
38403
+ }
38404
+ await streaming.closeAll();
38405
+ const prevAgent = opts.agent;
38406
+ const transcript = history.recentTranscript(HANDOFF_MAX_CHARS);
38407
+ await client3.stop();
38408
+ const adapter = await resolveAcpAdapterWithRetry(nextAgent);
38409
+ if (!adapter) throw new Error(`no ACP adapter available for ${nextAgent}`);
38410
+ const disable1m = loadCliConfig().sessions.find((s) => s.pluginId === opts.pluginId)?.disable1mContext === true;
38411
+ clientOptions.adapter = adapter;
38412
+ clientOptions.extraEnv = {
38413
+ ...computeAdapterExtraEnv({
38414
+ agent: nextAgent,
38415
+ autoApprovePermissions: opts.autoApprovePermissions,
38416
+ disable1mContext: disable1m
38417
+ }),
38418
+ ...switchCredentialEnv
38419
+ };
38420
+ const next = new AcpClient(clientOptions);
38421
+ const hs = await next.start();
38422
+ client3 = next;
38423
+ opts.agent = nextAgent;
38424
+ opts.adapter = adapter;
38425
+ acpSessionId = hs.sessionId;
38426
+ agentCaps = hs.initialize.agentCapabilities;
38427
+ runtime = createInteractiveAgentStrategy(nextAgent, createOsStrategy());
38428
+ history = new AcpHistory(publisher, {
38429
+ agent: nextAgent,
38430
+ acpSessionId,
38431
+ listSessions: () => client3.listSessions()
38432
+ });
38433
+ jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
38434
+ pluginAuthToken: opts.pluginAuthToken
38435
+ });
38436
+ budgetRecovery = makeBudgetRecovery();
38437
+ pendingHandoff.current = buildHandoffPreamble(prevAgent, nextAgent, transcript);
38438
+ void publisher.publishOutput({
38439
+ type: "agent_banner",
38440
+ agentId: nextAgent,
38441
+ title: "Welcome back!",
38442
+ subtitle: buildBannerSubtitle(nextAgent, hs.sessionId, hs.model, hs.tier),
38443
+ path: opts.cwd,
38444
+ done: true
38445
+ });
38446
+ };
38447
+ const emitSwitchEvent = makeSerializedSwitchEmitter(
38448
+ (type, payload) => postAgentSwitchEvent({
38449
+ sessionId: opts.sessionId,
38450
+ pluginId: opts.pluginId,
38451
+ pluginAuthToken: opts.pluginAuthToken,
38452
+ type,
38453
+ payload
38454
+ })
38455
+ );
38456
+ const switchAgentForSession = (rawAgentId) => performAgentSwitch(
38457
+ {
38458
+ currentAgent: () => opts.agent,
38459
+ postEvent: emitSwitchEvent,
38460
+ fetchCredential: (agentId) => fetchProvisionCredential({
38461
+ agentId,
38462
+ sessionId: opts.sessionId,
38463
+ pluginId: opts.pluginId,
38464
+ pluginAuthToken: opts.pluginAuthToken,
38465
+ includeInstallScript: true
38466
+ }),
38467
+ provisionCredential: (agentId, auth) => {
38468
+ switchCredentialEnv = provisionAgentCredentials(agentId, auth);
38469
+ },
38470
+ ensureBinary: (agentId, installScript) => ensureAgentBinaryForSwitch(agentId, installScript),
38471
+ swapRuntime: relaunchWith,
38472
+ revertRuntime: relaunchWith,
38473
+ persistAgent: (agentId) => setSessionAgent(opts.pluginId, agentId),
38474
+ reannounce: (agentId) => {
38475
+ relay.setAgentMeta({ id: agentId, name: agentId, displayName: agentId });
38476
+ relay.reannounceAgents();
38477
+ }
38478
+ },
38479
+ rawAgentId
38480
+ );
38131
38481
  await onboardingWelcomeDone;
38132
38482
  relay.start();
38133
38483
  void createWakeCredentialProbe({
@@ -38158,7 +38508,7 @@ async function runAcpSession(opts) {
38158
38508
  await new Promise(() => {
38159
38509
  });
38160
38510
  }
38161
- async function handleCommand(cmd, client3, relay, acpSessionId, streaming, opts, history, jsonlHistory, agentCaps, turnFiles, getBeads, publisher, recentStderr, budgetRecovery, budgetReachedFlag, onActiveSessionChanged) {
38511
+ async function handleCommand(cmd, client3, relay, acpSessionId, streaming, opts, history, jsonlHistory, agentCaps, turnFiles, getBeads, publisher, recentStderr, budgetRecovery, budgetReachedFlag, onActiveSessionChanged, switchAgent, pendingHandoff) {
38162
38512
  const session = {
38163
38513
  client: client3,
38164
38514
  relay,
@@ -38174,16 +38524,18 @@ async function handleCommand(cmd, client3, relay, acpSessionId, streaming, opts,
38174
38524
  recentStderr,
38175
38525
  budgetRecovery,
38176
38526
  budgetReachedFlag,
38177
- onActiveSessionChanged
38527
+ onActiveSessionChanged,
38528
+ switchAgent,
38529
+ pendingHandoff
38178
38530
  };
38179
38531
  await dispatchAcpCommand(assembleAcpCommandContext(session, cmd));
38180
38532
  }
38181
38533
  function buildBannerSubtitle(agentId, acpSessionId, model, tier) {
38182
38534
  const meta = AGENT_REGISTRY[agentId];
38183
- const displayName = meta?.displayName ?? agentId;
38184
- if (model && tier) return `${displayName} \xB7 ${model} \xB7 ${tier}`;
38185
- if (model) return `${displayName} \xB7 ${model}`;
38186
- return `${displayName} \xB7 ACP \xB7 ${acpSessionId.slice(0, 8)}`;
38535
+ const displayName2 = meta?.displayName ?? agentId;
38536
+ if (model && tier) return `${displayName2} \xB7 ${model} \xB7 ${tier}`;
38537
+ if (model) return `${displayName2} \xB7 ${model}`;
38538
+ return `${displayName2} \xB7 ACP \xB7 ${acpSessionId.slice(0, 8)}`;
38187
38539
  }
38188
38540
 
38189
38541
  // src/services/output/chrome-tracker.ts
@@ -39236,7 +39588,7 @@ function startClaudeCredentialSync(opts) {
39236
39588
  // src/beads/workflow-hint.ts
39237
39589
  var fs75 = __toESM(require("fs"));
39238
39590
  var path82 = __toESM(require("path"));
39239
- var os59 = __toESM(require("os"));
39591
+ var os60 = __toESM(require("os"));
39240
39592
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
39241
39593
  var BEADS_HINT = `${BEADS_HINT_MARKER}
39242
39594
  # Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
@@ -39250,7 +39602,7 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
39250
39602
  - \`bd ready\` (available work) \xB7 \`bd show <id>\` \xB7 \`bd update <id> --claim\` \xB7 \`bd close <id>\`.
39251
39603
  - Use \`bd remember "..."\` for persistent knowledge \u2014 do NOT use MEMORY.md files.
39252
39604
  ${BEADS_HINT_MARKER}`;
39253
- function ensureBeadsWorkflowHint(homeDir2 = os59.homedir()) {
39605
+ function ensureBeadsWorkflowHint(homeDir2 = os60.homedir()) {
39254
39606
  try {
39255
39607
  const file = path82.join(homeDir2, ".claude", "CLAUDE.md");
39256
39608
  let existing = "";
@@ -40003,12 +40355,12 @@ function keepDeviceAwake(deps = {}) {
40003
40355
 
40004
40356
  // src/agents/claude/onboarding.ts
40005
40357
  var fs77 = __toESM(require("fs"));
40006
- var os61 = __toESM(require("os"));
40358
+ var os62 = __toESM(require("os"));
40007
40359
  var path83 = __toESM(require("path"));
40008
40360
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
40009
40361
  function ensureClaudeOnboarded(cwd) {
40010
40362
  try {
40011
- const file = path83.join(os61.homedir(), ".claude.json");
40363
+ const file = path83.join(os62.homedir(), ".claude.json");
40012
40364
  let config = {};
40013
40365
  try {
40014
40366
  config = JSON.parse(fs77.readFileSync(file, "utf8"));
@@ -40054,10 +40406,10 @@ async function start(requestedAgent, presetSession) {
40054
40406
  const session = presetSession ? presetSession : requestedAgent ? getActiveSessionForAgent(requestedAgent) : getActiveSession();
40055
40407
  if (!session) {
40056
40408
  if (requestedAgent) {
40057
- const displayName = AGENT_REGISTRY[requestedAgent]?.displayName ?? requestedAgent;
40058
- console.log(` ${import_picocolors4.default.dim(`No paired ${displayName} session found.`)}`);
40409
+ const displayName2 = AGENT_REGISTRY[requestedAgent]?.displayName ?? requestedAgent;
40410
+ console.log(` ${import_picocolors4.default.dim(`No paired ${displayName2} session found.`)}`);
40059
40411
  console.log(
40060
- ` ${import_picocolors4.default.dim(`Run ${import_picocolors4.default.white("codeam pair")} from a ${displayName} setup to connect your mobile app.`)}
40412
+ ` ${import_picocolors4.default.dim(`Run ${import_picocolors4.default.white("codeam pair")} from a ${displayName2} setup to connect your mobile app.`)}
40061
40413
  `
40062
40414
  );
40063
40415
  } else {
@@ -40766,11 +41118,11 @@ async function logout() {
40766
41118
  var import_picocolors11 = __toESM(require("picocolors"));
40767
41119
 
40768
41120
  // src/services/providers/github-codespaces.ts
40769
- var import_child_process29 = require("child_process");
41121
+ var import_child_process30 = require("child_process");
40770
41122
  var import_util4 = require("util");
40771
41123
  var import_picocolors9 = __toESM(require("picocolors"));
40772
41124
  var path84 = __toESM(require("path"));
40773
- var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
41125
+ var execFileP6 = (0, import_util4.promisify)(import_child_process30.execFile);
40774
41126
  var MAX_BUFFER = 8 * 1024 * 1024;
40775
41127
  function resetStdinForChild() {
40776
41128
  if (process.stdin.isTTY) {
@@ -40814,7 +41166,7 @@ var GitHubCodespacesProvider = class {
40814
41166
  if (!isAuthed) {
40815
41167
  resetStdinForChild();
40816
41168
  await new Promise((resolve9, reject) => {
40817
- const proc = (0, import_child_process29.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
41169
+ const proc = (0, import_child_process30.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
40818
41170
  stdio: "inherit"
40819
41171
  });
40820
41172
  proc.on("exit", (code) => {
@@ -40848,7 +41200,7 @@ var GitHubCodespacesProvider = class {
40848
41200
  wt(noteLines.join("\n"), "One more permission needed");
40849
41201
  resetStdinForChild();
40850
41202
  const refreshCode = await new Promise((resolve9, reject) => {
40851
- const proc = (0, import_child_process29.spawn)(
41203
+ const proc = (0, import_child_process30.spawn)(
40852
41204
  "gh",
40853
41205
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
40854
41206
  { stdio: "inherit" }
@@ -40998,7 +41350,7 @@ var GitHubCodespacesProvider = class {
40998
41350
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
40999
41351
  resetStdinForChild();
41000
41352
  const ok = await new Promise((resolve9) => {
41001
- const proc = (0, import_child_process29.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
41353
+ const proc = (0, import_child_process30.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
41002
41354
  proc.on("exit", (code) => resolve9(code === 0));
41003
41355
  proc.on("error", () => resolve9(false));
41004
41356
  });
@@ -41025,7 +41377,7 @@ var GitHubCodespacesProvider = class {
41025
41377
  );
41026
41378
  resetStdinForChild();
41027
41379
  await new Promise((resolve9, reject) => {
41028
- const proc = (0, import_child_process29.spawn)(
41380
+ const proc = (0, import_child_process30.spawn)(
41029
41381
  "gh",
41030
41382
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
41031
41383
  { stdio: "inherit" }
@@ -41203,7 +41555,7 @@ var GitHubCodespacesProvider = class {
41203
41555
  async streamCommand(workspaceId, command2) {
41204
41556
  resetStdinForChild();
41205
41557
  return new Promise((resolve9, reject) => {
41206
- const proc = (0, import_child_process29.spawn)(
41558
+ const proc = (0, import_child_process30.spawn)(
41207
41559
  "gh",
41208
41560
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
41209
41561
  { stdio: "inherit" }
@@ -41230,11 +41582,11 @@ var GitHubCodespacesProvider = class {
41230
41582
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
41231
41583
  ];
41232
41584
  await new Promise((resolve9, reject) => {
41233
- const tar = (0, import_child_process29.spawn)("tar", tarArgs, {
41585
+ const tar = (0, import_child_process30.spawn)("tar", tarArgs, {
41234
41586
  stdio: ["ignore", "pipe", "pipe"],
41235
41587
  env: tarEnv
41236
41588
  });
41237
- const ssh = (0, import_child_process29.spawn)("gh", sshArgs, {
41589
+ const ssh = (0, import_child_process30.spawn)("gh", sshArgs, {
41238
41590
  stdio: [tar.stdout, "pipe", "pipe"]
41239
41591
  });
41240
41592
  let tarErr = "";
@@ -41268,7 +41620,7 @@ var GitHubCodespacesProvider = class {
41268
41620
  }
41269
41621
  const cmd = parts.join(" && ");
41270
41622
  await new Promise((resolve9, reject) => {
41271
- const proc = (0, import_child_process29.spawn)(
41623
+ const proc = (0, import_child_process30.spawn)(
41272
41624
  "gh",
41273
41625
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
41274
41626
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -41326,11 +41678,11 @@ function shellQuote(s) {
41326
41678
  }
41327
41679
 
41328
41680
  // src/services/providers/gitpod.ts
41329
- var import_child_process30 = require("child_process");
41681
+ var import_child_process31 = require("child_process");
41330
41682
  var import_util5 = require("util");
41331
41683
  var path85 = __toESM(require("path"));
41332
41684
  var import_picocolors10 = __toESM(require("picocolors"));
41333
- var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
41685
+ var execFileP7 = (0, import_util5.promisify)(import_child_process31.execFile);
41334
41686
  var MAX_BUFFER2 = 8 * 1024 * 1024;
41335
41687
  function resetStdinForChild2() {
41336
41688
  if (process.stdin.isTTY) {
@@ -41370,7 +41722,7 @@ var GitpodProvider = class {
41370
41722
  );
41371
41723
  resetStdinForChild2();
41372
41724
  await new Promise((resolve9, reject) => {
41373
- const proc = (0, import_child_process30.spawn)("gitpod", ["login"], { stdio: "inherit" });
41725
+ const proc = (0, import_child_process31.spawn)("gitpod", ["login"], { stdio: "inherit" });
41374
41726
  proc.on("exit", (code) => {
41375
41727
  if (code === 0) resolve9();
41376
41728
  else reject(new Error("gitpod login failed."));
@@ -41522,7 +41874,7 @@ var GitpodProvider = class {
41522
41874
  async streamCommand(workspaceId, command2) {
41523
41875
  resetStdinForChild2();
41524
41876
  return new Promise((resolve9, reject) => {
41525
- const proc = (0, import_child_process30.spawn)(
41877
+ const proc = (0, import_child_process31.spawn)(
41526
41878
  "gitpod",
41527
41879
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
41528
41880
  { stdio: "inherit" }
@@ -41542,11 +41894,11 @@ var GitpodProvider = class {
41542
41894
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
41543
41895
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
41544
41896
  await new Promise((resolve9, reject) => {
41545
- const tar = (0, import_child_process30.spawn)("tar", tarArgs, {
41897
+ const tar = (0, import_child_process31.spawn)("tar", tarArgs, {
41546
41898
  stdio: ["ignore", "pipe", "pipe"],
41547
41899
  env: tarEnv
41548
41900
  });
41549
- const ssh = (0, import_child_process30.spawn)(
41901
+ const ssh = (0, import_child_process31.spawn)(
41550
41902
  "gitpod",
41551
41903
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
41552
41904
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -41578,7 +41930,7 @@ var GitpodProvider = class {
41578
41930
  }
41579
41931
  const cmd = parts.join(" && ");
41580
41932
  await new Promise((resolve9, reject) => {
41581
- const proc = (0, import_child_process30.spawn)(
41933
+ const proc = (0, import_child_process31.spawn)(
41582
41934
  "gitpod",
41583
41935
  ["workspace", "ssh", workspaceId, "--", cmd],
41584
41936
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -41602,10 +41954,10 @@ function shellQuote2(s) {
41602
41954
  }
41603
41955
 
41604
41956
  // src/services/providers/gitlab-workspaces.ts
41605
- var import_child_process31 = require("child_process");
41957
+ var import_child_process32 = require("child_process");
41606
41958
  var import_util6 = require("util");
41607
41959
  var path86 = __toESM(require("path"));
41608
- var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
41960
+ var execFileP8 = (0, import_util6.promisify)(import_child_process32.execFile);
41609
41961
  var MAX_BUFFER3 = 8 * 1024 * 1024;
41610
41962
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
41611
41963
  function resetStdinForChild3() {
@@ -41647,7 +41999,7 @@ var GitLabWorkspacesProvider = class {
41647
41999
  );
41648
42000
  resetStdinForChild3();
41649
42001
  await new Promise((resolve9, reject) => {
41650
- const proc = (0, import_child_process31.spawn)(
42002
+ const proc = (0, import_child_process32.spawn)(
41651
42003
  "glab",
41652
42004
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
41653
42005
  { stdio: "inherit" }
@@ -41819,7 +42171,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41819
42171
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
41820
42172
  resetStdinForChild3();
41821
42173
  return new Promise((resolve9, reject) => {
41822
- const proc = (0, import_child_process31.spawn)(
42174
+ const proc = (0, import_child_process32.spawn)(
41823
42175
  "ssh",
41824
42176
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
41825
42177
  { stdio: "inherit" }
@@ -41840,8 +42192,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41840
42192
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
41841
42193
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
41842
42194
  await new Promise((resolve9, reject) => {
41843
- const tar = (0, import_child_process31.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
41844
- const ssh = (0, import_child_process31.spawn)(
42195
+ const tar = (0, import_child_process32.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
42196
+ const ssh = (0, import_child_process32.spawn)(
41845
42197
  "ssh",
41846
42198
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
41847
42199
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -41871,7 +42223,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41871
42223
  }
41872
42224
  const cmd = parts.join(" && ");
41873
42225
  await new Promise((resolve9, reject) => {
41874
- const proc = (0, import_child_process31.spawn)(
42226
+ const proc = (0, import_child_process32.spawn)(
41875
42227
  "ssh",
41876
42228
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
41877
42229
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -41930,10 +42282,10 @@ function shellQuote3(s) {
41930
42282
  }
41931
42283
 
41932
42284
  // src/services/providers/railway.ts
41933
- var import_child_process32 = require("child_process");
42285
+ var import_child_process33 = require("child_process");
41934
42286
  var import_util7 = require("util");
41935
42287
  var path87 = __toESM(require("path"));
41936
- var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
42288
+ var execFileP9 = (0, import_util7.promisify)(import_child_process33.execFile);
41937
42289
  var MAX_BUFFER4 = 8 * 1024 * 1024;
41938
42290
  function resetStdinForChild4() {
41939
42291
  if (process.stdin.isTTY) {
@@ -41974,7 +42326,7 @@ var RailwayProvider = class {
41974
42326
  );
41975
42327
  resetStdinForChild4();
41976
42328
  await new Promise((resolve9, reject) => {
41977
- const proc = (0, import_child_process32.spawn)("railway", ["login"], { stdio: "inherit" });
42329
+ const proc = (0, import_child_process33.spawn)("railway", ["login"], { stdio: "inherit" });
41978
42330
  proc.on("exit", (code) => {
41979
42331
  if (code === 0) resolve9();
41980
42332
  else reject(new Error("railway login failed."));
@@ -42117,7 +42469,7 @@ var RailwayProvider = class {
42117
42469
  }
42118
42470
  resetStdinForChild4();
42119
42471
  return new Promise((resolve9, reject) => {
42120
- const proc = (0, import_child_process32.spawn)(
42472
+ const proc = (0, import_child_process33.spawn)(
42121
42473
  "railway",
42122
42474
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
42123
42475
  { stdio: "inherit" }
@@ -42141,8 +42493,8 @@ var RailwayProvider = class {
42141
42493
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
42142
42494
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
42143
42495
  await new Promise((resolve9, reject) => {
42144
- const tar = (0, import_child_process32.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
42145
- const sh = (0, import_child_process32.spawn)(
42496
+ const tar = (0, import_child_process33.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
42497
+ const sh = (0, import_child_process33.spawn)(
42146
42498
  "railway",
42147
42499
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
42148
42500
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -42175,7 +42527,7 @@ var RailwayProvider = class {
42175
42527
  }
42176
42528
  const cmd = parts.join(" && ");
42177
42529
  await new Promise((resolve9, reject) => {
42178
- const proc = (0, import_child_process32.spawn)(
42530
+ const proc = (0, import_child_process33.spawn)(
42179
42531
  "railway",
42180
42532
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
42181
42533
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -42917,9 +43269,9 @@ function checkSessions() {
42917
43269
  }
42918
43270
  }
42919
43271
  function checkAgentBinaries() {
42920
- const os64 = createOsStrategy();
43272
+ const os65 = createOsStrategy();
42921
43273
  return getEnabledAgents().map((meta) => {
42922
- const found = os64.findInPath(meta.binaryName);
43274
+ const found = os65.findInPath(meta.binaryName);
42923
43275
  return {
42924
43276
  id: `agent-${meta.id}`,
42925
43277
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -42983,7 +43335,7 @@ function checkChokidar() {
42983
43335
  }
42984
43336
  async function doctor(args2 = []) {
42985
43337
  const json = args2.includes("--json");
42986
- const cliVersion = true ? "2.62.2" : "0.0.0-dev";
43338
+ const cliVersion = true ? "2.63.1" : "0.0.0-dev";
42987
43339
  const apiBase2 = resolveApiBaseUrl();
42988
43340
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
42989
43341
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -43374,7 +43726,7 @@ async function mcpRun(args2) {
43374
43726
  // src/commands/version.ts
43375
43727
  var import_picocolors15 = __toESM(require("picocolors"));
43376
43728
  function version2() {
43377
- const v = true ? "2.62.2" : "unknown";
43729
+ const v = true ? "2.63.1" : "unknown";
43378
43730
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
43379
43731
  }
43380
43732
 
@@ -43523,10 +43875,10 @@ var EXIT_CODE_NAMES = {
43523
43875
  };
43524
43876
 
43525
43877
  // src/index.ts
43526
- var os63 = __toESM(require("os"));
43878
+ var os64 = __toESM(require("os"));
43527
43879
  if (!process.env.HOME) {
43528
43880
  try {
43529
- const home = os63.homedir();
43881
+ const home = os64.homedir();
43530
43882
  if (home) process.env.HOME = home;
43531
43883
  } catch {
43532
43884
  }