codeam-cli 2.62.0 → 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 +12 -0
  2. package/dist/index.js +927 -752
  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.0" : "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.0",
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",
@@ -8863,6 +8863,7 @@ function computePollDelay({ baseMs, failures }) {
8863
8863
  var fs7 = __toESM(require("fs"));
8864
8864
  var os7 = __toESM(require("os"));
8865
8865
  var path6 = __toESM(require("path"));
8866
+ var net = __toESM(require("net"));
8866
8867
 
8867
8868
  // src/services/headroom/proxy-process.ts
8868
8869
  var import_child_process2 = require("child_process");
@@ -8915,12 +8916,13 @@ function isPidAlive(pid) {
8915
8916
  return false;
8916
8917
  }
8917
8918
  }
8918
- function pidLooksLikeProxy(pid) {
8919
+ function pidLooksLikeProxy(pid, opts = {}) {
8919
8920
  try {
8920
8921
  const cmd = fs5.readFileSync(`/proc/${pid}/cmdline`, "utf8").replace(/\0/g, " ").toLowerCase();
8921
8922
  if (cmd.trim() === "") return false;
8922
8923
  return cmd.includes("headroom") && cmd.includes("proxy");
8923
8924
  } catch {
8925
+ if (opts.strict) return false;
8924
8926
  return isPidAlive(pid);
8925
8927
  }
8926
8928
  }
@@ -8959,7 +8961,7 @@ function findRunningProxyPid() {
8959
8961
  if (!/^\d+$/.test(name)) continue;
8960
8962
  const pid = Number(name);
8961
8963
  if (pid === process.pid) continue;
8962
- if (pidLooksLikeProxy(pid)) return pid;
8964
+ if (pidLooksLikeProxy(pid, { strict: true })) return pid;
8963
8965
  }
8964
8966
  return null;
8965
8967
  }
