codeam-cli 2.62.1 → 2.62.2

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 +6 -0
  2. package/dist/index.js +891 -741
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3120,11 +3120,11 @@ function quiet(fn) {
3120
3120
  log.debug(TAG, "ignored sync error", err);
3121
3121
  }
3122
3122
  }
3123
- function rmIfExistsQuiet(path89) {
3123
+ function rmIfExistsQuiet(path90) {
3124
3124
  try {
3125
- fs2.rmSync(path89, { force: true });
3125
+ fs2.rmSync(path90, { force: true });
3126
3126
  } catch (err) {
3127
- log.debug(TAG, `rmIfExists failed for ${path89}`, err);
3127
+ log.debug(TAG, `rmIfExists failed for ${path90}`, err);
3128
3128
  }
3129
3129
  }
3130
3130
  function killQuiet(target, signal = "SIGTERM") {
@@ -3272,7 +3272,7 @@ var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, ge
3272
3272
  // src/commands/pair-auto.ts
3273
3273
  var fs63 = __toESM(require("fs"));
3274
3274
  var os52 = __toESM(require("os"));
3275
- var path67 = __toESM(require("path"));
3275
+ var path68 = __toESM(require("path"));
3276
3276
  var import_crypto4 = require("crypto");
3277
3277
 
3278
3278
  // src/services/telemetry.service.ts
@@ -3308,8 +3308,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
3308
3308
  return decodedFile;
3309
3309
  };
3310
3310
  }
