codeam-cli 2.62.2 → 2.63.0

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 +7 -0
  2. package/dist/index.js +656 -309
  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.0" : "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.0",
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.0" ? { ideVersion: "2.63.0" } : {}
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.0" : 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.0" : 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.0" : 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 = "";
@@ -28455,7 +28523,7 @@ var import_node_crypto11 = require("crypto");
28455
28523
  // src/services/history.service.ts
28456
28524
  var fs65 = __toESM(require("fs"));
28457
28525
  var path71 = __toESM(require("path"));
28458
- var os54 = __toESM(require("os"));
28526
+ var os55 = __toESM(require("os"));
28459
28527
  var https7 = __toESM(require("https"));
28460
28528
  var http6 = __toESM(require("http"));
28461
28529
  var import_zod2 = require("zod");
@@ -28623,7 +28691,7 @@ var HistoryService = class _HistoryService {
28623
28691
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
28624
28692
  }
28625
28693
  get projectDir() {
28626
- return this.runtime.resolveHistoryDir(this.cwd) ?? path71.join(os54.homedir(), ".claude", "projects", encodeCwd(this.cwd));
28694
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path71.join(os55.homedir(), ".claude", "projects", encodeCwd(this.cwd));
28627
28695
  }
28628
28696
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
28629
28697
  setCurrentConversationId(id) {
@@ -29051,7 +29119,7 @@ var HistoryService = class _HistoryService {
29051
29119
  var import_node_child_process29 = require("child_process");
29052
29120
  var fs66 = __toESM(require("fs/promises"));
29053
29121
  var fsSync = __toESM(require("fs"));
29054
- var os56 = __toESM(require("os"));
29122
+ var os57 = __toESM(require("os"));
29055
29123
  var path73 = __toESM(require("path"));
29056
29124
  var import_node_stream = require("stream");
29057
29125
 
@@ -33079,7 +33147,7 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
33079
33147
 
33080
33148
  // src/agents/acp/internal-paths.ts
33081
33149
  var path72 = __toESM(require("path"));
33082
- var os55 = __toESM(require("os"));
33150
+ var os56 = __toESM(require("os"));
33083
33151
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
33084
33152
  var SELF_HOSTED_WORKSPACE_RE = /\.codeam[/\\]self-hosted/gi;
33085
33153
  function textReferencesInternal(text) {
@@ -33087,7 +33155,7 @@ function textReferencesInternal(text) {
33087
33155
  const scrubbed = text.replace(SELF_HOSTED_WORKSPACE_RE, " ");
33088
33156
  return INTERNAL_TOKENS.some((t2) => scrubbed.includes(t2));
33089
33157
  }
33090
- function pathIsInternal(p2, homeDir2 = os55.homedir()) {
33158
+ function pathIsInternal(p2, homeDir2 = os56.homedir()) {
33091
33159
  if (!p2) return false;
33092
33160
  const abs = path72.resolve(p2);
33093
33161
  const home = path72.resolve(homeDir2);
@@ -34135,7 +34203,7 @@ function applyLineRange(content, line, limit) {
34135
34203
  return { content: lines.slice(start2, end).join("\n") };
34136
34204
  }
34137
34205
  function knownAgentBinaryDirs() {
34138
- const home = os56.homedir();
34206
+ const home = os57.homedir();
34139
34207
  const out2 = [];
34140
34208
  out2.push("/tmp/codeam-node20/bin");
34141
34209
  for (const root of [
@@ -34190,12 +34258,12 @@ function buildRelaunchProxyEnv(baseEnv) {
34190
34258
  return env;
34191
34259
  }
34192
34260
  var relaunchProxyWithoutBudget = async () => {
34193
- const { spawn: spawn45 } = await import("child_process");
34261
+ const { spawn: spawn46 } = await import("child_process");
34194
34262
  killHeadroomProxy();
34195
34263
  await new Promise((r) => setTimeout(r, 500));
34196
34264
  const proxyEnv = buildRelaunchProxyEnv(process.env);
34197
34265
  try {
34198
- const proxy = spawn45(
34266
+ const proxy = spawn46(
34199
34267
  "headroom",
34200
34268
  ["proxy", "--port", "8787"],
34201
34269
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -34214,6 +34282,147 @@ var relaunchProxyWithoutBudget = async () => {
34214
34282
  await new Promise((r) => setTimeout(r, 3e3));
34215
34283
  };
34216
34284
 
34285
+ // src/agents/acp/switch-agent.ts
34286
+ var NON_SWITCHABLE = /* @__PURE__ */ new Set([
34287
+ // Review-only reviewer — added to a session, never the primary agent.
34288
+ "coderabbit"
34289
+ ]);
34290
+ function displayName(id) {
34291
+ return isKnownAgentId(id) ? AGENT_REGISTRY[id]?.displayName ?? id : id;
34292
+ }
34293
+ function resolveSwitchTarget(raw, currentAgent) {
34294
+ if (typeof raw !== "string" || raw.length === 0) {
34295
+ return { ok: false, error: "switch_agent: missing agentId" };
34296
+ }
34297
+ if (!isKnownAgentId(raw)) {
34298
+ return { ok: false, error: `Unknown agent "${raw}".` };
34299
+ }
34300
+ if (NON_SWITCHABLE.has(raw)) {
34301
+ return { ok: false, error: `${displayName(raw)} is a reviewer \u2014 it can't drive a session.` };
34302
+ }
34303
+ if (!requiresAcp(raw)) {
34304
+ return {
34305
+ ok: false,
34306
+ error: `${displayName(raw)} can't be switched to in a live session yet.`
34307
+ };
34308
+ }
34309
+ if (raw === currentAgent) {
34310
+ return { ok: false, error: `${displayName(raw)} is already this session's agent.` };
34311
+ }
34312
+ return { ok: true, agentId: raw };
34313
+ }
34314
+ function toAgentAuth(method, credential) {
34315
+ return { kind: method === "api_key" ? "api_key" : "oauth_token", value: credential };
34316
+ }
34317
+ async function ensureAgentBinaryForSwitch(agentId, installScript, deps = {}) {
34318
+ const resolveAdapter = deps.resolveAdapter ?? getAcpAdapter;
34319
+ const runInstall = deps.runInstall ?? runAgentInstallScript;
34320
+ const spec = resolveAdapter(agentId);
34321
+ if (!spec) {
34322
+ return { ok: false, error: `${displayName(agentId)} ACP adapter is unavailable on this CLI.` };
34323
+ }
34324
+ if (await spec.waitForBinary({ timeoutMs: 2e3 })) return { ok: true };
34325
+ if (!installScript) {
34326
+ return {
34327
+ ok: false,
34328
+ error: `${displayName(agentId)} CLI is not installed on this machine.`
34329
+ };
34330
+ }
34331
+ log.info("switchAgent", `installing ${agentId} binary (missing on PATH)`);
34332
+ const res = await runInstall(installScript, { logScope: "switchAgent" });
34333
+ if (!res.ok) {
34334
+ return {
34335
+ ok: false,
34336
+ error: res.timedOut ? `${displayName(agentId)} install timed out.` : `${displayName(agentId)} install failed.`
34337
+ };
34338
+ }
34339
+ if (await spec.waitForBinary({ timeoutMs: 3e4 })) return { ok: true };
34340
+ return {
34341
+ ok: false,
34342
+ error: `${displayName(agentId)} installed but its binary never appeared on PATH.`
34343
+ };
34344
+ }
34345
+ function buildHandoffPreamble(fromAgent, toAgent, transcript) {
34346
+ const trimmed = transcript.trim();
34347
+ if (trimmed.length === 0) return null;
34348
+ 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)}. `;
34349
+ return [
34350
+ takeover,
34351
+ `The conversation below is context from that session \u2014 continue the work seamlessly from where it left off. `,
34352
+ `Do not re-introduce yourself or re-do completed work.
34353
+
34354
+ `,
34355
+ `--- Recent conversation with ${displayName(fromAgent)} ---
34356
+ `,
34357
+ `${trimmed}
34358
+ `,
34359
+ `--- End of handoff context ---`
34360
+ ].join("");
34361
+ }
34362
+ function makeSerializedSwitchEmitter(post2) {
34363
+ let chain = Promise.resolve();
34364
+ return (type, payload) => {
34365
+ chain = chain.then(() => post2(type, payload)).catch(() => void 0);
34366
+ return chain;
34367
+ };
34368
+ }
34369
+ async function performAgentSwitch(deps, rawAgentId) {
34370
+ const from = deps.currentAgent();
34371
+ const target = resolveSwitchTarget(rawAgentId, from);
34372
+ if (!target.ok) {
34373
+ return { ok: false, agentId: typeof rawAgentId === "string" ? rawAgentId : "", error: target.error };
34374
+ }
34375
+ const agentId = target.agentId;
34376
+ const emitStatus = (status2) => deps.postEvent("switch_agent_status", { ...status2 });
34377
+ const emitStep = (step) => deps.postEvent("switch_agent_progress", { step, agentId });
34378
+ const fail2 = (error) => {
34379
+ void emitStatus({ state: "error", agentId, fromAgentId: from, error });
34380
+ return { ok: false, agentId, error };
34381
+ };
34382
+ log.info("switchAgent", `switch requested ${from} \u2192 ${agentId}`);
34383
+ void emitStatus({ state: "switching", agentId, fromAgentId: from });
34384
+ void emitStep("credential");
34385
+ const cred = await deps.fetchCredential(agentId);
34386
+ if (!cred) {
34387
+ return fail2(
34388
+ `No linked credential for ${displayName(agentId)}. Link it in Profile \u203A Agents first.`
34389
+ );
34390
+ }
34391
+ try {
34392
+ deps.provisionCredential(agentId, toAgentAuth(cred.method, cred.credential));
34393
+ } catch (err) {
34394
+ log.warn("switchAgent", `credential provisioning failed: ${err.message}`);
34395
+ return fail2(`Couldn't write the ${displayName(agentId)} credential on this machine.`);
34396
+ }
34397
+ void emitStep("install");
34398
+ const bin = await deps.ensureBinary(agentId, cred.installScript);
34399
+ if (!bin.ok) return fail2(bin.error);
34400
+ void emitStep("restart");
34401
+ try {
34402
+ await deps.swapRuntime(agentId);
34403
+ } catch (err) {
34404
+ log.warn("switchAgent", `swap failed, reverting to ${from}: ${err.message}`);
34405
+ try {
34406
+ await deps.revertRuntime(from);
34407
+ } catch (revertErr) {
34408
+ log.warn("switchAgent", `revert failed: ${revertErr.message}`);
34409
+ return fail2(
34410
+ `Switching to ${displayName(agentId)} failed and ${displayName(from)} couldn't be restored \u2014 restart the session.`
34411
+ );
34412
+ }
34413
+ return fail2(`Couldn't start ${displayName(agentId)} \u2014 the session stays on ${displayName(from)}.`);
34414
+ }
34415
+ try {
34416
+ deps.persistAgent(agentId);
34417
+ } catch (err) {
34418
+ log.warn("switchAgent", `persist failed (non-fatal): ${err.message}`);
34419
+ }
34420
+ deps.reannounce(agentId);
34421
+ await emitStatus({ state: "ready", agentId, fromAgentId: from });
34422
+ log.info("switchAgent", `switch complete ${from} \u2192 ${agentId}`);
34423
+ return { ok: true, agentId };
34424
+ }
34425
+
34217
34426
  // src/services/streaming/transport.ts
34218
34427
  var http7 = __toESM(require("http"));
34219
34428
  var https8 = __toESM(require("https"));
@@ -34660,12 +34869,12 @@ function commonPrefixLength(a, b) {
34660
34869
  }
34661
34870
 
34662
34871
  // src/agents/acp/onboarding.ts
34663
- var import_child_process27 = require("child_process");
34872
+ var import_child_process28 = require("child_process");
34664
34873
  var fs67 = __toESM(require("fs"));
34665
- var os57 = __toESM(require("os"));
34874
+ var os58 = __toESM(require("os"));
34666
34875
  var path74 = __toESM(require("path"));
34667
34876
  var _onboardingSeam = {
34668
- markerPath: (sessionId) => path74.join(os57.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34877
+ markerPath: (sessionId) => path74.join(os58.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34669
34878
  exists: (p2) => fs67.existsSync(p2),
34670
34879
  write: (p2) => {
34671
34880
  fs67.mkdirSync(path74.dirname(p2), { recursive: true });
@@ -34681,7 +34890,7 @@ var _onboardingSeam = {
34681
34890
  */
34682
34891
  gitRemoteUrl: (cwd) => {
34683
34892
  try {
34684
- return (0, import_child_process27.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
34893
+ return (0, import_child_process28.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
34685
34894
  encoding: "utf8",
34686
34895
  stdio: ["ignore", "pipe", "ignore"],
34687
34896
  timeout: 2e3
@@ -34963,7 +35172,7 @@ function extractSelectPrompt(text) {
34963
35172
  var import_crypto5 = require("crypto");
34964
35173
 
34965
35174
  // src/services/turn-files/git-changeset.ts
34966
- var import_child_process28 = require("child_process");
35175
+ var import_child_process29 = require("child_process");
34967
35176
  var fs69 = __toESM(require("fs/promises"));
34968
35177
  var path76 = __toESM(require("path"));
34969
35178
 
@@ -35149,7 +35358,7 @@ function defaultRunGit(cwd, args2) {
35149
35358
  return new Promise((resolve9) => {
35150
35359
  let proc;
35151
35360
  try {
35152
- proc = (0, import_child_process28.spawn)("git", args2, { cwd, env: process.env });
35361
+ proc = (0, import_child_process29.spawn)("git", args2, { cwd, env: process.env });
35153
35362
  } catch {
35154
35363
  resolve9(null);
35155
35364
  return;
@@ -36539,8 +36748,8 @@ function buildAcpPromptBlocks(payload) {
36539
36748
  // src/agents/agent-standard.ts
36540
36749
  var fs74 = __toESM(require("fs"));
36541
36750
  var path81 = __toESM(require("path"));
36542
- var os58 = __toESM(require("os"));
36543
- function ensureAgentStandard(homeDir2 = os58.homedir()) {
36751
+ var os59 = __toESM(require("os"));
36752
+ function ensureAgentStandard(homeDir2 = os59.homedir()) {
36544
36753
  try {
36545
36754
  const file = path81.join(homeDir2, ".claude", "CLAUDE.md");
36546
36755
  let existing = "";
@@ -36561,7 +36770,7 @@ ${AGENT_STANDARD_BLOCK}
36561
36770
  }
36562
36771
  var _agentStandardSeam = {
36563
36772
  isLocalSession: () => isLocalSession(),
36564
- markerPath: (sessionId) => path81.join(os58.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36773
+ markerPath: (sessionId) => path81.join(os59.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36565
36774
  exists: (p2) => fs74.existsSync(p2),
36566
36775
  write: (p2) => {
36567
36776
  fs74.mkdirSync(path81.dirname(p2), { recursive: true });
@@ -36703,6 +36912,10 @@ async function startTaskH(ctx) {
36703
36912
  await streaming.beginTurn();
36704
36913
  history.appendUserPrompt(promptText);
36705
36914
  maybePrefaceAgentStandard(blocks, opts.agent, opts.sessionId);
36915
+ if (ctx.pendingHandoff?.current) {
36916
+ blocks.unshift({ type: "text", text: ctx.pendingHandoff.current });
36917
+ ctx.pendingHandoff.current = null;
36918
+ }
36706
36919
  let turnClosed = false;
36707
36920
  try {
36708
36921
  const reply = await client3.prompt(blocks);
@@ -37246,6 +37459,27 @@ async function integrationsDetectH(ctx) {
37246
37459
  });
37247
37460
  }
37248
37461
  }
37462
+ async function switchAgentH(ctx) {
37463
+ const { cmd, relay } = ctx;
37464
+ if (!ctx.switchAgent) {
37465
+ await relay.sendResult(cmd.id, "failed", {
37466
+ error: "Switching agents is not supported on this session."
37467
+ });
37468
+ return;
37469
+ }
37470
+ const rawAgentId = cmd.payload?.agentId;
37471
+ try {
37472
+ const result = await ctx.switchAgent(rawAgentId);
37473
+ await relay.sendResult(
37474
+ cmd.id,
37475
+ result.ok ? "completed" : "failed",
37476
+ result
37477
+ );
37478
+ } catch (err) {
37479
+ log.warn("acpRunner", `switch_agent failed: ${describeError(err)}`);
37480
+ await relay.sendResult(cmd.id, "failed", { error: describeError(err) });
37481
+ }
37482
+ }
37249
37483
  var ACP_COMMAND_HANDLERS = {
37250
37484
  integrations_sync: integrationsSyncH,
37251
37485
  integrations_detect: integrationsDetectH,
@@ -37263,6 +37497,7 @@ var ACP_COMMAND_HANDLERS = {
37263
37497
  select_option: selectOptionH,
37264
37498
  provide_input: provideInputH,
37265
37499
  resume_session: resumeSessionH,
37500
+ switch_agent: switchAgentH,
37266
37501
  change_model: changeModelH,
37267
37502
  summarize: summarizeH,
37268
37503
  session_terminated: sessionShutdownH,
@@ -37712,6 +37947,27 @@ var AcpHistory = class {
37712
37947
  this.messages.length = 0;
37713
37948
  this.summary = null;
37714
37949
  }
37950
+ /**
37951
+ * Render the TAIL of the buffered conversation as plain text, bounded to
37952
+ * `maxChars` — the in-session agent switch captures this right before the
37953
+ * old client stops and prefixes it to the first post-switch prompt, so the
37954
+ * NEW agent inherits the session's context (a cross-agent `session/load`
37955
+ * is impossible; this handoff is the continuity mechanism). Walks newest →
37956
+ * oldest so the most recent turns always survive the cap, then restores
37957
+ * chronological order.
37958
+ */
37959
+ recentTranscript(maxChars) {
37960
+ const lines = [];
37961
+ let used = 0;
37962
+ for (let i = this.messages.length - 1; i >= 0; i--) {
37963
+ const m = this.messages[i];
37964
+ const line = `${m.role === "user" ? "User" : "Agent"}: ${m.text.trim()}`;
37965
+ if (used + line.length > maxChars) break;
37966
+ lines.push(line);
37967
+ used += line.length + 2;
37968
+ }
37969
+ return lines.reverse().join("\n\n");
37970
+ }
37715
37971
  appendUserPrompt(text) {
37716
37972
  if (this.summary === null) {
37717
37973
  const trimmed = text.trim().replace(/\s+/g, " ");
@@ -37953,9 +38209,9 @@ async function runAcpSession(opts) {
37953
38209
  })();
37954
38210
  }
37955
38211
  };
37956
- const client3 = new AcpClient(clientOptions);
38212
+ let client3 = new AcpClient(clientOptions);
37957
38213
  let _budgetReachedPosted = false;
37958
- const budgetRecovery = createBudgetRecovery({
38214
+ const makeBudgetRecovery = () => createBudgetRecovery({
37959
38215
  publishText: (text) => publisher.publishOutput({ type: "text", content: text, done: true }),
37960
38216
  publishSelectPrompt: (question, options) => publisher.publishOutput({
37961
38217
  type: "select_prompt",
@@ -37974,6 +38230,7 @@ async function runAcpSession(opts) {
37974
38230
  agentId: opts.agent,
37975
38231
  log: (msg) => log.info("acpRunner", msg)
37976
38232
  });
38233
+ let budgetRecovery = makeBudgetRecovery();
37977
38234
  showInfo(`Starting ${opts.agent} via ACP adapter (${opts.adapter.requiresAgentBinary})\u2026`);
37978
38235
  let handshake;
37979
38236
  try {
@@ -37992,6 +38249,7 @@ async function runAcpSession(opts) {
37992
38249
  }
37993
38250
  let acpSessionId = handshake.sessionId;
37994
38251
  const { initialize, model: handshakeModel, tier: handshakeTier } = handshake;
38252
+ let agentCaps = initialize.agentCapabilities;
37995
38253
  log.trace(
37996
38254
  "acpRunner",
37997
38255
  `adapter handshake ok protocolVersion=${initialize.protocolVersion} sessionId=${acpSessionId.slice(0, 8)}`
@@ -38027,8 +38285,8 @@ async function runAcpSession(opts) {
38027
38285
  path: opts.cwd,
38028
38286
  done: true
38029
38287
  });
38030
- const runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
38031
- const history = new AcpHistory(publisher, {
38288
+ let runtime = createInteractiveAgentStrategy(opts.agent, createOsStrategy());
38289
+ let history = new AcpHistory(publisher, {
38032
38290
  agent: opts.agent,
38033
38291
  acpSessionId,
38034
38292
  // Agent-agnostic RECENT list: enumerate via the ACP session/list RPC (any
@@ -38036,7 +38294,7 @@ async function runAcpSession(opts) {
38036
38294
  // agents → flush() falls back to the current session only.
38037
38295
  listSessions: () => client3.listSessions()
38038
38296
  });
38039
- const jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
38297
+ let jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
38040
38298
  pluginAuthToken: opts.pluginAuthToken
38041
38299
  });
38042
38300
  void (async () => {
@@ -38107,7 +38365,7 @@ async function runAcpSession(opts) {
38107
38365
  opts,
38108
38366
  history,
38109
38367
  jsonlHistory,
38110
- initialize.agentCapabilities,
38368
+ agentCaps,
38111
38369
  turnFiles,
38112
38370
  getBeads,
38113
38371
  publisher,
@@ -38123,11 +38381,98 @@ async function runAcpSession(opts) {
38123
38381
  // conversation" fix).
38124
38382
  (id) => {
38125
38383
  acpSessionId = id;
38126
- }
38384
+ },
38385
+ switchAgentForSession,
38386
+ pendingHandoff
38127
38387
  );
38128
38388
  },
38129
38389
  { id: opts.agent, name: opts.agent, displayName: opts.agent }
38130
38390
  );
38391
+ const HANDOFF_MAX_CHARS = 16e3;
38392
+ const pendingHandoff = { current: null };
38393
+ let switchCredentialEnv = {};
38394
+ const relaunchWith = async (nextAgent) => {
38395
+ try {
38396
+ await client3.cancel();
38397
+ } catch {
38398
+ }
38399
+ await streaming.closeAll();
38400
+ const prevAgent = opts.agent;
38401
+ const transcript = history.recentTranscript(HANDOFF_MAX_CHARS);
38402
+ await client3.stop();
38403
+ const adapter = await resolveAcpAdapterWithRetry(nextAgent);
38404
+ if (!adapter) throw new Error(`no ACP adapter available for ${nextAgent}`);
38405
+ const disable1m = loadCliConfig().sessions.find((s) => s.pluginId === opts.pluginId)?.disable1mContext === true;
38406
+ clientOptions.adapter = adapter;
38407
+ clientOptions.extraEnv = {
38408
+ ...computeAdapterExtraEnv({
38409
+ agent: nextAgent,
38410
+ autoApprovePermissions: opts.autoApprovePermissions,
38411
+ disable1mContext: disable1m
38412
+ }),
38413
+ ...switchCredentialEnv
38414
+ };
38415
+ const next = new AcpClient(clientOptions);
38416
+ const hs = await next.start();
38417
+ client3 = next;
38418
+ opts.agent = nextAgent;
38419
+ opts.adapter = adapter;
38420
+ acpSessionId = hs.sessionId;
38421
+ agentCaps = hs.initialize.agentCapabilities;
38422
+ runtime = createInteractiveAgentStrategy(nextAgent, createOsStrategy());
38423
+ history = new AcpHistory(publisher, {
38424
+ agent: nextAgent,
38425
+ acpSessionId,
38426
+ listSessions: () => client3.listSessions()
38427
+ });
38428
+ jsonlHistory = new HistoryService(runtime, opts.pluginId, opts.cwd, {
38429
+ pluginAuthToken: opts.pluginAuthToken
38430
+ });
38431
+ budgetRecovery = makeBudgetRecovery();
38432
+ pendingHandoff.current = buildHandoffPreamble(prevAgent, nextAgent, transcript);
38433
+ void publisher.publishOutput({
38434
+ type: "agent_banner",
38435
+ agentId: nextAgent,
38436
+ title: "Welcome back!",
38437
+ subtitle: buildBannerSubtitle(nextAgent, hs.sessionId, hs.model, hs.tier),
38438
+ path: opts.cwd,
38439
+ done: true
38440
+ });
38441
+ };
38442
+ const emitSwitchEvent = makeSerializedSwitchEmitter(
38443
+ (type, payload) => postAgentSwitchEvent({
38444
+ sessionId: opts.sessionId,
38445
+ pluginId: opts.pluginId,
38446
+ pluginAuthToken: opts.pluginAuthToken,
38447
+ type,
38448
+ payload
38449
+ })
38450
+ );
38451
+ const switchAgentForSession = (rawAgentId) => performAgentSwitch(
38452
+ {
38453
+ currentAgent: () => opts.agent,
38454
+ postEvent: emitSwitchEvent,
38455
+ fetchCredential: (agentId) => fetchProvisionCredential({
38456
+ agentId,
38457
+ sessionId: opts.sessionId,
38458
+ pluginId: opts.pluginId,
38459
+ pluginAuthToken: opts.pluginAuthToken,
38460
+ includeInstallScript: true
38461
+ }),
38462
+ provisionCredential: (agentId, auth) => {
38463
+ switchCredentialEnv = provisionAgentCredentials(agentId, auth);
38464
+ },
38465
+ ensureBinary: (agentId, installScript) => ensureAgentBinaryForSwitch(agentId, installScript),
38466
+ swapRuntime: relaunchWith,
38467
+ revertRuntime: relaunchWith,
38468
+ persistAgent: (agentId) => setSessionAgent(opts.pluginId, agentId),
38469
+ reannounce: (agentId) => {
38470
+ relay.setAgentMeta({ id: agentId, name: agentId, displayName: agentId });
38471
+ relay.reannounceAgents();
38472
+ }
38473
+ },
38474
+ rawAgentId
38475
+ );
38131
38476
  await onboardingWelcomeDone;
38132
38477
  relay.start();
38133
38478
  void createWakeCredentialProbe({
@@ -38158,7 +38503,7 @@ async function runAcpSession(opts) {
38158
38503
  await new Promise(() => {
38159
38504
  });
38160
38505
  }
38161
- async function handleCommand(cmd, client3, relay, acpSessionId, streaming, opts, history, jsonlHistory, agentCaps, turnFiles, getBeads, publisher, recentStderr, budgetRecovery, budgetReachedFlag, onActiveSessionChanged) {
38506
+ async function handleCommand(cmd, client3, relay, acpSessionId, streaming, opts, history, jsonlHistory, agentCaps, turnFiles, getBeads, publisher, recentStderr, budgetRecovery, budgetReachedFlag, onActiveSessionChanged, switchAgent, pendingHandoff) {
38162
38507
  const session = {
38163
38508
  client: client3,
38164
38509
  relay,
@@ -38174,16 +38519,18 @@ async function handleCommand(cmd, client3, relay, acpSessionId, streaming, opts,
38174
38519
  recentStderr,
38175
38520
  budgetRecovery,
38176
38521
  budgetReachedFlag,
38177
- onActiveSessionChanged
38522
+ onActiveSessionChanged,
38523
+ switchAgent,
38524
+ pendingHandoff
38178
38525
  };
38179
38526
  await dispatchAcpCommand(assembleAcpCommandContext(session, cmd));
38180
38527
  }
38181
38528
  function buildBannerSubtitle(agentId, acpSessionId, model, tier) {
38182
38529
  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)}`;
38530
+ const displayName2 = meta?.displayName ?? agentId;
38531
+ if (model && tier) return `${displayName2} \xB7 ${model} \xB7 ${tier}`;
38532
+ if (model) return `${displayName2} \xB7 ${model}`;
38533
+ return `${displayName2} \xB7 ACP \xB7 ${acpSessionId.slice(0, 8)}`;
38187
38534
  }
38188
38535
 
38189
38536
  // src/services/output/chrome-tracker.ts
@@ -39236,7 +39583,7 @@ function startClaudeCredentialSync(opts) {
39236
39583
  // src/beads/workflow-hint.ts
39237
39584
  var fs75 = __toESM(require("fs"));
39238
39585
  var path82 = __toESM(require("path"));
39239
- var os59 = __toESM(require("os"));
39586
+ var os60 = __toESM(require("os"));
39240
39587
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
39241
39588
  var BEADS_HINT = `${BEADS_HINT_MARKER}
39242
39589
  # Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
@@ -39250,7 +39597,7 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
39250
39597
  - \`bd ready\` (available work) \xB7 \`bd show <id>\` \xB7 \`bd update <id> --claim\` \xB7 \`bd close <id>\`.
39251
39598
  - Use \`bd remember "..."\` for persistent knowledge \u2014 do NOT use MEMORY.md files.
39252
39599
  ${BEADS_HINT_MARKER}`;
39253
- function ensureBeadsWorkflowHint(homeDir2 = os59.homedir()) {
39600
+ function ensureBeadsWorkflowHint(homeDir2 = os60.homedir()) {
39254
39601
  try {
39255
39602
  const file = path82.join(homeDir2, ".claude", "CLAUDE.md");
39256
39603
  let existing = "";
@@ -40003,12 +40350,12 @@ function keepDeviceAwake(deps = {}) {
40003
40350
 
40004
40351
  // src/agents/claude/onboarding.ts
40005
40352
  var fs77 = __toESM(require("fs"));
40006
- var os61 = __toESM(require("os"));
40353
+ var os62 = __toESM(require("os"));
40007
40354
  var path83 = __toESM(require("path"));
40008
40355
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
40009
40356
  function ensureClaudeOnboarded(cwd) {
40010
40357
  try {
40011
- const file = path83.join(os61.homedir(), ".claude.json");
40358
+ const file = path83.join(os62.homedir(), ".claude.json");
40012
40359
  let config = {};
40013
40360
  try {
40014
40361
  config = JSON.parse(fs77.readFileSync(file, "utf8"));
@@ -40054,10 +40401,10 @@ async function start(requestedAgent, presetSession) {
40054
40401
  const session = presetSession ? presetSession : requestedAgent ? getActiveSessionForAgent(requestedAgent) : getActiveSession();
40055
40402
  if (!session) {
40056
40403
  if (requestedAgent) {
40057
- const displayName = AGENT_REGISTRY[requestedAgent]?.displayName ?? requestedAgent;
40058
- console.log(` ${import_picocolors4.default.dim(`No paired ${displayName} session found.`)}`);
40404
+ const displayName2 = AGENT_REGISTRY[requestedAgent]?.displayName ?? requestedAgent;
40405
+ console.log(` ${import_picocolors4.default.dim(`No paired ${displayName2} session found.`)}`);
40059
40406
  console.log(
40060
- ` ${import_picocolors4.default.dim(`Run ${import_picocolors4.default.white("codeam pair")} from a ${displayName} setup to connect your mobile app.`)}
40407
+ ` ${import_picocolors4.default.dim(`Run ${import_picocolors4.default.white("codeam pair")} from a ${displayName2} setup to connect your mobile app.`)}
40061
40408
  `
40062
40409
  );
40063
40410
  } else {
@@ -40766,11 +41113,11 @@ async function logout() {
40766
41113
  var import_picocolors11 = __toESM(require("picocolors"));
40767
41114
 
40768
41115
  // src/services/providers/github-codespaces.ts
40769
- var import_child_process29 = require("child_process");
41116
+ var import_child_process30 = require("child_process");
40770
41117
  var import_util4 = require("util");
40771
41118
  var import_picocolors9 = __toESM(require("picocolors"));
40772
41119
  var path84 = __toESM(require("path"));
40773
- var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
41120
+ var execFileP6 = (0, import_util4.promisify)(import_child_process30.execFile);
40774
41121
  var MAX_BUFFER = 8 * 1024 * 1024;
40775
41122
  function resetStdinForChild() {
40776
41123
  if (process.stdin.isTTY) {
@@ -40814,7 +41161,7 @@ var GitHubCodespacesProvider = class {
40814
41161
  if (!isAuthed) {
40815
41162
  resetStdinForChild();
40816
41163
  await new Promise((resolve9, reject) => {
40817
- const proc = (0, import_child_process29.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
41164
+ const proc = (0, import_child_process30.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
40818
41165
  stdio: "inherit"
40819
41166
  });
40820
41167
  proc.on("exit", (code) => {
@@ -40848,7 +41195,7 @@ var GitHubCodespacesProvider = class {
40848
41195
  wt(noteLines.join("\n"), "One more permission needed");
40849
41196
  resetStdinForChild();
40850
41197
  const refreshCode = await new Promise((resolve9, reject) => {
40851
- const proc = (0, import_child_process29.spawn)(
41198
+ const proc = (0, import_child_process30.spawn)(
40852
41199
  "gh",
40853
41200
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
40854
41201
  { stdio: "inherit" }
@@ -40998,7 +41345,7 @@ var GitHubCodespacesProvider = class {
40998
41345
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
40999
41346
  resetStdinForChild();
41000
41347
  const ok = await new Promise((resolve9) => {
41001
- const proc = (0, import_child_process29.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
41348
+ const proc = (0, import_child_process30.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
41002
41349
  proc.on("exit", (code) => resolve9(code === 0));
41003
41350
  proc.on("error", () => resolve9(false));
41004
41351
  });
@@ -41025,7 +41372,7 @@ var GitHubCodespacesProvider = class {
41025
41372
  );
41026
41373
  resetStdinForChild();
41027
41374
  await new Promise((resolve9, reject) => {
41028
- const proc = (0, import_child_process29.spawn)(
41375
+ const proc = (0, import_child_process30.spawn)(
41029
41376
  "gh",
41030
41377
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
41031
41378
  { stdio: "inherit" }
@@ -41203,7 +41550,7 @@ var GitHubCodespacesProvider = class {
41203
41550
  async streamCommand(workspaceId, command2) {
41204
41551
  resetStdinForChild();
41205
41552
  return new Promise((resolve9, reject) => {
41206
- const proc = (0, import_child_process29.spawn)(
41553
+ const proc = (0, import_child_process30.spawn)(
41207
41554
  "gh",
41208
41555
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
41209
41556
  { stdio: "inherit" }
@@ -41230,11 +41577,11 @@ var GitHubCodespacesProvider = class {
41230
41577
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
41231
41578
  ];
41232
41579
  await new Promise((resolve9, reject) => {
41233
- const tar = (0, import_child_process29.spawn)("tar", tarArgs, {
41580
+ const tar = (0, import_child_process30.spawn)("tar", tarArgs, {
41234
41581
  stdio: ["ignore", "pipe", "pipe"],
41235
41582
  env: tarEnv
41236
41583
  });
41237
- const ssh = (0, import_child_process29.spawn)("gh", sshArgs, {
41584
+ const ssh = (0, import_child_process30.spawn)("gh", sshArgs, {
41238
41585
  stdio: [tar.stdout, "pipe", "pipe"]
41239
41586
  });
41240
41587
  let tarErr = "";
@@ -41268,7 +41615,7 @@ var GitHubCodespacesProvider = class {
41268
41615
  }
41269
41616
  const cmd = parts.join(" && ");
41270
41617
  await new Promise((resolve9, reject) => {
41271
- const proc = (0, import_child_process29.spawn)(
41618
+ const proc = (0, import_child_process30.spawn)(
41272
41619
  "gh",
41273
41620
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
41274
41621
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -41326,11 +41673,11 @@ function shellQuote(s) {
41326
41673
  }
41327
41674
 
41328
41675
  // src/services/providers/gitpod.ts
41329
- var import_child_process30 = require("child_process");
41676
+ var import_child_process31 = require("child_process");
41330
41677
  var import_util5 = require("util");
41331
41678
  var path85 = __toESM(require("path"));
41332
41679
  var import_picocolors10 = __toESM(require("picocolors"));
41333
- var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
41680
+ var execFileP7 = (0, import_util5.promisify)(import_child_process31.execFile);
41334
41681
  var MAX_BUFFER2 = 8 * 1024 * 1024;
41335
41682
  function resetStdinForChild2() {
41336
41683
  if (process.stdin.isTTY) {
@@ -41370,7 +41717,7 @@ var GitpodProvider = class {
41370
41717
  );
41371
41718
  resetStdinForChild2();
41372
41719
  await new Promise((resolve9, reject) => {
41373
- const proc = (0, import_child_process30.spawn)("gitpod", ["login"], { stdio: "inherit" });
41720
+ const proc = (0, import_child_process31.spawn)("gitpod", ["login"], { stdio: "inherit" });
41374
41721
  proc.on("exit", (code) => {
41375
41722
  if (code === 0) resolve9();
41376
41723
  else reject(new Error("gitpod login failed."));
@@ -41522,7 +41869,7 @@ var GitpodProvider = class {
41522
41869
  async streamCommand(workspaceId, command2) {
41523
41870
  resetStdinForChild2();
41524
41871
  return new Promise((resolve9, reject) => {
41525
- const proc = (0, import_child_process30.spawn)(
41872
+ const proc = (0, import_child_process31.spawn)(
41526
41873
  "gitpod",
41527
41874
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
41528
41875
  { stdio: "inherit" }
@@ -41542,11 +41889,11 @@ var GitpodProvider = class {
41542
41889
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
41543
41890
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
41544
41891
  await new Promise((resolve9, reject) => {
41545
- const tar = (0, import_child_process30.spawn)("tar", tarArgs, {
41892
+ const tar = (0, import_child_process31.spawn)("tar", tarArgs, {
41546
41893
  stdio: ["ignore", "pipe", "pipe"],
41547
41894
  env: tarEnv
41548
41895
  });
41549
- const ssh = (0, import_child_process30.spawn)(
41896
+ const ssh = (0, import_child_process31.spawn)(
41550
41897
  "gitpod",
41551
41898
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
41552
41899
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -41578,7 +41925,7 @@ var GitpodProvider = class {
41578
41925
  }
41579
41926
  const cmd = parts.join(" && ");
41580
41927
  await new Promise((resolve9, reject) => {
41581
- const proc = (0, import_child_process30.spawn)(
41928
+ const proc = (0, import_child_process31.spawn)(
41582
41929
  "gitpod",
41583
41930
  ["workspace", "ssh", workspaceId, "--", cmd],
41584
41931
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -41602,10 +41949,10 @@ function shellQuote2(s) {
41602
41949
  }
41603
41950
 
41604
41951
  // src/services/providers/gitlab-workspaces.ts
41605
- var import_child_process31 = require("child_process");
41952
+ var import_child_process32 = require("child_process");
41606
41953
  var import_util6 = require("util");
41607
41954
  var path86 = __toESM(require("path"));
41608
- var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
41955
+ var execFileP8 = (0, import_util6.promisify)(import_child_process32.execFile);
41609
41956
  var MAX_BUFFER3 = 8 * 1024 * 1024;
41610
41957
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
41611
41958
  function resetStdinForChild3() {
@@ -41647,7 +41994,7 @@ var GitLabWorkspacesProvider = class {
41647
41994
  );
41648
41995
  resetStdinForChild3();
41649
41996
  await new Promise((resolve9, reject) => {
41650
- const proc = (0, import_child_process31.spawn)(
41997
+ const proc = (0, import_child_process32.spawn)(
41651
41998
  "glab",
41652
41999
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
41653
42000
  { stdio: "inherit" }
@@ -41819,7 +42166,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41819
42166
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
41820
42167
  resetStdinForChild3();
41821
42168
  return new Promise((resolve9, reject) => {
41822
- const proc = (0, import_child_process31.spawn)(
42169
+ const proc = (0, import_child_process32.spawn)(
41823
42170
  "ssh",
41824
42171
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
41825
42172
  { stdio: "inherit" }
@@ -41840,8 +42187,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41840
42187
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
41841
42188
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
41842
42189
  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)(
42190
+ const tar = (0, import_child_process32.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
42191
+ const ssh = (0, import_child_process32.spawn)(
41845
42192
  "ssh",
41846
42193
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
41847
42194
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -41871,7 +42218,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41871
42218
  }
41872
42219
  const cmd = parts.join(" && ");
41873
42220
  await new Promise((resolve9, reject) => {
41874
- const proc = (0, import_child_process31.spawn)(
42221
+ const proc = (0, import_child_process32.spawn)(
41875
42222
  "ssh",
41876
42223
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
41877
42224
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -41930,10 +42277,10 @@ function shellQuote3(s) {
41930
42277
  }
41931
42278
 
41932
42279
  // src/services/providers/railway.ts
41933
- var import_child_process32 = require("child_process");
42280
+ var import_child_process33 = require("child_process");
41934
42281
  var import_util7 = require("util");
41935
42282
  var path87 = __toESM(require("path"));
41936
- var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
42283
+ var execFileP9 = (0, import_util7.promisify)(import_child_process33.execFile);
41937
42284
  var MAX_BUFFER4 = 8 * 1024 * 1024;
41938
42285
  function resetStdinForChild4() {
41939
42286
  if (process.stdin.isTTY) {
@@ -41974,7 +42321,7 @@ var RailwayProvider = class {
41974
42321
  );
41975
42322
  resetStdinForChild4();
41976
42323
  await new Promise((resolve9, reject) => {
41977
- const proc = (0, import_child_process32.spawn)("railway", ["login"], { stdio: "inherit" });
42324
+ const proc = (0, import_child_process33.spawn)("railway", ["login"], { stdio: "inherit" });
41978
42325
  proc.on("exit", (code) => {
41979
42326
  if (code === 0) resolve9();
41980
42327
  else reject(new Error("railway login failed."));
@@ -42117,7 +42464,7 @@ var RailwayProvider = class {
42117
42464
  }
42118
42465
  resetStdinForChild4();
42119
42466
  return new Promise((resolve9, reject) => {
42120
- const proc = (0, import_child_process32.spawn)(
42467
+ const proc = (0, import_child_process33.spawn)(
42121
42468
  "railway",
42122
42469
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
42123
42470
  { stdio: "inherit" }
@@ -42141,8 +42488,8 @@ var RailwayProvider = class {
42141
42488
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
42142
42489
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
42143
42490
  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)(
42491
+ const tar = (0, import_child_process33.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
42492
+ const sh = (0, import_child_process33.spawn)(
42146
42493
  "railway",
42147
42494
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
42148
42495
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -42175,7 +42522,7 @@ var RailwayProvider = class {
42175
42522
  }
42176
42523
  const cmd = parts.join(" && ");
42177
42524
  await new Promise((resolve9, reject) => {
42178
- const proc = (0, import_child_process32.spawn)(
42525
+ const proc = (0, import_child_process33.spawn)(
42179
42526
  "railway",
42180
42527
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
42181
42528
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -42917,9 +43264,9 @@ function checkSessions() {
42917
43264
  }
42918
43265
  }
42919
43266
  function checkAgentBinaries() {
42920
- const os64 = createOsStrategy();
43267
+ const os65 = createOsStrategy();
42921
43268
  return getEnabledAgents().map((meta) => {
42922
- const found = os64.findInPath(meta.binaryName);
43269
+ const found = os65.findInPath(meta.binaryName);
42923
43270
  return {
42924
43271
  id: `agent-${meta.id}`,
42925
43272
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -42983,7 +43330,7 @@ function checkChokidar() {
42983
43330
  }
42984
43331
  async function doctor(args2 = []) {
42985
43332
  const json = args2.includes("--json");
42986
- const cliVersion = true ? "2.62.2" : "0.0.0-dev";
43333
+ const cliVersion = true ? "2.63.0" : "0.0.0-dev";
42987
43334
  const apiBase2 = resolveApiBaseUrl();
42988
43335
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
42989
43336
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -43374,7 +43721,7 @@ async function mcpRun(args2) {
43374
43721
  // src/commands/version.ts
43375
43722
  var import_picocolors15 = __toESM(require("picocolors"));
43376
43723
  function version2() {
43377
- const v = true ? "2.62.2" : "unknown";
43724
+ const v = true ? "2.63.0" : "unknown";
43378
43725
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
43379
43726
  }
43380
43727
 
@@ -43523,10 +43870,10 @@ var EXIT_CODE_NAMES = {
43523
43870
  };
43524
43871
 
43525
43872
  // src/index.ts
43526
- var os63 = __toESM(require("os"));
43873
+ var os64 = __toESM(require("os"));
43527
43874
  if (!process.env.HOME) {
43528
43875
  try {
43529
- const home = os63.homedir();
43876
+ const home = os64.homedir();
43530
43877
  if (home) process.env.HOME = home;
43531
43878
  } catch {
43532
43879
  }