@@ -9088,6 +9090,7 @@ function spawnHeadroomProxy(logging, opts = {}) {
9088
9090
 
9089
9091
  // src/services/headroom/proxy-supervisor.ts
9090
9092
  var PROXY_STARTUP_GRACE_MS = 45e3;
9093
+ var PRE_TURN_READY_TIMEOUT_MS = 15e4;
9091
9094
  async function ensureHeadroomProxy(deps) {
9092
9095
  if (!deps.isConfigured()) return "skip";
9093
9096
  let alive = false;
@@ -9119,11 +9122,19 @@ async function ensureHeadroomProxyReady(deps, opts = {}) {
9119
9122
  (deps.spawnProxyForce ?? deps.spawnProxy)();
9120
9123
  const sleep5 = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
9121
9124
  const pollMs = opts.pollMs ?? 1500;
9122
- const maxPolls = Math.max(1, Math.ceil((opts.timeoutMs ?? 6e4) / pollMs));
9125
+ const maxPolls = Math.max(1, Math.ceil((opts.timeoutMs ?? PRE_TURN_READY_TIMEOUT_MS) / pollMs));
9123
9126
  for (let i = 0; i < maxPolls; i += 1) {
9124
9127
  await sleep5(pollMs);
9128
+ const elapsed = (i + 1) * pollMs / 1e3;
9125
9129
  if (await deps.probeAlive().catch(() => false)) {
9126
- log.info("headroom-supervisor", `proxy :8787 ready after ~${(i + 1) * pollMs / 1e3}s`);
9130
+ log.info("headroom-supervisor", `proxy :8787 ready after ~${elapsed}s`);
9131
+ return true;
9132
+ }
9133
+ if (await (deps.probePortOpen?.() ?? Promise.resolve(false)).catch(() => false)) {
9134
+ log.info(
9135
+ "headroom-supervisor",
9136
+ `proxy :8787 accepting connections after ~${elapsed}s (still warming \u2014 turn is safe to send)`
9137
+ );
9127
9138
  return true;
9128
9139
  }
9129
9140
  }
@@ -9166,6 +9177,20 @@ async function probeProxyAliveReal() {
9166
9177
  clearTimeout(timer);
9167
9178
  }
9168
9179
  }
9180
+ async function probeProxyPortOpenReal() {
9181
+ return new Promise((resolve9) => {
9182
+ const socket = net.connect({ host: "127.0.0.1", port: 8787 });
9183
+ const done = (ok) => {
9184
+ socket.removeAllListeners();
9185
+ socket.destroy();
9186
+ resolve9(ok);
9187
+ };
9188
+ socket.setTimeout(2e3);
9189
+ socket.once("connect", () => done(true));
9190
+ socket.once("timeout", () => done(false));
9191
+ socket.once("error", () => done(false));
9192
+ });
9193
+ }
9169
9194
  function spawnProxyReal() {
9170
9195
  spawnHeadroomProxy({
9171
9196
  tag: "headroom-supervisor",
@@ -9177,6 +9202,7 @@ function makeRealProxySupervisorDeps() {
9177
9202
  return {
9178
9203
  isConfigured: () => isHeadroomConfiguredReal(),
9179
9204
  probeAlive: probeProxyAliveReal,
9205
+ probePortOpen: probeProxyPortOpenReal,
9180
9206
  proxyProcessAlive: () => isHeadroomProxyProcessAlive(),
9181
9207
  proxyStartupAgeMs: () => headroomProxyPidfileAgeMs(Date.now()),
9182
9208
  adoptRunningProxy: () => adoptRunningProxy(),
@@ -9587,7 +9613,7 @@ var CommandRelayService = class _CommandRelayService {
9587
9613
  // fresh + clear the "CLI update available" banner after a self-update
9588
9614
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9589
9615
  // pair/reconnect). Older backends ignore the extra field.
9590
- ..."2.62.0" ? { ideVersion: "2.62.0" } : {}
9616
+ ..."2.62.2" ? { ideVersion: "2.62.2" } : {}
9591
9617
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9592
9618
  }
9593
9619
  /**
@@ -9814,10 +9840,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
9814
9840
  /[\\/]Start Menu([\\/]|$)/i,
9815
9841
  /[\\/]Templates([\\/]|$)/i
9816
9842
  ];
9817
- function isUnsafeWindowsWatchRoot(dir, homedir52) {
9843
+ function isUnsafeWindowsWatchRoot(dir, homedir51) {
9818
9844
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
9819
9845
  const cwd = norm(dir);
9820
- const home = norm(homedir52);
9846
+ const home = norm(homedir51);
9821
9847
  if (cwd === home) return true;
9822
9848
  if (/^[a-z]:$/.test(cwd)) return true;
9823
9849
  const sysRoots = [
@@ -10963,7 +10989,7 @@ function closeAllTerminals() {
10963
10989
  // src/commands/start/handlers.ts
10964
10990
  var fs62 = __toESM(require("fs"));
10965
10991
  var os51 = __toESM(require("os"));
10966
- var path66 = __toESM(require("path"));
10992
+ var path67 = __toESM(require("path"));
10967
10993
  var import_crypto3 = require("crypto");
10968
10994
  var import_child_process24 = require("child_process");
10969
10995
 
@@ -11796,7 +11822,7 @@ function findGitRoot2(startDir) {
11796
11822
  // src/commands/link.ts
11797
11823
  var import_node_crypto8 = require("crypto");
11798
11824
  var fs31 = __toESM(require("fs"));
11799
- var path35 = __toESM(require("path"));
11825
+ var path36 = __toESM(require("path"));
11800
11826
  var import_chokidar = __toESM(require("chokidar"));
11801
11827
  var import_picocolors2 = __toESM(require("picocolors"));
11802
11828
 
@@ -13757,7 +13783,7 @@ function subscribeToPairCompletion(pluginId, onPaired, onTimeout, pollSecret) {
13757
13783
  onPaired(info);
13758
13784
  };
13759
13785
  dispatchers.add(dispatch);
13760
- const connect = () => {
13786
+ const connect2 = () => {
13761
13787
  if (stopped) return;
13762
13788
  const url2 = new URL(`${API_BASE5}/api/commands/pending/stream`);
13763
13789
  url2.searchParams.set("pluginId", pluginId);
@@ -13783,7 +13809,7 @@ function subscribeToPairCompletion(pluginId, onPaired, onTimeout, pollSecret) {
13783
13809
  `sse status=${res.statusCode}; will reconnect in 1s`
13784
13810
  );
13785
13811
  res.resume();
13786
- setTimeout(connect, 1e3);
13812
+ setTimeout(connect2, 1e3);
13787
13813
  return;
13788
13814
  }
13789
13815
  let buf = "";
@@ -13798,23 +13824,23 @@ function subscribeToPairCompletion(pluginId, onPaired, onTimeout, pollSecret) {
13798
13824
  }
13799
13825
  });
13800
13826
  res.on("end", () => {
13801
- if (!stopped) setTimeout(connect, 250);
13827
+ if (!stopped) setTimeout(connect2, 250);
13802
13828
  });
13803
13829
  res.on("error", () => {
13804
- if (!stopped) setTimeout(connect, 1e3);
13830
+ if (!stopped) setTimeout(connect2, 1e3);
13805
13831
  });
13806
13832
  }
13807
13833
  );
13808
13834
  req.on("error", () => {
13809
- if (!stopped) setTimeout(connect, 1e3);
13835
+ if (!stopped) setTimeout(connect2, 1e3);
13810
13836
  });
13811
13837
  req.on("timeout", () => {
13812
13838
  req?.destroy();
13813
- if (!stopped) setTimeout(connect, 250);
13839
+ if (!stopped) setTimeout(connect2, 250);
13814
13840
  });
13815
13841
  req.end();
13816
13842
  };
13817
- connect();
13843
+ connect2();
13818
13844
  timeoutTimer = setTimeout(() => {
13819
13845
  stop();
13820
13846
  onTimeout();
@@ -16091,55 +16117,478 @@ var CodexDeployStrategy = class {
16091
16117
  };
16092
16118
 
16093
16119
  // src/agents/coderabbit/runtime.ts
16094
- var import_node_child_process8 = require("child_process");
16120
+ var import_node_child_process9 = require("child_process");
16095
16121
 
16096
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
16097
16128
  var import_node_child_process6 = require("child_process");
16098
- var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
16099
- async function ensureCoderabbitInstalled(os64) {
16100
- if (os64.findInPath("coderabbit")) return true;
16101
- if (os64.id === "win32") {
16102
- console.error(
16103
- "\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"
16264
+ );
16265
+ return false;
16266
+ }
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`
16104
16297
  );
16105
16298
  return false;
16106
16299
  }
16107
- console.log("\n CodeRabbit CLI not found \u2014 installing via the official script\u2026\n");
16108
- const ok = await new Promise((resolve9) => {
16109
- const INSTALL_TIMEOUT_MS2 = 15e4;
16110
- const proc = (0, import_node_child_process6.spawn)(
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)(
16111
16504
  "sh",
16112
16505
  ["-c", `curl -fsSL --connect-timeout 15 --max-time 120 ${INSTALL_URL} | sh`],
16113
- { stdio: "inherit" }
16506
+ { stdio: ["ignore", "pipe", "pipe"], env }
16114
16507
  );
16508
+ let output = "";
16115
16509
  let settled = false;
16116
- const finish = (v) => {
16510
+ const finish = (code) => {
16117
16511
  if (settled) return;
16118
16512
  settled = true;
16119
16513
  clearTimeout(timer);
16120
- resolve9(v);
16514
+ resolve9({ code, output });
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}`);
16121
16521
  };
16522
+ proc.stdout?.on("data", onData);
16523
+ proc.stderr?.on("data", onData);
16122
16524
  const timer = setTimeout(() => {
16123
- console.error("\n \u2717 CodeRabbit install timed out \u2014 check network egress and retry.\n");
16124
16525
  try {
16125
16526
  proc.kill("SIGKILL");
16126
16527
  } catch {
16127
16528
  }
16128
- finish(false);
16129
- }, INSTALL_TIMEOUT_MS2);
16130
- proc.on("close", (code) => finish(code === 0));
16131
- 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
+ });
16132
16538
  });
16133
- 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
+ }
16134
16576
  os64.augmentPath([`${os64.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
16135
- 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 };
16136
16585
  }
16137
16586
 
16138
16587
  // src/agents/coderabbit/link.ts
16139
- var import_node_child_process7 = require("child_process");
16588
+ var import_node_child_process8 = require("child_process");
16140
16589
  var fs23 = __toESM(require("fs"));
16141
16590
  var os21 = __toESM(require("os"));
16142
- var path27 = __toESM(require("path"));
16591
+ var path28 = __toESM(require("path"));
16143
16592
 
16144
16593
  // src/agents/strategy.ts
16145
16594
  function validateNonEmptyCredential(token) {
@@ -16148,7 +16597,7 @@ function validateNonEmptyCredential(token) {
16148
16597
 
16149
16598
  // src/agents/coderabbit/link.ts
16150
16599
  function authPath() {
16151
- return path27.join(os21.homedir(), ".coderabbit", "auth.json");
16600
+ return path28.join(os21.homedir(), ".coderabbit", "auth.json");
16152
16601
  }
16153
16602
  async function extractLocalCoderabbitToken() {
16154
16603
  const file = authPath();
@@ -16170,10 +16619,14 @@ function coderabbitCredentialLocator() {
16170
16619
  function coderabbitLoginLauncher(os64) {
16171
16620
  return {
16172
16621
  async ensureInstalled() {
16173
- 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;
16174
16627
  },
16175
16628
  launch() {
16176
- 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" });
16177
16630
  }
16178
16631
  };
16179
16632
  }
@@ -16226,8 +16679,8 @@ function pickLine(obj) {
16226
16679
  function toHunk(raw, groupSeverity) {
16227
16680
  if (!raw || typeof raw !== "object") return null;
16228
16681
  const o = raw;
16229
- const path89 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
16230
- 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;
16231
16684
  const message = asString(
16232
16685
  pick(o, [
16233
16686
  "comment",
@@ -16244,7 +16697,7 @@ function toHunk(raw, groupSeverity) {
16244
16697
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
16245
16698
  const locObj = pick(o, ["location"]) ?? o;
16246
16699
  return {
16247
- path: path89.trim(),
16700
+ path: path90.trim(),
16248
16701
  line: pickLine(o) ?? pickLine(locObj),
16249
16702
  severity,
16250
16703
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -16327,10 +16780,10 @@ function parsePlain(stdout) {
16327
16780
  for (const line of stdout.split(/\r?\n/)) {
16328
16781
  const m = line.match(HUNK_LINE_RE);
16329
16782
  if (!m) continue;
16330
- const [, path89, lineNo, sevToken, message] = m;
16331
- if (!path89 || !lineNo || !message) continue;
16783
+ const [, path90, lineNo, sevToken, message] = m;
16784
+ if (!path90 || !lineNo || !message) continue;
16332
16785
  hunks.push({
16333
- path: path89.trim(),
16786
+ path: path90.trim(),
16334
16787
  line: Number(lineNo),
16335
16788
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
16336
16789
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -16430,7 +16883,7 @@ var CoderabbitRuntimeStrategy = class {
16430
16883
  return new Promise((resolve9, reject) => {
16431
16884
  const stdoutBuf = [];
16432
16885
  const stderrBuf = [];
16433
- 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, {
16434
16887
  env: { ...process.env, ...launch.env ?? {} },
16435
16888
  stdio: ["ignore", "pipe", "pipe"]
16436
16889
  });
@@ -16495,37 +16948,37 @@ CodeRabbit review timed out after ${Math.round(
16495
16948
  // src/agents/cursor/history.ts
16496
16949
  var fs24 = __toESM(require("fs"));
16497
16950
  var os22 = __toESM(require("os"));
16498
- var path28 = __toESM(require("path"));
16951
+ var path29 = __toESM(require("path"));
16499
16952
  var import_node_crypto5 = require("crypto");
16500
- var HISTORY_ROOT = path28.join(os22.homedir(), ".cursor", "projects");
16501
- 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");
16502
16955
  var STORE_FILES = ["store.db", "store.db-wal", "store.db-shm"];
16503
16956
  function acpSessionDir(sessionId) {
16504
- return path28.join(CURSOR_HOME, "acp-sessions", sessionId);
16957
+ return path29.join(CURSOR_HOME, "acp-sessions", sessionId);
16505
16958
  }
16506
16959
  function nativeStoreDir(cwd, sessionId) {
16507
- const chatsRoot = path28.join(CURSOR_HOME, "chats");
16960
+ const chatsRoot = path29.join(CURSOR_HOME, "chats");
16508
16961
  let buckets = [];
16509
16962
  try {
16510
16963
  buckets = fs24.readdirSync(chatsRoot);
16511
16964
  } catch {
16512
16965
  }
16513
16966
  for (const b of buckets) {
16514
- const candidate = path28.join(chatsRoot, b, sessionId);
16515
- 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;
16516
16969
  }
16517
- 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);
16518
16971
  return fs24.existsSync(computed) ? computed : null;
16519
16972
  }
16520
16973
  function copyStoreFiles(srcDir, dstDir) {
16521
16974
  fs24.mkdirSync(dstDir, { recursive: true });
16522
16975
  for (const f of STORE_FILES) {
16523
- const dst = path28.join(dstDir, f);
16976
+ const dst = path29.join(dstDir, f);
16524
16977
  if (fs24.existsSync(dst)) fs24.rmSync(dst, { force: true });
16525
16978
  }
16526
16979
  for (const f of STORE_FILES) {
16527
- const src = path28.join(srcDir, f);
16528
- 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));
16529
16982
  }
16530
16983
  }
16531
16984
  function bridgeNativeToAcp(cwd, sessionId) {
@@ -16538,7 +16991,7 @@ function bridgeNativeToAcp(cwd, sessionId) {
16538
16991
  const dst = acpSessionDir(sessionId);
16539
16992
  copyStoreFiles(src, dst);
16540
16993
  fs24.writeFileSync(
16541
- path28.join(dst, "meta.json"),
16994
+ path29.join(dst, "meta.json"),
16542
16995
  JSON.stringify({ schemaVersion: 1, cwd })
16543
16996
  );
16544
16997
  log.info("cursor", `baton bridge native\u2192acp ok (${sessionId.slice(0, 8)})`);
@@ -16549,11 +17002,11 @@ function bridgeNativeToAcp(cwd, sessionId) {
16549
17002
  function bridgeAcpToNative(cwd, sessionId) {
16550
17003
  try {
16551
17004
  const src = acpSessionDir(sessionId);
16552
- if (!fs24.existsSync(path28.join(src, "store.db"))) {
17005
+ if (!fs24.existsSync(path29.join(src, "store.db"))) {
16553
17006
  log.warn("cursor", `baton bridge: no acp store for ${sessionId.slice(0, 8)} \u2014 skip`);
16554
17007
  return;
16555
17008
  }
16556
- 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);
16557
17010
  copyStoreFiles(src, dst);
16558
17011
  log.info("cursor", `baton bridge acp\u2192native ok (${sessionId.slice(0, 8)})`);
16559
17012
  } catch (err) {
@@ -16564,8 +17017,8 @@ function encodeCursorCwd(cwd) {
16564
17017
  return cwd.replace(/^[/\\]+/, "").replace(/[/\\:]/g, "-");
16565
17018
  }
16566
17019
  function resolveHistoryFile3(cwd, sessionId, root = HISTORY_ROOT) {
16567
- const rel = path28.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
16568
- 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);
16569
17022
  if (fs24.existsSync(primary)) return primary;
16570
17023
  let entries;
16571
17024
  try {
@@ -16575,14 +17028,14 @@ function resolveHistoryFile3(cwd, sessionId, root = HISTORY_ROOT) {
16575
17028
  }
16576
17029
  for (const e of entries) {
16577
17030
  if (!e.isDirectory()) continue;
16578
- const candidate = path28.join(root, e.name, rel);
17031
+ const candidate = path29.join(root, e.name, rel);
16579
17032
  if (fs24.existsSync(candidate)) return candidate;
16580
17033
  }
16581
17034
  return null;
16582
17035
  }
16583
17036
  function resolveHistoryDir3(cwd) {
16584
17037
  if (!fs24.existsSync(HISTORY_ROOT)) return null;
16585
- const dir = path28.join(HISTORY_ROOT, encodeCursorCwd(cwd));
17038
+ const dir = path29.join(HISTORY_ROOT, encodeCursorCwd(cwd));
16586
17039
  return fs24.existsSync(dir) ? dir : null;
16587
17040
  }
16588
17041
  function extractText2(content) {
@@ -16631,14 +17084,14 @@ function getCurrentUsage3(_historyDir) {
16631
17084
  }
16632
17085
 
16633
17086
  // src/agents/cursor/link.ts
16634
- var import_node_child_process9 = require("child_process");
17087
+ var import_node_child_process10 = require("child_process");
16635
17088
 
16636
17089
  // src/agents/cursor/local-token.ts
16637
17090
  var fs25 = __toESM(require("fs"));
16638
17091
  var os23 = __toESM(require("os"));
16639
- var path29 = __toESM(require("path"));
17092
+ var path30 = __toESM(require("path"));
16640
17093
  function cursorCredentialsPath() {
16641
- return path29.join(os23.homedir(), ".cursor", "auth.json");
17094
+ return path30.join(os23.homedir(), ".cursor", "auth.json");
16642
17095
  }
16643
17096
  async function extractLocalCursorToken() {
16644
17097
  const file = cursorCredentialsPath();
@@ -16672,7 +17125,7 @@ function cursorLoginLauncher(os64) {
16672
17125
  return false;
16673
17126
  },
16674
17127
  launch() {
16675
- 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" });
16676
17129
  }
16677
17130
  };
16678
17131
  }
@@ -16716,7 +17169,7 @@ function detectCursorSelector(lines) {
16716
17169
  }
16717
17170
 
16718
17171
  // src/agents/cursor/runtime.ts
16719
- var import_node_child_process10 = require("child_process");
17172
+ var import_node_child_process11 = require("child_process");
16720
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;
16721
17174
  var CURSOR_CONTEXT_WINDOW = 2e5;
16722
17175
  var CURSOR_MODELS = [
@@ -16764,7 +17217,7 @@ var CursorRuntimeStrategy = class {
16764
17217
  mintChatId(binary) {
16765
17218
  try {
16766
17219
  const launch = this.os.buildLaunch(binary, ["create-chat"]);
16767
- 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, {
16768
17221
  encoding: "utf8",
16769
17222
  timeout: 2e4,
16770
17223
  stdio: ["ignore", "pipe", "pipe"]
@@ -16887,10 +17340,10 @@ var CursorRuntimeStrategy = class {
16887
17340
 
16888
17341
  // src/agents/aider/history.ts
16889
17342
  var fs26 = __toESM(require("fs"));
16890
- var path30 = __toESM(require("path"));
17343
+ var path31 = __toESM(require("path"));
16891
17344
  var AIDER_HISTORY_FILE = ".aider.chat.history.md";
16892
17345
  function resolveHistoryDir4(cwd) {
16893
- const candidate = path30.join(cwd, AIDER_HISTORY_FILE);
17346
+ const candidate = path31.join(cwd, AIDER_HISTORY_FILE);
16894
17347
  return fs26.existsSync(candidate) ? cwd : null;
16895
17348
  }
16896
17349
  function parseHistoryFile4(_filePath) {
@@ -16901,13 +17354,13 @@ function getCurrentUsage4(_historyDir) {
16901
17354
  }
16902
17355
 
16903
17356
  // src/agents/aider/link.ts
16904
- var import_node_child_process11 = require("child_process");
17357
+ var import_node_child_process12 = require("child_process");
16905
17358
 
16906
17359
  // src/agents/aider/local-token.ts
16907
17360
  var fs27 = __toESM(require("fs"));
16908
17361
  var os24 = __toESM(require("os"));
16909
- var path31 = __toESM(require("path"));
16910
- 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");
16911
17364
  var API_KEY_ENV_VARS = [
16912
17365
  "ANTHROPIC_API_KEY",
16913
17366
  "OPENAI_API_KEY",
@@ -16959,7 +17412,7 @@ function aiderLoginLauncher(os64) {
16959
17412
  console.error(
16960
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"
16961
17414
  );
16962
- 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"], {
16963
17416
  stdio: "ignore"
16964
17417
  });
16965
17418
  }
@@ -17103,14 +17556,14 @@ var AiderRuntimeStrategy = class {
17103
17556
  var import_node_crypto6 = require("crypto");
17104
17557
 
17105
17558
  // src/agents/gemini/link.ts
17106
- var import_node_child_process12 = require("child_process");
17559
+ var import_node_child_process13 = require("child_process");
17107
17560
 
17108
17561
  // src/agents/gemini/local-token.ts
17109
17562
  var fs28 = __toESM(require("fs"));
17110
17563
  var os25 = __toESM(require("os"));
17111
- var path32 = __toESM(require("path"));
17564
+ var path33 = __toESM(require("path"));
17112
17565
  function geminiCredentialsPath() {
17113
- return path32.join(os25.homedir(), ".gemini", "oauth_creds.json");
17566
+ return path33.join(os25.homedir(), ".gemini", "oauth_creds.json");
17114
17567
  }
17115
17568
  function geminiCredentialsPaths() {
17116
17569
  return [geminiCredentialsPath()];
@@ -17168,7 +17621,7 @@ function geminiLoginLauncher() {
17168
17621
  return os64.findInPath("gemini") !== null;
17169
17622
  },
17170
17623
  launch() {
17171
- 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" });
17172
17625
  }
17173
17626
  };
17174
17627
  }
@@ -17176,12 +17629,12 @@ function geminiLoginLauncher() {
17176
17629
  // src/agents/gemini/history.ts
17177
17630
  var fs29 = __toESM(require("fs"));
17178
17631
  var os26 = __toESM(require("os"));
17179
- var path33 = __toESM(require("path"));
17180
- var GEMINI_ROOT = path33.join(os26.homedir(), ".gemini");
17632
+ var path34 = __toESM(require("path"));
17633
+ var GEMINI_ROOT = path34.join(os26.homedir(), ".gemini");
17181
17634
  function projectNameForCwd(cwd, root) {
17182
17635
  try {
17183
17636
  const parsed = JSON.parse(
17184
- fs29.readFileSync(path33.join(root, "projects.json"), "utf8")
17637
+ fs29.readFileSync(path34.join(root, "projects.json"), "utf8")
17185
17638
  );
17186
17639
  const map = parsed.projects;
17187
17640
  if (map && typeof map === "object") {
@@ -17196,7 +17649,7 @@ function projectNameForCwd(cwd, root) {
17196
17649
  } catch (err) {
17197
17650
  log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
17198
17651
  }
17199
- return path33.basename(cwd) || null;
17652
+ return path34.basename(cwd) || null;
17200
17653
  }
17201
17654
  function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17202
17655
  const name = projectNameForCwd(cwd, root);
@@ -17204,7 +17657,7 @@ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17204
17657
  log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
17205
17658
  return null;
17206
17659
  }
17207
- const dir = path33.join(root, "tmp", name, "chats");
17660
+ const dir = path34.join(root, "tmp", name, "chats");
17208
17661
  if (!fs29.existsSync(dir)) {
17209
17662
  log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
17210
17663
  return null;
@@ -17229,10 +17682,10 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17229
17682
  const byName = files.find((f) => id8.length > 0 && f.includes(id8));
17230
17683
  if (byName) {
17231
17684
  log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
17232
- return path33.join(dir, byName);
17685
+ return path34.join(dir, byName);
17233
17686
  }
17234
17687
  for (const f of files) {
17235
- const full = path33.join(dir, f);
17688
+ const full = path34.join(dir, f);
17236
17689
  try {
17237
17690
  const firstLine = fs29.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
17238
17691
  const hdr = JSON.parse(firstLine);
@@ -17247,7 +17700,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17247
17700
  let newest = null;
17248
17701
  for (const f of files) {
17249
17702
  try {
17250
- const mtime = fs29.statSync(path33.join(dir, f)).mtimeMs;
17703
+ const mtime = fs29.statSync(path34.join(dir, f)).mtimeMs;
17251
17704
  if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
17252
17705
  } catch {
17253
17706
  }
@@ -17256,7 +17709,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17256
17709
  "gemini",
17257
17710
  `resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
17258
17711
  );
17259
- return newest ? path33.join(dir, newest.file) : null;
17712
+ return newest ? path34.join(dir, newest.file) : null;
17260
17713
  }
17261
17714
  function extractGeminiText(content) {
17262
17715
  const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
@@ -17325,7 +17778,7 @@ function parseHistoryFile5(filePath) {
17325
17778
  }
17326
17779
  log.trace(
17327
17780
  "gemini",
17328
- `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)` : "")
17329
17782
  );
17330
17783
  return out2;
17331
17784
  }
@@ -17464,39 +17917,39 @@ var GeminiRuntimeStrategy = class {
17464
17917
  };
17465
17918
 
17466
17919
  // src/agents/kimi/runtime.ts
17467
- var import_node_child_process13 = require("child_process");
17920
+ var import_node_child_process14 = require("child_process");
17468
17921
  var import_node_os3 = require("os");
17469
17922
  var import_node_path4 = require("path");
17470
17923
 
17471
17924
  // src/agents/kimi/history.ts
17472
17925
  var fs30 = __toESM(require("fs"));
17473
17926
  var os27 = __toESM(require("os"));
17474
- var path34 = __toESM(require("path"));
17927
+ var path35 = __toESM(require("path"));
17475
17928
  var import_node_crypto7 = require("crypto");
17476
17929
  function kimiHome() {
17477
- 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");
17478
17931
  }
17479
17932
  function workDirKey(cwd) {
17480
17933
  const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
17481
- return `wd_${path34.basename(cwd)}_${hash}`;
17934
+ return `wd_${path35.basename(cwd)}_${hash}`;
17482
17935
  }
17483
17936
  function resolveHistoryDir6(cwd) {
17484
- const dir = path34.join(kimiHome(), "sessions", workDirKey(cwd));
17937
+ const dir = path35.join(kimiHome(), "sessions", workDirKey(cwd));
17485
17938
  if (!fs30.existsSync(dir)) {
17486
17939
  log.debug("kimi", `resolveHistoryDir \u2014 session bucket not present yet: ${dir}`);
17487
17940
  return null;
17488
17941
  }
17489
17942
  return dir;
17490
17943
  }
17491
- var WIRE_REL = path34.join("agents", "main", "wire.jsonl");
17944
+ var WIRE_REL = path35.join("agents", "main", "wire.jsonl");
17492
17945
  function resolveHistoryFile5(cwd, sessionId) {
17493
17946
  const fromIndex = sessionDirFromIndex(sessionId);
17494
17947
  if (fromIndex) {
17495
- const p2 = path34.join(fromIndex, WIRE_REL);
17948
+ const p2 = path35.join(fromIndex, WIRE_REL);
17496
17949
  if (fs30.existsSync(p2)) return p2;
17497
17950
  }
17498
- const bucket2 = path34.join(kimiHome(), "sessions", workDirKey(cwd));
17499
- 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);
17500
17953
  if (fs30.existsSync(computed)) return computed;
17501
17954
  const scanned = scanBucketsForSession(sessionId);
17502
17955
  if (scanned) return scanned;
@@ -17504,7 +17957,7 @@ function resolveHistoryFile5(cwd, sessionId) {
17504
17957
  }
17505
17958
  function sessionDirFromIndex(sessionId) {
17506
17959
  try {
17507
- const raw = fs30.readFileSync(path34.join(kimiHome(), "session_index.jsonl"), "utf8");
17960
+ const raw = fs30.readFileSync(path35.join(kimiHome(), "session_index.jsonl"), "utf8");
17508
17961
  for (const line of raw.split("\n")) {
17509
17962
  if (!line.includes(sessionId)) continue;
17510
17963
  try {
@@ -17520,7 +17973,7 @@ function sessionDirFromIndex(sessionId) {
17520
17973
  return null;
17521
17974
  }
17522
17975
  function scanBucketsForSession(sessionId) {
17523
- const sessionsRoot = path34.join(kimiHome(), "sessions");
17976
+ const sessionsRoot = path35.join(kimiHome(), "sessions");
17524
17977
  let buckets;
17525
17978
  try {
17526
17979
  buckets = fs30.readdirSync(sessionsRoot, { withFileTypes: true });
@@ -17529,13 +17982,13 @@ function scanBucketsForSession(sessionId) {
17529
17982
  }
17530
17983
  for (const b of buckets) {
17531
17984
  if (!b.isDirectory()) continue;
17532
- const candidate = path34.join(sessionsRoot, b.name, sessionId, WIRE_REL);
17985
+ const candidate = path35.join(sessionsRoot, b.name, sessionId, WIRE_REL);
17533
17986
  if (fs30.existsSync(candidate)) return candidate;
17534
17987
  }
17535
17988
  return null;
17536
17989
  }
17537
17990
  async function discoverSessionId2(cwd, opts) {
17538
- const bucket2 = path34.join(kimiHome(), "sessions", workDirKey(cwd));
17991
+ const bucket2 = path35.join(kimiHome(), "sessions", workDirKey(cwd));
17539
17992
  const floor = opts.sinceMs - 2e3;
17540
17993
  const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
17541
17994
  for (; ; ) {
@@ -17558,7 +18011,7 @@ function newestSessionSince(bucket2, floorMs) {
17558
18011
  if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
17559
18012
  let mtime;
17560
18013
  try {
17561
- mtime = fs30.statSync(path34.join(bucket2, e.name)).mtimeMs;
18014
+ mtime = fs30.statSync(path35.join(bucket2, e.name)).mtimeMs;
17562
18015
  } catch {
17563
18016
  continue;
17564
18017
  }
@@ -17753,14 +18206,14 @@ var KimiRuntimeStrategy = class {
17753
18206
  return createOsStrategy().findInPath("kimi") !== null;
17754
18207
  },
17755
18208
  launch() {
17756
- return (0, import_node_child_process13.spawn)("kimi", [], { stdio: "inherit" });
18209
+ return (0, import_node_child_process14.spawn)("kimi", [], { stdio: "inherit" });
17757
18210
  }
17758
18211
  };
17759
18212
  }
17760
18213
  };
17761
18214
 
17762
18215
  // src/agents/opencode/runtime.ts
17763
- var import_node_child_process14 = require("child_process");
18216
+ var import_node_child_process15 = require("child_process");
17764
18217
 
17765
18218
  // src/agents/opencode/local-token.ts
17766
18219
  var API_KEY_ENV_VARS2 = [
@@ -17867,7 +18320,7 @@ var OpencodeRuntimeStrategy = class {
17867
18320
  return createOsStrategy().findInPath("opencode") !== null;
17868
18321
  },
17869
18322
  launch() {
17870
- 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" });
17871
18324
  }
17872
18325
  };
17873
18326
  }
@@ -17957,7 +18410,7 @@ function parseLinkArgs(args2) {
17957
18410
  if (apiKeyFileArg) {
17958
18411
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
17959
18412
  try {
17960
- apiKey = fs31.readFileSync(path35.resolve(filePath), "utf8").trim();
18413
+ apiKey = fs31.readFileSync(path36.resolve(filePath), "utf8").trim();
17961
18414
  } catch (err) {
17962
18415
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
17963
18416
  }
@@ -18084,7 +18537,7 @@ async function link(args2 = []) {
18084
18537
  return;
18085
18538
  }
18086
18539
  if (parsed.tokenFile) {
18087
- const credential = fs31.readFileSync(path35.resolve(parsed.tokenFile), "utf8").trim();
18540
+ const credential = fs31.readFileSync(path36.resolve(parsed.tokenFile), "utf8").trim();
18088
18541
  if (!credential) {
18089
18542
  showError(`--token-file ${parsed.tokenFile} is empty.`);
18090
18543
  process.exit(1);
@@ -18301,16 +18754,15 @@ async function linkDryRunPreflight(ctx) {
18301
18754
  }
18302
18755
 
18303
18756
  // src/agents/coderabbit/configure.ts
18304
- var import_node_child_process16 = require("child_process");
18305
- var import_node_os4 = require("os");
18306
- var import_node_fs5 = require("fs");
18307
- 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"));
18308
18760
 
18309
18761
  // src/agents/coderabbit/oauth.ts
18310
- var import_node_child_process15 = require("child_process");
18762
+ var import_node_child_process16 = require("child_process");
18311
18763
  var fs32 = __toESM(require("fs"));
18312
18764
  var os28 = __toESM(require("os"));
18313
- var path36 = __toESM(require("path"));
18765
+ var path37 = __toESM(require("path"));
18314
18766
  function parseCoderabbitAuthEvent(line) {
18315
18767
  const l = line.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "").trim();
18316
18768
  if (!l || l[0] !== "{") return null;
@@ -18349,7 +18801,7 @@ function parseCoderabbitAuthEvent(line) {
18349
18801
  function resolvePython() {
18350
18802
  for (const bin of ["python3", "python"]) {
18351
18803
  try {
18352
- 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 });
18353
18805
  if (!r.error && r.status === 0) return bin;
18354
18806
  } catch {
18355
18807
  }
@@ -18359,15 +18811,15 @@ function resolvePython() {
18359
18811
  function spawnCoderabbitLoginProc(cmd, args2) {
18360
18812
  const python = resolvePython();
18361
18813
  if (python) {
18362
- const helper = path36.join(os28.tmpdir(), "codeam-cr-pty.py");
18814
+ const helper = path37.join(os28.tmpdir(), "codeam-cr-pty.py");
18363
18815
  fs32.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
18364
- return (0, import_node_child_process15.spawn)(python, [helper, cmd, ...args2], {
18816
+ return (0, import_node_child_process16.spawn)(python, [helper, cmd, ...args2], {
18365
18817
  stdio: ["pipe", "pipe", "pipe"],
18366
18818
  env: { ...process.env, TERM: "xterm-256color", COLUMNS: "220", LINES: "50" },
18367
18819
  shell: false
18368
18820
  });
18369
18821
  }
18370
- 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 });
18371
18823
  }
18372
18824
  var pendingCoderabbitLogin = null;
18373
18825
  function setPendingCoderabbitLogin(handle) {
@@ -18471,7 +18923,7 @@ function runCoderabbitOAuthLogin(deps) {
18471
18923
  });
18472
18924
  }
18473
18925
  function coderabbitDir(home) {
18474
- return path36.join(home ?? os28.homedir(), ".coderabbit");
18926
+ return path37.join(home ?? os28.homedir(), ".coderabbit");
18475
18927
  }
18476
18928
  var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
18477
18929
  function snapshotCredentialDir(home) {
@@ -18486,7 +18938,7 @@ function snapshotCredentialDir(home) {
18486
18938
  for (const e of entries) {
18487
18939
  if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
18488
18940
  try {
18489
- const st3 = fs32.statSync(path36.join(dir, e.name));
18941
+ const st3 = fs32.statSync(path37.join(dir, e.name));
18490
18942
  snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
18491
18943
  } catch {
18492
18944
  }
@@ -18504,7 +18956,7 @@ function diffCapturedCredential(before, home) {
18504
18956
  }
18505
18957
  if (!best) return null;
18506
18958
  try {
18507
- 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") };
18508
18960
  } catch {
18509
18961
  return null;
18510
18962
  }
@@ -18512,7 +18964,7 @@ function diffCapturedCredential(before, home) {
18512
18964
 
18513
18965
  // src/agents/coderabbit/configure.ts
18514
18966
  function defaultIsLoggedIn() {
18515
- 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"], {
18516
18968
  encoding: "utf8",
18517
18969
  timeout: 15e3
18518
18970
  });
@@ -18530,7 +18982,7 @@ function defaultIsLoggedIn() {
18530
18982
  return false;
18531
18983
  }
18532
18984
  function defaultLoginWithApiKey(key) {
18533
- 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], {
18534
18986
  encoding: "utf8",
18535
18987
  timeout: 3e4
18536
18988
  });
@@ -18544,7 +18996,7 @@ function defaultLoginWithApiKey(key) {
18544
18996
  function collectChangedFiles(cwd) {
18545
18997
  const run = (args2) => {
18546
18998
  try {
18547
- 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 });
18548
19000
  return r.status === 0 && typeof r.stdout === "string" ? r.stdout : "";
18549
19001
  } catch {
18550
19002
  return "";
@@ -18580,22 +19032,25 @@ function collectChangedFiles(cwd) {
18580
19032
  }
18581
19033
  return [...byPath.values()];
18582
19034
  }
18583
- function restoreCoderabbitOauthBlob(value) {
18584
- const dir = path37.join((0, import_node_os4.homedir)(), ".coderabbit");
18585
- (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 });
18586
19038
  let file = "auth.json";
18587
19039
  let contents = value.trim();
18588
19040
  if (contents.startsWith("{")) {
18589
19041
  try {
18590
19042
  const parsed = JSON.parse(contents);
18591
19043
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
18592
- file = path37.basename(parsed.file);
19044
+ file = path38.basename(parsed.file);
18593
19045
  contents = parsed.contents;
18594
19046
  }
18595
19047
  } catch {
18596
19048
  }
18597
19049
  }
18598
- (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";
18599
19054
  }
18600
19055
  async function configureCoderabbit(input, deps = {}) {
18601
19056
  const os64 = deps.os ?? createOsStrategy();
@@ -18608,10 +19063,10 @@ async function configureCoderabbit(input, deps = {}) {
18608
19063
  const home = os64.homeDir();
18609
19064
  os64.augmentPath(
18610
19065
  os64.id === "win32" ? [
18611
- path37.join(home, ".local", "bin"),
18612
- path37.join(process.env.APPDATA ?? path37.join(home, "AppData", "Roaming"), "npm"),
18613
- path37.join(home, "scoop", "shims")
18614
- ] : [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"]
18615
19070
  );
18616
19071
  const installed2 = os64.findInPath("coderabbit") !== null;
18617
19072
  const base = () => ({
@@ -18631,9 +19086,9 @@ async function configureCoderabbit(input, deps = {}) {
18631
19086
  const key = (input.apiKey ?? "").trim();
18632
19087
  if (!key) return { ...res2, error: "No API key provided" };
18633
19088
  if (!res2.installed) {
18634
- const ok = await ensureInstalled(os64);
18635
- res2.installed = ok;
18636
- 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) };
18637
19092
  }
18638
19093
  const login = loginWithApiKey(key);
18639
19094
  if (!login.ok) {
@@ -18655,9 +19110,9 @@ async function configureCoderabbit(input, deps = {}) {
18655
19110
  }
18656
19111
  if (!res2.installed) {
18657
19112
  deps.onEvent?.({ kind: "installing" });
18658
- const ok = await ensureInstalled(os64);
18659
- res2.installed = ok;
18660
- 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) };
18661
19116
  }
18662
19117
  if (cred.method === "api_key") {
18663
19118
  const login = loginWithApiKey(cred.credential.trim());
@@ -18672,22 +19127,33 @@ async function configureCoderabbit(input, deps = {}) {
18672
19127
  return { ...res2, loggedIn: true, linked: true };
18673
19128
  }
18674
19129
  try {
18675
- restoreCoderabbitOauthBlob(cred.credential);
19130
+ restoreCoderabbitOauthBlob(os64, cred.credential);
18676
19131
  } catch (err) {
18677
19132
  return {
18678
19133
  ...res2,
18679
19134
  error: err instanceof Error ? err.message : "Failed to restore the vaulted credential"
18680
19135
  };
18681
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
+ }
18682
19148
  return { ...res2, loggedIn: true, linked: true };
18683
19149
  }
18684
19150
  if (input.action === "link_oauth") {
18685
19151
  const res2 = base();
18686
19152
  if (!installed2) {
18687
19153
  deps.onEvent?.({ kind: "installing" });
18688
- const ok = await ensureInstalled(os64);
18689
- res2.installed = ok;
18690
- 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) };
18691
19157
  }
18692
19158
  const before = snapshot();
18693
19159
  const login = await runOAuth({
@@ -18725,9 +19191,9 @@ async function configureCoderabbit(input, deps = {}) {
18725
19191
  }
18726
19192
  const res = base();
18727
19193
  if (!res.installed) {
18728
- const ok = await ensureInstalled(os64);
18729
- res.installed = ok;
18730
- 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) };
18731
19197
  }
18732
19198
  if (!deps.runReview) return { ...res, error: "No reviewer available" };
18733
19199
  const out2 = await deps.runReview(input.review ?? {});
@@ -18753,7 +19219,7 @@ async function configureCoderabbit(input, deps = {}) {
18753
19219
  }
18754
19220
 
18755
19221
  // src/agents/coderabbit/review-pr.ts
18756
- var import_node_child_process17 = require("child_process");
19222
+ var import_node_child_process18 = require("child_process");
18757
19223
  function repoSlug(prRef) {
18758
19224
  return `${prRef.owner}/${prRef.repo}`;
18759
19225
  }
@@ -18887,7 +19353,7 @@ function defaultRunGh(args2) {
18887
19353
  const stderr = [];
18888
19354
  let proc;
18889
19355
  try {
18890
- 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"] });
18891
19357
  } catch (err) {
18892
19358
  resolve9({ code: -1, stdout: "", stderr: err instanceof Error ? err.message : String(err) });
18893
19359
  return;
@@ -18911,17 +19377,17 @@ function defaultRunGh(args2) {
18911
19377
  var import_node_child_process25 = require("child_process");
18912
19378
  var os40 = __toESM(require("os"));
18913
19379
  var fs45 = __toESM(require("fs"));
18914
- var path48 = __toESM(require("path"));
19380
+ var path49 = __toESM(require("path"));
18915
19381
 
18916
19382
  // src/integrations/manifest.ts
18917
- var import_node_fs7 = __toESM(require("fs"));
18918
- var import_node_os6 = __toESM(require("os"));
19383
+ var import_node_fs8 = __toESM(require("fs"));
19384
+ var import_node_os5 = __toESM(require("os"));
18919
19385
  var import_node_path5 = __toESM(require("path"));
18920
19386
 
18921
19387
  // src/lib/restrict-to-owner.ts
18922
- var import_node_fs6 = __toESM(require("fs"));
18923
- var import_node_os5 = __toESM(require("os"));
18924
- 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");
18925
19391
  var BROAD_WINDOWS_SIDS = [
18926
19392
  "*S-1-1-0",
18927
19393
  "*S-1-5-11",
@@ -18932,8 +19398,8 @@ var BROAD_WINDOWS_SIDS = [
18932
19398
  function restrictToOwner(filePath) {
18933
19399
  try {
18934
19400
  if (process.platform === "win32") {
18935
- const username = import_node_os5.default.userInfo().username;
18936
- (0, import_node_child_process18.execFileSync)(
19401
+ const username = import_node_os4.default.userInfo().username;
19402
+ (0, import_node_child_process19.execFileSync)(
18937
19403
  "icacls",
18938
19404
  [
18939
19405
  filePath,
@@ -18945,7 +19411,7 @@ function restrictToOwner(filePath) {
18945
19411
  { stdio: "ignore" }
18946
19412
  );
18947
19413
  } else {
18948
- import_node_fs6.default.chmodSync(filePath, 384);
19414
+ import_node_fs7.default.chmodSync(filePath, 384);
18949
19415
  }
18950
19416
  } catch {
18951
19417
  }
@@ -18953,11 +19419,11 @@ function restrictToOwner(filePath) {
18953
19419
 
18954
19420
  // src/integrations/manifest.ts
18955
19421
  function integrationsManifestPath() {
18956
- 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");
18957
19423
  }
18958
19424
  function readIntegrationsManifest() {
18959
19425
  try {
18960
- const raw = JSON.parse(import_node_fs7.default.readFileSync(integrationsManifestPath(), "utf8"));
19426
+ const raw = JSON.parse(import_node_fs8.default.readFileSync(integrationsManifestPath(), "utf8"));
18961
19427
  if (!Array.isArray(raw?.integrations)) return null;
18962
19428
  return raw;
18963
19429
  } catch {
@@ -18967,10 +19433,10 @@ function readIntegrationsManifest() {
18967
19433
  function persistIntegrationsManifest(m) {
18968
19434
  try {
18969
19435
  const file = integrationsManifestPath();
18970
- 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 });
18971
19437
  const tmp = `${file}.tmp-${process.pid}`;
18972
- import_node_fs7.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
18973
- 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);
18974
19440
  restrictToOwner(file);
18975
19441
  } catch (err) {
18976
19442
  log.warn(
@@ -18981,21 +19447,21 @@ function persistIntegrationsManifest(m) {
18981
19447
  }
18982
19448
  function clearIntegrationsManifest() {
18983
19449
  try {
18984
- import_node_fs7.default.rmSync(integrationsManifestPath(), { force: true });
19450
+ import_node_fs8.default.rmSync(integrationsManifestPath(), { force: true });
18985
19451
  } catch {
18986
19452
  }
18987
19453
  }
18988
19454
 
18989
19455
  // src/skills/manifest.ts
18990
- var import_node_fs8 = __toESM(require("fs"));
18991
- var import_node_os7 = __toESM(require("os"));
19456
+ var import_node_fs9 = __toESM(require("fs"));
19457
+ var import_node_os6 = __toESM(require("os"));
18992
19458
  var import_node_path6 = __toESM(require("path"));
18993
19459
  function skillsManifestPath() {
18994
- 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");
18995
19461
  }
18996
19462
  function readSkillsManifest() {
18997
19463
  try {
18998
- const raw = JSON.parse(import_node_fs8.default.readFileSync(skillsManifestPath(), "utf8"));
19464
+ const raw = JSON.parse(import_node_fs9.default.readFileSync(skillsManifestPath(), "utf8"));
18999
19465
  if (!Array.isArray(raw?.skills)) return null;
19000
19466
  raw.skills = raw.skills.filter(
19001
19467
  (s) => Boolean(s) && typeof s === "object" && typeof s.id === "string"
@@ -19008,10 +19474,10 @@ function readSkillsManifest() {
19008
19474
  function persistSkillsManifest(m) {
19009
19475
  try {
19010
19476
  const file = skillsManifestPath();
19011
- 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 });
19012
19478
  const tmp = `${file}.tmp-${process.pid}`;
19013
- import_node_fs8.default.writeFileSync(tmp, JSON.stringify(m, null, 2), { encoding: "utf8", mode: 384 });
19014
- 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);
19015
19481
  restrictToOwner(file);
19016
19482
  } catch (err) {
19017
19483
  log.warn(
@@ -19022,7 +19488,7 @@ function persistSkillsManifest(m) {
19022
19488
  }
19023
19489
  function clearSkillsManifest() {
19024
19490
  try {
19025
- import_node_fs8.default.rmSync(skillsManifestPath(), { force: true });
19491
+ import_node_fs9.default.rmSync(skillsManifestPath(), { force: true });
19026
19492
  } catch {
19027
19493
  }
19028
19494
  }
@@ -19059,7 +19525,7 @@ function describeReason(reason) {
19059
19525
  // src/commands/host/host-client.ts
19060
19526
  var fs36 = __toESM(require("fs"));
19061
19527
  var os32 = __toESM(require("os"));
19062
- var path40 = __toESM(require("path"));
19528
+ var path41 = __toESM(require("path"));
19063
19529
  var import_node_crypto9 = require("crypto");
19064
19530
  function sampleCpuTimes() {
19065
19531
  let idle = 0;
@@ -19107,7 +19573,7 @@ function apiBase() {
19107
19573
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
19108
19574
  }
19109
19575
  function hostIdentityPath() {
19110
- return path40.join(os32.homedir(), ".codeam", "host-agent.json");
19576
+ return path41.join(os32.homedir(), ".codeam", "host-agent.json");
19111
19577
  }
19112
19578
  function collectOsInfo() {
19113
19579
  return {
@@ -19138,7 +19604,7 @@ function loadHostIdentity() {
19138
19604
  }
19139
19605
  function saveHostIdentity(identity) {
19140
19606
  const file = hostIdentityPath();
19141
- fs36.mkdirSync(path40.dirname(file), { recursive: true, mode: 448 });
19607
+ fs36.mkdirSync(path41.dirname(file), { recursive: true, mode: 448 });
19142
19608
  fs36.writeFileSync(file, JSON.stringify(identity, null, 2), {
19143
19609
  encoding: "utf8",
19144
19610
  mode: 384
@@ -19321,15 +19787,15 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
19321
19787
  // src/commands/host/workspace.ts
19322
19788
  var fs37 = __toESM(require("fs"));
19323
19789
  var os33 = __toESM(require("os"));
19324
- var path41 = __toESM(require("path"));
19325
- var import_node_child_process19 = require("child_process");
19790
+ var path42 = __toESM(require("path"));
19791
+ var import_node_child_process20 = require("child_process");
19326
19792
  var import_node_util4 = require("util");
19327
- 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);
19328
19794
  function isAbsolutePathTarget(target) {
19329
- return path41.isAbsolute(target);
19795
+ return path42.isAbsolute(target);
19330
19796
  }
19331
19797
  function selfHostedWorkspaceRoot() {
19332
- return path41.join(os33.homedir(), ".codeam", "self-hosted");
19798
+ return path42.join(os33.homedir(), ".codeam", "self-hosted");
19333
19799
  }
19334
19800
  function nonInteractiveGitEnv() {
19335
19801
  return {
@@ -19399,7 +19865,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
19399
19865
  const isGitlab = provider === "gitlab";
19400
19866
  if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
19401
19867
  if (!cloneToken) return;
19402
- const credFile = path41.join(dest, ".git", "codeam-credentials");
19868
+ const credFile = path42.join(dest, ".git", "codeam-credentials");
19403
19869
  const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
19404
19870
  ` : `https://x-access-token:${cloneToken}@github.com
19405
19871
  `;
@@ -19407,7 +19873,7 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
19407
19873
  restrictToOwner(credFile);
19408
19874
  const env = nonInteractiveGitEnv();
19409
19875
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
19410
- const credFilePosix = credFile.split(path41.sep).join("/");
19876
+ const credFilePosix = credFile.split(path42.sep).join("/");
19411
19877
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
19412
19878
  });
19413
19879
  await git2([
@@ -19445,8 +19911,8 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
19445
19911
  }
19446
19912
  return repoOrPath;
19447
19913
  }
19448
- const dest = path41.join(selfHostedWorkspaceRoot(), deployId);
19449
- if (fs37.existsSync(path41.join(dest, ".git"))) {
19914
+ const dest = path42.join(selfHostedWorkspaceRoot(), deployId);
19915
+ if (fs37.existsSync(path42.join(dest, ".git"))) {
19450
19916
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
19451
19917
  return dest;
19452
19918
  }
@@ -19470,7 +19936,7 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
19470
19936
  // src/commands/host/agent-provisioning.ts
19471
19937
  var fs38 = __toESM(require("fs"));
19472
19938
  var os34 = __toESM(require("os"));
19473
- var path42 = __toESM(require("path"));
19939
+ var path43 = __toESM(require("path"));
19474
19940
  var PUBLIC_TO_INTERNAL_AGENT = {
19475
19941
  claude_code: "claude",
19476
19942
  claude: "claude",
@@ -19490,7 +19956,7 @@ function ensureDir(dir) {
19490
19956
  fs38.mkdirSync(dir, { recursive: true, mode: 448 });
19491
19957
  }
19492
19958
  function writeFile0600(filePath, contents) {
19493
- ensureDir(path42.dirname(filePath));
19959
+ ensureDir(path43.dirname(filePath));
19494
19960
  fs38.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
19495
19961
  restrictToOwner(filePath);
19496
19962
  }
@@ -19502,7 +19968,7 @@ function rmIfExists(filePath) {
19502
19968
  }
19503
19969
  var claudeProvisioner = {
19504
19970
  write(auth, home) {
19505
- const credentialsJson = path42.join(home, ".claude", ".credentials.json");
19971
+ const credentialsJson = path43.join(home, ".claude", ".credentials.json");
19506
19972
  if (auth.kind === "api_key") {
19507
19973
  rmIfExists(credentialsJson);
19508
19974
  return { ANTHROPIC_API_KEY: auth.value };
@@ -19514,7 +19980,7 @@ var claudeProvisioner = {
19514
19980
  } else {
19515
19981
  rmIfExists(credentialsJson);
19516
19982
  }
19517
- const claudeJson = path42.join(home, ".claude.json");
19983
+ const claudeJson = path43.join(home, ".claude.json");
19518
19984
  if (!fs38.existsSync(claudeJson)) {
19519
19985
  writeFile0600(
19520
19986
  claudeJson,
@@ -19526,7 +19992,7 @@ var claudeProvisioner = {
19526
19992
  };
19527
19993
  var codexProvisioner = {
19528
19994
  write(auth, home) {
19529
- const authJson = path42.join(home, ".codex", "auth.json");
19995
+ const authJson = path43.join(home, ".codex", "auth.json");
19530
19996
  if (auth.kind === "api_key") {
19531
19997
  rmIfExists(authJson);
19532
19998
  return { OPENAI_API_KEY: auth.value };
@@ -19537,8 +20003,8 @@ var codexProvisioner = {
19537
20003
  };
19538
20004
  var geminiProvisioner = {
19539
20005
  write(auth, home) {
19540
- const settingsJson = path42.join(home, ".gemini", "settings.json");
19541
- 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");
19542
20008
  if (auth.kind === "api_key") {
19543
20009
  rmIfExists(oauthCreds);
19544
20010
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -19551,7 +20017,7 @@ var geminiProvisioner = {
19551
20017
  };
19552
20018
  var cursorProvisioner = {
19553
20019
  write(auth, home) {
19554
- const authJson = path42.join(home, ".config", "cursor", "auth.json");
20020
+ const authJson = path43.join(home, ".config", "cursor", "auth.json");
19555
20021
  if (auth.kind === "api_key") {
19556
20022
  rmIfExists(authJson);
19557
20023
  return { CURSOR_API_KEY: auth.value };
@@ -19593,22 +20059,22 @@ max_context_size = 262144
19593
20059
  var kimiProvisioner = {
19594
20060
  write(auth, home) {
19595
20061
  const credentialsFiles = [
19596
- path42.join(home, ".kimi", "credentials", "kimi-code.json"),
19597
- 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")
19598
20064
  ];
19599
20065
  if (auth.kind === "api_key") {
19600
20066
  credentialsFiles.forEach(rmIfExists);
19601
20067
  return { KIMI_API_KEY: auth.value };
19602
20068
  }
19603
20069
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
19604
- 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);
19605
20071
  return {};
19606
20072
  }
19607
20073
  };
19608
20074
  var coderabbitProvisioner = {
19609
20075
  write(auth, home) {
19610
- const dir = path42.join(home, ".coderabbit");
19611
- const authJson = path42.join(dir, "auth.json");
20076
+ const dir = path43.join(home, ".coderabbit");
20077
+ const authJson = path43.join(dir, "auth.json");
19612
20078
  if (auth.kind === "api_key") {
19613
20079
  rmIfExists(authJson);
19614
20080
  return { CODERABBIT_API_KEY: auth.value };
@@ -19620,13 +20086,13 @@ var coderabbitProvisioner = {
19620
20086
  try {
19621
20087
  const parsed = JSON.parse(value);
19622
20088
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
19623
- file = path42.basename(parsed.file);
20089
+ file = path43.basename(parsed.file);
19624
20090
  contents = parsed.contents;
19625
20091
  }
19626
20092
  } catch {
19627
20093
  }
19628
20094
  }
19629
- writeFile0600(path42.join(dir, file), contents);
20095
+ writeFile0600(path43.join(dir, file), contents);
19630
20096
  return {};
19631
20097
  }
19632
20098
  };
@@ -19663,12 +20129,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os34.homedir(
19663
20129
  }
19664
20130
 
19665
20131
  // src/commands/host/git-tooling.ts
19666
- var import_node_child_process20 = require("child_process");
20132
+ var import_node_child_process21 = require("child_process");
19667
20133
  var fs39 = __toESM(require("fs"));
19668
20134
  var os35 = __toESM(require("os"));
19669
- var path43 = __toESM(require("path"));
20135
+ var path44 = __toESM(require("path"));
19670
20136
  function codeamBinDir() {
19671
- 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");
19672
20138
  }
19673
20139
  var FALLBACK_GH_VERSION = "2.62.0";
19674
20140
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -19723,8 +20189,8 @@ async function ensureGhCli(runner, token, deps = {}) {
19723
20189
  const version3 = await resolveVersionFn(token);
19724
20190
  const asset = `gh_${version3}_${osToken}_${arch2}`;
19725
20191
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
19726
- const tmpRoot = fs39.mkdtempSync(path43.join(os35.tmpdir(), "codeam-gh-"));
19727
- 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}`);
19728
20194
  if (!await downloadFn(url2, archive)) {
19729
20195
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
19730
20196
  return null;
@@ -19734,14 +20200,14 @@ async function ensureGhCli(runner, token, deps = {}) {
19734
20200
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
19735
20201
  return null;
19736
20202
  }
19737
- const extractedBin = path43.join(tmpRoot, asset, "bin", binaryName);
20203
+ const extractedBin = path44.join(tmpRoot, asset, "bin", binaryName);
19738
20204
  if (!fs39.existsSync(extractedBin)) {
19739
20205
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
19740
20206
  return null;
19741
20207
  }
19742
20208
  const binDir = codeamBinDir();
19743
20209
  fs39.mkdirSync(binDir, { recursive: true });
19744
- const target = path43.join(binDir, binaryName);
20210
+ const target = path44.join(binDir, binaryName);
19745
20211
  fs39.copyFileSync(extractedBin, target);
19746
20212
  fs39.chmodSync(target, 493);
19747
20213
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
@@ -19803,8 +20269,8 @@ async function ensureGlabCli(runner, deps = {}) {
19803
20269
  const version3 = await resolveLatestGlabVersion();
19804
20270
  const asset = `glab_${version3}_${osToken}_${arch2}`;
19805
20271
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
19806
- const tmpRoot = fs39.mkdtempSync(path43.join(os35.tmpdir(), "codeam-glab-"));
19807
- 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}`);
19808
20274
  if (!await downloadFn(url2, archive)) {
19809
20275
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
19810
20276
  return null;
@@ -19815,9 +20281,9 @@ async function ensureGlabCli(runner, deps = {}) {
19815
20281
  return null;
19816
20282
  }
19817
20283
  const candidates = [
19818
- path43.join(tmpRoot, "bin", binaryName),
19819
- path43.join(tmpRoot, asset, "bin", binaryName),
19820
- path43.join(tmpRoot, binaryName)
20284
+ path44.join(tmpRoot, "bin", binaryName),
20285
+ path44.join(tmpRoot, asset, "bin", binaryName),
20286
+ path44.join(tmpRoot, binaryName)
19821
20287
  ];
19822
20288
  const extractedBin = candidates.find((c2) => fs39.existsSync(c2));
19823
20289
  if (!extractedBin) {
@@ -19826,7 +20292,7 @@ async function ensureGlabCli(runner, deps = {}) {
19826
20292
  }
19827
20293
  const binDir = codeamBinDir();
19828
20294
  fs39.mkdirSync(binDir, { recursive: true });
19829
- const target = path43.join(binDir, binaryName);
20295
+ const target = path44.join(binDir, binaryName);
19830
20296
  fs39.copyFileSync(extractedBin, target);
19831
20297
  fs39.chmodSync(target, 493);
19832
20298
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
@@ -19863,7 +20329,7 @@ var defaultGitToolingRunner = {
19863
20329
  which(cmd) {
19864
20330
  try {
19865
20331
  const probe = process.platform === "win32" ? "where" : "which";
19866
- (0, import_node_child_process20.execFileSync)(probe, [cmd], { stdio: "ignore" });
20332
+ (0, import_node_child_process21.execFileSync)(probe, [cmd], { stdio: "ignore" });
19867
20333
  return true;
19868
20334
  } catch {
19869
20335
  return false;
@@ -19871,7 +20337,7 @@ var defaultGitToolingRunner = {
19871
20337
  },
19872
20338
  run(cmd, args2, opts = {}) {
19873
20339
  return new Promise((resolve9) => {
19874
- const child = (0, import_node_child_process20.spawn)(cmd, args2, {
20340
+ const child = (0, import_node_child_process21.spawn)(cmd, args2, {
19875
20341
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
19876
20342
  });
19877
20343
  let stderr = "";
@@ -20024,313 +20490,22 @@ var HeadroomStatsReporter = class {
20024
20490
  }
20025
20491
  };
20026
20492
 
20027
- // src/commands/host/os-packages.ts
20028
- var import_node_child_process21 = require("child_process");
20029
- var PM_INSTALL_TIMEOUT_MS = 18e4;
20030
- var defaultHeadroomRunner = {
20031
- which(cmd) {
20032
- try {
20033
- (0, import_node_child_process21.execFileSync)("which", [cmd], { stdio: "ignore" });
20034
- return true;
20035
- } catch {
20036
- return false;
20037
- }
20038
- },
20039
- run(cmd, args2, opts = {}) {
20040
- return new Promise((resolve9) => {
20041
- const spawnEnv = opts.env ?? process.env;
20042
- const child = (0, import_node_child_process21.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
20043
- let stderrBuf = "";
20044
- let stdoutBuf = "";
20045
- let settled = false;
20046
- const done = (code) => {
20047
- if (settled) return;
20048
- settled = true;
20049
- resolve9({ code, stderr: stderrBuf, stdout: stdoutBuf });
20050
- };
20051
- child.stdout?.on("data", (b) => {
20052
- const chunk = b.toString();
20053
- stdoutBuf += chunk;
20054
- const line = chunk.replace(/\n+$/, "");
20055
- if (line) log.info("host-agent", `headroom[${cmd}]: ${line}`);
20056
- });
20057
- child.stderr?.on("data", (b) => {
20058
- const chunk = b.toString();
20059
- stderrBuf += chunk;
20060
- const line = chunk.replace(/\n+$/, "");
20061
- if (line) log.info("host-agent", `headroom[${cmd}]: ${line}`);
20062
- });
20063
- const timeoutMs = opts.timeoutMs;
20064
- let timer;
20065
- if (timeoutMs !== void 0) {
20066
- timer = setTimeout(() => {
20067
- log.warn(
20068
- "host-agent",
20069
- `headroom[${cmd}] timed out after ${timeoutMs / 1e3}s \u2014 aborting`
20070
- );
20071
- killQuiet(child);
20072
- done(null);
20073
- }, timeoutMs);
20074
- }
20075
- child.once("exit", (code) => {
20076
- if (timer !== void 0) clearTimeout(timer);
20077
- done(code);
20078
- });
20079
- child.once("error", (e) => {
20080
- if (timer !== void 0) clearTimeout(timer);
20081
- log.trace("host-agent", `headroom[${cmd}] spawn error: ${e.message}`);
20082
- done(null);
20083
- });
20084
- });
20085
- }
20086
- };
20087
- var PACKAGE_MANAGERS = [
20088
- "apt-get",
20089
- "apk",
20090
- "dnf",
20091
- "yum",
20092
- "pacman",
20093
- "zypper"
20094
- ];
20095
- var PROVISION_RECIPES = {
20096
- "apt-get": {
20097
- update: ["apt-get", "update"],
20098
- install: [
20099
- "apt-get",
20100
- "install",
20101
- "-y",
20102
- "python3",
20103
- "python3-pip",
20104
- "python3-venv",
20105
- "ca-certificates",
20106
- "curl"
20107
- ]
20108
- },
20109
- apk: {
20110
- install: ["apk", "add", "--no-cache", "python3", "py3-pip", "ca-certificates", "curl"]
20111
- },
20112
- dnf: {
20113
- install: ["dnf", "install", "-y", "python3", "python3-pip", "ca-certificates", "curl"]
20114
- },
20115
- yum: {
20116
- install: ["yum", "install", "-y", "python3", "python3-pip", "ca-certificates", "curl"]
20117
- },
20118
- pacman: {
20119
- install: ["pacman", "-Sy", "--noconfirm", "python", "python-pip", "ca-certificates", "curl"]
20120
- },
20121
- zypper: {
20122
- install: [
20123
- "zypper",
20124
- "--non-interactive",
20125
- "install",
20126
- "python3",
20127
- "python3-pip",
20128
- "ca-certificates",
20129
- "curl"
20130
- ]
20131
- }
20132
- };
20133
- function detectPackageManager(runner) {
20134
- for (const pm of PACKAGE_MANAGERS) {
20135
- if (runner.which(pm)) return pm;
20136
- }
20137
- return null;
20138
- }
20139
- function escalateCommand(argv) {
20140
- const isRoot = process.getuid?.() === 0;
20141
- return isRoot ? { cmd: argv[0], args: argv.slice(1) } : { cmd: "sudo", args: argv };
20142
- }
20143
- async function ensurePip(runner) {
20144
- if (runner.which("pip") || runner.which("pip3")) {
20145
- return true;
20146
- }
20147
- const pm = detectPackageManager(runner);
20148
- if (!pm) {
20149
- log.warn(
20150
- "host-agent",
20151
- "pip is absent and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) found \u2014 skipping Headroom"
20152
- );
20153
- return false;
20154
- }
20155
- const escalate = escalateCommand;
20156
- const recipe = PROVISION_RECIPES[pm];
20157
- log.info(
20158
- "host-agent",
20159
- `pip absent \u2014 provisioning bare box (python3+pip+ca-certificates+curl) via ${pm}`
20160
- );
20161
- try {
20162
- if (recipe.update) {
20163
- const { cmd: cmd2, args: args3 } = escalate(recipe.update);
20164
- const updateResult = await runner.run(cmd2, args3, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
20165
- if (updateResult.code !== 0) {
20166
- log.warn(
20167
- "host-agent",
20168
- `${pm} update exited ${String(updateResult.code)} \u2014 attempting install anyway`
20169
- );
20170
- }
20171
- }
20172
- const { cmd, args: args2 } = escalate(recipe.install);
20173
- const installResult = await runner.run(cmd, args2, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
20174
- if (installResult.code !== 0) {
20175
- log.warn(
20176
- "host-agent",
20177
- `${pm} bare-box provision failed (code=${String(installResult.code)}) \u2014 skipping Headroom`
20178
- );
20179
- return false;
20180
- }
20181
- } catch (e) {
20182
- log.warn(
20183
- "host-agent",
20184
- `bare-box provision threw unexpectedly: ${e instanceof Error ? e.message : String(e)} \u2014 skipping Headroom`
20185
- );
20186
- return false;
20187
- }
20188
- log.info("host-agent", `bare box provisioned via ${pm} (python3+pip+ca-certificates+curl)`);
20189
- return true;
20190
- }
20191
- async function resolveHeadroomPython(runner) {
20192
- const PROBE_TIMEOUT_MS = 5e3;
20193
- const SUFFIXES = ["python3.13", "python3.12", "python3.11", "python3.10"];
20194
- const PREFIX_DIRS = ["/opt/homebrew/bin", "/usr/local/bin"];
20195
- const probe = async (candidate) => {
20196
- try {
20197
- const r = await runner.run(
20198
- candidate,
20199
- ["-c", 'import sys; print("%d.%d" % sys.version_info[:2])'],
20200
- { timeoutMs: PROBE_TIMEOUT_MS }
20201
- );
20202
- if (r.code !== 0) return false;
20203
- const parts = (r.stdout ?? "").trim().split(".");
20204
- const major = parseInt(parts[0] ?? "", 10);
20205
- const minor = parseInt(parts[1] ?? "", 10);
20206
- if (!(major === 3 && minor >= 10)) return false;
20207
- const pipCheck = await runner.run(candidate, ["-m", "pip", "--version"], {
20208
- timeoutMs: PROBE_TIMEOUT_MS
20209
- });
20210
- return pipCheck.code === 0;
20211
- } catch {
20212
- return false;
20213
- }
20214
- };
20215
- for (const suffix of SUFFIXES) {
20216
- try {
20217
- if (await probe(suffix)) return suffix;
20218
- } catch {
20219
- }
20220
- }
20221
- for (const suffix of SUFFIXES) {
20222
- for (const dir of PREFIX_DIRS) {
20223
- const candidate = `${dir}/${suffix}`;
20224
- try {
20225
- if (await probe(candidate)) return candidate;
20226
- } catch {
20227
- }
20228
- }
20229
- }
20230
- try {
20231
- if (await probe("python3")) return "python3";
20232
- } catch {
20233
- }
20234
- return null;
20235
- }
20236
- var PY_INSTALL_TIMEOUT_MS = 6e5;
20237
- var MODERN_PYTHON_RECIPES = {
20238
- "apt-get": [
20239
- ["apt-get", "install", "-y", "python3.12"],
20240
- ["apt-get", "install", "-y", "python3.11"],
20241
- ["apt-get", "install", "-y", "python3"]
20242
- ],
20243
- dnf: [
20244
- ["dnf", "install", "-y", "python3.12"],
20245
- ["dnf", "install", "-y", "python3"]
20246
- ],
20247
- yum: [
20248
- ["yum", "install", "-y", "python3.12"],
20249
- ["yum", "install", "-y", "python3"]
20250
- ],
20251
- apk: [["apk", "add", "--no-cache", "python3"]],
20252
- pacman: [["pacman", "-Sy", "--noconfirm", "python"]],
20253
- zypper: [
20254
- ["zypper", "--non-interactive", "install", "python311"],
20255
- ["zypper", "--non-interactive", "install", "python3"]
20256
- ]
20257
- };
20258
- async function ensureModernPython(runner) {
20259
- let py = await resolveHeadroomPython(runner);
20260
- if (py !== null) return py;
20261
- try {
20262
- if (process.platform === "darwin") {
20263
- if (runner.which("brew")) {
20264
- log.info("host-agent", "no Python \u22653.10 found \u2014 installing python@3.12 via Homebrew");
20265
- const r = await runner.run("brew", ["install", "python@3.12"], {
20266
- timeoutMs: PY_INSTALL_TIMEOUT_MS
20267
- });
20268
- if (r.code !== 0) {
20269
- log.warn(
20270
- "host-agent",
20271
- `brew install python@3.12 exited ${String(r.code)} \u2014 will re-probe anyway`
20272
- );
20273
- }
20274
- } else {
20275
- log.warn(
20276
- "host-agent",
20277
- "no Python \u22653.10 and Homebrew is absent \u2014 cannot auto-install Python on macOS"
20278
- );
20279
- }
20280
- } else if (process.platform === "linux") {
20281
- const pm = detectPackageManager(runner);
20282
- if (!pm) {
20283
- log.warn(
20284
- "host-agent",
20285
- "no Python \u22653.10 and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) \u2014 cannot auto-install Python"
20286
- );
20287
- } else {
20288
- log.info("host-agent", `no Python \u22653.10 found \u2014 installing a modern Python via ${pm}`);
20289
- for (const argv of MODERN_PYTHON_RECIPES[pm]) {
20290
- const { cmd, args: args2 } = escalateCommand(argv);
20291
- const r = await runner.run(cmd, args2, { timeoutMs: PY_INSTALL_TIMEOUT_MS });
20292
- if (r.code === 0) {
20293
- log.info("host-agent", `installed Python package via ${pm}: ${argv.join(" ")}`);
20294
- break;
20295
- }
20296
- log.warn(
20297
- "host-agent",
20298
- `${pm} install '${argv.join(" ")}' exited ${String(r.code)} \u2014 trying next`
20299
- );
20300
- }
20301
- }
20302
- } else {
20303
- log.warn(
20304
- "host-agent",
20305
- `no Python \u22653.10 and platform '${process.platform}' has no auto-install path`
20306
- );
20307
- }
20308
- } catch (e) {
20309
- log.warn(
20310
- "host-agent",
20311
- `Python auto-install threw unexpectedly (best-effort): ${e instanceof Error ? e.message : String(e)}`
20312
- );
20313
- }
20314
- py = await resolveHeadroomPython(runner);
20315
- return py;
20316
- }
20317
-
20318
20493
  // src/commands/host/headroom-bootstrap.ts
20319
20494
  var fs41 = __toESM(require("fs"));
20320
- var path45 = __toESM(require("path"));
20495
+ var path46 = __toESM(require("path"));
20321
20496
  var os37 = __toESM(require("os"));
20322
20497
 
20323
20498
  // src/commands/host/headroom-config.ts
20324
20499
  var fs40 = __toESM(require("fs"));
20325
20500
  var os36 = __toESM(require("os"));
20326
- var path44 = __toESM(require("path"));
20501
+ var path45 = __toESM(require("path"));
20327
20502
  function headroomConfigPath() {
20328
- return path44.join(os36.homedir(), ".codeam", "headroom-config.json");
20503
+ return path45.join(os36.homedir(), ".codeam", "headroom-config.json");
20329
20504
  }
20330
20505
  function persistHeadroomConfig(config) {
20331
20506
  try {
20332
20507
  const file = headroomConfigPath();
20333
- fs40.mkdirSync(path44.dirname(file), { recursive: true, mode: 448 });
20508
+ fs40.mkdirSync(path45.dirname(file), { recursive: true, mode: 448 });
20334
20509
  const tmp = `${file}.tmp-${process.pid}`;
20335
20510
  fs40.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20336
20511
  fs40.renameSync(tmp, file);
@@ -20344,9 +20519,9 @@ function persistHeadroomConfig(config) {
20344
20519
  }
20345
20520
  function agentSettingsPath(kind) {
20346
20521
  const home = os36.homedir();
20347
- if (kind === "claude") return path44.join(home, ".claude", "settings.json");
20348
- if (kind === "codex") return path44.join(home, ".codex", "auth.json");
20349
- 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");
20350
20525
  return null;
20351
20526
  }
20352
20527
  function backupAgentHeadroomConfig(kind) {
@@ -20354,8 +20529,8 @@ function backupAgentHeadroomConfig(kind) {
20354
20529
  if (!src) return;
20355
20530
  try {
20356
20531
  if (!fs40.existsSync(src)) return;
20357
- const dest = path44.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20358
- 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 });
20359
20534
  fs40.copyFileSync(src, dest);
20360
20535
  fs40.chmodSync(dest, 384);
20361
20536
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
@@ -20369,10 +20544,10 @@ function backupAgentHeadroomConfig(kind) {
20369
20544
  function restoreAgentHeadroomConfig(kind) {
20370
20545
  const dest = agentSettingsPath(kind);
20371
20546
  if (!dest) return false;
20372
- const src = path44.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20547
+ const src = path45.join(os36.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20373
20548
  if (!fs40.existsSync(src)) return false;
20374
20549
  try {
20375
- fs40.mkdirSync(path44.dirname(dest), { recursive: true, mode: 448 });
20550
+ fs40.mkdirSync(path45.dirname(dest), { recursive: true, mode: 448 });
20376
20551
  fs40.copyFileSync(src, dest);
20377
20552
  fs40.chmodSync(dest, 384);
20378
20553
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
@@ -20423,20 +20598,20 @@ function bundledClaudeBinDir() {
20423
20598
  const roots = /* @__PURE__ */ new Set();
20424
20599
  let dir = __dirname;
20425
20600
  for (let i = 0; i < 6; i++) {
20426
- roots.add(path45.join(dir, "node_modules"));
20427
- const parent = path45.dirname(dir);
20601
+ roots.add(path46.join(dir, "node_modules"));
20602
+ const parent = path46.dirname(dir);
20428
20603
  if (parent === dir) break;
20429
20604
  dir = parent;
20430
20605
  }
20431
20606
  try {
20432
20607
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
20433
- const marker = `${path45.sep}@anthropic-ai${path45.sep}`;
20608
+ const marker = `${path46.sep}@anthropic-ai${path46.sep}`;
20434
20609
  const idx = main2.lastIndexOf(marker);
20435
20610
  if (idx !== -1) roots.add(main2.slice(0, idx));
20436
20611
  } catch {
20437
20612
  }
20438
20613
  for (const nm of roots) {
20439
- const atAnthropic = path45.join(nm, "@anthropic-ai");
20614
+ const atAnthropic = path46.join(nm, "@anthropic-ai");
20440
20615
  let entries;
20441
20616
  try {
20442
20617
  entries = fs41.readdirSync(atAnthropic);
@@ -20445,8 +20620,8 @@ function bundledClaudeBinDir() {
20445
20620
  }
20446
20621
  for (const entry of entries) {
20447
20622
  if (!entry.startsWith("claude-agent-sdk-")) continue;
20448
- const bin = path45.join(atAnthropic, entry, "claude");
20449
- 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);
20450
20625
  }
20451
20626
  }
20452
20627
  return null;
@@ -20460,12 +20635,12 @@ async function getFreeDiskBytes(dir) {
20460
20635
  }
20461
20636
  }
20462
20637
  function headroomModelsCached() {
20463
- const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path45.join(
20464
- 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"),
20465
20640
  "hub"
20466
20641
  );
20467
20642
  return HEADROOM_MODELS.every(
20468
- (m) => fs41.existsSync(path45.join(hubDir, `models--${m.repo.replace("/", "--")}`))
20643
+ (m) => fs41.existsSync(path46.join(hubDir, `models--${m.repo.replace("/", "--")}`))
20469
20644
  );
20470
20645
  }
20471
20646
  async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner, opts = {}) {
@@ -20534,7 +20709,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
20534
20709
  if (initKind === "claude") {
20535
20710
  const claudeDir = bundledClaudeBinDir();
20536
20711
  if (claudeDir) {
20537
- initEnv.PATH = `${claudeDir}${path45.delimiter}${process.env["PATH"] ?? ""}`;
20712
+ initEnv.PATH = `${claudeDir}${path46.delimiter}${process.env["PATH"] ?? ""}`;
20538
20713
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
20539
20714
  } else {
20540
20715
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -20573,14 +20748,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
20573
20748
  // src/commands/host/house-proxy-config.ts
20574
20749
  var fs42 = __toESM(require("fs"));
20575
20750
  var os38 = __toESM(require("os"));
20576
- var path46 = __toESM(require("path"));
20751
+ var path47 = __toESM(require("path"));
20577
20752
  function houseProxyConfigPath() {
20578
- return path46.join(os38.homedir(), ".codeam", "house-proxy.json");
20753
+ return path47.join(os38.homedir(), ".codeam", "house-proxy.json");
20579
20754
  }
20580
20755
  function persistHouseProxyConfig(config) {
20581
20756
  try {
20582
20757
  const file = houseProxyConfigPath();
20583
- fs42.mkdirSync(path46.dirname(file), { recursive: true, mode: 448 });
20758
+ fs42.mkdirSync(path47.dirname(file), { recursive: true, mode: 448 });
20584
20759
  const tmp = `${file}.tmp-${process.pid}`;
20585
20760
  fs42.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20586
20761
  fs42.renameSync(tmp, file);
@@ -20635,7 +20810,7 @@ var import_node_child_process23 = require("child_process");
20635
20810
  // src/lib/updateNotifier.ts
20636
20811
  var fs43 = __toESM(require("fs"));
20637
20812
  var os39 = __toESM(require("os"));
20638
- var path47 = __toESM(require("path"));
20813
+ var path48 = __toESM(require("path"));
20639
20814
  var https6 = __toESM(require("https"));
20640
20815
  var import_node_child_process22 = require("child_process");
20641
20816
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -20644,8 +20819,8 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
20644
20819
  var TTL_MS = 24 * 60 * 60 * 1e3;
20645
20820
  var REQUEST_TIMEOUT_MS = 1500;
20646
20821
  function cachePath() {
20647
- const dir = path47.join(os39.homedir(), ".codeam");
20648
- return path47.join(dir, "update-check.json");
20822
+ const dir = path48.join(os39.homedir(), ".codeam");
20823
+ return path48.join(dir, "update-check.json");
20649
20824
  }
20650
20825
  function readCache() {
20651
20826
  try {
@@ -20660,7 +20835,7 @@ function readCache() {
20660
20835
  function writeCache(cache) {
20661
20836
  try {
20662
20837
  const file = cachePath();
20663
- fs43.mkdirSync(path47.dirname(file), { recursive: true });
20838
+ fs43.mkdirSync(path48.dirname(file), { recursive: true });
20664
20839
  const tmp = `${file}.${process.pid}.tmp`;
20665
20840
  fs43.writeFileSync(tmp, JSON.stringify(cache));
20666
20841
  fs43.renameSync(tmp, file);
@@ -20737,7 +20912,7 @@ function isLinkedInstall() {
20737
20912
  timeout: 2e3
20738
20913
  }).trim();
20739
20914
  if (!root) return false;
20740
- const pkgPath = path47.join(root, PKG_NAME);
20915
+ const pkgPath = path48.join(root, PKG_NAME);
20741
20916
  return fs43.lstatSync(pkgPath).isSymbolicLink();
20742
20917
  } catch {
20743
20918
  return false;
@@ -20790,7 +20965,7 @@ async function autoUpgradeBeforeCriticalCommand() {
20790
20965
  if (process.env.NODE_ENV === "test") return;
20791
20966
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20792
20967
  if (process.env.CI) return;
20793
- const current2 = true ? "2.62.0" : null;
20968
+ const current2 = true ? "2.62.2" : null;
20794
20969
  if (!current2) return;
20795
20970
  const cache = readCache();
20796
20971
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -20807,7 +20982,7 @@ function checkForUpdates() {
20807
20982
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20808
20983
  if (process.env.CI) return;
20809
20984
  if (!process.stdout.isTTY) return;
20810
- const current2 = true ? "2.62.0" : null;
20985
+ const current2 = true ? "2.62.2" : null;
20811
20986
  if (!current2) return;
20812
20987
  const cache = readCache();
20813
20988
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -20827,7 +21002,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
20827
21002
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
20828
21003
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
20829
21004
  function currentCliVersion() {
20830
- return true ? "2.62.0" : null;
21005
+ return true ? "2.62.2" : null;
20831
21006
  }
20832
21007
  function runCmd(cmd, args2, timeoutMs) {
20833
21008
  return new Promise((resolve9) => {
@@ -21559,13 +21734,13 @@ var HostAgentSupervisor = class {
21559
21734
  const relay = this.relay;
21560
21735
  if (!relay) return;
21561
21736
  const raw = cmd.payload?.path;
21562
- 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();
21563
21738
  try {
21564
21739
  const dirents = await fs45.promises.readdir(target, { withFileTypes: true });
21565
21740
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
21566
21741
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
21567
21742
  );
21568
- const parent = path48.dirname(target);
21743
+ const parent = path49.dirname(target);
21569
21744
  await relay.sendResult(cmd.id, "completed", {
21570
21745
  path: target,
21571
21746
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -21798,7 +21973,7 @@ var HostAgentSupervisor = class {
21798
21973
  API_TIMEOUT_MS: "3000000",
21799
21974
  CODEAM_AUTO_TOKEN: payload.autoPairToken
21800
21975
  };
21801
- const houseConfigDir = path48.join(
21976
+ const houseConfigDir = path49.join(
21802
21977
  os40.homedir(),
21803
21978
  ".codeam",
21804
21979
  "house-claude",
@@ -21839,13 +22014,13 @@ var HostAgentSupervisor = class {
21839
22014
  if ((payload.repoProvider ?? "github") === "gitlab") {
21840
22015
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
21841
22016
  if (glabCmd) {
21842
- childEnv.PATH = `${codeamBinDir()}${path48.delimiter}${childEnv.PATH}`;
22017
+ childEnv.PATH = `${codeamBinDir()}${path49.delimiter}${childEnv.PATH}`;
21843
22018
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
21844
22019
  }
21845
22020
  } else {
21846
22021
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
21847
22022
  if (ghCmd) {
21848
- childEnv.PATH = `${codeamBinDir()}${path48.delimiter}${childEnv.PATH}`;
22023
+ childEnv.PATH = `${codeamBinDir()}${path49.delimiter}${childEnv.PATH}`;
21849
22024
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
21850
22025
  }
21851
22026
  }
@@ -21924,8 +22099,8 @@ var HostAgentSupervisor = class {
21924
22099
  );
21925
22100
  if (!payload.suppressOnboardingWelcome) {
21926
22101
  try {
21927
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path48.join(os40.homedir(), ".claude");
21928
- 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));
21929
22104
  const hasPriorConversation = fs45.existsSync(projectDir) && fs45.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
21930
22105
  if (hasPriorConversation) {
21931
22106
  childEnv.CODEAM_RESUME_LATEST = "1";
@@ -22162,8 +22337,8 @@ var HostAgentSupervisor = class {
22162
22337
  this.children.delete(deployId);
22163
22338
  }
22164
22339
  const dirs = [
22165
- path48.join(selfHostedWorkspaceRoot(), deployId),
22166
- path48.join(os40.homedir(), ".codeam", "house-claude", deployId)
22340
+ path49.join(selfHostedWorkspaceRoot(), deployId),
22341
+ path49.join(os40.homedir(), ".codeam", "house-claude", deployId)
22167
22342
  ];
22168
22343
  for (const dir of dirs) {
22169
22344
  try {
@@ -22306,7 +22481,7 @@ async function configureHeadroom(action, ctx, deps) {
22306
22481
  // src/services/headroom/budget-relaunch.ts
22307
22482
  var fs46 = __toESM(require("fs"));
22308
22483
  var os41 = __toESM(require("os"));
22309
- var path49 = __toESM(require("path"));
22484
+ var path50 = __toESM(require("path"));
22310
22485
  var import_child_process13 = require("child_process");
22311
22486
  function amendDeploymentManifestBudget(manifest, budget) {
22312
22487
  const rawArgs = manifest.proxy_args ?? [];
@@ -22340,7 +22515,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
22340
22515
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
22341
22516
  }
22342
22517
  function findHeadroomDeployments(homeDir2, deps) {
22343
- const deployDir = path49.join(homeDir2, ".headroom", "deploy");
22518
+ const deployDir = path50.join(homeDir2, ".headroom", "deploy");
22344
22519
  let profiles;
22345
22520
  try {
22346
22521
  profiles = deps.readDir(deployDir);
@@ -22349,7 +22524,7 @@ function findHeadroomDeployments(homeDir2, deps) {
22349
22524
  }
22350
22525
  const results = [];
22351
22526
  for (const profile of profiles) {
22352
- const manifestPath = path49.join(deployDir, profile, "manifest.json");
22527
+ const manifestPath = path50.join(deployDir, profile, "manifest.json");
22353
22528
  let raw;
22354
22529
  try {
22355
22530
  raw = deps.readJson(manifestPath);
@@ -22536,7 +22711,7 @@ async function defaultFetchJson(url2) {
22536
22711
  async function readUsageReport(deps = {}) {
22537
22712
  const port = deps.port ?? HEADROOM_PROXY_PORT;
22538
22713
  const base = `http://127.0.0.1:${port}`;
22539
- const get2 = deps.fetchJson ?? ((path89) => defaultFetchJson(`${base}${path89}`));
22714
+ const get2 = deps.fetchJson ?? ((path90) => defaultFetchJson(`${base}${path90}`));
22540
22715
  let history;
22541
22716
  try {
22542
22717
  history = await get2("/stats-history");
@@ -22555,11 +22730,11 @@ async function readUsageReport(deps = {}) {
22555
22730
 
22556
22731
  // src/agents/acp/guardrail-config.ts
22557
22732
  var fs47 = __toESM(require("fs"));
22558
- var path50 = __toESM(require("path"));
22733
+ var path51 = __toESM(require("path"));
22559
22734
  var os42 = __toESM(require("os"));
22560
22735
  var current = null;
22561
22736
  function guardrailConfigPath(homeDir2 = os42.homedir()) {
22562
- return path50.join(homeDir2, ".codeam", "guardrails.json");
22737
+ return path51.join(homeDir2, ".codeam", "guardrails.json");
22563
22738
  }
22564
22739
  function loadGuardrailPolicy(homeDir2 = os42.homedir()) {
22565
22740
  try {
@@ -22577,7 +22752,7 @@ function setGuardrailPolicy(raw, homeDir2 = os42.homedir()) {
22577
22752
  current = next;
22578
22753
  try {
22579
22754
  const p2 = guardrailConfigPath(homeDir2);
22580
- fs47.mkdirSync(path50.dirname(p2), { recursive: true });
22755
+ fs47.mkdirSync(path51.dirname(p2), { recursive: true });
22581
22756
  fs47.writeFileSync(p2, JSON.stringify(next, null, 2));
22582
22757
  } catch {
22583
22758
  }
@@ -22587,10 +22762,10 @@ function setGuardrailPolicy(raw, homeDir2 = os42.homedir()) {
22587
22762
  // src/services/preview/port-registry.ts
22588
22763
  var fs48 = __toESM(require("fs"));
22589
22764
  var os43 = __toESM(require("os"));
22590
- var path51 = __toESM(require("path"));
22765
+ var path52 = __toESM(require("path"));
22591
22766
  var import_child_process14 = require("child_process");
22592
22767
  function registryPath() {
22593
- return path51.join(os43.homedir(), ".codeam", "preview-ports.json");
22768
+ return path52.join(os43.homedir(), ".codeam", "preview-ports.json");
22594
22769
  }
22595
22770
  function readRegistry() {
22596
22771
  try {
@@ -22604,7 +22779,7 @@ function readRegistry() {
22604
22779
  function writeRegistry(reg) {
22605
22780
  try {
22606
22781
  const file = registryPath();
22607
- fs48.mkdirSync(path51.dirname(file), { recursive: true });
22782
+ fs48.mkdirSync(path52.dirname(file), { recursive: true });
22608
22783
  const tmp = `${file}.tmp`;
22609
22784
  fs48.writeFileSync(tmp, JSON.stringify(reg), "utf8");
22610
22785
  fs48.renameSync(tmp, file);
@@ -22673,7 +22848,7 @@ function reclaimOwnOrphanPort(port) {
22673
22848
 
22674
22849
  // src/services/preview/host-allow.ts
22675
22850
  var import_fs = require("fs");
22676
- var path52 = __toESM(require("path"));
22851
+ var path53 = __toESM(require("path"));
22677
22852
  var NEXT_ALLOWED_ORIGINS = [
22678
22853
  "*.trycloudflare.com",
22679
22854
  "*.preview.codeagent-mobile.com",
@@ -22693,7 +22868,7 @@ var MARKER_DIR = ".codeam";
22693
22868
  var MARKER_FILE = "preview-host-allow.json";
22694
22869
  var ORIG_INFIX = ".codeam-orig";
22695
22870
  function markerPath(cwd) {
22696
- return path52.join(cwd, MARKER_DIR, MARKER_FILE);
22871
+ return path53.join(cwd, MARKER_DIR, MARKER_FILE);
22697
22872
  }
22698
22873
  async function fileExists(p2) {
22699
22874
  try {
@@ -22706,13 +22881,13 @@ async function fileExists(p2) {
22706
22881
  async function findConfigFile(cwd, framework) {
22707
22882
  const base = CONFIG_BASENAMES[framework];
22708
22883
  for (const ext of CONFIG_EXTS) {
22709
- if (await fileExists(path52.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
22884
+ if (await fileExists(path53.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
22710
22885
  }
22711
22886
  return null;
22712
22887
  }
22713
22888
  async function dependsOn(cwd, pkgName) {
22714
22889
  try {
22715
- 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");
22716
22891
  const pkg = JSON.parse(raw);
22717
22892
  return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
22718
22893
  } catch {
@@ -22720,11 +22895,11 @@ async function dependsOn(cwd, pkgName) {
22720
22895
  }
22721
22896
  }
22722
22897
  async function isEsmConfig(cwd, configFile) {
22723
- const ext = path52.extname(configFile);
22898
+ const ext = path53.extname(configFile);
22724
22899
  if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
22725
22900
  if (ext === ".cjs") return false;
22726
22901
  try {
22727
- 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");
22728
22903
  return JSON.parse(raw).type === "module";
22729
22904
  } catch {
22730
22905
  return false;
@@ -22807,7 +22982,7 @@ function shimFor(framework, origBasename, esm) {
22807
22982
  return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
22808
22983
  }
22809
22984
  async function writeMarker(cwd, marker) {
22810
- 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 });
22811
22986
  await import_fs.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
22812
22987
  }
22813
22988
  async function readMarker(cwd) {
@@ -22822,9 +22997,9 @@ async function restorePreviewHostAllow(cwd) {
22822
22997
  const marker = await readMarker(cwd);
22823
22998
  if (!marker) return;
22824
22999
  try {
22825
- const configAbs = path52.join(cwd, marker.configFile);
23000
+ const configAbs = path53.join(cwd, marker.configFile);
22826
23001
  if (marker.backupFile) {
22827
- const backupAbs = path52.join(cwd, marker.backupFile);
23002
+ const backupAbs = path53.join(cwd, marker.backupFile);
22828
23003
  if (await fileExists(backupAbs)) {
22829
23004
  await import_fs.promises.rm(configAbs, { force: true });
22830
23005
  await import_fs.promises.rename(backupAbs, configAbs);
@@ -22857,16 +23032,16 @@ async function applyPreviewHostAllow(cwd) {
22857
23032
  }
22858
23033
  if (!framework) return;
22859
23034
  if (existing) {
22860
- const ext = path52.extname(existing);
23035
+ const ext = path53.extname(existing);
22861
23036
  const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
22862
23037
  const esm = await isEsmConfig(cwd, existing);
22863
- await import_fs.promises.rename(path52.join(cwd, existing), path52.join(cwd, origBasename));
22864
- 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");
22865
23040
  await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
22866
23041
  log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
22867
23042
  } else {
22868
23043
  const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
22869
- 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");
22870
23045
  await writeMarker(cwd, { framework, configFile, backupFile: null });
22871
23046
  log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
22872
23047
  }
@@ -23169,10 +23344,10 @@ function parseExpoUrl(stdout) {
23169
23344
  }
23170
23345
 
23171
23346
  // src/services/preview/port-ready.ts
23172
- var net = __toESM(require("net"));
23347
+ var net2 = __toESM(require("net"));
23173
23348
  function isPortListening(port, host2 = "127.0.0.1") {
23174
23349
  return new Promise((resolve9) => {
23175
- const socket = new net.Socket();
23350
+ const socket = new net2.Socket();
23176
23351
  const done = (result) => {
23177
23352
  socket.removeAllListeners();
23178
23353
  socket.destroy();
@@ -23549,18 +23724,18 @@ function activePreviewSessionIds() {
23549
23724
  // src/services/preview/start-orchestrator.ts
23550
23725
  var import_child_process19 = require("child_process");
23551
23726
  var fs56 = __toESM(require("fs"));
23552
- var path59 = __toESM(require("path"));
23727
+ var path60 = __toESM(require("path"));
23553
23728
  var import_which2 = __toESM(require("which"));
23554
23729
 
23555
23730
  // src/services/project-env/index.ts
23556
23731
  var import_fs5 = require("fs");
23557
- var path58 = __toESM(require("path"));
23732
+ var path59 = __toESM(require("path"));
23558
23733
 
23559
23734
  // src/beads/project-key.ts
23560
23735
  var import_child_process18 = require("child_process");
23561
23736
  var crypto2 = __toESM(require("crypto"));
23562
23737
  var fs54 = __toESM(require("fs"));
23563
- var path57 = __toESM(require("path"));
23738
+ var path58 = __toESM(require("path"));
23564
23739
  function normalizeOrigin(raw) {
23565
23740
  const trimmed = raw.trim();
23566
23741
  if (!trimmed) return null;
@@ -23586,17 +23761,17 @@ function normalizeOrigin(raw) {
23586
23761
  return `${host2}/${pathPart}`;
23587
23762
  }
23588
23763
  function findRepoRoot(cwd) {
23589
- let dir = path57.resolve(cwd);
23764
+ let dir = path58.resolve(cwd);
23590
23765
  const seen = /* @__PURE__ */ new Set();
23591
23766
  for (let i = 0; i < 256; i++) {
23592
23767
  if (seen.has(dir)) return null;
23593
23768
  seen.add(dir);
23594
23769
  try {
23595
- const stat3 = fs54.statSync(path57.join(dir, ".git"), { throwIfNoEntry: false });
23770
+ const stat3 = fs54.statSync(path58.join(dir, ".git"), { throwIfNoEntry: false });
23596
23771
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
23597
23772
  } catch {
23598
23773
  }
23599
- const parent = path57.dirname(dir);
23774
+ const parent = path58.dirname(dir);
23600
23775
  if (parent === dir) return null;
23601
23776
  dir = parent;
23602
23777
  }
@@ -23636,7 +23811,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
23636
23811
  } catch {
23637
23812
  }
23638
23813
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
23639
- return { projectKey: `path:${hash}`, projectLabel: path57.basename(real) || "project" };
23814
+ return { projectKey: `path:${hash}`, projectLabel: path58.basename(real) || "project" };
23640
23815
  }
23641
23816
 
23642
23817
  // src/services/project-env/index.ts
@@ -23649,7 +23824,7 @@ async function readIfExists(p2) {
23649
23824
  }
23650
23825
  async function syncProjectEnvUp(cwd, ctx) {
23651
23826
  if (!ctx.pluginAuthToken) return;
23652
- const content = await readIfExists(path58.join(cwd, ".env"));
23827
+ const content = await readIfExists(path59.join(cwd, ".env"));
23653
23828
  if (content == null) return;
23654
23829
  try {
23655
23830
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23671,7 +23846,7 @@ async function syncProjectEnvUp(cwd, ctx) {
23671
23846
  }
23672
23847
  async function restoreProjectEnvIfMissing(cwd, ctx) {
23673
23848
  if (!ctx.pluginAuthToken) return false;
23674
- const envPath = path58.join(cwd, ".env");
23849
+ const envPath = path59.join(cwd, ".env");
23675
23850
  if (await readIfExists(envPath) != null) return false;
23676
23851
  try {
23677
23852
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23682,7 +23857,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
23682
23857
  projectKey
23683
23858
  });
23684
23859
  if (!stored) return false;
23685
- const tmp = path58.join(cwd, ".env.codeam-restore.tmp");
23860
+ const tmp = path59.join(cwd, ".env.codeam-restore.tmp");
23686
23861
  await import_fs5.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
23687
23862
  await import_fs5.promises.rename(tmp, envPath);
23688
23863
  log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
@@ -23694,7 +23869,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
23694
23869
  }
23695
23870
 
23696
23871
  // src/services/preview/start-orchestrator.ts
23697
- var INSTALL_TIMEOUT_MS = 5 * 6e4;
23872
+ var INSTALL_TIMEOUT_MS2 = 5 * 6e4;
23698
23873
  var SETUP_TIMEOUT_MS = 2 * 6e4;
23699
23874
  var TUNNEL_REGISTER_DEADLINE_MS = 45e3;
23700
23875
  function compileReadyPattern(pattern) {
@@ -23759,7 +23934,7 @@ function normalizeDetectionForSpawn(detection, cwd) {
23759
23934
  if (args2.length === 0) return detection;
23760
23935
  const binName = args2[0];
23761
23936
  if (binName.startsWith("-")) return detection;
23762
- const binPath = path59.join(cwd, "node_modules", ".bin", binName);
23937
+ const binPath = path60.join(cwd, "node_modules", ".bin", binName);
23763
23938
  if (!fs56.existsSync(binPath)) return detection;
23764
23939
  return {
23765
23940
  ...detection,
@@ -23839,7 +24014,7 @@ async function provisionDeps(ctx) {
23839
24014
  ["install", "-g", "yarn"],
23840
24015
  cwd,
23841
24016
  detection.env,
23842
- { timeoutMs: INSTALL_TIMEOUT_MS }
24017
+ { timeoutMs: INSTALL_TIMEOUT_MS2 }
23843
24018
  );
23844
24019
  return { ok: r.status === "ok", code: r.code };
23845
24020
  }
@@ -23861,12 +24036,12 @@ async function provisionDeps(ctx) {
23861
24036
  missingDeps.args,
23862
24037
  cwd,
23863
24038
  detection.env,
23864
- { timeoutMs: INSTALL_TIMEOUT_MS }
24039
+ { timeoutMs: INSTALL_TIMEOUT_MS2 }
23865
24040
  );
23866
24041
  if (result.status === "timeout") {
23867
24042
  emit2(USER_EVENTS.PREVIEW_ERROR, {
23868
24043
  stage: "ready_timeout",
23869
- 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.`
23870
24045
  });
23871
24046
  return false;
23872
24047
  }
@@ -23893,7 +24068,7 @@ async function provisionDeps(ctx) {
23893
24068
  const agentSetupCommands = preflightRan ? normalizedSetup.filter((s) => !isJsInstallCommand(s.cmd, s.args)) : normalizedSetup;
23894
24069
  for (const setup of agentSetupCommands) {
23895
24070
  emitProgress("SETUP_RUN", `${setup.cmd} ${setup.args.join(" ")}`);
23896
- 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;
23897
24072
  const result = await runSetupCommand(
23898
24073
  setup.cmd,
23899
24074
  setup.args,
@@ -24135,7 +24310,7 @@ async function establishTunnel(ctx, dev) {
24135
24310
  var import_child_process20 = require("child_process");
24136
24311
  var fs57 = __toESM(require("fs"));
24137
24312
  var os45 = __toESM(require("os"));
24138
- var path60 = __toESM(require("path"));
24313
+ var path61 = __toESM(require("path"));
24139
24314
  var BD_PACKAGE = "@beads/bd";
24140
24315
  function resolveBundledBdBinary() {
24141
24316
  return _resolveSeam.resolveBundled();
@@ -24147,9 +24322,9 @@ function _defaultResolveBundled() {
24147
24322
  } catch {
24148
24323
  return null;
24149
24324
  }
24150
- const binDir = path60.join(path60.dirname(pkgJsonPath), "bin");
24325
+ const binDir = path61.join(path61.dirname(pkgJsonPath), "bin");
24151
24326
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
24152
- const binaryPath = path60.join(binDir, binaryName);
24327
+ const binaryPath = path61.join(binDir, binaryName);
24153
24328
  try {
24154
24329
  fs57.accessSync(binaryPath, fs57.constants.F_OK);
24155
24330
  return binaryPath;
@@ -24161,11 +24336,11 @@ function resolveBdOnPath() {
24161
24336
  return _resolveSeam.resolveOnPath();
24162
24337
  }
24163
24338
  function _defaultResolveOnPath() {
24164
- const dirs = (process.env.PATH ?? "").split(path60.delimiter).filter(Boolean);
24339
+ const dirs = (process.env.PATH ?? "").split(path61.delimiter).filter(Boolean);
24165
24340
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
24166
24341
  for (const dir of dirs) {
24167
24342
  for (const candidate of candidates) {
24168
- const full = path60.join(dir, candidate);
24343
+ const full = path61.join(dir, candidate);
24169
24344
  try {
24170
24345
  fs57.accessSync(full, fs57.constants.F_OK);
24171
24346
  return full;
@@ -24346,7 +24521,7 @@ function coerceIssue(row, projectKey) {
24346
24521
  var import_child_process23 = require("child_process");
24347
24522
  var fs59 = __toESM(require("fs"));
24348
24523
  var os47 = __toESM(require("os"));
24349
- var path62 = __toESM(require("path"));
24524
+ var path63 = __toESM(require("path"));
24350
24525
 
24351
24526
  // src/beads/install-bd.ts
24352
24527
  var import_child_process21 = require("child_process");
@@ -24413,7 +24588,7 @@ async function installBd(platform3 = process.platform) {
24413
24588
  var import_child_process22 = require("child_process");
24414
24589
  var fs58 = __toESM(require("fs"));
24415
24590
  var os46 = __toESM(require("os"));
24416
- var path61 = __toESM(require("path"));
24591
+ var path62 = __toESM(require("path"));
24417
24592
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
24418
24593
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
24419
24594
  function resolveDoltInstallStrategy(platform3) {
@@ -24520,7 +24695,7 @@ function doltBinaryNames(platform3) {
24520
24695
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
24521
24696
  }
24522
24697
  function knownDoltDirs(platform3) {
24523
- const P3 = platform3 === "win32" ? path61.win32 : path61.posix;
24698
+ const P3 = platform3 === "win32" ? path62.win32 : path62.posix;
24524
24699
  const home = _doltPathSeam.homedir();
24525
24700
  if (platform3 === "win32") {
24526
24701
  return [
@@ -24536,7 +24711,7 @@ function knownDoltDirs(platform3) {
24536
24711
  ].filter(Boolean);
24537
24712
  }
24538
24713
  function ensureDoltResolvable(platform3 = process.platform) {
24539
- const P3 = platform3 === "win32" ? path61.win32 : path61.posix;
24714
+ const P3 = platform3 === "win32" ? path62.win32 : path62.posix;
24540
24715
  const delim = platform3 === "win32" ? ";" : ":";
24541
24716
  const names = doltBinaryNames(platform3);
24542
24717
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -24744,9 +24919,9 @@ var _linkSeam = {
24744
24919
  * which `linkBdOntoPath` creates if missing.
24745
24920
  */
24746
24921
  cliBinDir: () => {
24747
- const pathDirs = (process.env.PATH ?? "").split(path62.delimiter).filter(Boolean);
24922
+ const pathDirs = (process.env.PATH ?? "").split(path63.delimiter).filter(Boolean);
24748
24923
  const home = _linkSeam.homedir();
24749
- const localBin = home ? path62.join(home, ".local", "bin") : null;
24924
+ const localBin = home ? path63.join(home, ".local", "bin") : null;
24750
24925
  if (localBin) {
24751
24926
  try {
24752
24927
  _linkSeam.ensureDir(localBin);
@@ -24756,16 +24931,16 @@ var _linkSeam = {
24756
24931
  const candidates = [];
24757
24932
  if (localBin) candidates.push(localBin);
24758
24933
  try {
24759
- candidates.push(path62.dirname(process.execPath));
24934
+ candidates.push(path63.dirname(process.execPath));
24760
24935
  } catch {
24761
24936
  }
24762
24937
  candidates.push("/usr/local/bin");
24763
24938
  const entry = process.argv[1];
24764
24939
  if (entry) {
24765
24940
  try {
24766
- candidates.push(path62.dirname(fs59.realpathSync(entry)));
24941
+ candidates.push(path63.dirname(fs59.realpathSync(entry)));
24767
24942
  } catch {
24768
- candidates.push(path62.dirname(entry));
24943
+ candidates.push(path63.dirname(entry));
24769
24944
  }
24770
24945
  }
24771
24946
  const onPathWritable = candidates.find(
@@ -24790,7 +24965,7 @@ function linkBdOntoPath(binaryPath) {
24790
24965
  const binDir = _linkSeam.cliBinDir();
24791
24966
  if (!binDir) return;
24792
24967
  _linkSeam.ensureDir(binDir);
24793
- const linkPath = path62.join(binDir, "bd");
24968
+ const linkPath = path63.join(binDir, "bd");
24794
24969
  if (linkPath === binaryPath) return;
24795
24970
  const current2 = _linkSeam.readlink(linkPath);
24796
24971
  if (current2 === binaryPath) return;
@@ -24985,7 +25160,7 @@ function dedupeRecipes(agents) {
24985
25160
 
24986
25161
  // src/beads/watcher.ts
24987
25162
  var crypto4 = __toESM(require("crypto"));
24988
- var path63 = __toESM(require("path"));
25163
+ var path64 = __toESM(require("path"));
24989
25164
  var API_BASE6 = resolveApiBaseUrl();
24990
25165
  var DEBOUNCE_MS2 = 400;
24991
25166
  var ZERO_SUMMARY = {
@@ -25009,7 +25184,7 @@ var BeadsWatcher = class {
25009
25184
  constructor(opts) {
25010
25185
  this.opts = opts;
25011
25186
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
25012
- 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");
25013
25188
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
25014
25189
  }
25015
25190
  opts;
@@ -25260,15 +25435,15 @@ async function handleBeadsActionCommand(action, started) {
25260
25435
  }
25261
25436
 
25262
25437
  // src/beads/config-store.ts
25263
- var import_node_fs9 = __toESM(require("fs"));
25264
- var import_node_os8 = __toESM(require("os"));
25438
+ var import_node_fs10 = __toESM(require("fs"));
25439
+ var import_node_os7 = __toESM(require("os"));
25265
25440
  var import_node_path7 = __toESM(require("path"));
25266
25441
  function beadsConfigPath() {
25267
- 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");
25268
25443
  }
25269
25444
  function readBeadsEnabled() {
25270
25445
  try {
25271
- const raw = import_node_fs9.default.readFileSync(beadsConfigPath(), "utf8");
25446
+ const raw = import_node_fs10.default.readFileSync(beadsConfigPath(), "utf8");
25272
25447
  const cfg = JSON.parse(raw);
25273
25448
  return cfg.enabled !== false;
25274
25449
  } catch {
@@ -25277,10 +25452,10 @@ function readBeadsEnabled() {
25277
25452
  }
25278
25453
  function persistBeadsConfig(cfg) {
25279
25454
  const file = beadsConfigPath();
25280
- 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 });
25281
25456
  const tmp = `${file}.tmp`;
25282
- import_node_fs9.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
25283
- 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);
25284
25459
  restrictToOwner(file);
25285
25460
  }
25286
25461
 
@@ -25416,14 +25591,14 @@ async function configureBeads(action, ctx, deps) {
25416
25591
  }
25417
25592
 
25418
25593
  // src/skills/configure.ts
25419
- var import_node_os10 = __toESM(require("os"));
25594
+ var import_node_os9 = __toESM(require("os"));
25420
25595
 
25421
25596
  // src/skills/materialize.ts
25422
- var import_node_fs10 = __toESM(require("fs"));
25423
- var import_node_os9 = __toESM(require("os"));
25597
+ var import_node_fs11 = __toESM(require("fs"));
25598
+ var import_node_os8 = __toESM(require("os"));
25424
25599
  var import_node_path8 = __toESM(require("path"));
25425
25600
  var NS = "codeam-";
25426
- function skillDirFor(id, home = import_node_os9.default.homedir()) {
25601
+ function skillDirFor(id, home = import_node_os8.default.homedir()) {
25427
25602
  return import_node_path8.default.join(home, ".claude", "skills", `${NS}${id}`);
25428
25603
  }
25429
25604
  function renderSkillMd(id, description, body) {
@@ -25436,13 +25611,13 @@ description: ${JSON.stringify(desc)}
25436
25611
  ${body.trim()}
25437
25612
  `;
25438
25613
  }
25439
- function materializeSkill(id, home = import_node_os9.default.homedir()) {
25614
+ function materializeSkill(id, home = import_node_os8.default.homedir()) {
25440
25615
  const def = getSkillDefinition(id);
25441
25616
  if (!def?.delivery.skillFile) return false;
25442
25617
  try {
25443
25618
  const dir = skillDirFor(id, home);
25444
- import_node_fs10.default.mkdirSync(dir, { recursive: true, mode: 448 });
25445
- import_node_fs10.default.writeFileSync(
25619
+ import_node_fs11.default.mkdirSync(dir, { recursive: true, mode: 448 });
25620
+ import_node_fs11.default.writeFileSync(
25446
25621
  import_node_path8.default.join(dir, "SKILL.md"),
25447
25622
  renderSkillMd(id, def.description, def.delivery.skillFile.body),
25448
25623
  { encoding: "utf8", mode: 384 }
@@ -25454,8 +25629,8 @@ function materializeSkill(id, home = import_node_os9.default.homedir()) {
25454
25629
  if (!import_node_path8.default.resolve(target).startsWith(baseDirWithSep) && import_node_path8.default.resolve(target) !== baseDir) {
25455
25630
  continue;
25456
25631
  }
25457
- import_node_fs10.default.mkdirSync(import_node_path8.default.dirname(target), { recursive: true, mode: 448 });
25458
- 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 });
25459
25634
  }
25460
25635
  return true;
25461
25636
  } catch (err) {
@@ -25463,9 +25638,9 @@ function materializeSkill(id, home = import_node_os9.default.homedir()) {
25463
25638
  return false;
25464
25639
  }
25465
25640
  }
25466
- function removeSkill(id, home = import_node_os9.default.homedir()) {
25641
+ function removeSkill(id, home = import_node_os8.default.homedir()) {
25467
25642
  try {
25468
- 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 });
25469
25644
  } catch {
25470
25645
  }
25471
25646
  }
@@ -25475,7 +25650,7 @@ function currentInstalled() {
25475
25650
  const m = readSkillsManifest();
25476
25651
  return (m?.skills ?? []).map((s) => s.id).filter(isSkillId);
25477
25652
  }
25478
- function configureSkill(action, skillId, home = import_node_os10.default.homedir()) {
25653
+ function configureSkill(action, skillId, home = import_node_os9.default.homedir()) {
25479
25654
  if (action === "list") return { ok: true, installed: currentInstalled() };
25480
25655
  if (!skillId || !isSkillId(skillId)) {
25481
25656
  return { ok: false, installed: currentInstalled(), error: `unknown skill: ${skillId ?? "(none)"}` };
@@ -25508,7 +25683,7 @@ function cleanupAttachmentTempFiles() {
25508
25683
  function saveFilesTemp(files) {
25509
25684
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
25510
25685
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
25511
- 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}`);
25512
25687
  fs62.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
25513
25688
  pendingAttachmentFiles.add(tmpPath);
25514
25689
  return tmpPath;
@@ -25721,7 +25896,7 @@ var listFiles = async (ctx, cmd, parsed) => {
25721
25896
  await ctx.relay.sendResult(cmd.id, "completed", result);
25722
25897
  };
25723
25898
  var envReadH = async (ctx, cmd) => {
25724
- const envPath = path66.join(process.cwd(), ".env");
25899
+ const envPath = path67.join(process.cwd(), ".env");
25725
25900
  await restoreProjectEnvIfMissing(process.cwd(), ctx);
25726
25901
  try {
25727
25902
  const raw = await fs62.promises.readFile(envPath, "utf8");
@@ -25755,8 +25930,8 @@ var envWriteH = async (ctx, cmd, parsed) => {
25755
25930
  }
25756
25931
  seen.add(v.key);
25757
25932
  }
25758
- const envPath = path66.join(process.cwd(), ".env");
25759
- 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");
25760
25935
  try {
25761
25936
  await fs62.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
25762
25937
  await fs62.promises.rename(tmpPath, envPath);
@@ -26293,7 +26468,7 @@ function buildNpmInstallInvocation(opts) {
26293
26468
  const execPath = opts?.execPath ?? process.execPath;
26294
26469
  const exists2 = opts?.existsSync ?? fs62.existsSync;
26295
26470
  const platform3 = opts?.platform ?? process.platform;
26296
- const p2 = platform3 === "win32" ? path66.win32 : path66.posix;
26471
+ const p2 = platform3 === "win32" ? path67.win32 : path67.posix;
26297
26472
  const normalized = entryScript.split(/[\\/]/).join("/");
26298
26473
  const marker = "/lib/node_modules/codeam-cli/";
26299
26474
  const markerIdx = normalized.indexOf(marker);
@@ -26315,7 +26490,7 @@ function isPermissionError(stderr) {
26315
26490
  function resolveGlobalNodeModulesDir(opts) {
26316
26491
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
26317
26492
  const platform3 = opts?.platform ?? process.platform;
26318
- const p2 = platform3 === "win32" ? path66.win32 : path66.posix;
26493
+ const p2 = platform3 === "win32" ? path67.win32 : path67.posix;
26319
26494
  const marker = "/lib/node_modules/codeam-cli/";
26320
26495
  const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
26321
26496
  if (markerIdx <= 0) return null;
@@ -26337,7 +26512,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
26337
26512
  }
26338
26513
  for (const name of entries) {
26339
26514
  if (!/^\.codeam-cli-/.test(name)) continue;
26340
- const full = path66.join(nodeModulesDir, name);
26515
+ const full = path67.join(nodeModulesDir, name);
26341
26516
  try {
26342
26517
  const st3 = statSync17(full);
26343
26518
  if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
@@ -27215,11 +27390,11 @@ function resolveTokenValue(args2) {
27215
27390
  }
27216
27391
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
27217
27392
  if (fileFlag) {
27218
- const path89 = fileFlag.slice("--token-file=".length);
27393
+ const path90 = fileFlag.slice("--token-file=".length);
27219
27394
  try {
27220
- const content = fs63.readFileSync(path89, "utf8").trim();
27221
- if (content.length === 0) fail(`--token-file ${path89} is empty`);
27222
- rmIfExistsQuiet(path89);
27395
+ const content = fs63.readFileSync(path90, "utf8").trim();
27396
+ if (content.length === 0) fail(`--token-file ${path90} is empty`);
27397
+ rmIfExistsQuiet(path90);
27223
27398
  return content;
27224
27399
  } catch (err) {
27225
27400
  fail(`Could not read --token-file: ${err.message}`);
@@ -27309,7 +27484,7 @@ async function claim(token, pluginId, pluginSecretHash) {
27309
27484
  }
27310
27485
  }
27311
27486
  function pairAutoLockPath() {
27312
- return path67.join(os52.homedir(), ".codeam", "pair-auto.lock");
27487
+ return path68.join(os52.homedir(), ".codeam", "pair-auto.lock");
27313
27488
  }
27314
27489
  function isLivePairAuto(pid) {
27315
27490
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -27329,12 +27504,12 @@ function isLiveCodeam(pid) {
27329
27504
  }
27330
27505
  function daemonLockPath(sessionId) {
27331
27506
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
27332
- return path67.join(os52.homedir(), ".codeam", `daemon-${safe}.lock`);
27507
+ return path68.join(os52.homedir(), ".codeam", `daemon-${safe}.lock`);
27333
27508
  }
27334
27509
  function acquireDaemonLock(sessionId) {
27335
27510
  const lockPath = daemonLockPath(sessionId);
27336
27511
  try {
27337
- fs63.mkdirSync(path67.dirname(lockPath), { recursive: true });
27512
+ fs63.mkdirSync(path68.dirname(lockPath), { recursive: true });
27338
27513
  try {
27339
27514
  fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27340
27515
  } catch (e) {
@@ -27368,7 +27543,7 @@ function acquireDaemonLock(sessionId) {
27368
27543
  function acquireSingletonLock() {
27369
27544
  const lockPath = pairAutoLockPath();
27370
27545
  try {
27371
- fs63.mkdirSync(path67.dirname(lockPath), { recursive: true });
27546
+ fs63.mkdirSync(path68.dirname(lockPath), { recursive: true });
27372
27547
  try {
27373
27548
  fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27374
27549
  } catch (e) {
@@ -27832,7 +28007,7 @@ var AgentService = class _AgentService {
27832
28007
  };
27833
28008
 
27834
28009
  // src/agents/acp/adapters.ts
27835
- var path69 = __toESM(require("path"));
28010
+ var path70 = __toESM(require("path"));
27836
28011
 
27837
28012
  // src/agents/acp/agent-binary.ts
27838
28013
  var import_fs6 = __toESM(require("fs"));
@@ -28008,11 +28183,11 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
28008
28183
 
28009
28184
  // src/agents/kimi/installer.ts
28010
28185
  var import_node_child_process27 = require("child_process");
28011
- var import_node_os11 = require("os");
28186
+ var import_node_os10 = require("os");
28012
28187
  var import_node_path9 = require("path");
28013
28188
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
28014
28189
  function kimiBinDir() {
28015
- 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");
28016
28191
  }
28017
28192
  function kimiRuns() {
28018
28193
  const r = (0, import_node_child_process27.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
@@ -28060,11 +28235,11 @@ async function ensureKimiInstalled() {
28060
28235
 
28061
28236
  // src/agents/opencode/installer.ts
28062
28237
  var import_node_child_process28 = require("child_process");
28063
- var import_node_os12 = require("os");
28238
+ var import_node_os11 = require("os");
28064
28239
  var import_node_path10 = require("path");
28065
28240
  var INSTALL_URL3 = "https://opencode.ai/install";
28066
28241
  function opencodeBinDir() {
28067
- 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");
28068
28243
  }
28069
28244
  function opencodeRuns() {
28070
28245
  const r = (0, import_node_child_process28.spawnSync)("opencode", ["--version"], { stdio: "ignore", timeout: 15e3 });
@@ -28122,13 +28297,13 @@ function resolveBin(pkgName, binName) {
28122
28297
  try {
28123
28298
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
28124
28299
  const manifest = require_(`${pkgName}/package.json`);
28125
- const pkgDir = path69.dirname(manifestPath);
28300
+ const pkgDir = path70.dirname(manifestPath);
28126
28301
  const bin = manifest.bin;
28127
28302
  if (!bin) return null;
28128
- if (typeof bin === "string") return path69.resolve(pkgDir, bin);
28303
+ if (typeof bin === "string") return path70.resolve(pkgDir, bin);
28129
28304
  const target = binName ?? Object.keys(bin)[0];
28130
28305
  if (!target || !bin[target]) return null;
28131
- return path69.resolve(pkgDir, bin[target]);
28306
+ return path70.resolve(pkgDir, bin[target]);
28132
28307
  } catch {
28133
28308
  return null;
28134
28309
  }
@@ -28279,7 +28454,7 @@ var import_node_crypto11 = require("crypto");
28279
28454
 
28280
28455
  // src/services/history.service.ts
28281
28456
  var fs65 = __toESM(require("fs"));
28282
- var path70 = __toESM(require("path"));
28457
+ var path71 = __toESM(require("path"));
28283
28458
  var os54 = __toESM(require("os"));
28284
28459
  var https7 = __toESM(require("https"));
28285
28460
  var http6 = __toESM(require("http"));
@@ -28448,7 +28623,7 @@ var HistoryService = class _HistoryService {
28448
28623
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
28449
28624
  }
28450
28625
  get projectDir() {
28451
- 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));
28452
28627
  }
28453
28628
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
28454
28629
  setCurrentConversationId(id) {
@@ -28460,7 +28635,7 @@ var HistoryService = class _HistoryService {
28460
28635
  /** Return the current message count in the active conversation. */
28461
28636
  getCurrentMessageCount() {
28462
28637
  if (!this.currentConversationId) return 0;
28463
- const filePath = path70.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28638
+ const filePath = path71.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28464
28639
  return parseJsonl(filePath).length;
28465
28640
  }
28466
28641
  /**
@@ -28471,7 +28646,7 @@ var HistoryService = class _HistoryService {
28471
28646
  const deadline = Date.now() + timeoutMs;
28472
28647
  while (Date.now() < deadline) {
28473
28648
  if (!this.currentConversationId) return null;
28474
- const filePath = path70.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28649
+ const filePath = path71.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28475
28650
  const messages = parseJsonl(filePath);
28476
28651
  if (messages.length > previousCount) {
28477
28652
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -28499,14 +28674,14 @@ var HistoryService = class _HistoryService {
28499
28674
  try {
28500
28675
  const files = fs65.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
28501
28676
  try {
28502
- const stat3 = fs65.statSync(path70.join(dir, e.name));
28677
+ const stat3 = fs65.statSync(path71.join(dir, e.name));
28503
28678
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
28504
28679
  } catch {
28505
28680
  return { name: e.name, mtime: 0, birthtime: 0 };
28506
28681
  }
28507
28682
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
28508
28683
  if (files.length > 0) {
28509
- this.currentConversationId = path70.basename(files[0].name, ".jsonl");
28684
+ this.currentConversationId = path71.basename(files[0].name, ".jsonl");
28510
28685
  }
28511
28686
  } catch {
28512
28687
  }
@@ -28546,7 +28721,7 @@ var HistoryService = class _HistoryService {
28546
28721
  }
28547
28722
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
28548
28723
  try {
28549
- const stat3 = fs65.statSync(path70.join(dir, e.name));
28724
+ const stat3 = fs65.statSync(path71.join(dir, e.name));
28550
28725
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
28551
28726
  } catch {
28552
28727
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -28555,7 +28730,7 @@ var HistoryService = class _HistoryService {
28555
28730
  if (files.length === 0) return null;
28556
28731
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
28557
28732
  if (!files.some((f) => f.name === targetFile)) return null;
28558
- return this.extractUsageFromFile(path70.join(dir, targetFile));
28733
+ return this.extractUsageFromFile(path71.join(dir, targetFile));
28559
28734
  }
28560
28735
  extractUsageFromFile(filePath) {
28561
28736
  let raw;
@@ -28607,7 +28782,7 @@ var HistoryService = class _HistoryService {
28607
28782
  try {
28608
28783
  files = fs65.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
28609
28784
  try {
28610
- return fs65.statSync(path70.join(projectDir, f)).mtimeMs >= monthStartMs;
28785
+ return fs65.statSync(path71.join(projectDir, f)).mtimeMs >= monthStartMs;
28611
28786
  } catch {
28612
28787
  return false;
28613
28788
  }
@@ -28618,7 +28793,7 @@ var HistoryService = class _HistoryService {
28618
28793
  for (const file of files) {
28619
28794
  let raw;
28620
28795
  try {
28621
- raw = fs65.readFileSync(path70.join(projectDir, file), "utf8");
28796
+ raw = fs65.readFileSync(path71.join(projectDir, file), "utf8");
28622
28797
  } catch {
28623
28798
  continue;
28624
28799
  }
@@ -28697,7 +28872,7 @@ var HistoryService = class _HistoryService {
28697
28872
  if (this.runtime.resolveHistoryFile) {
28698
28873
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
28699
28874
  }
28700
- return path70.join(this.projectDir, `${sessionId}.jsonl`);
28875
+ return path71.join(this.projectDir, `${sessionId}.jsonl`);
28701
28876
  }
28702
28877
  /**
28703
28878
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -28731,7 +28906,7 @@ var HistoryService = class _HistoryService {
28731
28906
  };
28732
28907
  });
28733
28908
  }
28734
- return parseJsonl(path70.join(this.projectDir, `${sessionId}.jsonl`));
28909
+ return parseJsonl(path71.join(this.projectDir, `${sessionId}.jsonl`));
28735
28910
  }
28736
28911
  async loadConversation(sessionId) {
28737
28912
  const messages = this.readConversation(sessionId);
@@ -28877,7 +29052,7 @@ var import_node_child_process29 = require("child_process");
28877
29052
  var fs66 = __toESM(require("fs/promises"));
28878
29053
  var fsSync = __toESM(require("fs"));
28879
29054
  var os56 = __toESM(require("os"));
28880
- var path72 = __toESM(require("path"));
29055
+ var path73 = __toESM(require("path"));
28881
29056
  var import_node_stream = require("stream");
28882
29057
 
28883
29058
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -32903,7 +33078,7 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
32903
33078
  }
32904
33079
 
32905
33080
  // src/agents/acp/internal-paths.ts
32906
- var path71 = __toESM(require("path"));
33081
+ var path72 = __toESM(require("path"));
32907
33082
  var os55 = __toESM(require("os"));
32908
33083
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
32909
33084
  var SELF_HOSTED_WORKSPACE_RE = /\.codeam[/\\]self-hosted/gi;
@@ -32914,11 +33089,11 @@ function textReferencesInternal(text) {
32914
33089
  }
32915
33090
  function pathIsInternal(p2, homeDir2 = os55.homedir()) {
32916
33091
  if (!p2) return false;
32917
- const abs = path71.resolve(p2);
32918
- const home = path71.resolve(homeDir2);
32919
- const within = (root) => abs === root || abs.startsWith(root + path71.sep);
32920
- if (within(path71.join(home, ".codeam", "self-hosted"))) return false;
32921
- 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`);
32922
33097
  }
32923
33098
  function toolCallReferencesInternal(call) {
32924
33099
  if (textReferencesInternal(call.title)) return true;
@@ -33965,24 +34140,24 @@ function knownAgentBinaryDirs() {
33965
34140
  out2.push("/tmp/codeam-node20/bin");
33966
34141
  for (const root of [
33967
34142
  "/usr/local/share/nvm/versions/node",
33968
- path72.join(home, ".nvm/versions/node")
34143
+ path73.join(home, ".nvm/versions/node")
33969
34144
  ]) {
33970
34145
  try {
33971
34146
  for (const child of fsSync.readdirSync(root)) {
33972
- out2.push(path72.join(root, child, "bin"));
34147
+ out2.push(path73.join(root, child, "bin"));
33973
34148
  }
33974
34149
  } catch {
33975
34150
  }
33976
34151
  }
33977
- out2.push(path72.join(home, ".volta/bin"));
34152
+ out2.push(path73.join(home, ".volta/bin"));
33978
34153
  out2.push("/usr/local/bin");
33979
34154
  out2.push("/usr/bin");
33980
- out2.push(path72.join(home, ".local/bin"));
33981
- out2.push(path72.join(home, "bin"));
34155
+ out2.push(path73.join(home, ".local/bin"));
34156
+ out2.push(path73.join(home, "bin"));
33982
34157
  if (process.platform === "win32") {
33983
34158
  const { LOCALAPPDATA, APPDATA } = process.env;
33984
- if (LOCALAPPDATA) out2.push(path72.join(LOCALAPPDATA, "cursor-agent"));
33985
- 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"));
33986
34161
  }
33987
34162
  return out2.filter((p2) => {
33988
34163
  try {
@@ -33994,7 +34169,7 @@ function knownAgentBinaryDirs() {
33994
34169
  }
33995
34170
  function expandPathForAgentBinaries(existingPath) {
33996
34171
  const existing = new Set(
33997
- existingPath.split(path72.delimiter).filter((p2) => p2.length > 0)
34172
+ existingPath.split(path73.delimiter).filter((p2) => p2.length > 0)
33998
34173
  );
33999
34174
  const additions = [];
34000
34175
  for (const dir of knownAgentBinaryDirs()) {
@@ -34004,7 +34179,7 @@ function expandPathForAgentBinaries(existingPath) {
34004
34179
  }
34005
34180
  }
34006
34181
  if (additions.length === 0) return existingPath;
34007
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path72.delimiter);
34182
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path73.delimiter);
34008
34183
  }
34009
34184
 
34010
34185
  // src/agents/acp/headroom-budget-proxy.ts
@@ -34488,12 +34663,12 @@ function commonPrefixLength(a, b) {
34488
34663
  var import_child_process27 = require("child_process");
34489
34664
  var fs67 = __toESM(require("fs"));
34490
34665
  var os57 = __toESM(require("os"));
34491
- var path73 = __toESM(require("path"));
34666
+ var path74 = __toESM(require("path"));
34492
34667
  var _onboardingSeam = {
34493
- markerPath: (sessionId) => path73.join(os57.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34668
+ markerPath: (sessionId) => path74.join(os57.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34494
34669
  exists: (p2) => fs67.existsSync(p2),
34495
34670
  write: (p2) => {
34496
- fs67.mkdirSync(path73.dirname(p2), { recursive: true });
34671
+ fs67.mkdirSync(path74.dirname(p2), { recursive: true });
34497
34672
  fs67.writeFileSync(p2, "");
34498
34673
  },
34499
34674
  disabled: () => {
@@ -34531,7 +34706,7 @@ function resolveRepoName(cwd) {
34531
34706
  if (name) return name;
34532
34707
  }
34533
34708
  }
34534
- const base = path73.basename(cwd || "");
34709
+ const base = path74.basename(cwd || "");
34535
34710
  if (base && !isUuid(base)) return base;
34536
34711
  return "this project";
34537
34712
  }
@@ -34790,12 +34965,12 @@ var import_crypto5 = require("crypto");
34790
34965
  // src/services/turn-files/git-changeset.ts
34791
34966
  var import_child_process28 = require("child_process");
34792
34967
  var fs69 = __toESM(require("fs/promises"));
34793
- var path75 = __toESM(require("path"));
34968
+ var path76 = __toESM(require("path"));
34794
34969
 
34795
34970
  // src/services/turn-files/review-ignore.ts
34796
34971
  var import_ignore2 = __toESM(require("ignore"));
34797
34972
  var fs68 = __toESM(require("fs"));
34798
- var path74 = __toESM(require("path"));
34973
+ var path75 = __toESM(require("path"));
34799
34974
  var CURATED_REVIEW_IGNORE = [
34800
34975
  // Google Cloud SDK (the incident) — installs a huge python tree.
34801
34976
  "google-cloud-sdk/",
@@ -34834,7 +35009,7 @@ var CURATED_REVIEW_IGNORE = [
34834
35009
  function makeReviewIgnore(repoRoot) {
34835
35010
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
34836
35011
  try {
34837
- const custom = fs68.readFileSync(path74.join(repoRoot, ".codeam", "reviewignore"), "utf8");
35012
+ const custom = fs68.readFileSync(path75.join(repoRoot, ".codeam", "reviewignore"), "utf8");
34838
35013
  ig.add(custom);
34839
35014
  } catch {
34840
35015
  }
@@ -34879,7 +35054,7 @@ async function collectRepoChangeset(opts) {
34879
35054
  let stats;
34880
35055
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
34881
35056
  const lineCount = await readUntrackedLineCount(
34882
- path75.join(opts.repoRoot, row.filePath)
35057
+ path76.join(opts.repoRoot, row.filePath)
34883
35058
  );
34884
35059
  stats = { added: lineCount, removed: 0 };
34885
35060
  } else {
@@ -35021,8 +35196,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
35021
35196
  if (hasGit) {
35022
35197
  out2.push({
35023
35198
  repoRoot: dir,
35024
- repoPath: path75.relative(workingDir, dir),
35025
- repoName: path75.basename(dir)
35199
+ repoPath: path76.relative(workingDir, dir),
35200
+ repoName: path76.basename(dir)
35026
35201
  });
35027
35202
  return;
35028
35203
  }
@@ -35030,14 +35205,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
35030
35205
  if (!entry.isDirectory) continue;
35031
35206
  if (entry.name === "node_modules") continue;
35032
35207
  if (entry.name === "dist" || entry.name === "build") continue;
35033
- await walk(path75.join(dir, entry.name), depth + 1);
35208
+ await walk(path76.join(dir, entry.name), depth + 1);
35034
35209
  }
35035
35210
  }
35036
35211
  }
35037
35212
 
35038
35213
  // src/services/turn-files/files-outbox.ts
35039
35214
  var fs70 = __toESM(require("fs/promises"));
35040
- var path76 = __toESM(require("path"));
35215
+ var path77 = __toESM(require("path"));
35041
35216
  var import_os12 = require("os");
35042
35217
  var HOME_OUTBOX_DIR = ".codeam/outbox";
35043
35218
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -35070,15 +35245,15 @@ var FilesOutbox = class {
35070
35245
  backoffIndex = 0;
35071
35246
  stopped = false;
35072
35247
  constructor(opts) {
35073
- const base = opts.baseDir ?? path76.join(homeDir(), HOME_OUTBOX_DIR);
35074
- 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`);
35075
35250
  this.post = opts.post;
35076
35251
  this.autoSchedule = opts.autoSchedule !== false;
35077
35252
  }
35078
35253
  /** Persist the entry to disk and trigger a flush. Returns once the
35079
35254
  * line is durable on disk (not once the POST succeeds). */
35080
35255
  async enqueue(entry) {
35081
- await fs70.mkdir(path76.dirname(this.filePath), { recursive: true });
35256
+ await fs70.mkdir(path77.dirname(this.filePath), { recursive: true });
35082
35257
  await fs70.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
35083
35258
  this.backoffIndex = 0;
35084
35259
  if (this.autoSchedule) this.scheduleFlush(0);
@@ -35656,7 +35831,7 @@ async function postBudgetReached(opts, fetchImpl = fetch) {
35656
35831
  // src/packs/gates.ts
35657
35832
  var import_node_child_process30 = require("child_process");
35658
35833
  var fs71 = __toESM(require("fs"));
35659
- var path77 = __toESM(require("path"));
35834
+ var path78 = __toESM(require("path"));
35660
35835
  var defaultCommandRunner = (file, args2, cwd, timeoutMs) => new Promise((resolve9) => {
35661
35836
  (0, import_node_child_process30.execFile)(
35662
35837
  file,
@@ -35693,14 +35868,14 @@ var NO_TEST_PLACEHOLDER = 'echo "Error: no test specified"';
35693
35868
  var CHECKS_TIMEOUT_MS = 5 * 6e4;
35694
35869
  function detectChecksCommand(cwd) {
35695
35870
  try {
35696
- 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"));
35697
35872
  if (typeof cfg.checksCommand === "string" && cfg.checksCommand.trim().length > 0) {
35698
35873
  return cfg.checksCommand.trim();
35699
35874
  }
35700
35875
  } catch {
35701
35876
  }
35702
35877
  try {
35703
- 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"));
35704
35879
  const test = pkg.scripts?.test;
35705
35880
  if (typeof test === "string" && test.trim().length > 0 && !test.includes(NO_TEST_PLACEHOLDER)) {
35706
35881
  return "npm test";
@@ -35719,36 +35894,36 @@ ${res.stderr}`.trim();
35719
35894
 
35720
35895
  // src/packs/run-store.ts
35721
35896
  var fs72 = __toESM(require("fs"));
35722
- var path78 = __toESM(require("path"));
35897
+ var path79 = __toESM(require("path"));
35723
35898
  var crypto5 = __toESM(require("crypto"));
35724
35899
  function packsDir(cwd) {
35725
- return path78.join(cwd, ".codeam", "packs");
35900
+ return path79.join(cwd, ".codeam", "packs");
35726
35901
  }
35727
35902
  function runDir(cwd, runId) {
35728
- return path78.join(packsDir(cwd), runId);
35903
+ return path79.join(packsDir(cwd), runId);
35729
35904
  }
35730
35905
  function newRunId() {
35731
35906
  return `pk_${Date.now().toString(36)}_${crypto5.randomBytes(4).toString("hex")}`;
35732
35907
  }
35733
35908
  function writeJsonAtomic(file, value) {
35734
- fs72.mkdirSync(path78.dirname(file), { recursive: true });
35909
+ fs72.mkdirSync(path79.dirname(file), { recursive: true });
35735
35910
  const tmp = `${file}.tmp`;
35736
35911
  fs72.writeFileSync(tmp, JSON.stringify(value, null, 2));
35737
35912
  fs72.renameSync(tmp, file);
35738
35913
  }
35739
35914
  function saveRun(cwd, state) {
35740
- writeJsonAtomic(path78.join(runDir(cwd, state.runId), "run.json"), state);
35915
+ writeJsonAtomic(path79.join(runDir(cwd, state.runId), "run.json"), state);
35741
35916
  }
35742
35917
  function saveStageHandoff(cwd, runId, stageIndex, role, handoff) {
35743
35918
  const name = `${String(stageIndex + 1).padStart(2, "0")}-${role}.json`;
35744
- writeJsonAtomic(path78.join(runDir(cwd, runId), name), handoff);
35919
+ writeJsonAtomic(path79.join(runDir(cwd, runId), name), handoff);
35745
35920
  }
35746
35921
  function loadLatestRun(cwd) {
35747
35922
  try {
35748
35923
  const dir = packsDir(cwd);
35749
35924
  const entries = fs72.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
35750
35925
  for (let i = entries.length - 1; i >= 0; i--) {
35751
- const file = path78.join(dir, entries[i], "run.json");
35926
+ const file = path79.join(dir, entries[i], "run.json");
35752
35927
  try {
35753
35928
  const parsed = JSON.parse(fs72.readFileSync(file, "utf8"));
35754
35929
  if (parsed && typeof parsed.runId === "string") return parsed;
@@ -35761,16 +35936,16 @@ function loadLatestRun(cwd) {
35761
35936
  }
35762
35937
  function ensureLedgerIgnored(cwd) {
35763
35938
  try {
35764
- const gitDir = path78.join(cwd, ".git");
35939
+ const gitDir = path79.join(cwd, ".git");
35765
35940
  if (!fs72.existsSync(gitDir)) return;
35766
- const exclude = path78.join(gitDir, "info", "exclude");
35941
+ const exclude = path79.join(gitDir, "info", "exclude");
35767
35942
  let existing = "";
35768
35943
  try {
35769
35944
  existing = fs72.readFileSync(exclude, "utf8");
35770
35945
  } catch {
35771
35946
  }
35772
35947
  if (existing.includes(".codeam/packs/")) return;
35773
- fs72.mkdirSync(path78.dirname(exclude), { recursive: true });
35948
+ fs72.mkdirSync(path79.dirname(exclude), { recursive: true });
35774
35949
  fs72.writeFileSync(exclude, `${existing.trimEnd()}
35775
35950
  .codeam/packs/
35776
35951
  `.trimStart());
@@ -36225,11 +36400,11 @@ function buildMcpServersForStart(ctx) {
36225
36400
  }
36226
36401
 
36227
36402
  // src/integrations/detect-stack.ts
36228
- var import_node_fs11 = __toESM(require("fs"));
36403
+ var import_node_fs12 = __toESM(require("fs"));
36229
36404
  var import_node_path11 = __toESM(require("path"));
36230
36405
  function readSafe(cwd, rel) {
36231
36406
  try {
36232
- 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");
36233
36408
  } catch {
36234
36409
  return "";
36235
36410
  }
@@ -36363,18 +36538,18 @@ function buildAcpPromptBlocks(payload) {
36363
36538
 
36364
36539
  // src/agents/agent-standard.ts
36365
36540
  var fs74 = __toESM(require("fs"));
36366
- var path80 = __toESM(require("path"));
36541
+ var path81 = __toESM(require("path"));
36367
36542
  var os58 = __toESM(require("os"));
36368
36543
  function ensureAgentStandard(homeDir2 = os58.homedir()) {
36369
36544
  try {
36370
- const file = path80.join(homeDir2, ".claude", "CLAUDE.md");
36545
+ const file = path81.join(homeDir2, ".claude", "CLAUDE.md");
36371
36546
  let existing = "";
36372
36547
  try {
36373
36548
  existing = fs74.readFileSync(file, "utf8");
36374
36549
  } catch {
36375
36550
  }
36376
36551
  if (existing.includes(AGENT_STANDARD_MARKER)) return;
36377
- fs74.mkdirSync(path80.dirname(file), { recursive: true });
36552
+ fs74.mkdirSync(path81.dirname(file), { recursive: true });
36378
36553
  const next = existing.trim() ? `${existing.trimEnd()}
36379
36554
 
36380
36555
  ${AGENT_STANDARD_BLOCK}
@@ -36386,10 +36561,10 @@ ${AGENT_STANDARD_BLOCK}
36386
36561
  }
36387
36562
  var _agentStandardSeam = {
36388
36563
  isLocalSession: () => isLocalSession(),
36389
- markerPath: (sessionId) => path80.join(os58.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36564
+ markerPath: (sessionId) => path81.join(os58.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36390
36565
  exists: (p2) => fs74.existsSync(p2),
36391
36566
  write: (p2) => {
36392
- fs74.mkdirSync(path80.dirname(p2), { recursive: true });
36567
+ fs74.mkdirSync(path81.dirname(p2), { recursive: true });
36393
36568
  fs74.writeFileSync(p2, "");
36394
36569
  }
36395
36570
  };
@@ -39060,7 +39235,7 @@ function startClaudeCredentialSync(opts) {
39060
39235
 
39061
39236
  // src/beads/workflow-hint.ts
39062
39237
  var fs75 = __toESM(require("fs"));
39063
- var path81 = __toESM(require("path"));
39238
+ var path82 = __toESM(require("path"));
39064
39239
  var os59 = __toESM(require("os"));
39065
39240
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
39066
39241
  var BEADS_HINT = `${BEADS_HINT_MARKER}
@@ -39077,14 +39252,14 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
39077
39252
  ${BEADS_HINT_MARKER}`;
39078
39253
  function ensureBeadsWorkflowHint(homeDir2 = os59.homedir()) {
39079
39254
  try {
39080
- const file = path81.join(homeDir2, ".claude", "CLAUDE.md");
39255
+ const file = path82.join(homeDir2, ".claude", "CLAUDE.md");
39081
39256
  let existing = "";
39082
39257
  try {
39083
39258
  existing = fs75.readFileSync(file, "utf8");
39084
39259
  } catch {
39085
39260
  }
39086
39261
  if (existing.includes(BEADS_HINT_MARKER)) return;
39087
- fs75.mkdirSync(path81.dirname(file), { recursive: true });
39262
+ fs75.mkdirSync(path82.dirname(file), { recursive: true });
39088
39263
  const next = existing.trim() ? `${existing.trimEnd()}
39089
39264
 
39090
39265
  ${BEADS_HINT}
@@ -39096,8 +39271,8 @@ ${BEADS_HINT}
39096
39271
  }
39097
39272
 
39098
39273
  // src/skills/provision.ts
39099
- var import_node_os13 = __toESM(require("os"));
39100
- 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()) {
39101
39276
  const materialized = [];
39102
39277
  try {
39103
39278
  const manifest = readSkillsManifest();
@@ -39829,11 +40004,11 @@ function keepDeviceAwake(deps = {}) {
39829
40004
  // src/agents/claude/onboarding.ts
39830
40005
  var fs77 = __toESM(require("fs"));
39831
40006
  var os61 = __toESM(require("os"));
39832
- var path82 = __toESM(require("path"));
40007
+ var path83 = __toESM(require("path"));
39833
40008
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
39834
40009
  function ensureClaudeOnboarded(cwd) {
39835
40010
  try {
39836
- const file = path82.join(os61.homedir(), ".claude.json");
40011
+ const file = path83.join(os61.homedir(), ".claude.json");
39837
40012
  let config = {};
39838
40013
  try {
39839
40014
  config = JSON.parse(fs77.readFileSync(file, "utf8"));
@@ -39861,7 +40036,7 @@ function ensureClaudeOnboarded(cwd) {
39861
40036
  }
39862
40037
  }
39863
40038
  if (!changed) return;
39864
- fs77.mkdirSync(path82.dirname(file), { recursive: true });
40039
+ fs77.mkdirSync(path83.dirname(file), { recursive: true });
39865
40040
  fs77.writeFileSync(file, JSON.stringify(config, null, 2));
39866
40041
  log.info(
39867
40042
  "claude",
@@ -40594,7 +40769,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
40594
40769
  var import_child_process29 = require("child_process");
40595
40770
  var import_util4 = require("util");
40596
40771
  var import_picocolors9 = __toESM(require("picocolors"));
40597
- var path83 = __toESM(require("path"));
40772
+ var path84 = __toESM(require("path"));
40598
40773
  var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
40599
40774
  var MAX_BUFFER = 8 * 1024 * 1024;
40600
40775
  function resetStdinForChild() {
@@ -41083,7 +41258,7 @@ var GitHubCodespacesProvider = class {
41083
41258
  });
41084
41259
  }
41085
41260
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
41086
- const remoteDir = path83.posix.dirname(remotePath);
41261
+ const remoteDir = path84.posix.dirname(remotePath);
41087
41262
  const parts = [
41088
41263
  `mkdir -p ${shellQuote(remoteDir)}`,
41089
41264
  `cat > ${shellQuote(remotePath)}`
@@ -41153,7 +41328,7 @@ function shellQuote(s) {
41153
41328
  // src/services/providers/gitpod.ts
41154
41329
  var import_child_process30 = require("child_process");
41155
41330
  var import_util5 = require("util");
41156
- var path84 = __toESM(require("path"));
41331
+ var path85 = __toESM(require("path"));
41157
41332
  var import_picocolors10 = __toESM(require("picocolors"));
41158
41333
  var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
41159
41334
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -41393,7 +41568,7 @@ var GitpodProvider = class {
41393
41568
  });
41394
41569
  }
41395
41570
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
41396
- const remoteDir = path84.posix.dirname(remotePath);
41571
+ const remoteDir = path85.posix.dirname(remotePath);
41397
41572
  const parts = [
41398
41573
  `mkdir -p ${shellQuote2(remoteDir)}`,
41399
41574
  `cat > ${shellQuote2(remotePath)}`
@@ -41429,7 +41604,7 @@ function shellQuote2(s) {
41429
41604
  // src/services/providers/gitlab-workspaces.ts
41430
41605
  var import_child_process31 = require("child_process");
41431
41606
  var import_util6 = require("util");
41432
- var path85 = __toESM(require("path"));
41607
+ var path86 = __toESM(require("path"));
41433
41608
  var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
41434
41609
  var MAX_BUFFER3 = 8 * 1024 * 1024;
41435
41610
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -41689,7 +41864,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
41689
41864
  }
41690
41865
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
41691
41866
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
41692
- const remoteDir = path85.posix.dirname(remotePath);
41867
+ const remoteDir = path86.posix.dirname(remotePath);
41693
41868
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
41694
41869
  if (options.mode != null) {
41695
41870
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -41757,7 +41932,7 @@ function shellQuote3(s) {
41757
41932
  // src/services/providers/railway.ts
41758
41933
  var import_child_process32 = require("child_process");
41759
41934
  var import_util7 = require("util");
41760
- var path86 = __toESM(require("path"));
41935
+ var path87 = __toESM(require("path"));
41761
41936
  var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
41762
41937
  var MAX_BUFFER4 = 8 * 1024 * 1024;
41763
41938
  function resetStdinForChild4() {
@@ -41993,7 +42168,7 @@ var RailwayProvider = class {
41993
42168
  if (!projectId || !serviceId) {
41994
42169
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
41995
42170
  }
41996
- const remoteDir = path86.posix.dirname(remotePath);
42171
+ const remoteDir = path87.posix.dirname(remotePath);
41997
42172
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
41998
42173
  if (options.mode != null) {
41999
42174
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -42640,7 +42815,7 @@ var import_node_dns = require("dns");
42640
42815
  var import_node_util5 = require("util");
42641
42816
  var import_node_crypto13 = require("crypto");
42642
42817
  var fs78 = __toESM(require("fs"));
42643
- var path87 = __toESM(require("path"));
42818
+ var path88 = __toESM(require("path"));
42644
42819
  var import_picocolors14 = __toESM(require("picocolors"));
42645
42820
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
42646
42821
  async function checkDns(apiBase2) {
@@ -42696,10 +42871,10 @@ async function checkHealth(apiBase2) {
42696
42871
  }
42697
42872
  }
42698
42873
  function checkConfigDir() {
42699
- const dir = path87.join(require("os").homedir(), ".codeam");
42874
+ const dir = path88.join(require("os").homedir(), ".codeam");
42700
42875
  try {
42701
42876
  fs78.mkdirSync(dir, { recursive: true, mode: 448 });
42702
- const probe = path87.join(dir, ".doctor-probe");
42877
+ const probe = path88.join(dir, ".doctor-probe");
42703
42878
  fs78.writeFileSync(probe, "ok", { mode: 384 });
42704
42879
  const read2 = fs78.readFileSync(probe, "utf8");
42705
42880
  fs78.unlinkSync(probe);
@@ -42766,7 +42941,7 @@ function checkNodePty() {
42766
42941
  detail: "not required on this platform"
42767
42942
  };
42768
42943
  }
42769
- const vendoredPath = path87.join(__dirname, "vendor", "node-pty");
42944
+ const vendoredPath = path88.join(__dirname, "vendor", "node-pty");
42770
42945
  for (const target of [vendoredPath, "node-pty"]) {
42771
42946
  try {
42772
42947
  require(target);
@@ -42808,7 +42983,7 @@ function checkChokidar() {
42808
42983
  }
42809
42984
  async function doctor(args2 = []) {
42810
42985
  const json = args2.includes("--json");
42811
- const cliVersion = true ? "2.62.0" : "0.0.0-dev";
42986
+ const cliVersion = true ? "2.62.2" : "0.0.0-dev";
42812
42987
  const apiBase2 = resolveApiBaseUrl();
42813
42988
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
42814
42989
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -43006,8 +43181,8 @@ async function completion(args2) {
43006
43181
 
43007
43182
  // src/integrations/mcp-run.ts
43008
43183
  var import_node_child_process34 = require("child_process");
43009
- var import_node_fs12 = require("fs");
43010
- var import_node_os14 = __toESM(require("os"));
43184
+ var import_node_fs13 = require("fs");
43185
+ var import_node_os13 = __toESM(require("os"));
43011
43186
  var import_node_path12 = __toESM(require("path"));
43012
43187
 
43013
43188
  // src/integrations/token-client.ts
@@ -43088,13 +43263,13 @@ function commandExists(command2) {
43088
43263
  }
43089
43264
  function localBinCandidates(command2) {
43090
43265
  return [
43091
- import_node_path12.default.join(import_node_os14.default.homedir(), ".local", "bin", command2),
43092
- 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)
43093
43268
  ];
43094
43269
  }
43095
43270
  function resolveLauncherPath(command2, deps = {
43096
43271
  commandExists,
43097
- existsSync: import_node_fs12.existsSync
43272
+ existsSync: import_node_fs13.existsSync
43098
43273
  }) {
43099
43274
  if (deps.commandExists(command2)) return command2;
43100
43275
  for (const candidate of localBinCandidates(command2)) {
@@ -43199,7 +43374,7 @@ async function mcpRun(args2) {
43199
43374
  // src/commands/version.ts
43200
43375
  var import_picocolors15 = __toESM(require("picocolors"));
43201
43376
  function version2() {
43202
- const v = true ? "2.62.0" : "unknown";
43377
+ const v = true ? "2.62.2" : "unknown";
43203
43378
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
43204
43379
  }
43205
43380