3311
- function normalizeWindowsPath(path89) {
3312
- return path89.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3311
+ function normalizeWindowsPath(path90) {
3312
+ return path90.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3313
3313
  }
3314
3314
 
3315
3315
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -5789,9 +5789,9 @@ async function addSourceContext(frames) {
5789
5789
  LRU_FILE_CONTENTS_CACHE.reduce();
5790
5790
  return frames;
5791
5791
  }
5792
- function getContextLinesFromFile(path89, ranges, output) {
5792
+ function getContextLinesFromFile(path90, ranges, output) {
5793
5793
  return new Promise((resolve9) => {
5794
- const stream = (0, import_node_fs.createReadStream)(path89);
5794
+ const stream = (0, import_node_fs.createReadStream)(path90);
5795
5795
  const lineReaded = (0, import_node_readline.createInterface)({
5796
5796
  input: stream
5797
5797
  });
@@ -5806,7 +5806,7 @@ function getContextLinesFromFile(path89, ranges, output) {
5806
5806
  let rangeStart = range[0];
5807
5807
  let rangeEnd = range[1];
5808
5808
  function onStreamError() {
5809
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path89, 1);
5809
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path90, 1);
5810
5810
  lineReaded.close();
5811
5811
  lineReaded.removeAllListeners();
5812
5812
  destroyStreamAndResolve();
@@ -5867,8 +5867,8 @@ function clearLineContext(frame) {
5867
5867
  delete frame.context_line;
5868
5868
  delete frame.post_context;
5869
5869
  }
5870
- function shouldSkipContextLinesForFile(path89) {
5871
- return path89.startsWith("node:") || path89.endsWith(".min.js") || path89.endsWith(".min.cjs") || path89.endsWith(".min.mjs") || path89.startsWith("data:");
5870
+ function shouldSkipContextLinesForFile(path90) {
5871
+ return path90.startsWith("node:") || path90.endsWith(".min.js") || path90.endsWith(".min.cjs") || path90.endsWith(".min.mjs") || path90.startsWith("data:");
5872
5872
  }
5873
5873
  function shouldSkipContextLinesForFrame(frame) {
5874
5874
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -8022,7 +8022,7 @@ function readAnonId() {
8022
8022
  }
8023
8023
  function superProperties() {
8024
8024
  return {
8025
- cliVersion: true ? "2.62.1" : "0.0.0-dev",
8025
+ cliVersion: true ? "2.62.2" : "0.0.0-dev",
8026
8026
  nodeVersion: process.version,
8027
8027
  platform: process.platform,
8028
8028
  arch: process.arch,
@@ -8203,7 +8203,7 @@ var os4 = __toESM(require("os"));
8203
8203
  // package.json
8204
8204
  var package_default = {
8205
8205
  name: "codeam-cli",
8206
- version: "2.62.1",
8206
+ version: "2.62.2",
8207
8207
  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
8208
  type: "commonjs",
8209
8209
  main: "dist/index.js",
@@ -8916,12 +8916,13 @@ function isPidAlive(pid) {
8916
8916
  return false;
8917
8917
  }
8918
8918
  }
8919
- function pidLooksLikeProxy(pid) {
8919
+ function pidLooksLikeProxy(pid, opts = {}) {
8920
8920
  try {
8921
8921
  const cmd = fs5.readFileSync(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ").toLowerCase();
8922
8922
  if (cmd.trim() === "") return false;
8923
8923
  return cmd.includes("headroom") && cmd.includes("proxy");
8924
8924
  } catch {
8925
+ if (opts.strict) return false;
8925
8926
  return isPidAlive(pid);
8926
8927
  }
8927
8928
  }
@@ -8960,7 +8961,7 @@ function findRunningProxyPid() {
8960
8961
  if (!/^\d+$/.test(name)) continue;
8961
8962
  const pid = Number(name);
8962
8963
  if (pid === process.pid) continue;
8963
- if (pidLooksLikeProxy(pid)) return pid;
8964
+ if (pidLooksLikeProxy(pid, { strict: true })) return pid;
8964
8965
  }
8965
8966
  return null;
8966
8967
  }
@@ -9612,7 +9613,7 @@ var CommandRelayService = class _CommandRelayService {
9612
9613
  // fresh + clear the "CLI update available" banner after a self-update
9613
9614
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9614
9615
  // pair/reconnect). Older backends ignore the extra field.
9615
- ..."2.62.1" ? { ideVersion: "2.62.1" } : {}
9616
+ ..."2.62.2" ? { ideVersion: "2.62.2" } : {}
9616
9617
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9617
9618
  }
9618
9619
  /**
@@ -9839,10 +9840,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
9839
9840
  /[\\/]Start Menu([\\/]|$)/i,
9840
9841
  /[\\/]Templates([\\/]|$)/i
9841
9842
  ];
9842
- function isUnsafeWindowsWatchRoot(dir, homedir52) {
9843
+ function isUnsafeWindowsWatchRoot(dir, homedir51) {
9843
9844
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
9844
9845
  const cwd = norm(dir);
9845
- const home = norm(homedir52);
9846
+ const home = norm(homedir51);
9846
9847
  if (cwd === home) return true;
9847
9848
  if (/^[a-z]:$/.test(cwd)) return true;
9848
9849
  const sysRoots = [
@@ -10988,7 +10989,7 @@ function closeAllTerminals() {
10988
10989
  // src/commands/start/handlers.ts
10989
10990
  var fs62 = __toESM(require("fs"));
10990
10991
  var os51 = __toESM(require("os"));
10991
- var path66 = __toESM(require("path"));
10992
+ var path67 = __toESM(require("path"));
10992
10993
  var import_crypto3 = require("crypto");
10993
10994
  var import_child_process24 = require("child_process");
10994
10995
 
@@ -11821,7 +11822,7 @@ function findGitRoot2(startDir) {
11821
11822
  // src/commands/link.ts
11822
11823
  var import_node_crypto8 = require("crypto");
11823
11824
  var fs31 = __toESM(require("fs"));
11824
- var path35 = __toESM(require("path"));
11825
+ var path36 = __toESM(require("path"));
11825
11826
  var import_chokidar = __toESM(require("chokidar"));
11826
11827
  var import_picocolors2 = __toESM(require("picocolors"));
11827
11828
 
@@ -16116,55 +16117,478 @@ var CodexDeployStrategy = class {
16116
16117
  };
16117
16118
 
16118
16119
  // src/agents/coderabbit/runtime.ts
16119
- var import_node_child_process8 = require("child_process");
16120
+ var import_node_child_process9 = require("child_process");
16120
16121
 
16121
16122
  // src/agents/coderabbit/installer.ts
16123
+ var import_node_child_process7 = require("child_process");
16124
+ var import_node_fs5 = require("fs");
16125
+ var path27 = __toESM(require("path"));
16126
+
16127
+ // src/commands/host/os-packages.ts
16122
16128
  var import_node_child_process6 = require("child_process");
16123
- var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
16124
- async function ensureCoderabbitInstalled(os64) {
16125
- if (os64.findInPath("coderabbit")) return true;
16126
- if (os64.id === "win32") {
16127
- console.error(
16128
- "\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
16129
+ var PM_INSTALL_TIMEOUT_MS = 18e4;
16130
+ var defaultHeadroomRunner = {
16131
+ which(cmd) {
16132
+ try {
16133
+ (0, import_node_child_process6.execFileSync)("which", [cmd], { stdio: "ignore" });
16134
+ return true;
16135
+ } catch {
16136
+ return false;
16137
+ }
16138
+ },
16139
+ run(cmd, args2, opts = {}) {
16140
+ return new Promise((resolve9) => {
16141
+ const spawnEnv = opts.env ?? process.env;
16142
+ const child = (0, import_node_child_process6.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
16143
+ let stderrBuf = "";
16144
+ let stdoutBuf = "";
16145
+ let settled = false;
16146
+ const done = (code) => {
16147
+ if (settled) return;
16148
+ settled = true;
16149
+ resolve9({ code, stderr: stderrBuf, stdout: stdoutBuf });
16150
+ };
16151
+ child.stdout?.on("data", (b) => {
16152
+ const chunk = b.toString();
16153
+ stdoutBuf += chunk;
16154
+ const line = chunk.replace(/\n+$/, "");
16155
+ if (line) log.info("host-agent", `headroom[${cmd}]: ${line}`);
16156
+ });
16157
+ child.stderr?.on("data", (b) => {
16158
+ const chunk = b.toString();
16159
+ stderrBuf += chunk;
16160
+ const line = chunk.replace(/\n+$/, "");
16161
+ if (line) log.info("host-agent", `headroom[${cmd}]: ${line}`);
16162
+ });
16163
+ const timeoutMs = opts.timeoutMs;
16164
+ let timer;
16165
+ if (timeoutMs !== void 0) {
16166
+ timer = setTimeout(() => {
16167
+ log.warn(
16168
+ "host-agent",
16169
+ `headroom[${cmd}] timed out after ${timeoutMs / 1e3}s \u2014 aborting`
16170
+ );
16171
+ killQuiet(child);
16172
+ done(null);
16173
+ }, timeoutMs);
16174
+ }
16175
+ child.once("exit", (code) => {
16176
+ if (timer !== void 0) clearTimeout(timer);
16177
+ done(code);
16178
+ });
16179
+ child.once("error", (e) => {
16180
+ if (timer !== void 0) clearTimeout(timer);
16181
+ log.trace("host-agent", `headroom[${cmd}] spawn error: ${e.message}`);
16182
+ done(null);
16183
+ });
16184
+ });
16185
+ }
16186
+ };
16187
+ var PACKAGE_MANAGERS = [
16188
+ "apt-get",
16189
+ "apk",
16190
+ "dnf",
16191
+ "yum",
16192
+ "pacman",
16193
+ "zypper"
16194
+ ];
16195
+ var PROVISION_RECIPES = {
16196
+ "apt-get": {
16197
+ update: ["apt-get", "update"],
16198
+ install: [
16199
+ "apt-get",
16200
+ "install",
16201
+ "-y",
16202
+ "python3",
16203
+ "python3-pip",
16204
+ "python3-venv",
16205
+ "ca-certificates",
16206
+ "curl"
16207
+ ]
16208
+ },
16209
+ apk: {
16210
+ install: ["apk", "add", "--no-cache", "python3", "py3-pip", "ca-certificates", "curl"]
16211
+ },
16212
+ dnf: {
16213
+ install: ["dnf", "install", "-y", "python3", "python3-pip", "ca-certificates", "curl"]
16214
+ },
16215
+ yum: {
16216
+ install: ["yum", "install", "-y", "python3", "python3-pip", "ca-certificates", "curl"]
16217
+ },
16218
+ pacman: {
16219
+ install: ["pacman", "-Sy", "--noconfirm", "python", "python-pip", "ca-certificates", "curl"]
16220
+ },
16221
+ zypper: {
16222
+ install: [
16223
+ "zypper",
16224
+ "--non-interactive",
16225
+ "install",
16226
+ "python3",
16227
+ "python3-pip",
16228
+ "ca-certificates",
16229
+ "curl"
16230
+ ]
16231
+ }
16232
+ };
16233
+ function detectPackageManager(runner) {
16234
+ for (const pm of PACKAGE_MANAGERS) {
16235
+ if (runner.which(pm)) return pm;
16236
+ }
16237
+ return null;
16238
+ }
16239
+ var INSTALL_ARGV_PREFIX = {
16240
+ "apt-get": ["apt-get", "install", "-y", "--no-install-recommends"],
16241
+ apk: ["apk", "add", "--no-cache"],
16242
+ dnf: ["dnf", "install", "-y"],
16243
+ yum: ["yum", "install", "-y"],
16244
+ pacman: ["pacman", "-Sy", "--noconfirm"],
16245
+ zypper: ["zypper", "--non-interactive", "install"]
16246
+ };
16247
+ function osPackageInstallArgv(pm, packages) {
16248
+ if (pm === null || packages.length === 0) return null;
16249
+ return [...INSTALL_ARGV_PREFIX[pm], ...packages];
16250
+ }
16251
+ function escalateCommand(argv) {
16252
+ const isRoot = process.getuid?.() === 0;
16253
+ return isRoot ? { cmd: argv[0], args: argv.slice(1) } : { cmd: "sudo", args: argv };
16254
+ }
16255
+ async function ensurePip(runner) {
16256
+ if (runner.which("pip") || runner.which("pip3")) {
16257
+ return true;
16258
+ }
16259
+ const pm = detectPackageManager(runner);
16260
+ if (!pm) {
16261
+ log.warn(
16262
+ "host-agent",
16263
+ "pip is absent and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) found \u2014 skipping Headroom"
16129
16264
  );
16130
16265
  return false;
16131
16266
  }
16132
- console.log("\n CodeRabbit CLI not found \u2014 installing via the official script\u2026\n");
16133
- const ok = await new Promise((resolve9) => {
16134
- const INSTALL_TIMEOUT_MS2 = 15e4;
16135
- const proc = (0, import_node_child_process6.spawn)(
16267
+ const escalate = escalateCommand;
16268
+ const recipe = PROVISION_RECIPES[pm];
16269
+ log.info(
16270
+ "host-agent",
16271
+ `pip absent \u2014 provisioning bare box (python3+pip+ca-certificates+curl) via ${pm}`
16272
+ );
16273
+ try {
16274
+ if (recipe.update) {
16275
+ const { cmd: cmd2, args: args3 } = escalate(recipe.update);
16276
+ const updateResult = await runner.run(cmd2, args3, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
16277
+ if (updateResult.code !== 0) {
16278
+ log.warn(
16279
+ "host-agent",
16280
+ `${pm} update exited ${String(updateResult.code)} \u2014 attempting install anyway`
16281
+ );
16282
+ }
16283
+ }
16284
+ const { cmd, args: args2 } = escalate(recipe.install);
16285
+ const installResult = await runner.run(cmd, args2, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
16286
+ if (installResult.code !== 0) {
16287
+ log.warn(
16288
+ "host-agent",
16289
+ `${pm} bare-box provision failed (code=${String(installResult.code)}) \u2014 skipping Headroom`
16290
+ );
16291
+ return false;
16292
+ }
16293
+ } catch (e) {
16294
+ log.warn(
16295
+ "host-agent",
16296
+ `bare-box provision threw unexpectedly: ${e instanceof Error ? e.message : String(e)} \u2014 skipping Headroom`
16297
+ );
16298
+ return false;
16299
+ }
16300
+ log.info("host-agent", `bare box provisioned via ${pm} (python3+pip+ca-certificates+curl)`);
16301
+ return true;
16302
+ }
16303
+ async function resolveHeadroomPython(runner) {
16304
+ const PROBE_TIMEOUT_MS = 5e3;
16305
+ const SUFFIXES = ["python3.13", "python3.12", "python3.11", "python3.10"];
16306
+ const PREFIX_DIRS = ["/opt/homebrew/bin", "/usr/local/bin"];
16307
+ const probe = async (candidate) => {
16308
+ try {
16309
+ const r = await runner.run(
16310
+ candidate,
16311
+ ["-c", 'import sys; print("%d.%d" % sys.version_info[:2])'],
16312
+ { timeoutMs: PROBE_TIMEOUT_MS }
16313
+ );
16314
+ if (r.code !== 0) return false;
16315
+ const parts = (r.stdout ?? "").trim().split(".");
16316
+ const major = parseInt(parts[0] ?? "", 10);
16317
+ const minor = parseInt(parts[1] ?? "", 10);
16318
+ if (!(major === 3 && minor >= 10)) return false;
16319
+ const pipCheck = await runner.run(candidate, ["-m", "pip", "--version"], {
16320
+ timeoutMs: PROBE_TIMEOUT_MS
16321
+ });
16322
+ return pipCheck.code === 0;
16323
+ } catch {
16324
+ return false;
16325
+ }
16326
+ };
16327
+ for (const suffix of SUFFIXES) {
16328
+ try {
16329
+ if (await probe(suffix)) return suffix;
16330
+ } catch {
16331
+ }
16332
+ }
16333
+ for (const suffix of SUFFIXES) {
16334
+ for (const dir of PREFIX_DIRS) {
16335
+ const candidate = `${dir}/${suffix}`;
16336
+ try {
16337
+ if (await probe(candidate)) return candidate;
16338
+ } catch {
16339
+ }
16340
+ }
16341
+ }
16342
+ try {
16343
+ if (await probe("python3")) return "python3";
16344
+ } catch {
16345
+ }
16346
+ return null;
16347
+ }
16348
+ var PY_INSTALL_TIMEOUT_MS = 6e5;
16349
+ var MODERN_PYTHON_RECIPES = {
16350
+ "apt-get": [
16351
+ ["apt-get", "install", "-y", "python3.12"],
16352
+ ["apt-get", "install", "-y", "python3.11"],
16353
+ ["apt-get", "install", "-y", "python3"]
16354
+ ],
16355
+ dnf: [
16356
+ ["dnf", "install", "-y", "python3.12"],
16357
+ ["dnf", "install", "-y", "python3"]
16358
+ ],
16359
+ yum: [
16360
+ ["yum", "install", "-y", "python3.12"],
16361
+ ["yum", "install", "-y", "python3"]
16362
+ ],
16363
+ apk: [["apk", "add", "--no-cache", "python3"]],
16364
+ pacman: [["pacman", "-Sy", "--noconfirm", "python"]],
16365
+ zypper: [
16366
+ ["zypper", "--non-interactive", "install", "python311"],
16367
+ ["zypper", "--non-interactive", "install", "python3"]
16368
+ ]
16369
+ };
16370
+ async function ensureModernPython(runner) {
16371
+ let py = await resolveHeadroomPython(runner);
16372
+ if (py !== null) return py;
16373
+ try {
16374
+ if (process.platform === "darwin") {
16375
+ if (runner.which("brew")) {
16376
+ log.info("host-agent", "no Python \u22653.10 found \u2014 installing python@3.12 via Homebrew");
16377
+ const r = await runner.run("brew", ["install", "python@3.12"], {
16378
+ timeoutMs: PY_INSTALL_TIMEOUT_MS
16379
+ });
16380
+ if (r.code !== 0) {
16381
+ log.warn(
16382
+ "host-agent",
16383
+ `brew install python@3.12 exited ${String(r.code)} \u2014 will re-probe anyway`
16384
+ );
16385
+ }
16386
+ } else {
16387
+ log.warn(
16388
+ "host-agent",
16389
+ "no Python \u22653.10 and Homebrew is absent \u2014 cannot auto-install Python on macOS"
16390
+ );
16391
+ }
16392
+ } else if (process.platform === "linux") {
16393
+ const pm = detectPackageManager(runner);
16394
+ if (!pm) {
16395
+ log.warn(
16396
+ "host-agent",
16397
+ "no Python \u22653.10 and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) \u2014 cannot auto-install Python"
16398
+ );
16399
+ } else {
16400
+ log.info("host-agent", `no Python \u22653.10 found \u2014 installing a modern Python via ${pm}`);
16401
+ for (const argv of MODERN_PYTHON_RECIPES[pm]) {
16402
+ const { cmd, args: args2 } = escalateCommand(argv);
16403
+ const r = await runner.run(cmd, args2, { timeoutMs: PY_INSTALL_TIMEOUT_MS });
16404
+ if (r.code === 0) {
16405
+ log.info("host-agent", `installed Python package via ${pm}: ${argv.join(" ")}`);
16406
+ break;
16407
+ }
16408
+ log.warn(
16409
+ "host-agent",
16410
+ `${pm} install '${argv.join(" ")}' exited ${String(r.code)} \u2014 trying next`
16411
+ );
16412
+ }
16413
+ }
16414
+ } else {
16415
+ log.warn(
16416
+ "host-agent",
16417
+ `no Python \u22653.10 and platform '${process.platform}' has no auto-install path`
16418
+ );
16419
+ }
16420
+ } catch (e) {
16421
+ log.warn(
16422
+ "host-agent",
16423
+ `Python auto-install threw unexpectedly (best-effort): ${e instanceof Error ? e.message : String(e)}`
16424
+ );
16425
+ }
16426
+ py = await resolveHeadroomPython(runner);
16427
+ return py;
16428
+ }
16429
+
16430
+ // src/agents/coderabbit/installer.ts
16431
+ var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
16432
+ var INSTALL_TIMEOUT_MS = 15e4;
16433
+ var PREREQ_INSTALL_TIMEOUT_MS = 12e4;
16434
+ var REQUIRED_TOOLS = ["unzip", "git"];
16435
+ function manualInstallHint(runner, tools) {
16436
+ const pkgs = tools.join(" ");
16437
+ const argv = osPackageInstallArgv(detectPackageManager(runner), [...tools]);
16438
+ return argv ? `\`sudo ${argv.join(" ")}\`` : `your package manager (e.g. \`${pkgs}\`)`;
16439
+ }
16440
+ function writeUnzipShim(os64, runner) {
16441
+ const python = ["python3", "python"].find((p2) => runner.which(p2));
16442
+ if (!python) return null;
16443
+ const dir = os64.scratchPath("codeam-cr-prereq");
16444
+ const shim = path27.join(dir, "unzip");
16445
+ const script = `#!/bin/sh
16446
+ set -e
16447
+ archive=""
16448
+ dest="."
16449
+ while [ $# -gt 0 ]; do
16450
+ case "$1" in
16451
+ -q|-o|-qq) shift ;;
16452
+ -d) dest="$2"; shift 2 ;;
16453
+ *) if [ -z "$archive" ]; then archive="$1"; fi; shift ;;
16454
+ esac
16455
+ done
16456
+ [ -n "$archive" ] || { echo "unzip shim: no archive given" >&2; exit 1; }
16457
+ mkdir -p "$dest"
16458
+ exec ${python} -m zipfile -e "$archive" "$dest"
16459
+ `;
16460
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
16461
+ (0, import_node_fs5.writeFileSync)(shim, script, { mode: 448 });
16462
+ (0, import_node_fs5.chmodSync)(shim, 448);
16463
+ return dir;
16464
+ }
16465
+ async function ensureInstallPrerequisites(os64, deps = {}) {
16466
+ const runner = deps.runner ?? defaultHeadroomRunner;
16467
+ const missing = REQUIRED_TOOLS.filter((t2) => os64.findInPath(t2) === null);
16468
+ if (missing.length === 0) return { ok: true, extraPath: [] };
16469
+ log.info(
16470
+ "coderabbit",
16471
+ `installer prerequisites missing: ${missing.join(", ")} \u2014 attempting to provision them`
16472
+ );
16473
+ const argv = osPackageInstallArgv(detectPackageManager(runner), [...missing]);
16474
+ if (argv) {
16475
+ const isRoot = process.getuid?.() === 0;
16476
+ const cmd = isRoot ? argv[0] : "sudo";
16477
+ const args2 = isRoot ? argv.slice(1) : ["-n", ...argv];
16478
+ const r = await runner.run(cmd, args2, { timeoutMs: PREREQ_INSTALL_TIMEOUT_MS });
16479
+ if (r.code !== 0) {
16480
+ log.warn(
16481
+ "coderabbit",
16482
+ `prerequisite install exited ${String(r.code)} \u2014 falling back to the unprivileged path`
16483
+ );
16484
+ }
16485
+ }
16486
+ const stillMissing = REQUIRED_TOOLS.filter((t2) => os64.findInPath(t2) === null);
16487
+ if (stillMissing.length === 0) return { ok: true, extraPath: [] };
16488
+ if (stillMissing.length === 1 && stillMissing[0] === "unzip") {
16489
+ const shimDir = writeUnzipShim(os64, runner);
16490
+ if (shimDir) {
16491
+ log.info("coderabbit", "unzip is unavailable \u2014 using a scoped python zipfile shim");
16492
+ return { ok: true, extraPath: [shimDir] };
16493
+ }
16494
+ }
16495
+ const list = stillMissing.join(" and ");
16496
+ return {
16497
+ ok: false,
16498
+ error: `CodeRabbit's installer needs ${list} on this machine, and it couldn't be installed automatically (no root / no passwordless sudo). Install it with ${manualInstallHint(runner, stillMissing)} and try again.`
16499
+ };
16500
+ }
16501
+ function defaultRunInstallScript(env) {
16502
+ return new Promise((resolve9) => {
16503
+ const proc = (0, import_node_child_process7.spawn)(
16136
16504
  "sh",
16137
16505
  ["-c", `curl -fsSL --connect-timeout 15 --max-time 120 ${INSTALL_URL} | sh`],
16138
- { stdio: "inherit" }
16506
+ { stdio: ["ignore", "pipe", "pipe"], env }
16139
16507
  );
16508
+ let output = "";
16140
16509
  let settled = false;
16141
- const finish = (v) => {
16510
+ const finish = (code) => {
16142
16511
  if (settled) return;
16143
16512
  settled = true;
16144
16513
  clearTimeout(timer);
16145
- resolve9(v);
16514
+ resolve9({ code, output });
16146
16515
  };
16516
+ const onData = (b) => {
16517
+ const chunk = b.toString();
16518
+ output += chunk;
16519
+ const line = chunk.replace(/\n+$/, "");
16520
+ if (line) log.info("coderabbit", `install: ${line}`);
16521
+ };
16522
+ proc.stdout?.on("data", onData);
16523
+ proc.stderr?.on("data", onData);
16147
16524
  const timer = setTimeout(() => {
16148
- console.error("\n \u2717 CodeRabbit install timed out \u2014 check network egress and retry.\n");
16149
16525
  try {
16150
16526
  proc.kill("SIGKILL");
16151
16527
  } catch {
16152
16528
  }
16153
- finish(false);
16154
- }, INSTALL_TIMEOUT_MS2);
16155
- proc.on("close", (code) => finish(code === 0));
16156
- proc.on("error", () => finish(false));
16529
+ output += "\ninstall timed out";
16530
+ finish(null);
16531
+ }, INSTALL_TIMEOUT_MS);
16532
+ proc.on("close", (code) => finish(code));
16533
+ proc.on("error", (e) => {
16534
+ output += `
16535
+ ${e.message}`;
16536
+ finish(null);
16537
+ });
16157
16538
  });
16158
- if (!ok) return false;
16539
+ }
16540
+ function summarizeInstallFailure(output) {
16541
+ const clean = output.replace(/\u001b\[[0-9;]*m/g, "");
16542
+ const lines = clean.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
16543
+ const err = lines.find((l) => /\[ERROR\]|^error[: ]/i.test(l));
16544
+ if (err) {
16545
+ const idx = lines.indexOf(err);
16546
+ const bullets = lines.slice(idx + 1).filter((l) => l.startsWith("- "));
16547
+ const detail = bullets.length > 0 ? ` ${bullets.join(", ")}` : "";
16548
+ return `${err.replace(/^\[ERROR\]\s*/, "")}${detail}`.trim();
16549
+ }
16550
+ return lines.length > 0 ? lines[lines.length - 1] : null;
16551
+ }
16552
+ async function ensureCoderabbitInstalled(os64, deps = {}) {
16553
+ if (os64.findInPath("coderabbit")) return { ok: true };
16554
+ if (os64.id === "win32") {
16555
+ return {
16556
+ ok: false,
16557
+ 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
+ };
16559
+ }
16560
+ const prereq = await ensureInstallPrerequisites(os64, deps);
16561
+ if (!prereq.ok) return { ok: false, error: prereq.error };
16562
+ const env = { ...process.env };
16563
+ if (prereq.extraPath.length > 0) {
16564
+ env.PATH = [...prereq.extraPath, process.env.PATH ?? ""].filter(Boolean).join(":");
16565
+ }
16566
+ log.info("coderabbit", "CodeRabbit CLI not found \u2014 installing via the official script");
16567
+ const run = deps.runInstallScript ?? defaultRunInstallScript;
16568
+ const { code, output } = await run(env);
16569
+ if (code !== 0) {
16570
+ const detail = summarizeInstallFailure(output);
16571
+ return {
16572
+ ok: false,
16573
+ error: detail ? `CodeRabbit CLI install failed: ${detail}` : "CodeRabbit CLI install failed \u2014 check this machine's network egress and try again."
16574
+ };
16575
+ }
16159
16576
  os64.augmentPath([`${os64.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
16160
- return os64.findInPath("coderabbit") !== null;
16577
+ if (os64.findInPath("coderabbit") === null) {
16578
+ const detail = summarizeInstallFailure(output);
16579
+ return {
16580
+ ok: false,
16581
+ error: detail ? `CodeRabbit CLI install did not produce a binary: ${detail}` : "CodeRabbit CLI install reported success but no `coderabbit` binary was found on PATH."
16582
+ };
16583
+ }
16584
+ return { ok: true };
16161
16585
  }
16162
16586
 
16163
16587
  // src/agents/coderabbit/link.ts
16164
- var import_node_child_process7 = require("child_process");
16588
+ var import_node_child_process8 = require("child_process");
16165
16589
  var fs23 = __toESM(require("fs"));
16166
16590
  var os21 = __toESM(require("os"));
16167
- var path27 = __toESM(require("path"));
16591
+ var path28 = __toESM(require("path"));
16168
16592
 
16169
16593
  // src/agents/strategy.ts
16170
16594
  function validateNonEmptyCredential(token) {
@@ -16173,7 +16597,7 @@ function validateNonEmptyCredential(token) {
16173
16597
 
16174
16598
  // src/agents/coderabbit/link.ts
16175
16599
  function authPath() {
16176
- return path27.join(os21.homedir(), ".coderabbit", "auth.json");
16600
+ return path28.join(os21.homedir(), ".coderabbit", "auth.json");
16177
16601
  }
16178
16602
  async function extractLocalCoderabbitToken() {
16179
16603
  const file = authPath();
@@ -16195,10 +16619,14 @@ function coderabbitCredentialLocator() {
16195
16619
  function coderabbitLoginLauncher(os64) {
16196
16620
  return {
16197
16621
  async ensureInstalled() {
16198
- return ensureCoderabbitInstalled(os64);
16622
+ const result = await ensureCoderabbitInstalled(os64);
16623
+ if (!result.ok && result.error) console.error(`
16624
+ \u2717 ${result.error}
16625
+ `);
16626
+ return result.ok;
16199
16627
  },
16200
16628
  launch() {
16201
- return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
16629
+ return (0, import_node_child_process8.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
16202
16630
  }
16203
16631
  };
16204
16632
  }
@@ -16251,8 +16679,8 @@ function pickLine(obj) {
16251
16679
  function toHunk(raw, groupSeverity) {
16252
16680
  if (!raw || typeof raw !== "object") return null;
16253
16681
  const o = raw;
16254
- const path89 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
16255
- if (!path89) return null;
16682
+ const path90 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
16683
+ if (!path90) return null;
16256
16684
  const message = asString(
16257
16685
  pick(o, [
16258
16686
  "comment",
@@ -16269,7 +16697,7 @@ function toHunk(raw, groupSeverity) {
16269
16697
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
16270
16698
  const locObj = pick(o, ["location"]) ?? o;
16271
16699
  return {
16272
- path: path89.trim(),
16700
+ path: path90.trim(),
16273
16701
  line: pickLine(o) ?? pickLine(locObj),
16274
16702
  severity,
16275
16703
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -16352,10 +16780,10 @@ function parsePlain(stdout) {
16352
16780
  for (const line of stdout.split(/\r?\n/)) {
16353
16781
  const m = line.match(HUNK_LINE_RE);
16354
16782
  if (!m) continue;
16355
- const [, path89, lineNo, sevToken, message] = m;
16356
- if (!path89 || !lineNo || !message) continue;
16783
+ const [, path90, lineNo, sevToken, message] = m;
16784
+ if (!path90 || !lineNo || !message) continue;
16357
16785
  hunks.push({
16358
- path: path89.trim(),
16786
+ path: path90.trim(),
16359
16787
  line: Number(lineNo),
16360
16788
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
16361
16789
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -16455,7 +16883,7 @@ var CoderabbitRuntimeStrategy = class {
16455
16883
  return new Promise((resolve9, reject) => {
16456
16884
  const stdoutBuf = [];
16457
16885
  const stderrBuf = [];
16458
- const proc = (0, import_node_child_process8.spawn)(launch.cmd, launch.args, {
16886
+ const proc = (0, import_node_child_process9.spawn)(launch.cmd, launch.args, {
16459
16887
  env: { ...process.env, ...launch.env ?? {} },
16460
16888
  stdio: ["ignore", "pipe", "pipe"]
16461
16889
  });
@@ -16520,37 +16948,37 @@ CodeRabbit review timed out after ${Math.round(
16520
16948
  // src/agents/cursor/history.ts
16521
16949
  var fs24 = __toESM(require("fs"));
16522
16950
  var os22 = __toESM(require("os"));
16523
- var path28 = __toESM(require("path"));
16951
+ var path29 = __toESM(require("path"));
16524
16952
  var import_node_crypto5 = require("crypto");
16525
- var HISTORY_ROOT = path28.join(os22.homedir(), ".cursor", "projects");
16526
- var CURSOR_HOME = path28.join(os22.homedir(), ".cursor");
16953
+ var HISTORY_ROOT = path29.join(os22.homedir(), ".cursor", "projects");
16954
+ var CURSOR_HOME = path29.join(os22.homedir(), ".cursor");
16527
16955
  var STORE_FILES = ["store.db", "store.db-wal", "store.db-shm"];
16528
16956
  function acpSessionDir(sessionId) {
16529
- return path28.join(CURSOR_HOME, "acp-sessions", sessionId);
16957
+ return path29.join(CURSOR_HOME, "acp-sessions", sessionId);
16530
16958
  }
16531
16959
  function nativeStoreDir(cwd, sessionId) {
16532
- const chatsRoot = path28.join(CURSOR_HOME, "chats");
16960
+ const chatsRoot = path29.join(CURSOR_HOME, "chats");
16533
16961
  let buckets = [];
16534
16962
  try {
16535
16963
  buckets = fs24.readdirSync(chatsRoot);
16536
16964
  } catch {
16537
16965
  }
16538
16966
  for (const b of buckets) {
16539
- const candidate = path28.join(chatsRoot, b, sessionId);
16540
- if (fs24.existsSync(path28.join(candidate, "store.db"))) return candidate;
16967
+ const candidate = path29.join(chatsRoot, b, sessionId);
16968
+ if (fs24.existsSync(path29.join(candidate, "store.db"))) return candidate;
16541
16969
  }
16542
- const computed = path28.join(chatsRoot, (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
16970
+ const computed = path29.join(chatsRoot, (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
16543
16971
  return fs24.existsSync(computed) ? computed : null;
16544
16972
  }
16545
16973
  function copyStoreFiles(srcDir, dstDir) {
16546
16974
  fs24.mkdirSync(dstDir, { recursive: true });
16547
16975
  for (const f of STORE_FILES) {
16548
- const dst = path28.join(dstDir, f);
16976
+ const dst = path29.join(dstDir, f);
16549
16977
  if (fs24.existsSync(dst)) fs24.rmSync(dst, { force: true });
16550
16978
  }
16551
16979
  for (const f of STORE_FILES) {
16552
- const src = path28.join(srcDir, f);
16553
- if (fs24.existsSync(src)) fs24.copyFileSync(src, path28.join(dstDir, f));
16980
+ const src = path29.join(srcDir, f);
16981
+ if (fs24.existsSync(src)) fs24.copyFileSync(src, path29.join(dstDir, f));
16554
16982
  }
16555
16983
  }
16556
16984
  function bridgeNativeToAcp(cwd, sessionId) {
@@ -16563,7 +16991,7 @@ function bridgeNativeToAcp(cwd, sessionId) {
16563
16991
  const dst = acpSessionDir(sessionId);
16564
16992
  copyStoreFiles(src, dst);
16565
16993
  fs24.writeFileSync(
16566
- path28.join(dst, "meta.json"),
16994
+ path29.join(dst, "meta.json"),
16567
16995
  JSON.stringify({ schemaVersion: 1, cwd })
16568
16996
  );
16569
16997
  log.info("cursor", `baton bridge native\u2192acp ok (${sessionId.slice(0, 8)})`);
@@ -16574,11 +17002,11 @@ function bridgeNativeToAcp(cwd, sessionId) {
16574
17002
  function bridgeAcpToNative(cwd, sessionId) {
16575
17003
  try {
16576
17004
  const src = acpSessionDir(sessionId);
16577
- if (!fs24.existsSync(path28.join(src, "store.db"))) {
17005
+ if (!fs24.existsSync(path29.join(src, "store.db"))) {
16578
17006
  log.warn("cursor", `baton bridge: no acp store for ${sessionId.slice(0, 8)} \u2014 skip`);
16579
17007
  return;
16580
17008
  }
16581
- const dst = nativeStoreDir(cwd, sessionId) ?? path28.join(CURSOR_HOME, "chats", (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
17009
+ const dst = nativeStoreDir(cwd, sessionId) ?? path29.join(CURSOR_HOME, "chats", (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
16582
17010
  copyStoreFiles(src, dst);
16583
17011
  log.info("cursor", `baton bridge acp\u2192native ok (${sessionId.slice(0, 8)})`);
16584
17012
  } catch (err) {
@@ -16589,8 +17017,8 @@ function encodeCursorCwd(cwd) {
16589
17017
  return cwd.replace(/^[/\\]+/, "").replace(/[/\\:]/g, "-");
16590
17018
  }
16591
17019
  function resolveHistoryFile3(cwd, sessionId, root = HISTORY_ROOT) {
16592
- const rel = path28.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
16593
- const primary = path28.join(root, encodeCursorCwd(cwd), rel);
17020
+ const rel = path29.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
17021
+ const primary = path29.join(root, encodeCursorCwd(cwd), rel);
16594
17022
  if (fs24.existsSync(primary)) return primary;
16595
17023
  let entries;
16596
17024
  try {
@@ -16600,14 +17028,14 @@ function resolveHistoryFile3(cwd, sessionId, root = HISTORY_ROOT) {
16600
17028
  }
16601
17029
  for (const e of entries) {
16602
17030
  if (!e.isDirectory()) continue;
16603
- const candidate = path28.join(root, e.name, rel);
17031
+ const candidate = path29.join(root, e.name, rel);
16604
17032
  if (fs24.existsSync(candidate)) return candidate;
16605
17033
  }
16606
17034
  return null;
16607
17035
  }
16608
17036
  function resolveHistoryDir3(cwd) {
16609
17037
  if (!fs24.existsSync(HISTORY_ROOT)) return null;
16610
- const dir = path28.join(HISTORY_ROOT, encodeCursorCwd(cwd));
17038
+ const dir = path29.join(HISTORY_ROOT, encodeCursorCwd(cwd));
16611
17039
  return fs24.existsSync(dir) ? dir : null;
16612
17040
  }
16613
17041
  function extractText2(content) {
@@ -16656,14 +17084,14 @@ function getCurrentUsage3(_historyDir) {
16656
17084
  }
16657
17085
 
16658
17086
  // src/agents/cursor/link.ts
16659
- var import_node_child_process9 = require("child_process");
17087
+ var import_node_child_process10 = require("child_process");
16660
17088
 
16661
17089
  // src/agents/cursor/local-token.ts
16662
17090
  var fs25 = __toESM(require("fs"));
16663
17091
  var os23 = __toESM(require("os"));
16664
- var path29 = __toESM(require("path"));
17092
+ var path30 = __toESM(require("path"));
16665
17093
  function cursorCredentialsPath() {
16666
- return path29.join(os23.homedir(), ".cursor", "auth.json");
17094
+ return path30.join(os23.homedir(), ".cursor", "auth.json");
16667
17095
  }
16668
17096
  async function extractLocalCursorToken() {
16669
17097
  const file = cursorCredentialsPath();
@@ -16697,7 +17125,7 @@ function cursorLoginLauncher(os64) {
16697
17125
  return false;
16698
17126
  },
16699
17127
  launch() {
16700
- return (0, import_node_child_process9.spawn)("cursor-agent", ["login"], { stdio: "inherit" });
17128
+ return (0, import_node_child_process10.spawn)("cursor-agent", ["login"], { stdio: "inherit" });
16701
17129
  }
16702
17130
  };
16703
17131
  }
@@ -16741,7 +17169,7 @@ function detectCursorSelector(lines) {
16741
17169
  }
16742
17170
 
16743
17171
  // src/agents/cursor/runtime.ts
16744
- var import_node_child_process10 = require("child_process");
17172
+ var import_node_child_process11 = require("child_process");
16745
17173
  var UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
16746
17174
  var CURSOR_CONTEXT_WINDOW = 2e5;
16747
17175
  var CURSOR_MODELS = [
@@ -16789,7 +17217,7 @@ var CursorRuntimeStrategy = class {
16789
17217
  mintChatId(binary) {
16790
17218
  try {
16791
17219
  const launch = this.os.buildLaunch(binary, ["create-chat"]);
16792
- const r = (0, import_node_child_process10.spawnSync)(launch.cmd, launch.args, {
17220
+ const r = (0, import_node_child_process11.spawnSync)(launch.cmd, launch.args, {
16793
17221
  encoding: "utf8",
16794
17222
  timeout: 2e4,
16795
17223
  stdio: ["ignore", "pipe", "pipe"]
@@ -16912,10 +17340,10 @@ var CursorRuntimeStrategy = class {
16912
17340
 
16913
17341
  // src/agents/aider/history.ts
16914
17342
  var fs26 = __toESM(require("fs"));
16915
- var path30 = __toESM(require("path"));
17343
+ var path31 = __toESM(require("path"));
16916
17344
  var AIDER_HISTORY_FILE = ".aider.chat.history.md";
16917
17345
  function resolveHistoryDir4(cwd) {
16918
- const candidate = path30.join(cwd, AIDER_HISTORY_FILE);
17346
+ const candidate = path31.join(cwd, AIDER_HISTORY_FILE);
16919
17347
  return fs26.existsSync(candidate) ? cwd : null;
16920
17348
  }
16921
17349
  function parseHistoryFile4(_filePath) {
@@ -16926,13 +17354,13 @@ function getCurrentUsage4(_historyDir) {
16926
17354
  }
16927
17355
 
16928
17356
  // src/agents/aider/link.ts
16929
- var import_node_child_process11 = require("child_process");
17357
+ var import_node_child_process12 = require("child_process");
16930
17358
 
16931
17359
  // src/agents/aider/local-token.ts
16932
17360
  var fs27 = __toESM(require("fs"));
16933
17361
  var os24 = __toESM(require("os"));
16934
- var path31 = __toESM(require("path"));
16935
- var AIDER_CONF_FILE = path31.join(os24.homedir(), ".aider.conf.yml");
17362
+ var path32 = __toESM(require("path"));
17363
+ var AIDER_CONF_FILE = path32.join(os24.homedir(), ".aider.conf.yml");
16936
17364
  var API_KEY_ENV_VARS = [
16937
17365
  "ANTHROPIC_API_KEY",
16938
17366
  "OPENAI_API_KEY",
@@ -16984,7 +17412,7 @@ function aiderLoginLauncher(os64) {
16984
17412
  console.error(
16985
17413
  "\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"
16986
17414
  );
16987
- return (0, import_node_child_process11.spawn)(os64.id === "win32" ? "cmd.exe" : "sh", os64.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
17415
+ return (0, import_node_child_process12.spawn)(os64.id === "win32" ? "cmd.exe" : "sh", os64.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
16988
17416
  stdio: "ignore"
16989
17417
  });
16990
17418
  }
@@ -17128,14 +17556,14 @@ var AiderRuntimeStrategy = class {
17128
17556
  var import_node_crypto6 = require("crypto");
17129
17557
 
17130
17558
  // src/agents/gemini/link.ts
17131
- var import_node_child_process12 = require("child_process");
17559
+ var import_node_child_process13 = require("child_process");
17132
17560
 
17133
17561
  // src/agents/gemini/local-token.ts
17134
17562
  var fs28 = __toESM(require("fs"));
17135
17563
  var os25 = __toESM(require("os"));
17136
- var path32 = __toESM(require("path"));
17564
+ var path33 = __toESM(require("path"));
17137
17565
  function geminiCredentialsPath() {
17138
- return path32.join(os25.homedir(), ".gemini", "oauth_creds.json");
17566
+ return path33.join(os25.homedir(), ".gemini", "oauth_creds.json");
17139
17567
  }
17140
17568
  function geminiCredentialsPaths() {
17141
17569
  return [geminiCredentialsPath()];
@@ -17193,7 +17621,7 @@ function geminiLoginLauncher() {
17193
17621
  return os64.findInPath("gemini") !== null;
17194
17622
  },
17195
17623
  launch() {
17196
- return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
17624
+ return (0, import_node_child_process13.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
17197
17625
  }
17198
17626
  };
17199
17627
  }
@@ -17201,12 +17629,12 @@ function geminiLoginLauncher() {
17201
17629
  // src/agents/gemini/history.ts
17202
17630
  var fs29 = __toESM(require("fs"));
17203
17631
  var os26 = __toESM(require("os"));
17204
- var path33 = __toESM(require("path"));
17205
- var GEMINI_ROOT = path33.join(os26.homedir(), ".gemini");
17632
+ var path34 = __toESM(require("path"));
17633
+ var GEMINI_ROOT = path34.join(os26.homedir(), ".gemini");
17206
17634
  function projectNameForCwd(cwd, root) {
17207
17635
  try {
17208
17636
  const parsed = JSON.parse(
17209
- fs29.readFileSync(path33.join(root, "projects.json"), "utf8")
17637
+ fs29.readFileSync(path34.join(root, "projects.json"), "utf8")
17210
17638
  );
17211
17639
  const map = parsed.projects;
17212
17640
  if (map && typeof map === "object") {
@@ -17221,7 +17649,7 @@ function projectNameForCwd(cwd, root) {
17221
17649
  } catch (err) {
17222
17650
  log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
17223
17651
  }
17224
- return path33.basename(cwd) || null;
17652
+ return path34.basename(cwd) || null;
17225
17653
  }
17226
17654
  function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17227
17655
  const name = projectNameForCwd(cwd, root);
@@ -17229,7 +17657,7 @@ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17229
17657
  log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
17230
17658
  return null;
17231
17659
  }
17232
- const dir = path33.join(root, "tmp", name, "chats");
17660
+ const dir = path34.join(root, "tmp", name, "chats");
17233
17661
  if (!fs29.existsSync(dir)) {
17234
17662
  log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
17235
17663
  return null;
@@ -17254,10 +17682,10 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17254
17682
  const byName = files.find((f) => id8.length > 0 && f.includes(id8));
17255
17683
  if (byName) {
17256
17684
  log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
17257
- return path33.join(dir, byName);
17685
+ return path34.join(dir, byName);
17258
17686
  }
17259
17687
  for (const f of files) {
17260
- const full = path33.join(dir, f);
17688
+ const full = path34.join(dir, f);
17261
17689
  try {
17262
17690
  const firstLine = fs29.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
17263
17691
  const hdr = JSON.parse(firstLine);
@@ -17272,7 +17700,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17272
17700
  let newest = null;
17273
17701
  for (const f of files) {
17274
17702
  try {
17275
- const mtime = fs29.statSync(path33.join(dir, f)).mtimeMs;
17703
+ const mtime = fs29.statSync(path34.join(dir, f)).mtimeMs;
17276
17704
  if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
17277
17705
  } catch {
17278
17706
  }
@@ -17281,7 +17709,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17281
17709
  "gemini",
17282
17710
  `resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
17283
17711
  );
17284
- return newest ? path33.join(dir, newest.file) : null;
17712
+ return newest ? path34.join(dir, newest.file) : null;
17285
17713
  }
17286
17714
  function extractGeminiText(content) {
17287
17715
  const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
@@ -17350,7 +17778,7 @@ function parseHistoryFile5(filePath) {
17350
17778
  }
17351
17779
  log.trace(
17352
17780
  "gemini",
17353
- `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path33.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
17781
+ `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path34.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
17354
17782
  );
17355
17783
  return out2;
17356
17784
  }
@@ -17489,39 +17917,39 @@ var GeminiRuntimeStrategy = class {
17489
17917
  };
17490
17918
 
17491
17919
  // src/agents/kimi/runtime.ts
17492
- var import_node_child_process13 = require("child_process");
17920
+ var import_node_child_process14 = require("child_process");
17493
17921
  var import_node_os3 = require("os");
17494
17922
  var import_node_path4 = require("path");
17495
17923
 
17496
17924
  // src/agents/kimi/history.ts
17497
17925
  var fs30 = __toESM(require("fs"));
17498
17926
  var os27 = __toESM(require("os"));
17499
- var path34 = __toESM(require("path"));
17927
+ var path35 = __toESM(require("path"));
17500
17928
  var import_node_crypto7 = require("crypto");
17501
17929
  function kimiHome() {
17502
- return process.env.KIMI_CODE_HOME || path34.join(os27.homedir(), ".kimi-code");
17930
+ return process.env.KIMI_CODE_HOME || path35.join(os27.homedir(), ".kimi-code");
17503
17931
  }
17504
17932
  function workDirKey(cwd) {
17505
17933
  const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
17506
- return `wd_${path34.basename(cwd)}_${hash}`;
17934
+ return `wd_${path35.basename(cwd)}_${hash}`;
17507
17935
  }
17508
17936
  function resolveHistoryDir6(cwd) {
17509
- const dir = path34.join(kimiHome(), "sessions", workDirKey(cwd));
17937
+ const dir = path35.join(kimiHome(), "sessions", workDirKey(cwd));
17510
17938
  if (!fs30.existsSync(dir)) {
17511
17939
  log.debug("kimi", `resolveHistoryDir \u2014 session bucket not present yet: ${dir}`);
17512
17940
  return null;
17513
17941
  }
17514
17942
  return dir;
17515
17943
  }
17516
- var WIRE_REL = path34.join("agents", "main", "wire.jsonl");
17944
+ var WIRE_REL = path35.join("agents", "main", "wire.jsonl");
17517
17945
  function resolveHistoryFile5(cwd, sessionId) {
17518
17946
  const fromIndex = sessionDirFromIndex(sessionId);
17519
17947
  if (fromIndex) {
17520
- const p2 = path34.join(fromIndex, WIRE_REL);
17948
+ const p2 = path35.join(fromIndex, WIRE_REL);
17521
17949
  if (fs30.existsSync(p2)) return p2;
17522
17950
  }
17523
- const bucket2 = path34.join(kimiHome(), "sessions", workDirKey(cwd));
17524
- const computed = path34.join(bucket2, sessionId, WIRE_REL);
17951
+ const bucket2 = path35.join(kimiHome(), "sessions", workDirKey(cwd));
17952
+ const computed = path35.join(bucket2, sessionId, WIRE_REL);
17525
17953
  if (fs30.existsSync(computed)) return computed;
17526
17954
  const scanned = scanBucketsForSession(sessionId);
17527
17955
  if (scanned) return scanned;
@@ -17529,7 +17957,7 @@ function resolveHistoryFile5(cwd, sessionId) {
17529
17957
  }
17530
17958
  function sessionDirFromIndex(sessionId) {
17531
17959
  try {
17532
- const raw = fs30.readFileSync(path34.join(kimiHome(), "session_index.jsonl"), "utf8");
17960
+ const raw = fs30.readFileSync(path35.join(kimiHome(), "session_index.jsonl"), "utf8");
17533
17961
  for (const line of raw.split("\n")) {
17534
17962
  if (!line.includes(sessionId)) continue;
17535
17963
  try {
@@ -17545,7 +17973,7 @@ function sessionDirFromIndex(sessionId) {
17545
17973
  return null;
17546
17974
  }
17547
17975
  function scanBucketsForSession(sessionId) {
17548
- const sessionsRoot = path34.join(kimiHome(), "sessions");
17976
+ const sessionsRoot = path35.join(kimiHome(), "sessions");
17549
17977
  let buckets;
17550
17978
  try {
17551
17979
  buckets = fs30.readdirSync(sessionsRoot, { withFileTypes: true });
@@ -17554,13 +17982,13 @@ function scanBucketsForSession(sessionId) {
17554
17982
  }
17555
17983
  for (const b of buckets) {
17556
17984
  if (!b.isDirectory()) continue;
17557
- const candidate = path34.join(sessionsRoot, b.name, sessionId, WIRE_REL);
17985
+ const candidate = path35.join(sessionsRoot, b.name, sessionId, WIRE_REL);
17558
17986
  if (fs30.existsSync(candidate)) return candidate;
17559
17987
  }
17560
17988
  return null;
17561
17989
  }
17562
17990
  async function discoverSessionId2(cwd, opts) {
17563
- const bucket2 = path34.join(kimiHome(), "sessions", workDirKey(cwd));
17991
+ const bucket2 = path35.join(kimiHome(), "sessions", workDirKey(cwd));
17564
17992
  const floor = opts.sinceMs - 2e3;
17565
17993
  const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
17566
17994
  for (; ; ) {
@@ -17583,7 +18011,7 @@ function newestSessionSince(bucket2, floorMs) {
17583
18011
  if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
17584
18012
  let mtime;
17585
18013
  try {
17586
- mtime = fs30.statSync(path34.join(bucket2, e.name)).mtimeMs;
18014
+ mtime = fs30.statSync(path35.join(bucket2, e.name)).mtimeMs;
17587
18015
  } catch {
17588
18016
  continue;
17589
18017
  }
@@ -17778,14 +18206,14 @@ var KimiRuntimeStrategy = class {
17778
18206
  return createOsStrategy().findInPath("kimi") !== null;
17779
18207
  },
17780
18208
  launch() {
17781
- return (0, import_node_child_process13.spawn)("kimi", [], { stdio: "inherit" });
18209
+ return (0, import_node_child_process14.spawn)("kimi", [], { stdio: "inherit" });
17782
18210
  }
17783
18211
  };
17784
18212
  }
17785
18213
  };
17786
18214
 
17787
18215
  // src/agents/opencode/runtime.ts
17788
- var import_node_child_process14 = require("child_process");
18216
+ var import_node_child_process15 = require("child_process");
17789
18217
 
17790
18218
  // src/agents/opencode/local-token.ts
17791
18219
  var API_KEY_ENV_VARS2 = [
@@ -17892,7 +18320,7 @@ var OpencodeRuntimeStrategy = class {
17892
18320
  return createOsStrategy().findInPath("opencode") !== null;
17893
18321
  },
17894
18322
  launch() {
17895
- return (0, import_node_child_process14.spawn)("opencode", ["auth", "login"], { stdio: "inherit" });
18323
+ return (0, import_node_child_process15.spawn)("opencode", ["auth", "login"], { stdio: "inherit" });
17896
18324
  }
17897
18325
  };
17898
18326
  }
@@ -17982,7 +18410,7 @@ function parseLinkArgs(args2) {
17982
18410
  if (apiKeyFileArg) {
17983
18411
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
17984
18412
  try {
17985
- apiKey = fs31.readFileSync(path35.resolve(filePath), "utf8").trim();
18413
+ apiKey = fs31.readFileSync(path36.resolve(filePath), "utf8").trim();
17986
18414
  } catch (err) {
17987
18415
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
17988
18416
  }
@@ -18109,7 +18537,7 @@ async function link(args2 = []) {
18109
18537
  return;
18110
18538
  }
18111
18539
  if (parsed.tokenFile) {
18112
- const credential = fs31.readFileSync(path35.resolve(parsed.tokenFile), "utf8").trim();
18540
+ const credential = fs31.readFileSync(path36.resolve(parsed.tokenFile), "utf8").trim();
18113
18541
  if (!credential) {
18114
18542
  showError(`--token-file ${parsed.tokenFile} is empty.`);
18115
18543
  process.exit(1);
@@ -18326,16 +18754,15 @@ async function linkDryRunPreflight(ctx) {
18326
18754
  }
18327
18755
 
18328
18756
  // src/agents/coderabbit/configure.ts
18329
- var import_node_child_process16 = require("child_process");
18330
- var import_node_os4 = require("os");
18331
- var import_node_fs5 = require("fs");
18332
- var path37 = __toESM(require("path"));
18757
+ var import_node_child_process17 = require("child_process");
18758
+ var import_node_fs6 = require("fs");
18759
+ var path38 = __toESM(require("path"));
18333
18760
 
18334
18761
  // src/agents/coderabbit/oauth.ts
18335
- var import_node_child_process15 = require("child_process");
18762
+ var import_node_child_process16 = require("child_process");
18336
18763
  var fs32 = __toESM(require("fs"));
18337
18764
  var os28 = __toESM(require("os"));
18338
- var path36 = __toESM(require("path"));
18765
+ var path37 = __toESM(require("path"));
18339
18766
  function parseCoderabbitAuthEvent(line) {
18340
18767
  const l = line.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "").trim();
18341
18768
  if (!l || l[0] !== "{") return null;
@@ -18374,7 +18801,7 @@ function parseCoderabbitAuthEvent(line) {
18374
18801
  function resolvePython() {
18375
18802
  for (const bin of ["python3", "python"]) {
18376
18803
  try {
18377
- const r = (0, import_node_child_process15.spawnSync)(bin, ["--version"], { stdio: "ignore", timeout: 4e3 });
18804
+ const r = (0, import_node_child_process16.spawnSync)(bin, ["--version"], { stdio: "ignore", timeout: 4e3 });
18378
18805
  if (!r.error && r.status === 0) return bin;
18379
18806
  } catch {
18380
18807
  }
@@ -18384,15 +18811,15 @@ function resolvePython() {
18384
18811
  function spawnCoderabbitLoginProc(cmd, args2) {
18385
18812
  const python = resolvePython();
18386
18813
  if (python) {
18387
- const helper = path36.join(os28.tmpdir(), "codeam-cr-pty.py");
18814
+ const helper = path37.join(os28.tmpdir(), "codeam-cr-pty.py");
18388
18815
  fs32.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
18389
- return (0, import_node_child_process15.spawn)(python, [helper, cmd, ...args2], {
18816
+ return (0, import_node_child_process16.spawn)(python, [helper, cmd, ...args2], {
18390
18817
  stdio: ["pipe", "pipe", "pipe"],
18391
18818
  env: { ...process.env, TERM: "xterm-256color", COLUMNS: "220", LINES: "50" },
18392
18819
  shell: false
18393
18820
  });
18394
18821
  }
18395
- return (0, import_node_child_process15.spawn)(cmd, args2, { stdio: ["pipe", "pipe", "pipe"], shell: false });
18822
+ return (0, import_node_child_process16.spawn)(cmd, args2, { stdio: ["pipe", "pipe", "pipe"], shell: false });
18396
18823
  }
18397
18824
  var pendingCoderabbitLogin = null;
18398
18825
  function setPendingCoderabbitLogin(handle) {
@@ -18496,7 +18923,7 @@ function runCoderabbitOAuthLogin(deps) {
18496
18923
  });
18497
18924
  }
18498
18925
  function coderabbitDir(home) {
18499
- return path36.join(home ?? os28.homedir(), ".coderabbit");
18926
+ return path37.join(home ?? os28.homedir(), ".coderabbit");
18500
18927
  }
18501
18928
  var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
18502
18929
  function snapshotCredentialDir(home) {
@@ -18511,7 +18938,7 @@ function snapshotCredentialDir(home) {
18511
18938
  for (const e of entries) {
18512
18939
  if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
18513
18940
  try {
18514
- const st3 = fs32.statSync(path36.join(dir, e.name));
18941
+ const st3 = fs32.statSync(path37.join(dir, e.name));
18515
18942
  snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
18516
18943
  } catch {
18517
18944
  }
@@ -18529,7 +18956,7 @@ function diffCapturedCredential(before, home) {
18529
18956
  }
18530
18957
  if (!best) return null;
18531
18958
  try {
18532
- return { file: best.file, contents: fs32.readFileSync(path36.join(dir, best.file), "utf8") };
18959
+ return { file: best.file, contents: fs32.readFileSync(path37.join(dir, best.file), "utf8") };
18533
18960
  } catch {
18534
18961
  return null;
18535
18962
  }
@@ -18537,7 +18964,7 @@ function diffCapturedCredential(before, home) {
18537
18964
 
18538
18965
  // src/agents/coderabbit/configure.ts
18539
18966
  function defaultIsLoggedIn() {
18540
- const r = (0, import_node_child_process16.spawnSync)("coderabbit", ["auth", "status", "--agent"], {
18967
+ const r = (0, import_node_child_process17.spawnSync)("coderabbit", ["auth", "status", "--agent"], {
18541
18968
  encoding: "utf8",
18542
18969
  timeout: 15e3
18543
18970
  });
@@ -18555,7 +18982,7 @@ function defaultIsLoggedIn() {
18555
18982
  return false;
18556
18983
  }
18557
18984
  function defaultLoginWithApiKey(key) {
18558
- const r = (0, import_node_child_process16.spawnSync)("coderabbit", ["auth", "login", "--api-key", key], {
18985
+ const r = (0, import_node_child_process17.spawnSync)("coderabbit", ["auth", "login", "--api-key", key], {
18559
18986
  encoding: "utf8",
18560
18987
  timeout: 3e4
18561
18988
  });
@@ -18569,7 +18996,7 @@ function defaultLoginWithApiKey(key) {
18569
18996
  function collectChangedFiles(cwd) {
18570
18997
  const run = (args2) => {
18571
18998
  try {
18572
- const r = (0, import_node_child_process16.spawnSync)("git", args2, { cwd, encoding: "utf8", timeout: 1e4 });
18999
+ const r = (0, import_node_child_process17.spawnSync)("git", args2, { cwd, encoding: "utf8", timeout: 1e4 });
18573
19000
  return r.status === 0 && typeof r.stdout === "string" ? r.stdout : "";
18574
19001
  } catch {
18575
19002
  return "";
@@ -18605,22 +19032,25 @@ function collectChangedFiles(cwd) {
18605
19032
  }
18606
19033
  return [...byPath.values()];
18607
19034
  }
18608
- function restoreCoderabbitOauthBlob(value) {
18609
- const dir = path37.join((0, import_node_os4.homedir)(), ".coderabbit");
18610
- (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
19035
+ function restoreCoderabbitOauthBlob(os64, value) {
19036
+ const dir = path38.join(os64.homeDir(), ".coderabbit");
19037
+ (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
18611
19038
  let file = "auth.json";
18612
19039
  let contents = value.trim();
18613
19040
  if (contents.startsWith("{")) {
18614
19041
  try {
18615
19042
  const parsed = JSON.parse(contents);
18616
19043
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
18617
- file = path37.basename(parsed.file);
19044
+ file = path38.basename(parsed.file);
18618
19045
  contents = parsed.contents;
18619
19046
  }
18620
19047
  } catch {
18621
19048
  }
18622
19049
  }
18623
- (0, import_node_fs5.writeFileSync)(path37.join(dir, file), contents, { mode: 384 });
19050
+ (0, import_node_fs6.writeFileSync)(path38.join(dir, file), contents, { mode: 384 });
19051
+ }
19052
+ function installFailureMessage(result) {
19053
+ return result.error ?? "CodeRabbit CLI could not be installed";
18624
19054
  }
18625
19055
  async function configureCoderabbit(input, deps = {}) {
18626
19056
  const os64 = deps.os ?? createOsStrategy();
@@ -18633,10 +19063,10 @@ async function configureCoderabbit(input, deps = {}) {
18633
19063
  const home = os64.homeDir();
18634
19064
  os64.augmentPath(
18635
19065
  os64.id === "win32" ? [
18636
- path37.join(home, ".local", "bin"),
18637
- path37.join(process.env.APPDATA ?? path37.join(home, "AppData", "Roaming"), "npm"),
18638
- path37.join(home, "scoop", "shims")
18639
- ] : [path37.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
19066
+ path38.join(home, ".local", "bin"),
19067
+ path38.join(process.env.APPDATA ?? path38.join(home, "AppData", "Roaming"), "npm"),
19068
+ path38.join(home, "scoop", "shims")
19069
+ ] : [path38.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
18640
19070
  );
18641
19071
  const installed2 = os64.findInPath("coderabbit") !== null;
18642
19072
  const base = () => ({
@@ -18656,9 +19086,9 @@ async function configureCoderabbit(input, deps = {}) {
18656
19086
  const key = (input.apiKey ?? "").trim();
18657
19087
  if (!key) return { ...res2, error: "No API key provided" };
18658
19088
  if (!res2.installed) {
18659
- const ok = await ensureInstalled(os64);
18660
- res2.installed = ok;
18661
- if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
19089
+ const inst = await ensureInstalled(os64);
19090
+ res2.installed = inst.ok;
19091
+ if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
18662
19092
  }
18663
19093
  const login = loginWithApiKey(key);
18664
19094
  if (!login.ok) {
@@ -18680,9 +19110,9 @@ async function configureCoderabbit(input, deps = {}) {
18680
19110
  }
18681
19111
  if (!res2.installed) {
18682
19112
  deps.onEvent?.({ kind: "installing" });
18683
- const ok = await ensureInstalled(os64);
18684
- res2.installed = ok;
18685
- if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
19113
+ const inst = await ensureInstalled(os64);
19114
+ res2.installed = inst.ok;
19115
+ if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
18686
19116
  }
18687
19117
  if (cred.method === "api_key") {
18688
19118
  const login = loginWithApiKey(cred.credential.trim());
@@ -18697,22 +19127,33 @@ async function configureCoderabbit(input, deps = {}) {
18697
19127
  return { ...res2, loggedIn: true, linked: true };
18698
19128
  }
18699
19129
  try {
18700
- restoreCoderabbitOauthBlob(cred.credential);
19130
+ restoreCoderabbitOauthBlob(os64, cred.credential);
18701
19131
  } catch (err) {
18702
19132
  return {
18703
19133
  ...res2,
18704
19134
  error: err instanceof Error ? err.message : "Failed to restore the vaulted credential"
18705
19135
  };
18706
19136
  }
19137
+ if (!isLoggedIn()) {
19138
+ return {
19139
+ ...res2,
19140
+ loggedIn: false,
19141
+ linked: false,
19142
+ // Deliberately phrased as "couldn't confirm", not "is invalid": a
19143
+ // transient `coderabbit auth status` failure is not proof the credential
19144
+ // is dead, and both remedies (retry / re-link) are offered.
19145
+ error: "Your saved CodeRabbit sign-in couldn't be confirmed on this machine \u2014 try again, or sign in with your browser to refresh it."
19146
+ };
19147
+ }
18707
19148
  return { ...res2, loggedIn: true, linked: true };
18708
19149
  }
18709
19150
  if (input.action === "link_oauth") {
18710
19151
  const res2 = base();
18711
19152
  if (!installed2) {
18712
19153
  deps.onEvent?.({ kind: "installing" });
18713
- const ok = await ensureInstalled(os64);
18714
- res2.installed = ok;
18715
- if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
19154
+ const inst = await ensureInstalled(os64);
19155
+ res2.installed = inst.ok;
19156
+ if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
18716
19157
  }
18717
19158
  const before = snapshot();
18718
19159
  const login = await runOAuth({
@@ -18750,9 +19191,9 @@ async function configureCoderabbit(input, deps = {}) {
18750
19191
  }
18751
19192
  const res = base();
18752
19193
  if (!res.installed) {
18753
- const ok = await ensureInstalled(os64);
18754
- res.installed = ok;
18755
- if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
19194
+ const inst = await ensureInstalled(os64);
19195
+ res.installed = inst.ok;
19196
+ if (!inst.ok) return { ...res, error: installFailureMessage(inst) };
18756
19197
  }
18757
19198
  if (!deps.runReview) return { ...res, error: "No reviewer available" };
18758
19199
  const out2 = await deps.runReview(input.review ?? {});
@@ -18778,7 +19219,7 @@ async function configureCoderabbit(input, deps = {}) {
18778
19219
  }
18779
19220
 
18780
19221
  // src/agents/coderabbit/review-pr.ts
18781
- var import_node_child_process17 = require("child_process");
19222
+ var import_node_child_process18 = require("child_process");
18782
19223
  function repoSlug(prRef) {
18783
19224
  return `${prRef.owner}/${prRef.repo}`;
18784
19225
  }
@@ -18912,7 +19353,7 @@ function defaultRunGh(args2) {
18912
19353
  const stderr = [];
18913
19354
  let proc;
18914
19355
  try {
18915
- proc = (0, import_node_child_process17.spawn)("gh", args2, { stdio: ["ignore", "pipe", "pipe"] });
19356
+ proc = (0, import_node_child_process18.spawn)("gh", args2, { stdio: ["ignore", "pipe", "pipe"] });
18916
19357
  } catch (err) {
18917
19358
  resolve9({ code: -1, stdout: "", stderr: err instanceof Error ? err.message : String(err) });
18918
19359
  return;
@@ -18936,17 +19377,17 @@ function defaultRunGh(args2) {
18936
19377
  var import_node_child_process25 = require("child_process");
18937
19378
  var os40 = __toESM(require("os"));
18938
19379
  var fs45 = __toESM(require("fs"));
18939
- var path48 = __toESM(require("path"));
19380
+ var path49 = __toESM(require("path"));
18940
19381
 
18941
19382
  // src/integrations/manifest.ts
18942
- var import_node_fs7 = __toESM(require("fs"));
18943
- var import_node_os6 = __toESM(require("os"));
19383
+ var import_node_fs8 = __toESM(require("fs"));
19384
+ var import_node_os5 = __toESM(require("os"));
18944
19385
  var import_node_path5 = __toESM(require("path"));
18945
19386
 
18946
19387
  // src/lib/restrict-to-owner.ts
18947
- var import_node_fs6 = __toESM(require("fs"));
18948
- var import_node_os5 = __toESM(require("os"));
18949
- var import_node_child_process18 = require("child_process");
19388
+ var import_node_fs7 = __toESM(require("fs"));
19389
+ var import_node_os4 = __toESM(require("os"));
19390
+ var import_node_child_process19 = require("child_process");
18950
19391
  var BROAD_WINDOWS_SIDS = [
18951
19392
  "*S-1-1-0",
18952
19393
  "*S-1-5-11",
@@ -18957,8 +19398,8 @@ var BROAD_WINDOWS_SIDS = [
18957
19398
  function restrictToOwner(filePath) {
18958
19399
  try {
18959
19400
  if (process.platform === "win32") {
18960
- const username = import_node_os5.default.userInfo().username;
18961
- (0, import_node_child_process18.execFileSync)(
19401
+ const username = import_node_os4.default.userInfo().username;
19402
+ (0, import_node_child_process19.execFileSync)(
18962
19403
  "icacls",
18963
19404
  [
18964
19405
  filePath,
@@ -18970,7 +19411,7 @@ function restrictToOwner(filePath) {
18970
19411
  { stdio: "ignore" }
18971
19412
  );
18972
19413
  } else {
18973
- import_node_fs6.default.chmodSync(filePath, 384);
19414
+ import_node_fs7.default.chmodSync(filePath, 384);
18974
19415
  }
18975
19416
  } catch {
18976
19417
  }
@@ -18978,11 +19419,11 @@ function restrictToOwner(filePath) {
18978
19419
 
18979
19420
  // src/integrations/manifest.ts
18980
19421
  function integrationsManifestPath() {
18981
- return import_node_path5.default.join(import_node_os6.default.homedir(), ".codeam", "integrations.json");
19422
+ return import_node_path5.default.join(import_node_os5.default.homedir(), ".codeam", "integrations.json");
18982
19423
  }
18983
19424
  function readIntegrationsManifest() {
18984
19425
  try {
18985
- const raw = JSON.parse(import_node_fs7.default.readFileSync(integrationsManifestPath(), "utf8"));
19426
+ const raw = JSON.parse(import_node_fs8.default.readFileSync(integrationsManifestPath(), "utf8"));
18986
19427
  if (!Array.isArray(raw?.integrations)) return null;
18987
19428
  return raw;
18988
19429
  } catch {
@@ -18992,10 +19433,10 @@ function readIntegrationsManifest() {
18992
19433
  function persistIntegrationsManifest(m) {
18993
19434
  try {
18994
19435
  const file = integrationsManifestPath();
18995
- import_node_fs7.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true, mode: 448 });
19436
+ import_node_fs8.default.mkdirSync(import_node_path5.default.dirname(file), { recursive: true, mode: 448 });
18996
19437
  const tmp = `${file}.tmp-${process.pid}`;
18997
- import_node_fs7.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
18998
- import_node_fs7.default.renameSync(tmp, file);
19438
+ import_node_fs8.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
19439
+ import_node_fs8.default.renameSync(tmp, file);
18999
19440
  restrictToOwner(file);
19000
19441
  } catch (err) {
19001
19442
  log.warn(
@@ -19006,21 +19447,21 @@ function persistIntegrationsManifest(m) {
19006
19447
  }
19007
19448
  function clearIntegrationsManifest() {
19008
19449
  try {
19009
- import_node_fs7.default.rmSync(integrationsManifestPath(), { force: true });
19450
+ import_node_fs8.default.rmSync(integrationsManifestPath(), { force: true });
19010
19451
  } catch {
19011
19452
  }
19012
19453
  }
19013
19454
 
19014
19455
  // src/skills/manifest.ts
19015
- var import_node_fs8 = __toESM(require("fs"));
19016
- var import_node_os7 = __toESM(require("os"));
19456
+ var import_node_fs9 = __toESM(require("fs"));
19457
+ var import_node_os6 = __toESM(require("os"));
19017
19458
  var import_node_path6 = __toESM(require("path"));
19018
19459
  function skillsManifestPath() {
19019
- return import_node_path6.default.join(import_node_os7.default.homedir(), ".codeam", "skills.json");
19460
+ return import_node_path6.default.join(import_node_os6.default.homedir(), ".codeam", "skills.json");
19020
19461
  }
19021
19462
  function readSkillsManifest() {
19022
19463
  try {
19023
- const raw = JSON.parse(import_node_fs8.default.readFileSync(skillsManifestPath(), "utf8"));
19464
+ const raw = JSON.parse(import_node_fs9.default.readFileSync(skillsManifestPath(), "utf8"));
19024
19465
  if (!Array.isArray(raw?.skills)) return null;
19025
19466
  raw.skills = raw.skills.filter(
19026
19467
  (s) => Boolean(s) && typeof s === "object" && typeof s.id === "string"
@@ -19033,10 +19474,10 @@ function readSkillsManifest() {
19033
19474
  function persistSkillsManifest(m) {
19034
19475
  try {
19035
19476
  const file = skillsManifestPath();
19036
- import_node_fs8.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true, mode: 448 });
19477
+ import_node_fs9.default.mkdirSync(import_node_path6.default.dirname(file), { recursive: true, mode: 448 });
19037
19478
  const tmp = `${file}.tmp-${process.pid}`;
19038
- import_node_fs8.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
19039
- import_node_fs8.default.renameSync(tmp, file);
19479
+ import_node_fs9.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
19480
+ import_node_fs9.default.renameSync(tmp, file);
19040
19481
  restrictToOwner(file);
19041
19482
  } catch (err) {
19042
19483
  log.warn(
@@ -19047,7 +19488,7 @@ function persistSkillsManifest(m) {
19047
19488
  }
19048
19489
  function clearSkillsManifest() {
19049
19490
  try {
19050
- import_node_fs8.default.rmSync(skillsManifestPath(), { force: true });
19491
+ import_node_fs9.default.rmSync(skillsManifestPath(), { force: true });
19051
19492
  } catch {
19052
19493
  }
19053
19494
  }
@@ -19084,7 +19525,7 @@ function describeReason(reason) {
19084
19525
  // src/commands/host/host-client.ts
19085
19526
  var fs36 = __toESM(require("fs"));
19086
19527
  var os32 = __toESM(require("os"));
19087
- var path40 = __toESM(require("path"));
19528
+ var path41 = __toESM(require("path"));
19088
19529
  var import_node_crypto9 = require("crypto");
19089
19530
  function sampleCpuTimes() {
19090
19531
  let idle = 0;
@@ -19132,7 +19573,7 @@ function apiBase() {
19132
19573
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
19133
19574
  }
19134
19575
  function hostIdentityPath() {
19135
- return path40.join(os32.homedir(), ".codeam", "host-agent.json");
19576
+ return path41.join(os32.homedir(), ".codeam", "host-agent.json");
19136
19577
  }
19137
19578
  function collectOsInfo() {
19138
19579
  return {
@@ -19163,7 +19604,7 @@ function loadHostIdentity() {
19163
19604
  }
19164
19605
  function saveHostIdentity(identity) {
19165
19606
  const file = hostIdentityPath();
19166
- fs36.mkdirSync(path40.dirname(file), { recursive: true, mode: 448 });
19607
+ fs36.mkdirSync(path41.dirname(file), { recursive: true, mode: 448 });
19167
19608
  fs36.writeFileSync(file, JSON.stringify(identity, null, 2), {
19168
19609
  encoding: "utf8",
19169
19610
  mode: 384
@@ -19346,15 +19787,15 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
19346
19787
  // src/commands/host/workspace.ts
19347
19788
  var fs37 = __toESM(require("fs"));
19348
19789
  var os33 = __toESM(require("os"));
19349
- var path41 = __toESM(require("path"));
19350
- var import_node_child_process19 = require("child_process");
19790
+ var path42 = __toESM(require("path"));
19791
+ var import_node_child_process20 = require("child_process");
19351
19792
  var import_node_util4 = require("util");
19352
- var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process19.execFile);
19793
+ var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process20.execFile);
19353
19794
  function isAbsolutePathTarget(target) {
19354
- return path41.isAbsolute(target);
19795
+ return path42.isAbsolute(target);
19355
19796
  }
19356
19797
  function selfHostedWorkspaceRoot() {
19357
- return path41.join(os33.homedir(), ".codeam", "self-hosted");
19798
+ return path42.join(os33.homedir(), ".codeam", "self-hosted");
19358
19799
  }
19359
19800
  function nonInteractiveGitEnv() {
19360
19801
  return {
@@ -19424,7 +19865,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
19424
19865
  const isGitlab = provider === "gitlab";
19425
19866
  if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
19426
19867
  if (!cloneToken) return;
19427
- const credFile = path41.join(dest, ".git", "codeam-credentials");
19868
+ const credFile = path42.join(dest, ".git", "codeam-credentials");
19428
19869
  const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
19429
19870
  ` : `https://x-access-token:${cloneToken}@github.com
19430
19871
  `;
@@ -19432,7 +19873,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
19432
19873
  restrictToOwner(credFile);
19433
19874
  const env = nonInteractiveGitEnv();
19434
19875
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
19435
- const credFilePosix = credFile.split(path41.sep).join("/");
19876
+ const credFilePosix = credFile.split(path42.sep).join("/");
19436
19877
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
19437
19878
  });
19438
19879
  await git2([
@@ -19470,8 +19911,8 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
19470
19911
  }
19471
19912
  return repoOrPath;
19472
19913
  }
19473
- const dest = path41.join(selfHostedWorkspaceRoot(), deployId);
19474
- if (fs37.existsSync(path41.join(dest, ".git"))) {
19914
+ const dest = path42.join(selfHostedWorkspaceRoot(), deployId);
19915
+ if (fs37.existsSync(path42.join(dest, ".git"))) {
19475
19916
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
19476
19917
  return dest;
19477
19918
  }
@@ -19495,7 +19936,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
19495
19936
  // src/commands/host/agent-provisioning.ts
19496
19937
  var fs38 = __toESM(require("fs"));
19497
19938
  var os34 = __toESM(require("os"));
19498
- var path42 = __toESM(require("path"));
19939
+ var path43 = __toESM(require("path"));
19499
19940
  var PUBLIC_TO_INTERNAL_AGENT = {
19500
19941
  claude_code: "claude",
19501
19942
  claude: "claude",
@@ -19515,7 +19956,7 @@ function ensureDir(dir) {
19515
19956
  fs38.mkdirSync(dir, { recursive: true, mode: 448 });
19516
19957
  }
19517
19958
  function writeFile0600(filePath, contents) {
19518
- ensureDir(path42.dirname(filePath));
19959
+ ensureDir(path43.dirname(filePath));
19519
19960
  fs38.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
19520
19961
  restrictToOwner(filePath);
19521
19962
  }
@@ -19527,7 +19968,7 @@ function rmIfExists(filePath) {
19527
19968
  }
19528
19969
  var claudeProvisioner = {
19529
19970
  write(auth, home) {
19530
- const credentialsJson = path42.join(home, ".claude", ".credentials.json");
19971
+ const credentialsJson = path43.join(home, ".claude", ".credentials.json");
19531
19972
  if (auth.kind === "api_key") {
19532
19973
  rmIfExists(credentialsJson);
19533
19974
  return { ANTHROPIC_API_KEY: auth.value };
@@ -19539,7 +19980,7 @@ var claudeProvisioner = {
19539
19980
  } else {
19540
19981
  rmIfExists(credentialsJson);
19541
19982
  }
19542
- const claudeJson = path42.join(home, ".claude.json");
19983
+ const claudeJson = path43.join(home, ".claude.json");
19543
19984
  if (!fs38.existsSync(claudeJson)) {
19544
19985
  writeFile0600(
19545
19986
  claudeJson,
@@ -19551,7 +19992,7 @@ var claudeProvisioner = {
19551
19992
  };
19552
19993
  var codexProvisioner = {
19553
19994
  write(auth, home) {
19554
- const authJson = path42.join(home, ".codex", "auth.json");
19995
+ const authJson = path43.join(home, ".codex", "auth.json");
19555
19996
  if (auth.kind === "api_key") {
19556
19997
  rmIfExists(authJson);
19557
19998
  return { OPENAI_API_KEY: auth.value };
@@ -19562,8 +20003,8 @@ var codexProvisioner = {
19562
20003
  };
19563
20004
  var geminiProvisioner = {
19564
20005
  write(auth, home) {
19565
- const settingsJson = path42.join(home, ".gemini", "settings.json");
19566
- const oauthCreds = path42.join(home, ".gemini", "oauth_creds.json");
20006
+ const settingsJson = path43.join(home, ".gemini", "settings.json");
20007
+ const oauthCreds = path43.join(home, ".gemini", "oauth_creds.json");
19567
20008
  if (auth.kind === "api_key") {
19568
20009
  rmIfExists(oauthCreds);
19569
20010
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -19576,7 +20017,7 @@ var geminiProvisioner = {
19576
20017
  };
19577
20018
  var cursorProvisioner = {
19578
20019
  write(auth, home) {
19579
- const authJson = path42.join(home, ".config", "cursor", "auth.json");
20020
+ const authJson = path43.join(home, ".config", "cursor", "auth.json");
19580
20021
  if (auth.kind === "api_key") {
19581
20022
  rmIfExists(authJson);
19582
20023
  return { CURSOR_API_KEY: auth.value };
@@ -19618,22 +20059,22 @@ max_context_size = 262144
19618
20059
  var kimiProvisioner = {
19619
20060
  write(auth, home) {
19620
20061
  const credentialsFiles = [
19621
- path42.join(home, ".kimi", "credentials", "kimi-code.json"),
19622
- path42.join(home, ".kimi-code", "credentials", "kimi-code.json")
20062
+ path43.join(home, ".kimi", "credentials", "kimi-code.json"),
20063
+ path43.join(home, ".kimi-code", "credentials", "kimi-code.json")
19623
20064
  ];
19624
20065
  if (auth.kind === "api_key") {
19625
20066
  credentialsFiles.forEach(rmIfExists);
19626
20067
  return { KIMI_API_KEY: auth.value };
19627
20068
  }
19628
20069
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
19629
- writeFile0600(path42.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
20070
+ writeFile0600(path43.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
19630
20071
  return {};
19631
20072
  }
19632
20073
  };
19633
20074
  var coderabbitProvisioner = {
19634
20075
  write(auth, home) {
19635
- const dir = path42.join(home, ".coderabbit");
19636
- const authJson = path42.join(dir, "auth.json");
20076
+ const dir = path43.join(home, ".coderabbit");
20077
+ const authJson = path43.join(dir, "auth.json");
19637
20078
  if (auth.kind === "api_key") {
19638
20079
  rmIfExists(authJson);
19639
20080
  return { CODERABBIT_API_KEY: auth.value };
@@ -19645,13 +20086,13 @@ var coderabbitProvisioner = {
19645
20086
  try {
19646
20087
  const parsed = JSON.parse(value);
19647
20088
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
19648
- file = path42.basename(parsed.file);
20089
+ file = path43.basename(parsed.file);
19649
20090
  contents = parsed.contents;
19650
20091
  }
19651
20092
  } catch {
19652
20093
  }
19653
20094
  }
19654
- writeFile0600(path42.join(dir, file), contents);
20095
+ writeFile0600(path43.join(dir, file), contents);
19655
20096
  return {};
19656
20097
  }
19657
20098
  };
@@ -19688,12 +20129,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os34.homedir(
19688
20129
  }
19689
20130
 
19690
20131
  // src/commands/host/git-tooling.ts
19691
- var import_node_child_process20 = require("child_process");
20132
+ var import_node_child_process21 = require("child_process");
19692
20133
  var fs39 = __toESM(require("fs"));
19693
20134
  var os35 = __toESM(require("os"));
19694
- var path43 = __toESM(require("path"));
20135
+ var path44 = __toESM(require("path"));
19695
20136
  function codeamBinDir() {
19696
- return process.env.CODEAM_BIN_DIR ?? path43.join(os35.homedir(), ".codeam", "bin");
20137
+ return process.env.CODEAM_BIN_DIR ?? path44.join(os35.homedir(), ".codeam", "bin");
19697
20138
  }
19698
20139
  var FALLBACK_GH_VERSION = "2.62.0";
19699
20140
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -19748,8 +20189,8 @@ async function ensureGhCli(runner, token, deps = {}) {
19748
20189
  const version3 = await resolveVersionFn(token);
19749
20190
  const asset = `gh_${version3}_${osToken}_${arch2}`;
19750
20191
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
19751
- const tmpRoot = fs39.mkdtempSync(path43.join(os35.tmpdir(), "codeam-gh-"));
19752
- const archive = path43.join(tmpRoot, `${asset}.${ext}`);
20192
+ const tmpRoot = fs39.mkdtempSync(path44.join(os35.tmpdir(), "codeam-gh-"));
20193
+ const archive = path44.join(tmpRoot, `${asset}.${ext}`);
19753
20194
  if (!await downloadFn(url2, archive)) {
19754
20195
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
19755
20196
  return null;
@@ -19759,14 +20200,14 @@ async function ensureGhCli(runner, token, deps = {}) {
19759
20200
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
19760
20201
  return null;
19761
20202
  }
19762
- const extractedBin = path43.join(tmpRoot, asset, "bin", binaryName);
20203
+ const extractedBin = path44.join(tmpRoot, asset, "bin", binaryName);
19763
20204
  if (!fs39.existsSync(extractedBin)) {
19764
20205
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
19765
20206
  return null;
19766
20207
  }
19767
20208
  const binDir = codeamBinDir();
19768
20209
  fs39.mkdirSync(binDir, { recursive: true });
19769
- const target = path43.join(binDir, binaryName);
20210
+ const target = path44.join(binDir, binaryName);
19770
20211
  fs39.copyFileSync(extractedBin, target);
19771
20212
  fs39.chmodSync(target, 493);
19772
20213
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
@@ -19828,8 +20269,8 @@ async function ensureGlabCli(runner, deps = {}) {
19828
20269
  const version3 = await resolveLatestGlabVersion();
19829
20270
  const asset = `glab_${version3}_${osToken}_${arch2}`;
19830
20271
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
19831
- const tmpRoot = fs39.mkdtempSync(path43.join(os35.tmpdir(), "codeam-glab-"));
19832
- const archive = path43.join(tmpRoot, `${asset}.${ext}`);
20272
+ const tmpRoot = fs39.mkdtempSync(path44.join(os35.tmpdir(), "codeam-glab-"));
20273
+ const archive = path44.join(tmpRoot, `${asset}.${ext}`);
19833
20274
  if (!await downloadFn(url2, archive)) {
19834
20275
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
19835
20276
  return null;
@@ -19840,9 +20281,9 @@ async function ensureGlabCli(runner, deps = {}) {
19840
20281
  return null;
19841
20282
  }
19842
20283
  const candidates = [
19843
- path43.join(tmpRoot, "bin", binaryName),
19844
- path43.join(tmpRoot, asset, "bin", binaryName),
19845
- path43.join(tmpRoot, binaryName)
20284
+ path44.join(tmpRoot, "bin", binaryName),
20285
+ path44.join(tmpRoot, asset, "bin", binaryName),
20286
+ path44.join(tmpRoot, binaryName)
19846
20287
  ];
19847
20288
  const extractedBin = candidates.find((c2) => fs39.existsSync(c2));
19848
20289
  if (!extractedBin) {
@@ -19851,7 +20292,7 @@ async function ensureGlabCli(runner, deps = {}) {
19851
20292
  }
19852
20293
  const binDir = codeamBinDir();
19853
20294
  fs39.mkdirSync(binDir, { recursive: true });
19854
- const target = path43.join(binDir, binaryName);
20295
+ const target = path44.join(binDir, binaryName);
19855
20296
  fs39.copyFileSync(extractedBin, target);
19856
20297
  fs39.chmodSync(target, 493);
19857
20298
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
@@ -19888,7 +20329,7 @@ var defaultGitToolingRunner = {
19888
20329
  which(cmd) {
19889
20330
  try {
19890
20331
  const probe = process.platform === "win32" ? "where" : "which";
19891
- (0, import_node_child_process20.execFileSync)(probe, [cmd], { stdio: "ignore" });
20332
+ (0, import_node_child_process21.execFileSync)(probe, [cmd], { stdio: "ignore" });
19892
20333
  return true;
19893
20334
  } catch {
19894
20335
  return false;
@@ -19896,7 +20337,7 @@ var defaultGitToolingRunner = {
19896
20337
  },
19897
20338
  run(cmd, args2, opts = {}) {
19898
20339
  return new Promise((resolve9) => {
19899
- const child = (0, import_node_child_process20.spawn)(cmd, args2, {
20340
+ const child = (0, import_node_child_process21.spawn)(cmd, args2, {
19900
20341
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
19901
20342
  });
19902
20343
  let stderr = "";
@@ -20049,313 +20490,22 @@ var HeadroomStatsReporter = class {
20049
20490
  }
20050
20491
  };
20051
20492
 
20052
- // src/commands/host/os-packages.ts
20053
- var import_node_child_process21 = require("child_process");
20054
- var PM_INSTALL_TIMEOUT_MS = 18e4;
20055
- var defaultHeadroomRunner = {
20056
- which(cmd) {
20057
- try {
20058
- (0, import_node_child_process21.execFileSync)("which", [cmd], { stdio: "ignore" });
20059
- return true;
20060
- } catch {
20061
- return false;
20062
- }
20063
- },
20064
- run(cmd, args2, opts = {}) {
20065
- return new Promise((resolve9) => {
20066
- const spawnEnv = opts.env ?? process.env;
20067
- const child = (0, import_node_child_process21.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
20068
- let stderrBuf = "";
20069
- let stdoutBuf = "";
20070
- let settled = false;
20071
- const done = (code) => {
20072
- if (settled) return;
20073
- settled = true;
20074
- resolve9({ code, stderr: stderrBuf, stdout: stdoutBuf });
20075
- };
20076
- child.stdout?.on("data", (b) => {
20077
- const chunk = b.toString();
20078
- stdoutBuf += chunk;
20079
- const line = chunk.replace(/\n+$/, "");
20080
- if (line) log.info("host-agent", `headroom[${cmd}]: ${line}`);
20081
- });
20082
- child.stderr?.on("data", (b) => {
20083
- const chunk = b.toString();
20084
- stderrBuf += chunk;
20085
- const line = chunk.replace(/\n+$/, "");
20086
- if (line) log.info("host-agent", `headroom[${cmd}]: ${line}`);
20087
- });
20088
- const timeoutMs = opts.timeoutMs;
20089
- let timer;
20090
- if (timeoutMs !== void 0) {
20091
- timer = setTimeout(() => {
20092
- log.warn(
20093
- "host-agent",
20094
- `headroom[${cmd}] timed out after ${timeoutMs / 1e3}s \u2014 aborting`
20095
- );
20096
- killQuiet(child);
20097
- done(null);
20098
- }, timeoutMs);
20099
- }
20100
- child.once("exit", (code) => {
20101
- if (timer !== void 0) clearTimeout(timer);
20102
- done(code);
20103
- });
20104
- child.once("error", (e) => {
20105
- if (timer !== void 0) clearTimeout(timer);
20106
- log.trace("host-agent", `headroom[${cmd}] spawn error: ${e.message}`);
20107
- done(null);
20108
- });
20109
- });
20110
- }
20111
- };
20112
- var PACKAGE_MANAGERS = [
20113
- "apt-get",
20114
- "apk",
20115
- "dnf",
20116
- "yum",
20117
- "pacman",
20118
- "zypper"
20119
- ];
20120
- var PROVISION_RECIPES = {
20121
- "apt-get": {
20122
- update: ["apt-get", "update"],
20123
- install: [
20124
- "apt-get",
20125
- "install",
20126
- "-y",
20127
- "python3",
20128
- "python3-pip",
20129
- "python3-venv",
20130
- "ca-certificates",
20131
- "curl"
20132
- ]
20133
- },
20134
- apk: {
20135
- install: ["apk", "add", "--no-cache", "python3", "py3-pip", "ca-certificates", "curl"]
20136
- },
20137
- dnf: {
20138
- install: ["dnf", "install", "-y", "python3", "python3-pip", "ca-certificates", "curl"]
20139
- },
20140
- yum: {
20141
- install: ["yum", "install", "-y", "python3", "python3-pip", "ca-certificates", "curl"]
20142
- },
20143
- pacman: {
20144
- install: ["pacman", "-Sy", "--noconfirm", "python", "python-pip", "ca-certificates", "curl"]
20145
- },
20146
- zypper: {
20147
- install: [
20148
- "zypper",
20149
- "--non-interactive",
20150
- "install",
20151
- "python3",
20152
- "python3-pip",
20153
- "ca-certificates",
20154
- "curl"
20155
- ]
20156
- }
20157
- };
20158
- function detectPackageManager(runner) {
20159
- for (const pm of PACKAGE_MANAGERS) {
20160
- if (runner.which(pm)) return pm;
20161
- }
20162
- return null;
20163
- }
20164
- function escalateCommand(argv) {
20165
- const isRoot = process.getuid?.() === 0;
20166
- return isRoot ? { cmd: argv[0], args: argv.slice(1) } : { cmd: "sudo", args: argv };
20167
- }
20168
- async function ensurePip(runner) {
20169
- if (runner.which("pip") || runner.which("pip3")) {
20170
- return true;
20171
- }
20172
- const pm = detectPackageManager(runner);
20173
- if (!pm) {
20174
- log.warn(
20175
- "host-agent",
20176
- "pip is absent and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) found \u2014 skipping Headroom"
20177
- );
20178
- return false;
20179
- }
20180
- const escalate = escalateCommand;
20181
- const recipe = PROVISION_RECIPES[pm];
20182
- log.info(
20183
- "host-agent",
20184
- `pip absent \u2014 provisioning bare box (python3+pip+ca-certificates+curl) via ${pm}`
20185
- );
20186
- try {
20187
- if (recipe.update) {
20188
- const { cmd: cmd2, args: args3 } = escalate(recipe.update);
20189
- const updateResult = await runner.run(cmd2, args3, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
20190
- if (updateResult.code !== 0) {
20191
- log.warn(
20192
- "host-agent",
20193
- `${pm} update exited ${String(updateResult.code)} \u2014 attempting install anyway`
20194
- );
20195
- }
20196
- }
20197
- const { cmd, args: args2 } = escalate(recipe.install);
20198
- const installResult = await runner.run(cmd, args2, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
20199
- if (installResult.code !== 0) {
20200
- log.warn(
20201
- "host-agent",
20202
- `${pm} bare-box provision failed (code=${String(installResult.code)}) \u2014 skipping Headroom`
20203
- );
20204
- return false;
20205
- }
20206
- } catch (e) {
20207
- log.warn(
20208
- "host-agent",
20209
- `bare-box provision threw unexpectedly: ${e instanceof Error ? e.message : String(e)} \u2014 skipping Headroom`
20210
- );
20211
- return false;
20212
- }
20213
- log.info("host-agent", `bare box provisioned via ${pm} (python3+pip+ca-certificates+curl)`);
20214
- return true;
20215
- }
20216
- async function resolveHeadroomPython(runner) {
20217
- const PROBE_TIMEOUT_MS = 5e3;
20218
- const SUFFIXES = ["python3.13", "python3.12", "python3.11", "python3.10"];
20219
- const PREFIX_DIRS = ["/opt/homebrew/bin", "/usr/local/bin"];
20220
- const probe = async (candidate) => {
20221
- try {
20222
- const r = await runner.run(
20223
- candidate,
20224
- ["-c", 'import sys; print("%d.%d" % sys.version_info[:2])'],
20225
- { timeoutMs: PROBE_TIMEOUT_MS }
20226
- );
20227
- if (r.code !== 0) return false;
20228
- const parts = (r.stdout ?? "").trim().split(".");
20229
- const major = parseInt(parts[0] ?? "", 10);
20230
- const minor = parseInt(parts[1] ?? "", 10);
20231
- if (!(major === 3 && minor >= 10)) return false;
20232
- const pipCheck = await runner.run(candidate, ["-m", "pip", "--version"], {
20233
- timeoutMs: PROBE_TIMEOUT_MS
20234
- });
20235
- return pipCheck.code === 0;
20236
- } catch {
20237
- return false;
20238
- }
20239
- };
20240
- for (const suffix of SUFFIXES) {
20241
- try {
20242
- if (await probe(suffix)) return suffix;
20243
- } catch {
20244
- }
20245
- }
20246
- for (const suffix of SUFFIXES) {
20247
- for (const dir of PREFIX_DIRS) {
20248
- const candidate = `${dir}/${suffix}`;
20249
- try {
20250
- if (await probe(candidate)) return candidate;
20251
- } catch {
20252
- }
20253
- }
20254
- }
20255
- try {
20256
- if (await probe("python3")) return "python3";
20257
- } catch {
20258
- }
20259
- return null;
20260
- }
20261
- var PY_INSTALL_TIMEOUT_MS = 6e5;
20262
- var MODERN_PYTHON_RECIPES = {
20263
- "apt-get": [
20264
- ["apt-get", "install", "-y", "python3.12"],
20265
- ["apt-get", "install", "-y", "python3.11"],
20266
- ["apt-get", "install", "-y", "python3"]
20267
- ],
20268
- dnf: [
20269
- ["dnf", "install", "-y", "python3.12"],
20270
- ["dnf", "install", "-y", "python3"]
20271
- ],
20272
- yum: [
20273
- ["yum", "install", "-y", "python3.12"],
20274
- ["yum", "install", "-y", "python3"]
20275
- ],
20276
- apk: [["apk", "add", "--no-cache", "python3"]],
20277
- pacman: [["pacman", "-Sy", "--noconfirm", "python"]],
20278
- zypper: [
20279
- ["zypper", "--non-interactive", "install", "python311"],
20280
- ["zypper", "--non-interactive", "install", "python3"]
20281
- ]
20282
- };
20283
- async function ensureModernPython(runner) {
20284
- let py = await resolveHeadroomPython(runner);
20285
- if (py !== null) return py;
20286
- try {
20287
- if (process.platform === "darwin") {
20288
- if (runner.which("brew")) {
20289
- log.info("host-agent", "no Python \u22653.10 found \u2014 installing python@3.12 via Homebrew");
20290
- const r = await runner.run("brew", ["install", "python@3.12"], {
20291
- timeoutMs: PY_INSTALL_TIMEOUT_MS
20292
- });
20293
- if (r.code !== 0) {
20294
- log.warn(
20295
- "host-agent",
20296
- `brew install python@3.12 exited ${String(r.code)} \u2014 will re-probe anyway`
20297
- );
20298
- }
20299
- } else {
20300
- log.warn(
20301
- "host-agent",
20302
- "no Python \u22653.10 and Homebrew is absent \u2014 cannot auto-install Python on macOS"
20303
- );
20304
- }
20305
- } else if (process.platform === "linux") {
20306
- const pm = detectPackageManager(runner);
20307
- if (!pm) {
20308
- log.warn(
20309
- "host-agent",
20310
- "no Python \u22653.10 and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) \u2014 cannot auto-install Python"
20311
- );
20312
- } else {
20313
- log.info("host-agent", `no Python \u22653.10 found \u2014 installing a modern Python via ${pm}`);
20314
- for (const argv of MODERN_PYTHON_RECIPES[pm]) {
20315
- const { cmd, args: args2 } = escalateCommand(argv);
20316
- const r = await runner.run(cmd, args2, { timeoutMs: PY_INSTALL_TIMEOUT_MS });
20317
- if (r.code === 0) {
20318
- log.info("host-agent", `installed Python package via ${pm}: ${argv.join(" ")}`);
20319
- break;
20320
- }
20321
- log.warn(
20322
- "host-agent",
20323
- `${pm} install '${argv.join(" ")}' exited ${String(r.code)} \u2014 trying next`
20324
- );
20325
- }
20326
- }
20327
- } else {
20328
- log.warn(
20329
- "host-agent",
20330
- `no Python \u22653.10 and platform '${process.platform}' has no auto-install path`
20331
- );
20332
- }
20333
- } catch (e) {
20334
- log.warn(
20335
- "host-agent",
20336
- `Python auto-install threw unexpectedly (best-effort): ${e instanceof Error ? e.message : String(e)}`
20337
- );
20338
- }
20339
- py = await resolveHeadroomPython(runner);
20340
- return py;
20341
- }
20342
-
20343
20493
  // src/commands/host/headroom-bootstrap.ts
20344
20494
  var fs41 = __toESM(require("fs"));
20345
- var path45 = __toESM(require("path"));
20495
+ var path46 = __toESM(require("path"));
20346
20496
  var os37 = __toESM(require("os"));
20347
20497
 
20348
20498
  // src/commands/host/headroom-config.ts
20349
20499
  var fs40 = __toESM(require("fs"));
20350
20500
  var os36 = __toESM(require("os"));
20351
- var path44 = __toESM(require("path"));
20501
+ var path45 = __toESM(require("path"));
20352
20502
  function headroomConfigPath() {
20353
- return path44.join(os36.homedir(), ".codeam", "headroom-config.json");
20503
+ return path45.join(os36.homedir(), ".codeam", "headroom-config.json");
20354
20504
  }
20355
20505
  function persistHeadroomConfig(config) {
20356
20506
  try {
20357
20507
  const file = headroomConfigPath();
20358
- fs40.mkdirSync(path44.dirname(file), { recursive: true, mode: 448 });
20508
+ fs40.mkdirSync(path45.dirname(file), { recursive: true, mode: 448 });
20359
20509
  const tmp = `${file}.tmp-${process.pid}`;
20360
20510
  fs40.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20361
20511
  fs40.renameSync(tmp, file);
@@ -20369,9 +20519,9 @@ function persistHeadroomConfig(config) {
20369
20519
  }
20370
20520
  function agentSettingsPath(kind) {
20371
20521
  const home = os36.homedir();
20372
- if (kind === "claude") return path44.join(home, ".claude", "settings.json");
20373
- if (kind === "codex") return path44.join(home, ".codex", "auth.json");
20374
- if (kind === "copilot") return path44.join(home, ".config", "github-copilot", "hosts.json");
20522
+ if (kind === "claude") return path45.join(home, ".claude", "settings.json");
20523
+ if (kind === "codex") return path45.join(home, ".codex", "auth.json");
20524
+ if (kind === "copilot") return path45.join(home, ".config", "github-copilot", "hosts.json");
20375
20525
  return null;
20376
20526
  }
20377
20527
  function backupAgentHeadroomConfig(kind) {
@@ -20379,8 +20529,8 @@ function backupAgentHeadroomConfig(kind) {
20379
20529
  if (!src) return;
20380
20530
  try {
20381
20531
  if (!fs40.existsSync(src)) return;
20382
- const dest = path44.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20383
- fs40.mkdirSync(path44.dirname(dest), { recursive: true, mode: 448 });
20532
+ const dest = path45.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20533
+ fs40.mkdirSync(path45.dirname(dest), { recursive: true, mode: 448 });
20384
20534
  fs40.copyFileSync(src, dest);
20385
20535
  fs40.chmodSync(dest, 384);
20386
20536
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
@@ -20394,10 +20544,10 @@ function backupAgentHeadroomConfig(kind) {
20394
20544
  function restoreAgentHeadroomConfig(kind) {
20395
20545
  const dest = agentSettingsPath(kind);
20396
20546
  if (!dest) return false;
20397
- const src = path44.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20547
+ const src = path45.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20398
20548
  if (!fs40.existsSync(src)) return false;
20399
20549
  try {
20400
- fs40.mkdirSync(path44.dirname(dest), { recursive: true, mode: 448 });
20550
+ fs40.mkdirSync(path45.dirname(dest), { recursive: true, mode: 448 });
20401
20551
  fs40.copyFileSync(src, dest);
20402
20552
  fs40.chmodSync(dest, 384);
20403
20553
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
@@ -20448,20 +20598,20 @@ function bundledClaudeBinDir() {
20448
20598
  const roots = /* @__PURE__ */ new Set();
20449
20599
  let dir = __dirname;
20450
20600
  for (let i = 0; i < 6; i++) {
20451
- roots.add(path45.join(dir, "node_modules"));
20452
- const parent = path45.dirname(dir);
20601
+ roots.add(path46.join(dir, "node_modules"));
20602
+ const parent = path46.dirname(dir);
20453
20603
  if (parent === dir) break;
20454
20604
  dir = parent;
20455
20605
  }
20456
20606
  try {
20457
20607
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
20458
- const marker = `${path45.sep}@anthropic-ai${path45.sep}`;
20608
+ const marker = `${path46.sep}@anthropic-ai${path46.sep}`;
20459
20609
  const idx = main2.lastIndexOf(marker);
20460
20610
  if (idx !== -1) roots.add(main2.slice(0, idx));
20461
20611
  } catch {
20462
20612
  }
20463
20613
  for (const nm of roots) {
20464
- const atAnthropic = path45.join(nm, "@anthropic-ai");
20614
+ const atAnthropic = path46.join(nm, "@anthropic-ai");
20465
20615
  let entries;
20466
20616
  try {
20467
20617
  entries = fs41.readdirSync(atAnthropic);
@@ -20470,8 +20620,8 @@ function bundledClaudeBinDir() {
20470
20620
  }
20471
20621
  for (const entry of entries) {
20472
20622
  if (!entry.startsWith("claude-agent-sdk-")) continue;
20473
- const bin = path45.join(atAnthropic, entry, "claude");
20474
- if (fs41.existsSync(bin)) return path45.dirname(bin);
20623
+ const bin = path46.join(atAnthropic, entry, "claude");
20624
+ if (fs41.existsSync(bin)) return path46.dirname(bin);
20475
20625
  }
20476
20626
  }
20477
20627
  return null;
@@ -20485,12 +20635,12 @@ async function getFreeDiskBytes(dir) {
20485
20635
  }
20486
20636
  }
20487
20637
  function headroomModelsCached() {
20488
- const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path45.join(
20489
- process.env.HF_HOME || path45.join(os37.homedir(), ".cache", "huggingface"),
20638
+ const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path46.join(
20639
+ process.env.HF_HOME || path46.join(os37.homedir(), ".cache", "huggingface"),
20490
20640
  "hub"
20491
20641
  );
20492
20642
  return HEADROOM_MODELS.every(
20493
- (m) => fs41.existsSync(path45.join(hubDir, `models--${m.repo.replace("/", "--")}`))
20643
+ (m) => fs41.existsSync(path46.join(hubDir, `models--${m.repo.replace("/", "--")}`))
20494
20644
  );
20495
20645
  }
20496
20646
  async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner, opts = {}) {
@@ -20559,7 +20709,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
20559
20709
  if (initKind === "claude") {
20560
20710
  const claudeDir = bundledClaudeBinDir();
20561
20711
  if (claudeDir) {
20562
- initEnv.PATH = `${claudeDir}${path45.delimiter}${process.env["PATH"] ?? ""}`;
20712
+ initEnv.PATH = `${claudeDir}${path46.delimiter}${process.env["PATH"] ?? ""}`;
20563
20713
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
20564
20714
  } else {
20565
20715
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -20598,14 +20748,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
20598
20748
  // src/commands/host/house-proxy-config.ts
20599
20749
  var fs42 = __toESM(require("fs"));
20600
20750
  var os38 = __toESM(require("os"));
20601
- var path46 = __toESM(require("path"));
20751
+ var path47 = __toESM(require("path"));
20602
20752
  function houseProxyConfigPath() {
20603
- return path46.join(os38.homedir(), ".codeam", "house-proxy.json");
20753
+ return path47.join(os38.homedir(), ".codeam", "house-proxy.json");
20604
20754
  }
20605
20755
  function persistHouseProxyConfig(config) {
20606
20756
  try {
20607
20757
  const file = houseProxyConfigPath();
20608
- fs42.mkdirSync(path46.dirname(file), { recursive: true, mode: 448 });
20758
+ fs42.mkdirSync(path47.dirname(file), { recursive: true, mode: 448 });
20609
20759
  const tmp = `${file}.tmp-${process.pid}`;
20610
20760
  fs42.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20611
20761
  fs42.renameSync(tmp, file);
@@ -20660,7 +20810,7 @@ var import_node_child_process23 = require("child_process");
20660
20810
  // src/lib/updateNotifier.ts
20661
20811
  var fs43 = __toESM(require("fs"));
20662
20812
  var os39 = __toESM(require("os"));
20663
- var path47 = __toESM(require("path"));
20813
+ var path48 = __toESM(require("path"));
20664
20814
  var https6 = __toESM(require("https"));
20665
20815
  var import_node_child_process22 = require("child_process");
20666
20816
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -20669,8 +20819,8 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
20669
20819
  var TTL_MS = 24 * 60 * 60 * 1e3;
20670
20820
  var REQUEST_TIMEOUT_MS = 1500;
20671
20821
  function cachePath() {
20672
- const dir = path47.join(os39.homedir(), ".codeam");
20673
- return path47.join(dir, "update-check.json");
20822
+ const dir = path48.join(os39.homedir(), ".codeam");
20823
+ return path48.join(dir, "update-check.json");
20674
20824
  }
20675
20825
  function readCache() {
20676
20826
  try {
@@ -20685,7 +20835,7 @@ function readCache() {
20685
20835
  function writeCache(cache) {
20686
20836
  try {
20687
20837
  const file = cachePath();
20688
- fs43.mkdirSync(path47.dirname(file), { recursive: true });
20838
+ fs43.mkdirSync(path48.dirname(file), { recursive: true });
20689
20839
  const tmp = `${file}.${process.pid}.tmp`;
20690
20840
  fs43.writeFileSync(tmp, JSON.stringify(cache));
20691
20841
  fs43.renameSync(tmp, file);
@@ -20762,7 +20912,7 @@ function isLinkedInstall() {
20762
20912
  timeout: 2e3
20763
20913
  }).trim();
20764
20914
  if (!root) return false;
20765
- const pkgPath = path47.join(root, PKG_NAME);
20915
+ const pkgPath = path48.join(root, PKG_NAME);
20766
20916
  return fs43.lstatSync(pkgPath).isSymbolicLink();
20767
20917
  } catch {
20768
20918
  return false;
@@ -20815,7 +20965,7 @@ async function autoUpgradeBeforeCriticalCommand() {
20815
20965
  if (process.env.NODE_ENV === "test") return;
20816
20966
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20817
20967
  if (process.env.CI) return;
20818
- const current2 = true ? "2.62.1" : null;
20968
+ const current2 = true ? "2.62.2" : null;
20819
20969
  if (!current2) return;
20820
20970
  const cache = readCache();
20821
20971
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -20832,7 +20982,7 @@ function checkForUpdates() {
20832
20982
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20833
20983
  if (process.env.CI) return;
20834
20984
  if (!process.stdout.isTTY) return;
20835
- const current2 = true ? "2.62.1" : null;
20985
+ const current2 = true ? "2.62.2" : null;
20836
20986
  if (!current2) return;
20837
20987
  const cache = readCache();
20838
20988
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -20852,7 +21002,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
20852
21002
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
20853
21003
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
20854
21004
  function currentCliVersion() {
20855
- return true ? "2.62.1" : null;
21005
+ return true ? "2.62.2" : null;
20856
21006
  }
20857
21007
  function runCmd(cmd, args2, timeoutMs) {
20858
21008
  return new Promise((resolve9) => {
@@ -21584,13 +21734,13 @@ var HostAgentSupervisor = class {
21584
21734
  const relay = this.relay;
21585
21735
  if (!relay) return;
21586
21736
  const raw = cmd.payload?.path;
21587
- const target = typeof raw === "string" && raw.trim() ? path48.resolve(raw.trim()) : os40.homedir();
21737
+ const target = typeof raw === "string" && raw.trim() ? path49.resolve(raw.trim()) : os40.homedir();
21588
21738
  try {
21589
21739
  const dirents = await fs45.promises.readdir(target, { withFileTypes: true });
21590
21740
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
21591
21741
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
21592
21742
  );
21593
- const parent = path48.dirname(target);
21743
+ const parent = path49.dirname(target);
21594
21744
  await relay.sendResult(cmd.id, "completed", {
21595
21745
  path: target,
21596
21746
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -21823,7 +21973,7 @@ var HostAgentSupervisor = class {
21823
21973
  API_TIMEOUT_MS: "3000000",
21824
21974
  CODEAM_AUTO_TOKEN: payload.autoPairToken
21825
21975
  };
21826
- const houseConfigDir = path48.join(
21976
+ const houseConfigDir = path49.join(
21827
21977
  os40.homedir(),
21828
21978
  ".codeam",
21829
21979
  "house-claude",
@@ -21864,13 +22014,13 @@ var HostAgentSupervisor = class {
21864
22014
  if ((payload.repoProvider ?? "github") === "gitlab") {
21865
22015
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
21866
22016
  if (glabCmd) {
21867
- childEnv.PATH = `${codeamBinDir()}${path48.delimiter}${childEnv.PATH}`;
22017
+ childEnv.PATH = `${codeamBinDir()}${path49.delimiter}${childEnv.PATH}`;
21868
22018
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
21869
22019
  }
21870
22020
  } else {
21871
22021
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
21872
22022
  if (ghCmd) {
21873
- childEnv.PATH = `${codeamBinDir()}${path48.delimiter}${childEnv.PATH}`;
22023
+ childEnv.PATH = `${codeamBinDir()}${path49.delimiter}${childEnv.PATH}`;
21874
22024
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
21875
22025
  }
21876
22026
  }
@@ -21949,8 +22099,8 @@ var HostAgentSupervisor = class {
21949
22099
  );
21950
22100
  if (!payload.suppressOnboardingWelcome) {
21951
22101
  try {
21952
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path48.join(os40.homedir(), ".claude");
21953
- const projectDir = path48.join(cfgDir, "projects", encodeCwd(cwd));
22102
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path49.join(os40.homedir(), ".claude");
22103
+ const projectDir = path49.join(cfgDir, "projects", encodeCwd(cwd));
21954
22104
  const hasPriorConversation = fs45.existsSync(projectDir) && fs45.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
21955
22105
  if (hasPriorConversation) {
21956
22106
  childEnv.CODEAM_RESUME_LATEST = "1";
@@ -22187,8 +22337,8 @@ var HostAgentSupervisor = class {
22187
22337
  this.children.delete(deployId);
22188
22338
  }
22189
22339
  const dirs = [
22190
- path48.join(selfHostedWorkspaceRoot(), deployId),
22191
- path48.join(os40.homedir(), ".codeam", "house-claude", deployId)
22340
+ path49.join(selfHostedWorkspaceRoot(), deployId),
22341
+ path49.join(os40.homedir(), ".codeam", "house-claude", deployId)
22192
22342
  ];
22193
22343
  for (const dir of dirs) {
22194
22344
  try {
@@ -22331,7 +22481,7 @@ async function configureHeadroom(action, ctx, deps) {
22331
22481
  // src/services/headroom/budget-relaunch.ts
22332
22482
  var fs46 = __toESM(require("fs"));
22333
22483
  var os41 = __toESM(require("os"));
22334
- var path49 = __toESM(require("path"));
22484
+ var path50 = __toESM(require("path"));
22335
22485
  var import_child_process13 = require("child_process");
22336
22486
  function amendDeploymentManifestBudget(manifest, budget) {
22337
22487
  const rawArgs = manifest.proxy_args ?? [];
@@ -22365,7 +22515,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
22365
22515
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
22366
22516
  }
22367
22517
  function findHeadroomDeployments(homeDir2, deps) {
22368
- const deployDir = path49.join(homeDir2, ".headroom", "deploy");
22518
+ const deployDir = path50.join(homeDir2, ".headroom", "deploy");
22369
22519
  let profiles;
22370
22520
  try {
22371
22521
  profiles = deps.readDir(deployDir);
@@ -22374,7 +22524,7 @@ function findHeadroomDeployments(homeDir2, deps) {
22374
22524
  }
22375
22525
  const results = [];
22376
22526
  for (const profile of profiles) {
22377
- const manifestPath = path49.join(deployDir, profile, "manifest.json");
22527
+ const manifestPath = path50.join(deployDir, profile, "manifest.json");
22378
22528
  let raw;
22379
22529
  try {
22380
22530
  raw = deps.readJson(manifestPath);
@@ -22561,7 +22711,7 @@ async function defaultFetchJson(url2) {
22561
22711
  async function readUsageReport(deps = {}) {
22562
22712
  const port = deps.port ?? HEADROOM_PROXY_PORT;
22563
22713
  const base = `http://127.0.0.1:${port}`;
22564
- const get2 = deps.fetchJson ?? ((path89) => defaultFetchJson(`${base}${path89}`));
22714
+ const get2 = deps.fetchJson ?? ((path90) => defaultFetchJson(`${base}${path90}`));
22565
22715
  let history;
22566
22716
  try {
22567
22717
  history = await get2("/stats-history");
@@ -22580,11 +22730,11 @@ async function readUsageReport(deps = {}) {
22580
22730
 
22581
22731
  // src/agents/acp/guardrail-config.ts
22582
22732
  var fs47 = __toESM(require("fs"));
22583
- var path50 = __toESM(require("path"));
22733
+ var path51 = __toESM(require("path"));
22584
22734
  var os42 = __toESM(require("os"));
22585
22735
  var current = null;
22586
22736
  function guardrailConfigPath(homeDir2 = os42.homedir()) {
22587
- return path50.join(homeDir2, ".codeam", "guardrails.json");
22737
+ return path51.join(homeDir2, ".codeam", "guardrails.json");
22588
22738
  }
22589
22739
  function loadGuardrailPolicy(homeDir2 = os42.homedir()) {
22590
22740
  try {
@@ -22602,7 +22752,7 @@ function setGuardrailPolicy(raw, homeDir2 = os42.homedir()) {
22602
22752
  current = next;
22603
22753
  try {
22604
22754
  const p2 = guardrailConfigPath(homeDir2);
22605
- fs47.mkdirSync(path50.dirname(p2), { recursive: true });
22755
+ fs47.mkdirSync(path51.dirname(p2), { recursive: true });
22606
22756
  fs47.writeFileSync(p2, JSON.stringify(next, null, 2));
22607
22757
  } catch {
22608
22758
  }
@@ -22612,10 +22762,10 @@ function setGuardrailPolicy(raw, homeDir2 = os42.homedir()) {
22612
22762
  // src/services/preview/port-registry.ts
22613
22763
  var fs48 = __toESM(require("fs"));
22614
22764
  var os43 = __toESM(require("os"));
22615
- var path51 = __toESM(require("path"));
22765
+ var path52 = __toESM(require("path"));
22616
22766
  var import_child_process14 = require("child_process");
22617
22767
  function registryPath() {
22618
- return path51.join(os43.homedir(), ".codeam", "preview-ports.json");
22768
+ return path52.join(os43.homedir(), ".codeam", "preview-ports.json");
22619
22769
  }
22620
22770
  function readRegistry() {
22621
22771
  try {
@@ -22629,7 +22779,7 @@ function readRegistry() {
22629
22779
  function writeRegistry(reg) {
22630
22780
  try {
22631
22781
  const file = registryPath();
22632
- fs48.mkdirSync(path51.dirname(file), { recursive: true });
22782
+ fs48.mkdirSync(path52.dirname(file), { recursive: true });
22633
22783
  const tmp = `${file}.tmp`;
22634
22784
  fs48.writeFileSync(tmp, JSON.stringify(reg), "utf8");
22635
22785
  fs48.renameSync(tmp, file);
@@ -22698,7 +22848,7 @@ function reclaimOwnOrphanPort(port) {
22698
22848
 
22699
22849
  // src/services/preview/host-allow.ts
22700
22850
  var import_fs = require("fs");
22701
- var path52 = __toESM(require("path"));
22851
+ var path53 = __toESM(require("path"));
22702
22852
  var NEXT_ALLOWED_ORIGINS = [
22703
22853
  "*.trycloudflare.com",
22704
22854
  "*.preview.codeagent-mobile.com",
@@ -22718,7 +22868,7 @@ var MARKER_DIR = ".codeam";
22718
22868
  var MARKER_FILE = "preview-host-allow.json";
22719
22869
  var ORIG_INFIX = ".codeam-orig";
22720
22870
  function markerPath(cwd) {
22721
- return path52.join(cwd, MARKER_DIR, MARKER_FILE);
22871
+ return path53.join(cwd, MARKER_DIR, MARKER_FILE);
22722
22872
  }
22723
22873
  async function fileExists(p2) {
22724
22874
  try {
@@ -22731,13 +22881,13 @@ async function fileExists(p2) {
22731
22881
  async function findConfigFile(cwd, framework) {
22732
22882
  const base = CONFIG_BASENAMES[framework];
22733
22883
  for (const ext of CONFIG_EXTS) {
22734
- if (await fileExists(path52.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
22884
+ if (await fileExists(path53.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
22735
22885
  }
22736
22886
  return null;
22737
22887
  }
22738
22888
  async function dependsOn(cwd, pkgName) {
22739
22889
  try {
22740
- const raw = await import_fs.promises.readFile(path52.join(cwd, "package.json"), "utf8");
22890
+ const raw = await import_fs.promises.readFile(path53.join(cwd, "package.json"), "utf8");
22741
22891
  const pkg = JSON.parse(raw);
22742
22892
  return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
22743
22893
  } catch {
@@ -22745,11 +22895,11 @@ async function dependsOn(cwd, pkgName) {
22745
22895
  }
22746
22896
  }
22747
22897
  async function isEsmConfig(cwd, configFile) {
22748
- const ext = path52.extname(configFile);
22898
+ const ext = path53.extname(configFile);
22749
22899
  if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
22750
22900
  if (ext === ".cjs") return false;
22751
22901
  try {
22752
- const raw = await import_fs.promises.readFile(path52.join(cwd, "package.json"), "utf8");
22902
+ const raw = await import_fs.promises.readFile(path53.join(cwd, "package.json"), "utf8");
22753
22903
  return JSON.parse(raw).type === "module";
22754
22904
  } catch {
22755
22905
  return false;
@@ -22832,7 +22982,7 @@ function shimFor(framework, origBasename, esm) {
22832
22982
  return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
22833
22983
  }
22834
22984
  async function writeMarker(cwd, marker) {
22835
- await import_fs.promises.mkdir(path52.join(cwd, MARKER_DIR), { recursive: true });
22985
+ await import_fs.promises.mkdir(path53.join(cwd, MARKER_DIR), { recursive: true });
22836
22986
  await import_fs.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
22837
22987
  }
22838
22988
  async function readMarker(cwd) {
@@ -22847,9 +22997,9 @@ async function restorePreviewHostAllow(cwd) {
22847
22997
  const marker = await readMarker(cwd);
22848
22998
  if (!marker) return;
22849
22999
  try {
22850
- const configAbs = path52.join(cwd, marker.configFile);
23000
+ const configAbs = path53.join(cwd, marker.configFile);
22851
23001
  if (marker.backupFile) {
22852
- const backupAbs = path52.join(cwd, marker.backupFile);
23002
+ const backupAbs = path53.join(cwd, marker.backupFile);
22853
23003
  if (await fileExists(backupAbs)) {
22854
23004
  await import_fs.promises.rm(configAbs, { force: true });
22855
23005
  await import_fs.promises.rename(backupAbs, configAbs);
@@ -22882,16 +23032,16 @@ async function applyPreviewHostAllow(cwd) {
22882
23032
  }
22883
23033
  if (!framework) return;
22884
23034
  if (existing) {
22885
- const ext = path52.extname(existing);
23035
+ const ext = path53.extname(existing);
22886
23036
  const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
22887
23037
  const esm = await isEsmConfig(cwd, existing);
22888
- await import_fs.promises.rename(path52.join(cwd, existing), path52.join(cwd, origBasename));
22889
- await import_fs.promises.writeFile(path52.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
23038
+ await import_fs.promises.rename(path53.join(cwd, existing), path53.join(cwd, origBasename));
23039
+ await import_fs.promises.writeFile(path53.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
22890
23040
  await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
22891
23041
  log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
22892
23042
  } else {
22893
23043
  const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
22894
- await import_fs.promises.writeFile(path52.join(cwd, configFile), shimFor(framework, null, true), "utf8");
23044
+ await import_fs.promises.writeFile(path53.join(cwd, configFile), shimFor(framework, null, true), "utf8");
22895
23045
  await writeMarker(cwd, { framework, configFile, backupFile: null });
22896
23046
  log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
22897
23047
  }
@@ -23574,18 +23724,18 @@ function activePreviewSessionIds() {
23574
23724
  // src/services/preview/start-orchestrator.ts
23575
23725
  var import_child_process19 = require("child_process");
23576
23726
  var fs56 = __toESM(require("fs"));
23577
- var path59 = __toESM(require("path"));
23727
+ var path60 = __toESM(require("path"));
23578
23728
  var import_which2 = __toESM(require("which"));
23579
23729
 
23580
23730
  // src/services/project-env/index.ts
23581
23731
  var import_fs5 = require("fs");
23582
- var path58 = __toESM(require("path"));
23732
+ var path59 = __toESM(require("path"));
23583
23733
 
23584
23734
  // src/beads/project-key.ts
23585
23735
  var import_child_process18 = require("child_process");
23586
23736
  var crypto2 = __toESM(require("crypto"));
23587
23737
  var fs54 = __toESM(require("fs"));
23588
- var path57 = __toESM(require("path"));
23738
+ var path58 = __toESM(require("path"));
23589
23739
  function normalizeOrigin(raw) {
23590
23740
  const trimmed = raw.trim();
23591
23741
  if (!trimmed) return null;
@@ -23611,17 +23761,17 @@ function normalizeOrigin(raw) {
23611
23761
  return `${host2}/${pathPart}`;
23612
23762
  }
23613
23763
  function findRepoRoot(cwd) {
23614
- let dir = path57.resolve(cwd);
23764
+ let dir = path58.resolve(cwd);
23615
23765
  const seen = /* @__PURE__ */ new Set();
23616
23766
  for (let i = 0; i < 256; i++) {
23617
23767
  if (seen.has(dir)) return null;
23618
23768
  seen.add(dir);
23619
23769
  try {
23620
- const stat3 = fs54.statSync(path57.join(dir, ".git"), { throwIfNoEntry: false });
23770
+ const stat3 = fs54.statSync(path58.join(dir, ".git"), { throwIfNoEntry: false });
23621
23771
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
23622
23772
  } catch {
23623
23773
  }
23624
- const parent = path57.dirname(dir);
23774
+ const parent = path58.dirname(dir);
23625
23775
  if (parent === dir) return null;
23626
23776
  dir = parent;
23627
23777
  }
@@ -23661,7 +23811,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
23661
23811
  } catch {
23662
23812
  }
23663
23813
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
23664
- return { projectKey: `path:${hash}`, projectLabel: path57.basename(real) || "project" };
23814
+ return { projectKey: `path:${hash}`, projectLabel: path58.basename(real) || "project" };
23665
23815
  }
23666
23816
 
23667
23817
  // src/services/project-env/index.ts
@@ -23674,7 +23824,7 @@ async function readIfExists(p2) {
23674
23824
  }
23675
23825
  async function syncProjectEnvUp(cwd, ctx) {
23676
23826
  if (!ctx.pluginAuthToken) return;
23677
- const content = await readIfExists(path58.join(cwd, ".env"));
23827
+ const content = await readIfExists(path59.join(cwd, ".env"));
23678
23828
  if (content == null) return;
23679
23829
  try {
23680
23830
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23696,7 +23846,7 @@ async function syncProjectEnvUp(cwd, ctx) {
23696
23846
  }
23697
23847
  async function restoreProjectEnvIfMissing(cwd, ctx) {
23698
23848
  if (!ctx.pluginAuthToken) return false;
23699
- const envPath = path58.join(cwd, ".env");
23849
+ const envPath = path59.join(cwd, ".env");
23700
23850
  if (await readIfExists(envPath) != null) return false;
23701
23851
  try {
23702
23852
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23707,7 +23857,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
23707
23857
  projectKey
23708
23858
  });
23709
23859
  if (!stored) return false;
23710
- const tmp = path58.join(cwd, ".env.codeam-restore.tmp");
23860
+ const tmp = path59.join(cwd, ".env.codeam-restore.tmp");
23711
23861
  await import_fs5.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
23712
23862
  await import_fs5.promises.rename(tmp, envPath);
23713
23863
  log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
@@ -23719,7 +23869,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
23719
23869
  }
23720
23870
 
23721
23871
  // src/services/preview/start-orchestrator.ts
23722
- var INSTALL_TIMEOUT_MS = 5 * 6e4;
23872
+ var INSTALL_TIMEOUT_MS2 = 5 * 6e4;
23723
23873
  var SETUP_TIMEOUT_MS = 2 * 6e4;
23724
23874
  var TUNNEL_REGISTER_DEADLINE_MS = 45e3;
23725
23875
  function compileReadyPattern(pattern) {
@@ -23784,7 +23934,7 @@ function normalizeDetectionForSpawn(detection, cwd) {
23784
23934
  if (args2.length === 0) return detection;
23785
23935
  const binName = args2[0];
23786
23936
  if (binName.startsWith("-")) return detection;
23787
- const binPath = path59.join(cwd, "node_modules", ".bin", binName);
23937
+ const binPath = path60.join(cwd, "node_modules", ".bin", binName);
23788
23938
  if (!fs56.existsSync(binPath)) return detection;
23789
23939
  return {
23790
23940
  ...detection,
@@ -23864,7 +24014,7 @@ async function provisionDeps(ctx) {
23864
24014
  ["install", "-g", "yarn"],
23865
24015
  cwd,
23866
24016
  detection.env,
23867
- { timeoutMs: INSTALL_TIMEOUT_MS }
24017
+ { timeoutMs: INSTALL_TIMEOUT_MS2 }
23868
24018
  );
23869
24019
  return { ok: r.status === "ok", code: r.code };
23870
24020
  }
@@ -23886,12 +24036,12 @@ async function provisionDeps(ctx) {
23886
24036
  missingDeps.args,
23887
24037
  cwd,
23888
24038
  detection.env,
23889
- { timeoutMs: INSTALL_TIMEOUT_MS }
24039
+ { timeoutMs: INSTALL_TIMEOUT_MS2 }
23890
24040
  );
23891
24041
  if (result.status === "timeout") {
23892
24042
  emit2(USER_EVENTS.PREVIEW_ERROR, {
23893
24043
  stage: "ready_timeout",
23894
- message: `Dependency install (${missingDeps.cmd} ${missingDeps.args.join(" ")}) didn't finish within ${Math.round(INSTALL_TIMEOUT_MS / 1e3)}s and was stopped. Run it manually in this project, then try the preview again.`
24044
+ message: `Dependency install (${missingDeps.cmd} ${missingDeps.args.join(" ")}) didn't finish within ${Math.round(INSTALL_TIMEOUT_MS2 / 1e3)}s and was stopped. Run it manually in this project, then try the preview again.`
23895
24045
  });
23896
24046
  return false;
23897
24047
  }
@@ -23918,7 +24068,7 @@ async function provisionDeps(ctx) {
23918
24068
  const agentSetupCommands = preflightRan ? normalizedSetup.filter((s) => !isJsInstallCommand(s.cmd, s.args)) : normalizedSetup;
23919
24069
  for (const setup of agentSetupCommands) {
23920
24070
  emitProgress("SETUP_RUN", `${setup.cmd} ${setup.args.join(" ")}`);
23921
- const timeoutMs = isJsInstallCommand(setup.cmd, setup.args) ? INSTALL_TIMEOUT_MS : SETUP_TIMEOUT_MS;
24071
+ const timeoutMs = isJsInstallCommand(setup.cmd, setup.args) ? INSTALL_TIMEOUT_MS2 : SETUP_TIMEOUT_MS;
23922
24072
  const result = await runSetupCommand(
23923
24073
  setup.cmd,
23924
24074
  setup.args,
@@ -24160,7 +24310,7 @@ async function establishTunnel(ctx, dev) {
24160
24310
  var import_child_process20 = require("child_process");
24161
24311
  var fs57 = __toESM(require("fs"));
24162
24312
  var os45 = __toESM(require("os"));
24163
- var path60 = __toESM(require("path"));
24313
+ var path61 = __toESM(require("path"));
24164
24314
  var BD_PACKAGE = "@beads/bd";
24165
24315
  function resolveBundledBdBinary() {
24166
24316
  return _resolveSeam.resolveBundled();
@@ -24172,9 +24322,9 @@ function _defaultResolveBundled() {
24172
24322
  } catch {
24173
24323
  return null;
24174
24324
  }
24175
- const binDir = path60.join(path60.dirname(pkgJsonPath), "bin");
24325
+ const binDir = path61.join(path61.dirname(pkgJsonPath), "bin");
24176
24326
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
24177
- const binaryPath = path60.join(binDir, binaryName);
24327
+ const binaryPath = path61.join(binDir, binaryName);
24178
24328
  try {
24179
24329
  fs57.accessSync(binaryPath, fs57.constants.F_OK);
24180
24330
  return binaryPath;
@@ -24186,11 +24336,11 @@ function resolveBdOnPath() {
24186
24336
  return _resolveSeam.resolveOnPath();
24187
24337
  }
24188
24338
  function _defaultResolveOnPath() {
24189
- const dirs = (process.env.PATH ?? "").split(path60.delimiter).filter(Boolean);
24339
+ const dirs = (process.env.PATH ?? "").split(path61.delimiter).filter(Boolean);
24190
24340
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
24191
24341
  for (const dir of dirs) {
24192
24342
  for (const candidate of candidates) {
24193
- const full = path60.join(dir, candidate);
24343
+ const full = path61.join(dir, candidate);
24194
24344
  try {
24195
24345
  fs57.accessSync(full, fs57.constants.F_OK);
24196
24346
  return full;
@@ -24371,7 +24521,7 @@ function coerceIssue(row, projectKey) {
24371
24521
  var import_child_process23 = require("child_process");
24372
24522
  var fs59 = __toESM(require("fs"));
24373
24523
  var os47 = __toESM(require("os"));
24374
- var path62 = __toESM(require("path"));
24524
+ var path63 = __toESM(require("path"));
24375
24525
 
24376
24526
  // src/beads/install-bd.ts
24377
24527
  var import_child_process21 = require("child_process");
@@ -24438,7 +24588,7 @@ async function installBd(platform3 = process.platform) {
24438
24588
  var import_child_process22 = require("child_process");
24439
24589
  var fs58 = __toESM(require("fs"));
24440
24590
  var os46 = __toESM(require("os"));
24441
- var path61 = __toESM(require("path"));
24591
+ var path62 = __toESM(require("path"));
24442
24592
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
24443
24593
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
24444
24594
  function resolveDoltInstallStrategy(platform3) {
@@ -24545,7 +24695,7 @@ function doltBinaryNames(platform3) {
24545
24695
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
24546
24696
  }
24547
24697
  function knownDoltDirs(platform3) {
24548
- const P3 = platform3 === "win32" ? path61.win32 : path61.posix;
24698
+ const P3 = platform3 === "win32" ? path62.win32 : path62.posix;
24549
24699
  const home = _doltPathSeam.homedir();
24550
24700
  if (platform3 === "win32") {
24551
24701
  return [
@@ -24561,7 +24711,7 @@ function knownDoltDirs(platform3) {
24561
24711
  ].filter(Boolean);
24562
24712
  }
24563
24713
  function ensureDoltResolvable(platform3 = process.platform) {
24564
- const P3 = platform3 === "win32" ? path61.win32 : path61.posix;
24714
+ const P3 = platform3 === "win32" ? path62.win32 : path62.posix;
24565
24715
  const delim = platform3 === "win32" ? ";" : ":";
24566
24716
  const names = doltBinaryNames(platform3);
24567
24717
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -24769,9 +24919,9 @@ var _linkSeam = {
24769
24919
  * which `linkBdOntoPath` creates if missing.
24770
24920
  */
24771
24921
  cliBinDir: () => {
24772
- const pathDirs = (process.env.PATH ?? "").split(path62.delimiter).filter(Boolean);
24922
+ const pathDirs = (process.env.PATH ?? "").split(path63.delimiter).filter(Boolean);
24773
24923
  const home = _linkSeam.homedir();
24774
- const localBin = home ? path62.join(home, ".local", "bin") : null;
24924
+ const localBin = home ? path63.join(home, ".local", "bin") : null;
24775
24925
  if (localBin) {
24776
24926
  try {
24777
24927
  _linkSeam.ensureDir(localBin);
@@ -24781,16 +24931,16 @@ var _linkSeam = {
24781
24931
  const candidates = [];
24782
24932
  if (localBin) candidates.push(localBin);
24783
24933
  try {
24784
- candidates.push(path62.dirname(process.execPath));
24934
+ candidates.push(path63.dirname(process.execPath));
24785
24935
  } catch {
24786
24936
  }
24787
24937
  candidates.push("/usr/local/bin");
24788
24938
  const entry = process.argv[1];
24789
24939
  if (entry) {
24790
24940
  try {
24791
- candidates.push(path62.dirname(fs59.realpathSync(entry)));
24941
+ candidates.push(path63.dirname(fs59.realpathSync(entry)));
24792
24942
  } catch {
24793
- candidates.push(path62.dirname(entry));
24943
+ candidates.push(path63.dirname(entry));
24794
24944
  }
24795
24945
  }
24796
24946
  const onPathWritable = candidates.find(
@@ -24815,7 +24965,7 @@ function linkBdOntoPath(binaryPath) {
24815
24965
  const binDir = _linkSeam.cliBinDir();
24816
24966
  if (!binDir) return;
24817
24967
  _linkSeam.ensureDir(binDir);
24818
- const linkPath = path62.join(binDir, "bd");
24968
+ const linkPath = path63.join(binDir, "bd");
24819
24969
  if (linkPath === binaryPath) return;
24820
24970
  const current2 = _linkSeam.readlink(linkPath);
24821
24971
  if (current2 === binaryPath) return;
@@ -25010,7 +25160,7 @@ function dedupeRecipes(agents) {
25010
25160
 
25011
25161
  // src/beads/watcher.ts
25012
25162
  var crypto4 = __toESM(require("crypto"));
25013
- var path63 = __toESM(require("path"));
25163
+ var path64 = __toESM(require("path"));
25014
25164
  var API_BASE6 = resolveApiBaseUrl();
25015
25165
  var DEBOUNCE_MS2 = 400;
25016
25166
  var ZERO_SUMMARY = {
@@ -25034,7 +25184,7 @@ var BeadsWatcher = class {
25034
25184
  constructor(opts) {
25035
25185
  this.opts = opts;
25036
25186
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
25037
- this.feedPath = opts.feedPath ?? path63.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
25187
+ this.feedPath = opts.feedPath ?? path64.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
25038
25188
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
25039
25189
  }
25040
25190
  opts;
@@ -25285,15 +25435,15 @@ async function handleBeadsActionCommand(action, started) {
25285
25435
  }
25286
25436
 
25287
25437
  // src/beads/config-store.ts
25288
- var import_node_fs9 = __toESM(require("fs"));
25289
- var import_node_os8 = __toESM(require("os"));
25438
+ var import_node_fs10 = __toESM(require("fs"));
25439
+ var import_node_os7 = __toESM(require("os"));
25290
25440
  var import_node_path7 = __toESM(require("path"));
25291
25441
  function beadsConfigPath() {
25292
- return import_node_path7.default.join(import_node_os8.default.homedir(), ".codeam", "beads-config.json");
25442
+ return import_node_path7.default.join(import_node_os7.default.homedir(), ".codeam", "beads-config.json");
25293
25443
  }
25294
25444
  function readBeadsEnabled() {
25295
25445
  try {
25296
- const raw = import_node_fs9.default.readFileSync(beadsConfigPath(), "utf8");
25446
+ const raw = import_node_fs10.default.readFileSync(beadsConfigPath(), "utf8");
25297
25447
  const cfg = JSON.parse(raw);
25298
25448
  return cfg.enabled !== false;
25299
25449
  } catch {
@@ -25302,10 +25452,10 @@ function readBeadsEnabled() {
25302
25452
  }
25303
25453
  function persistBeadsConfig(cfg) {
25304
25454
  const file = beadsConfigPath();
25305
- import_node_fs9.default.mkdirSync(import_node_path7.default.dirname(file), { recursive: true });
25455
+ import_node_fs10.default.mkdirSync(import_node_path7.default.dirname(file), { recursive: true });
25306
25456
  const tmp = `${file}.tmp`;
25307
- import_node_fs9.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
25308
- import_node_fs9.default.renameSync(tmp, file);
25457
+ import_node_fs10.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
25458
+ import_node_fs10.default.renameSync(tmp, file);
25309
25459
  restrictToOwner(file);
25310
25460
  }
25311
25461
 
@@ -25441,14 +25591,14 @@ async function configureBeads(action, ctx, deps) {
25441
25591
  }
25442
25592
 
25443
25593
  // src/skills/configure.ts
25444
- var import_node_os10 = __toESM(require("os"));
25594
+ var import_node_os9 = __toESM(require("os"));
25445
25595
 
25446
25596
  // src/skills/materialize.ts
25447
- var import_node_fs10 = __toESM(require("fs"));
25448
- var import_node_os9 = __toESM(require("os"));
25597
+ var import_node_fs11 = __toESM(require("fs"));
25598
+ var import_node_os8 = __toESM(require("os"));
25449
25599
  var import_node_path8 = __toESM(require("path"));
25450
25600
  var NS = "codeam-";
25451
- function skillDirFor(id, home = import_node_os9.default.homedir()) {
25601
+ function skillDirFor(id, home = import_node_os8.default.homedir()) {
25452
25602
  return import_node_path8.default.join(home, ".claude", "skills", `${NS}${id}`);
25453
25603
  }
25454
25604
  function renderSkillMd(id, description, body) {
@@ -25461,13 +25611,13 @@ description: ${JSON.stringify(desc)}
25461
25611
  ${body.trim()}
25462
25612
  `;
25463
25613
  }
25464
- function materializeSkill(id, home = import_node_os9.default.homedir()) {
25614
+ function materializeSkill(id, home = import_node_os8.default.homedir()) {
25465
25615
  const def = getSkillDefinition(id);
25466
25616
  if (!def?.delivery.skillFile) return false;
25467
25617
  try {
25468
25618
  const dir = skillDirFor(id, home);
25469
- import_node_fs10.default.mkdirSync(dir, { recursive: true, mode: 448 });
25470
- import_node_fs10.default.writeFileSync(
25619
+ import_node_fs11.default.mkdirSync(dir, { recursive: true, mode: 448 });
25620
+ import_node_fs11.default.writeFileSync(
25471
25621
  import_node_path8.default.join(dir, "SKILL.md"),
25472
25622
  renderSkillMd(id, def.description, def.delivery.skillFile.body),
25473
25623
  { encoding: "utf8", mode: 384 }
@@ -25479,8 +25629,8 @@ function materializeSkill(id, home = import_node_os9.default.homedir()) {
25479
25629
  if (!import_node_path8.default.resolve(target).startsWith(baseDirWithSep) && import_node_path8.default.resolve(target) !== baseDir) {
25480
25630
  continue;
25481
25631
  }
25482
- import_node_fs10.default.mkdirSync(import_node_path8.default.dirname(target), { recursive: true, mode: 448 });
25483
- import_node_fs10.default.writeFileSync(target, contents, { encoding: "utf8", mode: 384 });
25632
+ import_node_fs11.default.mkdirSync(import_node_path8.default.dirname(target), { recursive: true, mode: 448 });
25633
+ import_node_fs11.default.writeFileSync(target, contents, { encoding: "utf8", mode: 384 });
25484
25634
  }
25485
25635
  return true;
25486
25636
  } catch (err) {
@@ -25488,9 +25638,9 @@ function materializeSkill(id, home = import_node_os9.default.homedir()) {
25488
25638
  return false;
25489
25639
  }
25490
25640
  }
25491
- function removeSkill(id, home = import_node_os9.default.homedir()) {
25641
+ function removeSkill(id, home = import_node_os8.default.homedir()) {
25492
25642
  try {
25493
- import_node_fs10.default.rmSync(skillDirFor(id, home), { recursive: true, force: true });
25643
+ import_node_fs11.default.rmSync(skillDirFor(id, home), { recursive: true, force: true });
25494
25644
  } catch {
25495
25645
  }
25496
25646
  }
@@ -25500,7 +25650,7 @@ function currentInstalled() {
25500
25650
  const m = readSkillsManifest();
25501
25651
  return (m?.skills ?? []).map((s) => s.id).filter(isSkillId);
25502
25652
  }
25503
- function configureSkill(action, skillId, home = import_node_os10.default.homedir()) {
25653
+ function configureSkill(action, skillId, home = import_node_os9.default.homedir()) {
25504
25654
  if (action === "list") return { ok: true, installed: currentInstalled() };
25505
25655
  if (!skillId || !isSkillId(skillId)) {
25506
25656
  return { ok: false, installed: currentInstalled(), error: `unknown skill: ${skillId ?? "(none)"}` };
@@ -25533,7 +25683,7 @@ function cleanupAttachmentTempFiles() {
25533
25683
  function saveFilesTemp(files) {
25534
25684
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
25535
25685
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
25536
- const tmpPath = path66.join(os51.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
25686
+ const tmpPath = path67.join(os51.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
25537
25687
  fs62.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
25538
25688
  pendingAttachmentFiles.add(tmpPath);
25539
25689
  return tmpPath;
@@ -25746,7 +25896,7 @@ var listFiles = async (ctx, cmd, parsed) => {
25746
25896
  await ctx.relay.sendResult(cmd.id, "completed", result);
25747
25897
  };
25748
25898
  var envReadH = async (ctx, cmd) => {
25749
- const envPath = path66.join(process.cwd(), ".env");
25899
+ const envPath = path67.join(process.cwd(), ".env");
25750
25900
  await restoreProjectEnvIfMissing(process.cwd(), ctx);
25751
25901
  try {
25752
25902
  const raw = await fs62.promises.readFile(envPath, "utf8");
@@ -25780,8 +25930,8 @@ var envWriteH = async (ctx, cmd, parsed) => {
25780
25930
  }
25781
25931
  seen.add(v.key);
25782
25932
  }
25783
- const envPath = path66.join(process.cwd(), ".env");
25784
- const tmpPath = path66.join(process.cwd(), ".env.codeam.tmp");
25933
+ const envPath = path67.join(process.cwd(), ".env");
25934
+ const tmpPath = path67.join(process.cwd(), ".env.codeam.tmp");
25785
25935
  try {
25786
25936
  await fs62.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
25787
25937
  await fs62.promises.rename(tmpPath, envPath);
@@ -26318,7 +26468,7 @@ function buildNpmInstallInvocation(opts) {
26318
26468
  const execPath = opts?.execPath ?? process.execPath;
26319
26469
  const exists2 = opts?.existsSync ?? fs62.existsSync;
26320
26470
  const platform3 = opts?.platform ?? process.platform;
26321
- const p2 = platform3 === "win32" ? path66.win32 : path66.posix;
26471
+ const p2 = platform3 === "win32" ? path67.win32 : path67.posix;
26322
26472
  const normalized = entryScript.split(/[\\/]/).join("/");
26323
26473
  const marker = "/lib/node_modules/codeam-cli/";
26324
26474
  const markerIdx = normalized.indexOf(marker);
@@ -26340,7 +26490,7 @@ function isPermissionError(stderr) {
26340
26490
  function resolveGlobalNodeModulesDir(opts) {
26341
26491
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
26342
26492
  const platform3 = opts?.platform ?? process.platform;
26343
- const p2 = platform3 === "win32" ? path66.win32 : path66.posix;
26493
+ const p2 = platform3 === "win32" ? path67.win32 : path67.posix;
26344
26494
  const marker = "/lib/node_modules/codeam-cli/";
26345
26495
  const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
26346
26496
  if (markerIdx <= 0) return null;
@@ -26362,7 +26512,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
26362
26512
  }
26363
26513
  for (const name of entries) {
26364
26514
  if (!/^\.codeam-cli-/.test(name)) continue;
26365
- const full = path66.join(nodeModulesDir, name);
26515
+ const full = path67.join(nodeModulesDir, name);
26366
26516
  try {
26367
26517
  const st3 = statSync17(full);
26368
26518
  if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
@@ -27240,11 +27390,11 @@ function resolveTokenValue(args2) {
27240
27390
  }
27241
27391
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
27242
27392
  if (fileFlag) {
27243
- const path89 = fileFlag.slice("--token-file=".length);
27393
+ const path90 = fileFlag.slice("--token-file=".length);
27244
27394
  try {
27245
- const content = fs63.readFileSync(path89, "utf8").trim();
27246
- if (content.length === 0) fail(`--token-file ${path89} is empty`);
27247
- rmIfExistsQuiet(path89);
27395
+ const content = fs63.readFileSync(path90, "utf8").trim();
27396
+ if (content.length === 0) fail(`--token-file ${path90} is empty`);
27397
+ rmIfExistsQuiet(path90);
27248
27398
  return content;
27249
27399
  } catch (err) {
27250
27400
  fail(`Could not read --token-file: ${err.message}`);
@@ -27334,7 +27484,7 @@ async function claim(token, pluginId, pluginSecretHash) {
27334
27484
  }
27335
27485
  }
27336
27486
  function pairAutoLockPath() {
27337
- return path67.join(os52.homedir(), ".codeam", "pair-auto.lock");
27487
+ return path68.join(os52.homedir(), ".codeam", "pair-auto.lock");
27338
27488
  }
27339
27489
  function isLivePairAuto(pid) {
27340
27490
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -27354,12 +27504,12 @@ function isLiveCodeam(pid) {
27354
27504
  }
27355
27505
  function daemonLockPath(sessionId) {
27356
27506
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
27357
- return path67.join(os52.homedir(), ".codeam", `daemon-${safe}.lock`);
27507
+ return path68.join(os52.homedir(), ".codeam", `daemon-${safe}.lock`);
27358
27508
  }
27359
27509
  function acquireDaemonLock(sessionId) {
27360
27510
  const lockPath = daemonLockPath(sessionId);
27361
27511
  try {
27362
- fs63.mkdirSync(path67.dirname(lockPath), { recursive: true });
27512
+ fs63.mkdirSync(path68.dirname(lockPath), { recursive: true });
27363
27513
  try {
27364
27514
  fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27365
27515
  } catch (e) {
@@ -27393,7 +27543,7 @@ function acquireDaemonLock(sessionId) {
27393
27543
  function acquireSingletonLock() {
27394
27544
  const lockPath = pairAutoLockPath();
27395
27545
  try {
27396
- fs63.mkdirSync(path67.dirname(lockPath), { recursive: true });
27546
+ fs63.mkdirSync(path68.dirname(lockPath), { recursive: true });
27397
27547
  try {
27398
27548
  fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27399
27549
  } catch (e) {
@@ -27857,7 +28007,7 @@ var AgentService = class _AgentService {
27857
28007
  };
27858
28008
 
27859
28009
  // src/agents/acp/adapters.ts
27860
- var path69 = __toESM(require("path"));
28010
+ var path70 = __toESM(require("path"));
27861
28011
 
27862
28012
  // src/agents/acp/agent-binary.ts
27863
28013
  var import_fs6 = __toESM(require("fs"));
@@ -28033,11 +28183,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
28033
28183
 
28034
28184
  // src/agents/kimi/installer.ts
28035
28185
  var import_node_child_process27 = require("child_process");
28036
- var import_node_os11 = require("os");
28186
+ var import_node_os10 = require("os");
28037
28187
  var import_node_path9 = require("path");
28038
28188
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
28039
28189
  function kimiBinDir() {
28040
- return (0, import_node_path9.join)(process.env.KIMI_CODE_HOME || (0, import_node_path9.join)((0, import_node_os11.homedir)(), ".kimi-code"), "bin");
28190
+ return (0, import_node_path9.join)(process.env.KIMI_CODE_HOME || (0, import_node_path9.join)((0, import_node_os10.homedir)(), ".kimi-code"), "bin");
28041
28191
  }
28042
28192
  function kimiRuns() {
28043
28193
  const r = (0, import_node_child_process27.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
@@ -28085,11 +28235,11 @@ async function ensureKimiInstalled() {
28085
28235
 
28086
28236
  // src/agents/opencode/installer.ts
28087
28237
  var import_node_child_process28 = require("child_process");
28088
- var import_node_os12 = require("os");
28238
+ var import_node_os11 = require("os");
28089
28239
  var import_node_path10 = require("path");
28090
28240
  var INSTALL_URL3 = "https://opencode.ai/install";
28091
28241
  function opencodeBinDir() {
28092
- return (0, import_node_path10.join)(process.env.OPENCODE_HOME || (0, import_node_path10.join)((0, import_node_os12.homedir)(), ".opencode"), "bin");
28242
+ return (0, import_node_path10.join)(process.env.OPENCODE_HOME || (0, import_node_path10.join)((0, import_node_os11.homedir)(), ".opencode"), "bin");
28093
28243
  }
28094
28244
  function opencodeRuns() {
28095
28245
  const r = (0, import_node_child_process28.spawnSync)("opencode", ["--version"], { stdio: "ignore", timeout: 15e3 });
@@ -28147,13 +28297,13 @@ function resolveBin(pkgName, binName) {
28147
28297
  try {
28148
28298
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
28149
28299
  const manifest = require_(`${pkgName}/package.json`);
28150
- const pkgDir = path69.dirname(manifestPath);
28300
+ const pkgDir = path70.dirname(manifestPath);
28151
28301
  const bin = manifest.bin;
28152
28302
  if (!bin) return null;
28153
- if (typeof bin === "string") return path69.resolve(pkgDir, bin);
28303
+ if (typeof bin === "string") return path70.resolve(pkgDir, bin);
28154
28304
  const target = binName ?? Object.keys(bin)[0];
28155
28305
  if (!target || !bin[target]) return null;
28156
- return path69.resolve(pkgDir, bin[target]);
28306
+ return path70.resolve(pkgDir, bin[target]);
28157
28307
  } catch {
28158
28308
  return null;
28159
28309
  }
@@ -28304,7 +28454,7 @@ var import_node_crypto11 = require("crypto");
28304
28454
 
28305
28455
  // src/services/history.service.ts
28306
28456
  var fs65 = __toESM(require("fs"));
28307
- var path70 = __toESM(require("path"));
28457
+ var path71 = __toESM(require("path"));
28308
28458
  var os54 = __toESM(require("os"));
28309
28459
  var https7 = __toESM(require("https"));
28310
28460
  var http6 = __toESM(require("http"));
@@ -28473,7 +28623,7 @@ var HistoryService = class _HistoryService {
28473
28623
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
28474
28624
  }
28475
28625
  get projectDir() {
28476
- return this.runtime.resolveHistoryDir(this.cwd) ?? path70.join(os54.homedir(), ".claude", "projects", encodeCwd(this.cwd));
28626
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path71.join(os54.homedir(), ".claude", "projects", encodeCwd(this.cwd));
28477
28627
  }
28478
28628
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
28479
28629
  setCurrentConversationId(id) {
@@ -28485,7 +28635,7 @@ var HistoryService = class _HistoryService {
28485
28635
  /** Return the current message count in the active conversation. */
28486
28636
  getCurrentMessageCount() {
28487
28637
  if (!this.currentConversationId) return 0;
28488
- const filePath = path70.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28638
+ const filePath = path71.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28489
28639
  return parseJsonl(filePath).length;
28490
28640
  }
28491
28641
  /**
@@ -28496,7 +28646,7 @@ var HistoryService = class _HistoryService {
28496
28646
  const deadline = Date.now() + timeoutMs;
28497
28647
  while (Date.now() < deadline) {
28498
28648
  if (!this.currentConversationId) return null;
28499
- const filePath = path70.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28649
+ const filePath = path71.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28500
28650
  const messages = parseJsonl(filePath);
28501
28651
  if (messages.length > previousCount) {
28502
28652
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -28524,14 +28674,14 @@ var HistoryService = class _HistoryService {
28524
28674
  try {
28525
28675
  const files = fs65.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
28526
28676
  try {
28527
- const stat3 = fs65.statSync(path70.join(dir, e.name));
28677
+ const stat3 = fs65.statSync(path71.join(dir, e.name));
28528
28678
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
28529
28679
  } catch {
28530
28680
  return { name: e.name, mtime: 0, birthtime: 0 };
28531
28681
  }
28532
28682
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
28533
28683
  if (files.length > 0) {
28534
- this.currentConversationId = path70.basename(files[0].name, ".jsonl");
28684
+ this.currentConversationId = path71.basename(files[0].name, ".jsonl");
28535
28685
  }
28536
28686
  } catch {
28537
28687
  }
@@ -28571,7 +28721,7 @@ var HistoryService = class _HistoryService {
28571
28721
  }
28572
28722
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
28573
28723
  try {
28574
- const stat3 = fs65.statSync(path70.join(dir, e.name));
28724
+ const stat3 = fs65.statSync(path71.join(dir, e.name));
28575
28725
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
28576
28726
  } catch {
28577
28727
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -28580,7 +28730,7 @@ var HistoryService = class _HistoryService {
28580
28730
  if (files.length === 0) return null;
28581
28731
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
28582
28732
  if (!files.some((f) => f.name === targetFile)) return null;
28583
- return this.extractUsageFromFile(path70.join(dir, targetFile));
28733
+ return this.extractUsageFromFile(path71.join(dir, targetFile));
28584
28734
  }
28585
28735
  extractUsageFromFile(filePath) {
28586
28736
  let raw;
@@ -28632,7 +28782,7 @@ var HistoryService = class _HistoryService {
28632
28782
  try {
28633
28783
  files = fs65.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
28634
28784
  try {
28635
- return fs65.statSync(path70.join(projectDir, f)).mtimeMs >= monthStartMs;
28785
+ return fs65.statSync(path71.join(projectDir, f)).mtimeMs >= monthStartMs;
28636
28786
  } catch {
28637
28787
  return false;
28638
28788
  }
@@ -28643,7 +28793,7 @@ var HistoryService = class _HistoryService {
28643
28793
  for (const file of files) {
28644
28794
  let raw;
28645
28795
  try {
28646
- raw = fs65.readFileSync(path70.join(projectDir, file), "utf8");
28796
+ raw = fs65.readFileSync(path71.join(projectDir, file), "utf8");
28647
28797
  } catch {
28648
28798
  continue;
28649
28799
  }
@@ -28722,7 +28872,7 @@ var HistoryService = class _HistoryService {
28722
28872
  if (this.runtime.resolveHistoryFile) {
28723
28873
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
28724
28874
  }
28725
- return path70.join(this.projectDir, `${sessionId}.jsonl`);
28875
+ return path71.join(this.projectDir, `${sessionId}.jsonl`);
28726
28876
  }
28727
28877
  /**
28728
28878
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -28756,7 +28906,7 @@ var HistoryService = class _HistoryService {
28756
28906
  };
28757
28907
  });
28758
28908
  }
28759
- return parseJsonl(path70.join(this.projectDir, `${sessionId}.jsonl`));
28909
+ return parseJsonl(path71.join(this.projectDir, `${sessionId}.jsonl`));
28760
28910
  }
28761
28911
  async loadConversation(sessionId) {
28762
28912
  const messages = this.readConversation(sessionId);
@@ -28902,7 +29052,7 @@ var import_node_child_process29 = require("child_process");
28902
29052
  var fs66 = __toESM(require("fs/promises"));
28903
29053
  var fsSync = __toESM(require("fs"));
28904
29054
  var os56 = __toESM(require("os"));
28905
- var path72 = __toESM(require("path"));
29055
+ var path73 = __toESM(require("path"));
28906
29056
  var import_node_stream = require("stream");
28907
29057
 
28908
29058
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -32928,7 +33078,7 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
32928
33078
  }
32929
33079
 
32930
33080
  // src/agents/acp/internal-paths.ts
32931
- var path71 = __toESM(require("path"));
33081
+ var path72 = __toESM(require("path"));
32932
33082
  var os55 = __toESM(require("os"));
32933
33083
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
32934
33084
  var SELF_HOSTED_WORKSPACE_RE = /\.codeam[/\\]self-hosted/gi;
@@ -32939,11 +33089,11 @@ function textReferencesInternal(text) {
32939
33089
  }
32940
33090
  function pathIsInternal(p2, homeDir2 = os55.homedir()) {
32941
33091
  if (!p2) return false;
32942
- const abs = path71.resolve(p2);
32943
- const home = path71.resolve(homeDir2);
32944
- const within = (root) => abs === root || abs.startsWith(root + path71.sep);
32945
- if (within(path71.join(home, ".codeam", "self-hosted"))) return false;
32946
- return within(path71.join(home, ".codeam")) || within(path71.join(home, ".beads")) || abs === path71.join(home, ".codeam-host.log") || abs.includes(`${path71.sep}house-claude${path71.sep}`) || abs.endsWith(`${path71.sep}house-claude`);
33092
+ const abs = path72.resolve(p2);
33093
+ const home = path72.resolve(homeDir2);
33094
+ const within = (root) => abs === root || abs.startsWith(root + path72.sep);
33095
+ if (within(path72.join(home, ".codeam", "self-hosted"))) return false;
33096
+ return within(path72.join(home, ".codeam")) || within(path72.join(home, ".beads")) || abs === path72.join(home, ".codeam-host.log") || abs.includes(`${path72.sep}house-claude${path72.sep}`) || abs.endsWith(`${path72.sep}house-claude`);
32947
33097
  }
32948
33098
  function toolCallReferencesInternal(call) {
32949
33099
  if (textReferencesInternal(call.title)) return true;
@@ -33990,24 +34140,24 @@ function knownAgentBinaryDirs() {
33990
34140
  out2.push("/tmp/codeam-node20/bin");
33991
34141
  for (const root of [
33992
34142
  "/usr/local/share/nvm/versions/node",
33993
- path72.join(home, ".nvm/versions/node")
34143
+ path73.join(home, ".nvm/versions/node")
33994
34144
  ]) {
33995
34145
  try {
33996
34146
  for (const child of fsSync.readdirSync(root)) {
33997
- out2.push(path72.join(root, child, "bin"));
34147
+ out2.push(path73.join(root, child, "bin"));
33998
34148
  }
33999
34149
  } catch {
34000
34150
  }
34001
34151
  }
34002
- out2.push(path72.join(home, ".volta/bin"));
34152
+ out2.push(path73.join(home, ".volta/bin"));
34003
34153
  out2.push("/usr/local/bin");
34004
34154
  out2.push("/usr/bin");
34005
- out2.push(path72.join(home, ".local/bin"));
34006
- out2.push(path72.join(home, "bin"));
34155
+ out2.push(path73.join(home, ".local/bin"));
34156
+ out2.push(path73.join(home, "bin"));
34007
34157
  if (process.platform === "win32") {
34008
34158
  const { LOCALAPPDATA, APPDATA } = process.env;
34009
- if (LOCALAPPDATA) out2.push(path72.join(LOCALAPPDATA, "cursor-agent"));
34010
- if (APPDATA) out2.push(path72.join(APPDATA, "npm"));
34159
+ if (LOCALAPPDATA) out2.push(path73.join(LOCALAPPDATA, "cursor-agent"));
34160
+ if (APPDATA) out2.push(path73.join(APPDATA, "npm"));
34011
34161
  }
34012
34162
  return out2.filter((p2) => {
34013
34163
  try {
@@ -34019,7 +34169,7 @@ function knownAgentBinaryDirs() {
34019
34169
  }
34020
34170
  function expandPathForAgentBinaries(existingPath) {
34021
34171
  const existing = new Set(
34022
- existingPath.split(path72.delimiter).filter((p2) => p2.length > 0)
34172
+ existingPath.split(path73.delimiter).filter((p2) => p2.length > 0)
34023
34173
  );
34024
34174
  const additions = [];
34025
34175
  for (const dir of knownAgentBinaryDirs()) {
@@ -34029,7 +34179,7 @@ function expandPathForAgentBinaries(existingPath) {
34029
34179
  }
34030
34180
  }
34031
34181
  if (additions.length === 0) return existingPath;
34032
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path72.delimiter);
34182
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path73.delimiter);
34033
34183
  }
34034
34184
 
34035
34185
  // src/agents/acp/headroom-budget-proxy.ts
@@ -34513,12 +34663,12 @@ function commonPrefixLength(a, b) {
34513
34663
  var import_child_process27 = require("child_process");
34514
34664
  var fs67 = __toESM(require("fs"));
34515
34665
  var os57 = __toESM(require("os"));
34516
- var path73 = __toESM(require("path"));
34666
+ var path74 = __toESM(require("path"));
34517
34667
  var _onboardingSeam = {
34518
- markerPath: (sessionId) => path73.join(os57.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34668
+ markerPath: (sessionId) => path74.join(os57.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34519
34669
  exists: (p2) => fs67.existsSync(p2),
34520
34670
  write: (p2) => {
34521
- fs67.mkdirSync(path73.dirname(p2), { recursive: true });
34671
+ fs67.mkdirSync(path74.dirname(p2), { recursive: true });
34522
34672
  fs67.writeFileSync(p2, "");
34523
34673
  },
34524
34674
  disabled: () => {
@@ -34556,7 +34706,7 @@ function resolveRepoName(cwd) {
34556
34706
  if (name) return name;
34557
34707
  }
34558
34708
  }
34559
- const base = path73.basename(cwd || "");
34709
+ const base = path74.basename(cwd || "");
34560
34710
  if (base && !isUuid(base)) return base;
34561
34711
  return "this project";
34562
34712
  }
@@ -34815,12 +34965,12 @@ var import_crypto5 = require("crypto");
34815
34965
  // src/services/turn-files/git-changeset.ts
34816
34966
  var import_child_process28 = require("child_process");
34817
34967
  var fs69 = __toESM(require("fs/promises"));
34818
- var path75 = __toESM(require("path"));
34968
+ var path76 = __toESM(require("path"));
34819
34969
 
34820
34970
  // src/services/turn-files/review-ignore.ts
34821
34971
  var import_ignore2 = __toESM(require("ignore"));
34822
34972
  var fs68 = __toESM(require("fs"));
34823
- var path74 = __toESM(require("path"));
34973
+ var path75 = __toESM(require("path"));
34824
34974
  var CURATED_REVIEW_IGNORE = [
34825
34975
  // Google Cloud SDK (the incident) — installs a huge python tree.
34826
34976
  "google-cloud-sdk/",
@@ -34859,7 +35009,7 @@ var CURATED_REVIEW_IGNORE = [
34859
35009
  function makeReviewIgnore(repoRoot) {
34860
35010
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
34861
35011
  try {
34862
- const custom = fs68.readFileSync(path74.join(repoRoot, ".codeam", "reviewignore"), "utf8");
35012
+ const custom = fs68.readFileSync(path75.join(repoRoot, ".codeam", "reviewignore"), "utf8");
34863
35013
  ig.add(custom);
34864
35014
  } catch {
34865
35015
  }
@@ -34904,7 +35054,7 @@ async function collectRepoChangeset(opts) {
34904
35054
  let stats;
34905
35055
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
34906
35056
  const lineCount = await readUntrackedLineCount(
34907
- path75.join(opts.repoRoot, row.filePath)
35057
+ path76.join(opts.repoRoot, row.filePath)
34908
35058
  );
34909
35059
  stats = { added: lineCount, removed: 0 };
34910
35060
  } else {
@@ -35046,8 +35196,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
35046
35196
  if (hasGit) {
35047
35197
  out2.push({
35048
35198
  repoRoot: dir,
35049
- repoPath: path75.relative(workingDir, dir),
35050
- repoName: path75.basename(dir)
35199
+ repoPath: path76.relative(workingDir, dir),
35200
+ repoName: path76.basename(dir)
35051
35201
  });
35052
35202
  return;
35053
35203
  }
@@ -35055,14 +35205,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
35055
35205
  if (!entry.isDirectory) continue;
35056
35206
  if (entry.name === "node_modules") continue;
35057
35207
  if (entry.name === "dist" || entry.name === "build") continue;
35058
- await walk(path75.join(dir, entry.name), depth + 1);
35208
+ await walk(path76.join(dir, entry.name), depth + 1);
35059
35209
  }
35060
35210
  }
35061
35211
  }
35062
35212
 
35063
35213
  // src/services/turn-files/files-outbox.ts
35064
35214
  var fs70 = __toESM(require("fs/promises"));
35065
- var path76 = __toESM(require("path"));
35215
+ var path77 = __toESM(require("path"));
35066
35216
  var import_os12 = require("os");
35067
35217
  var HOME_OUTBOX_DIR = ".codeam/outbox";
35068
35218
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -35095,15 +35245,15 @@ var FilesOutbox = class {
35095
35245
  backoffIndex = 0;
35096
35246
  stopped = false;
35097
35247
  constructor(opts) {
35098
- const base = opts.baseDir ?? path76.join(homeDir(), HOME_OUTBOX_DIR);
35099
- this.filePath = path76.join(base, `${opts.sessionId}.jsonl`);
35248
+ const base = opts.baseDir ?? path77.join(homeDir(), HOME_OUTBOX_DIR);
35249
+ this.filePath = path77.join(base, `${opts.sessionId}.jsonl`);
35100
35250
  this.post = opts.post;
35101
35251
  this.autoSchedule = opts.autoSchedule !== false;
35102
35252
  }
35103
35253
  /** Persist the entry to disk and trigger a flush. Returns once the
35104
35254
  * line is durable on disk (not once the POST succeeds). */
35105
35255
  async enqueue(entry) {
35106
- await fs70.mkdir(path76.dirname(this.filePath), { recursive: true });
35256
+ await fs70.mkdir(path77.dirname(this.filePath), { recursive: true });
35107
35257
  await fs70.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
35108
35258
  this.backoffIndex = 0;
35109
35259
  if (this.autoSchedule) this.scheduleFlush(0);
@@ -35681,7 +35831,7 @@ async function postBudgetReached(opts, fetchImpl = fetch) {
35681
35831
  // src/packs/gates.ts
35682
35832
  var import_node_child_process30 = require("child_process");
35683
35833
  var fs71 = __toESM(require("fs"));
35684
- var path77 = __toESM(require("path"));
35834
+ var path78 = __toESM(require("path"));
35685
35835
  var defaultCommandRunner = (file, args2, cwd, timeoutMs) => new Promise((resolve9) => {
35686
35836
  (0, import_node_child_process30.execFile)(
35687
35837
  file,
@@ -35718,14 +35868,14 @@ var NO_TEST_PLACEHOLDER = 'echo "Error: no test specified"';
35718
35868
  var CHECKS_TIMEOUT_MS = 5 * 6e4;
35719
35869
  function detectChecksCommand(cwd) {
35720
35870
  try {
35721
- const cfg = JSON.parse(fs71.readFileSync(path77.join(cwd, ".codeam", "pack.json"), "utf8"));
35871
+ const cfg = JSON.parse(fs71.readFileSync(path78.join(cwd, ".codeam", "pack.json"), "utf8"));
35722
35872
  if (typeof cfg.checksCommand === "string" && cfg.checksCommand.trim().length > 0) {
35723
35873
  return cfg.checksCommand.trim();
35724
35874
  }
35725
35875
  } catch {
35726
35876
  }
35727
35877
  try {
35728
- const pkg = JSON.parse(fs71.readFileSync(path77.join(cwd, "package.json"), "utf8"));
35878
+ const pkg = JSON.parse(fs71.readFileSync(path78.join(cwd, "package.json"), "utf8"));
35729
35879
  const test = pkg.scripts?.test;
35730
35880
  if (typeof test === "string" && test.trim().length > 0 && !test.includes(NO_TEST_PLACEHOLDER)) {
35731
35881
  return "npm test";
@@ -35744,36 +35894,36 @@ ${res.stderr}`.trim();
35744
35894
 
35745
35895
  // src/packs/run-store.ts
35746
35896
  var fs72 = __toESM(require("fs"));
35747
- var path78 = __toESM(require("path"));
35897
+ var path79 = __toESM(require("path"));
35748
35898
  var crypto5 = __toESM(require("crypto"));
35749
35899
  function packsDir(cwd) {
35750
- return path78.join(cwd, ".codeam", "packs");
35900
+ return path79.join(cwd, ".codeam", "packs");
35751
35901
  }
35752
35902
  function runDir(cwd, runId) {
35753
- return path78.join(packsDir(cwd), runId);
35903
+ return path79.join(packsDir(cwd), runId);
35754
35904
  }
35755
35905
  function newRunId() {
35756
35906
  return `pk_${Date.now().toString(36)}_${crypto5.randomBytes(4).toString("hex")}`;
35757
35907
  }
35758
35908
  function writeJsonAtomic(file, value) {
35759
- fs72.mkdirSync(path78.dirname(file), { recursive: true });
35909
+ fs72.mkdirSync(path79.dirname(file), { recursive: true });
35760
35910
  const tmp = `${file}.tmp`;
35761
35911
  fs72.writeFileSync(tmp, JSON.stringify(value, null, 2));
35762
35912
  fs72.renameSync(tmp, file);
35763
35913
  }
35764
35914
  function saveRun(cwd, state) {
35765
- writeJsonAtomic(path78.join(runDir(cwd, state.runId), "run.json"), state);
35915
+ writeJsonAtomic(path79.join(runDir(cwd, state.runId), "run.json"), state);
35766
35916
  }
35767
35917
  function saveStageHandoff(cwd, runId, stageIndex, role, handoff) {
35768
35918
  const name = `${String(stageIndex + 1).padStart(2, "0")}-${role}.json`;
35769
- writeJsonAtomic(path78.join(runDir(cwd, runId), name), handoff);
35919
+ writeJsonAtomic(path79.join(runDir(cwd, runId), name), handoff);
35770
35920
  }
35771
35921
  function loadLatestRun(cwd) {
35772
35922
  try {
35773
35923
  const dir = packsDir(cwd);
35774
35924
  const entries = fs72.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
35775
35925
  for (let i = entries.length - 1; i >= 0; i--) {
35776
- const file = path78.join(dir, entries[i], "run.json");
35926
+ const file = path79.join(dir, entries[i], "run.json");
35777
35927
  try {
35778
35928
  const parsed = JSON.parse(fs72.readFileSync(file, "utf8"));
35779
35929
  if (parsed && typeof parsed.runId === "string") return parsed;
@@ -35786,16 +35936,16 @@ function loadLatestRun(cwd) {
35786
35936
  }
35787
35937
  function ensureLedgerIgnored(cwd) {
35788
35938
  try {
35789
- const gitDir = path78.join(cwd, ".git");
35939
+ const gitDir = path79.join(cwd, ".git");
35790
35940
  if (!fs72.existsSync(gitDir)) return;
35791
- const exclude = path78.join(gitDir, "info", "exclude");
35941
+ const exclude = path79.join(gitDir, "info", "exclude");
35792
35942
  let existing = "";
35793
35943
  try {
35794
35944
  existing = fs72.readFileSync(exclude, "utf8");
35795
35945
  } catch {
35796
35946
  }
35797
35947
  if (existing.includes(".codeam/packs/")) return;
35798
- fs72.mkdirSync(path78.dirname(exclude), { recursive: true });
35948
+ fs72.mkdirSync(path79.dirname(exclude), { recursive: true });
35799
35949
  fs72.writeFileSync(exclude, `${existing.trimEnd()}
35800
35950
  .codeam/packs/
35801
35951
  `.trimStart());
@@ -36250,11 +36400,11 @@ function buildMcpServersForStart(ctx) {
36250
36400
  }
36251
36401
 
36252
36402
  // src/integrations/detect-stack.ts
36253
- var import_node_fs11 = __toESM(require("fs"));
36403
+ var import_node_fs12 = __toESM(require("fs"));
36254
36404
  var import_node_path11 = __toESM(require("path"));
36255
36405
  function readSafe(cwd, rel) {
36256
36406
  try {
36257
- return import_node_fs11.default.readFileSync(import_node_path11.default.join(cwd, rel), "utf8");
36407
+ return import_node_fs12.default.readFileSync(import_node_path11.default.join(cwd, rel), "utf8");
36258
36408
  } catch {
36259
36409
  return "";
36260
36410
  }
@@ -36388,18 +36538,18 @@ function buildAcpPromptBlocks(payload) {
36388
36538
 
36389
36539
  // src/agents/agent-standard.ts
36390
36540
  var fs74 = __toESM(require("fs"));
36391
- var path80 = __toESM(require("path"));
36541
+ var path81 = __toESM(require("path"));
36392
36542
  var os58 = __toESM(require("os"));
36393
36543
  function ensureAgentStandard(homeDir2 = os58.homedir()) {
36394
36544
  try {
36395
- const file = path80.join(homeDir2, ".claude", "CLAUDE.md");
36545
+ const file = path81.join(homeDir2, ".claude", "CLAUDE.md");
36396
36546
  let existing = "";
36397
36547
  try {
36398
36548
  existing = fs74.readFileSync(file, "utf8");
36399
36549
  } catch {
36400
36550
  }
36401
36551
  if (existing.includes(AGENT_STANDARD_MARKER)) return;
36402
- fs74.mkdirSync(path80.dirname(file), { recursive: true });
36552
+ fs74.mkdirSync(path81.dirname(file), { recursive: true });
36403
36553
  const next = existing.trim() ? `${existing.trimEnd()}
36404
36554
 
36405
36555
  ${AGENT_STANDARD_BLOCK}
@@ -36411,10 +36561,10 @@ ${AGENT_STANDARD_BLOCK}
36411
36561
  }
36412
36562
  var _agentStandardSeam = {
36413
36563
  isLocalSession: () => isLocalSession(),
36414
- markerPath: (sessionId) => path80.join(os58.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36564
+ markerPath: (sessionId) => path81.join(os58.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36415
36565
  exists: (p2) => fs74.existsSync(p2),
36416
36566
  write: (p2) => {
36417
- fs74.mkdirSync(path80.dirname(p2), { recursive: true });
36567
+ fs74.mkdirSync(path81.dirname(p2), { recursive: true });
36418
36568
  fs74.writeFileSync(p2, "");
36419
36569
  }
36420
36570
  };
@@ -39085,7 +39235,7 @@ function startClaudeCredentialSync(opts) {
39085
39235
 
39086
39236
  // src/beads/workflow-hint.ts
39087
39237
  var fs75 = __toESM(require("fs"));
39088
- var path81 = __toESM(require("path"));
39238
+ var path82 = __toESM(require("path"));
39089
39239
  var os59 = __toESM(require("os"));
39090
39240
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
39091
39241
  var BEADS_HINT = `${BEADS_HINT_MARKER}
@@ -39102,14 +39252,14 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
39102
39252
  ${BEADS_HINT_MARKER}`;
39103
39253
  function ensureBeadsWorkflowHint(homeDir2 = os59.homedir()) {
39104
39254
  try {
39105
- const file = path81.join(homeDir2, ".claude", "CLAUDE.md");
39255
+ const file = path82.join(homeDir2, ".claude", "CLAUDE.md");
39106
39256
  let existing = "";
39107
39257
  try {
39108
39258
  existing = fs75.readFileSync(file, "utf8");
39109
39259
  } catch {
39110
39260
  }
39111
39261
  if (existing.includes(BEADS_HINT_MARKER)) return;
39112
- fs75.mkdirSync(path81.dirname(file), { recursive: true });
39262
+ fs75.mkdirSync(path82.dirname(file), { recursive: true });
39113
39263
  const next = existing.trim() ? `${existing.trimEnd()}
39114
39264
 
39115
39265
  ${BEADS_HINT}
@@ -39121,8 +39271,8 @@ ${BEADS_HINT}
39121
39271
  }
39122
39272
 
39123
39273
  // src/skills/provision.ts
39124
- var import_node_os13 = __toESM(require("os"));
39125
- function provisionSkillsForStart(home = import_node_os13.default.homedir()) {
39274
+ var import_node_os12 = __toESM(require("os"));
39275
+ function provisionSkillsForStart(home = import_node_os12.default.homedir()) {
39126
39276
  const materialized = [];
39127
39277
  try {
39128
39278
  const manifest = readSkillsManifest();
@@ -39854,11 +40004,11 @@ function keepDeviceAwake(deps = {}) {
39854
40004
  // src/agents/claude/onboarding.ts
39855
40005
  var fs77 = __toESM(require("fs"));
39856
40006
  var os61 = __toESM(require("os"));
39857
- var path82 = __toESM(require("path"));
40007
+ var path83 = __toESM(require("path"));
39858
40008
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
39859
40009
  function ensureClaudeOnboarded(cwd) {
39860
40010
  try {
39861
- const file = path82.join(os61.homedir(), ".claude.json");
40011
+ const file = path83.join(os61.homedir(), ".claude.json");
39862
40012
  let config = {};
39863
40013
  try {
39864
40014
  config = JSON.parse(fs77.readFileSync(file, "utf8"));
@@ -39886,7 +40036,7 @@ function ensureClaudeOnboarded(cwd) {
39886
40036
  }
39887
40037
  }
39888
40038
  if (!changed) return;
39889
- fs77.mkdirSync(path82.dirname(file), { recursive: true });
40039
+ fs77.mkdirSync(path83.dirname(file), { recursive: true });
39890
40040
  fs77.writeFileSync(file, JSON.stringify(config, null, 2));
39891
40041
  log.info(
39892
40042
  "claude",
@@ -40619,7 +40769,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
40619
40769
  var import_child_process29 = require("child_process");
40620
40770
  var import_util4 = require("util");
40621
40771
  var import_picocolors9 = __toESM(require("picocolors"));
40622
- var path83 = __toESM(require("path"));
40772
+ var path84 = __toESM(require("path"));
40623
40773
  var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
40624
40774
  var MAX_BUFFER = 8 * 1024 * 1024;
40625
40775
  function resetStdinForChild() {
@@ -41108,7 +41258,7 @@ var GitHubCodespacesProvider = class {
41108
41258
  });
41109
41259
  }
41110
41260
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
41111
- const remoteDir = path83.posix.dirname(remotePath);
41261
+ const remoteDir = path84.posix.dirname(remotePath);
41112
41262
  const parts = [
41113
41263
  `mkdir -p ${shellQuote(remoteDir)}`,
41114
41264
  `cat > ${shellQuote(remotePath)}`
@@ -41178,7 +41328,7 @@ function shellQuote(s) {
41178
41328
  // src/services/providers/gitpod.ts
41179
41329
  var import_child_process30 = require("child_process");
41180
41330
  var import_util5 = require("util");
41181
- var path84 = __toESM(require("path"));
41331
+ var path85 = __toESM(require("path"));
41182
41332
  var import_picocolors10 = __toESM(require("picocolors"));
41183
41333
  var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
41184
41334
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -41418,7 +41568,7 @@ var GitpodProvider = class {
41418
41568
  });
41419
41569
  }
41420
41570
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
41421
- const remoteDir = path84.posix.dirname(remotePath);
41571
+ const remoteDir = path85.posix.dirname(remotePath);
41422
41572
  const parts = [
41423
41573
  `mkdir -p ${shellQuote2(remoteDir)}`,
41424
41574
  `cat > ${shellQuote2(remotePath)}`
@@ -41454,7 +41604,7 @@ function shellQuote2(s) {
41454
41604
  // src/services/providers/gitlab-workspaces.ts
41455
41605
  var import_child_process31 = require("child_process");
41456
41606
  var import_util6 = require("util");
41457
- var path85 = __toESM(require("path"));
41607
+ var path86 = __toESM(require("path"));
41458
41608
  var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
41459
41609
  var MAX_BUFFER3 = 8 * 1024 * 1024;
41460
41610
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -41714,7 +41864,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41714
41864
  }
41715
41865
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
41716
41866
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
41717
- const remoteDir = path85.posix.dirname(remotePath);
41867
+ const remoteDir = path86.posix.dirname(remotePath);
41718
41868
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
41719
41869
  if (options.mode != null) {
41720
41870
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -41782,7 +41932,7 @@ function shellQuote3(s) {
41782
41932
  // src/services/providers/railway.ts
41783
41933
  var import_child_process32 = require("child_process");
41784
41934
  var import_util7 = require("util");
41785
- var path86 = __toESM(require("path"));
41935
+ var path87 = __toESM(require("path"));
41786
41936
  var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
41787
41937
  var MAX_BUFFER4 = 8 * 1024 * 1024;
41788
41938
  function resetStdinForChild4() {
@@ -42018,7 +42168,7 @@ var RailwayProvider = class {
42018
42168
  if (!projectId || !serviceId) {
42019
42169
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
42020
42170
  }
42021
- const remoteDir = path86.posix.dirname(remotePath);
42171
+ const remoteDir = path87.posix.dirname(remotePath);
42022
42172
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
42023
42173
  if (options.mode != null) {
42024
42174
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -42665,7 +42815,7 @@ var import_node_dns = require("dns");
42665
42815
  var import_node_util5 = require("util");
42666
42816
  var import_node_crypto13 = require("crypto");
42667
42817
  var fs78 = __toESM(require("fs"));
42668
- var path87 = __toESM(require("path"));
42818
+ var path88 = __toESM(require("path"));
42669
42819
  var import_picocolors14 = __toESM(require("picocolors"));
42670
42820
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
42671
42821
  async function checkDns(apiBase2) {
@@ -42721,10 +42871,10 @@ async function checkHealth(apiBase2) {
42721
42871
  }
42722
42872
  }
42723
42873
  function checkConfigDir() {
42724
- const dir = path87.join(require("os").homedir(), ".codeam");
42874
+ const dir = path88.join(require("os").homedir(), ".codeam");
42725
42875
  try {
42726
42876
  fs78.mkdirSync(dir, { recursive: true, mode: 448 });
42727
- const probe = path87.join(dir, ".doctor-probe");
42877
+ const probe = path88.join(dir, ".doctor-probe");
42728
42878
  fs78.writeFileSync(probe, "ok", { mode: 384 });
42729
42879
  const read2 = fs78.readFileSync(probe, "utf8");
42730
42880
  fs78.unlinkSync(probe);
@@ -42791,7 +42941,7 @@ function checkNodePty() {
42791
42941
  detail: "not required on this platform"
42792
42942
  };
42793
42943
  }
42794
- const vendoredPath = path87.join(__dirname, "vendor", "node-pty");
42944
+ const vendoredPath = path88.join(__dirname, "vendor", "node-pty");
42795
42945
  for (const target of [vendoredPath, "node-pty"]) {
42796
42946
  try {
42797
42947
  require(target);
@@ -42833,7 +42983,7 @@ function checkChokidar() {
42833
42983
  }
42834
42984
  async function doctor(args2 = []) {
42835
42985
  const json = args2.includes("--json");
42836
- const cliVersion = true ? "2.62.1" : "0.0.0-dev";
42986
+ const cliVersion = true ? "2.62.2" : "0.0.0-dev";
42837
42987
  const apiBase2 = resolveApiBaseUrl();
42838
42988
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
42839
42989
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -43031,8 +43181,8 @@ async function completion(args2) {
43031
43181
 
43032
43182
  // src/integrations/mcp-run.ts
43033
43183
  var import_node_child_process34 = require("child_process");
43034
- var import_node_fs12 = require("fs");
43035
- var import_node_os14 = __toESM(require("os"));
43184
+ var import_node_fs13 = require("fs");
43185
+ var import_node_os13 = __toESM(require("os"));
43036
43186
  var import_node_path12 = __toESM(require("path"));
43037
43187
 
43038
43188
  // src/integrations/token-client.ts
@@ -43113,13 +43263,13 @@ function commandExists(command2) {
43113
43263
  }
43114
43264
  function localBinCandidates(command2) {
43115
43265
  return [
43116
- import_node_path12.default.join(import_node_os14.default.homedir(), ".local", "bin", command2),
43117
- import_node_path12.default.join(import_node_os14.default.homedir(), ".cargo", "bin", command2)
43266
+ import_node_path12.default.join(import_node_os13.default.homedir(), ".local", "bin", command2),
43267
+ import_node_path12.default.join(import_node_os13.default.homedir(), ".cargo", "bin", command2)
43118
43268
  ];
43119
43269
  }
43120
43270
  function resolveLauncherPath(command2, deps = {
43121
43271
  commandExists,
43122
- existsSync: import_node_fs12.existsSync
43272
+ existsSync: import_node_fs13.existsSync
43123
43273
  }) {
43124
43274
  if (deps.commandExists(command2)) return command2;
43125
43275
  for (const candidate of localBinCandidates(command2)) {
@@ -43224,7 +43374,7 @@ async function mcpRun(args2) {
43224
43374
  // src/commands/version.ts
43225
43375
  var import_picocolors15 = __toESM(require("picocolors"));
43226
43376
  function version2() {
43227
- const v = true ? "2.62.1" : "unknown";
43377
+ const v = true ? "2.62.2" : "unknown";
43228
43378
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
43229
43379
  }
43230
43380