codeam-cli 2.60.23 → 2.60.25

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 +814 -437
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -778,11 +778,11 @@ function quiet(fn) {
778
778
  log.debug(TAG, "ignored sync error", err);
779
779
  }
780
780
  }
781
- function rmIfExistsQuiet(path70) {
781
+ function rmIfExistsQuiet(path71) {
782
782
  try {
783
- fs2.rmSync(path70, { force: true });
783
+ fs2.rmSync(path71, { force: true });
784
784
  } catch (err) {
785
- log.debug(TAG, `rmIfExists failed for ${path70}`, err);
785
+ log.debug(TAG, `rmIfExists failed for ${path71}`, err);
786
786
  }
787
787
  }
788
788
  function killQuiet(target, signal = "SIGTERM") {
@@ -928,9 +928,9 @@ var _default = makeConfig();
928
928
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
929
929
 
930
930
  // src/commands/pair-auto.ts
931
- var fs53 = __toESM(require("fs"));
932
- var os42 = __toESM(require("os"));
933
- var path56 = __toESM(require("path"));
931
+ var fs54 = __toESM(require("fs"));
932
+ var os43 = __toESM(require("os"));
933
+ var path57 = __toESM(require("path"));
934
934
  var import_crypto4 = require("crypto");
935
935
 
936
936
  // src/services/telemetry.service.ts
@@ -966,8 +966,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
966
966
  return decodedFile;
967
967
  };
968
968
  }
969
- function normalizeWindowsPath(path70) {
970
- return path70.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
969
+ function normalizeWindowsPath(path71) {
970
+ return path71.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
971
971
  }
972
972
 
973
973
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3447,9 +3447,9 @@ async function addSourceContext(frames) {
3447
3447
  LRU_FILE_CONTENTS_CACHE.reduce();
3448
3448
  return frames;
3449
3449
  }
3450
- function getContextLinesFromFile(path70, ranges, output) {
3450
+ function getContextLinesFromFile(path71, ranges, output) {
3451
3451
  return new Promise((resolve7) => {
3452
- const stream = (0, import_node_fs.createReadStream)(path70);
3452
+ const stream = (0, import_node_fs.createReadStream)(path71);
3453
3453
  const lineReaded = (0, import_node_readline.createInterface)({
3454
3454
  input: stream
3455
3455
  });
@@ -3464,7 +3464,7 @@ function getContextLinesFromFile(path70, ranges, output) {
3464
3464
  let rangeStart = range[0];
3465
3465
  let rangeEnd = range[1];
3466
3466
  function onStreamError() {
3467
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path70, 1);
3467
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path71, 1);
3468
3468
  lineReaded.close();
3469
3469
  lineReaded.removeAllListeners();
3470
3470
  destroyStreamAndResolve();
@@ -3525,8 +3525,8 @@ function clearLineContext(frame) {
3525
3525
  delete frame.context_line;
3526
3526
  delete frame.post_context;
3527
3527
  }
3528
- function shouldSkipContextLinesForFile(path70) {
3529
- return path70.startsWith("node:") || path70.endsWith(".min.js") || path70.endsWith(".min.cjs") || path70.endsWith(".min.mjs") || path70.startsWith("data:");
3528
+ function shouldSkipContextLinesForFile(path71) {
3529
+ return path71.startsWith("node:") || path71.endsWith(".min.js") || path71.endsWith(".min.cjs") || path71.endsWith(".min.mjs") || path71.startsWith("data:");
3530
3530
  }
3531
3531
  function shouldSkipContextLinesForFrame(frame) {
3532
3532
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5680,7 +5680,7 @@ function readAnonId() {
5680
5680
  }
5681
5681
  function superProperties() {
5682
5682
  return {
5683
- cliVersion: true ? "2.60.23" : "0.0.0-dev",
5683
+ cliVersion: true ? "2.60.25" : "0.0.0-dev",
5684
5684
  nodeVersion: process.version,
5685
5685
  platform: process.platform,
5686
5686
  arch: process.arch,
@@ -5861,7 +5861,7 @@ var os4 = __toESM(require("os"));
5861
5861
  // package.json
5862
5862
  var package_default = {
5863
5863
  name: "codeam-cli",
5864
- version: "2.60.23",
5864
+ version: "2.60.25",
5865
5865
  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.",
5866
5866
  type: "commonjs",
5867
5867
  main: "dist/index.js",
@@ -6187,6 +6187,28 @@ async function postHeadroomEvent(input) {
6187
6187
  };
6188
6188
  }
6189
6189
  }
6190
+ async function postCoderabbitEvent(input) {
6191
+ try {
6192
+ await _transport.postJsonAuthed(
6193
+ `${API_BASE}/api/coderabbit/events`,
6194
+ {
6195
+ sessionId: input.sessionId,
6196
+ pluginId: input.pluginId,
6197
+ type: input.type,
6198
+ payload: input.payload ?? {}
6199
+ },
6200
+ input.pluginAuthToken
6201
+ );
6202
+ return { ok: true };
6203
+ } catch (err) {
6204
+ const e = err;
6205
+ return {
6206
+ ok: false,
6207
+ status: typeof e.statusCode === "number" ? e.statusCode : 0,
6208
+ message: e.message || "unknown"
6209
+ };
6210
+ }
6211
+ }
6190
6212
  async function postBeadsEvent(input) {
6191
6213
  try {
6192
6214
  await _transport.postJsonAuthed(
@@ -6932,7 +6954,7 @@ var CommandRelayService = class {
6932
6954
  // fresh + clear the "CLI update available" banner after a self-update
6933
6955
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
6934
6956
  // pair/reconnect). Older backends ignore the extra field.
6935
- ..."2.60.23" ? { ideVersion: "2.60.23" } : {}
6957
+ ..."2.60.25" ? { ideVersion: "2.60.25" } : {}
6936
6958
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
6937
6959
  }
6938
6960
  /**
@@ -7159,10 +7181,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
7159
7181
  /[\\/]Start Menu([\\/]|$)/i,
7160
7182
  /[\\/]Templates([\\/]|$)/i
7161
7183
  ];
7162
- function isUnsafeWindowsWatchRoot(dir, homedir41) {
7184
+ function isUnsafeWindowsWatchRoot(dir, homedir42) {
7163
7185
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
7164
7186
  const cwd = norm(dir);
7165
- const home = norm(homedir41);
7187
+ const home = norm(homedir42);
7166
7188
  if (cwd === home) return true;
7167
7189
  if (/^[a-z]:$/.test(cwd)) return true;
7168
7190
  const sysRoots = [
@@ -8306,9 +8328,9 @@ function closeAllTerminals() {
8306
8328
  }
8307
8329
 
8308
8330
  // src/commands/start/handlers.ts
8309
- var fs52 = __toESM(require("fs"));
8310
- var os41 = __toESM(require("os"));
8311
- var path55 = __toESM(require("path"));
8331
+ var fs53 = __toESM(require("fs"));
8332
+ var os42 = __toESM(require("os"));
8333
+ var path56 = __toESM(require("path"));
8312
8334
  var import_crypto3 = require("crypto");
8313
8335
  var import_child_process23 = require("child_process");
8314
8336
 
@@ -8371,10 +8393,27 @@ var startCommandSchema = import_zod.z.object({
8371
8393
  // `git restore` from there. `action='approved'` stages the edit,
8372
8394
  // `action='rejected'` discards every worktree change on the file.
8373
8395
  filePath: import_zod.z.string().min(1).max(4096).optional(),
8374
- action: import_zod.z.enum(["approved", "rejected", "enable", "disable", "status"]).optional(),
8396
+ action: import_zod.z.enum([
8397
+ "approved",
8398
+ "rejected",
8399
+ "enable",
8400
+ "disable",
8401
+ "status",
8402
+ // `coderabbit_configure` — link the reviewer (OAuth or API key) + run a review.
8403
+ "link_oauth",
8404
+ "link_apikey",
8405
+ "review"
8406
+ ]).optional(),
8375
8407
  // `headroom_configure` — savings ingest URL delivered from the session
8376
8408
  // when enabling Headroom on-demand. Bounded to 2048 chars.
8377
8409
  savingsIngestUrl: import_zod.z.string().url().max(2048).optional(),
8410
+ // `coderabbit_configure` (action='link_apikey') — the CodeRabbit API key.
8411
+ apiKey: import_zod.z.string().min(1).max(512).optional(),
8412
+ // `coderabbit_configure` (action='review') — review scope, mirroring the
8413
+ // CLI's `--type` / `--base` / `--dir`.
8414
+ changeSet: import_zod.z.enum(["all", "committed", "uncommitted"]).optional(),
8415
+ base: import_zod.z.string().max(255).optional(),
8416
+ reviewDir: import_zod.z.string().max(1024).optional(),
8378
8417
  // `request_link_credentials` — backend fires this from the
8379
8418
  // heartbeat handler when it notices the user is running an agent
8380
8419
  // they haven't vaulted yet. Also reused by `get_context` /
@@ -11738,10 +11777,10 @@ function buildForPlatform(platform3) {
11738
11777
  var import_node_crypto4 = require("crypto");
11739
11778
 
11740
11779
  // src/agents/claude/resolver.ts
11741
- function buildClaudeLaunch(extraArgs = [], os49 = createOsStrategy()) {
11742
- const found = os49.findInPath("claude") ?? os49.findInPath("claude-code");
11780
+ function buildClaudeLaunch(extraArgs = [], os50 = createOsStrategy()) {
11781
+ const found = os50.findInPath("claude") ?? os50.findInPath("claude-code");
11743
11782
  if (!found) return null;
11744
- return os49.buildLaunch(found, extraArgs);
11783
+ return os50.buildLaunch(found, extraArgs);
11745
11784
  }
11746
11785
 
11747
11786
  // src/agents/claude/installer.ts
@@ -12331,8 +12370,8 @@ var ClaudeRuntimeStrategy = class {
12331
12370
  meta = getAgent("claude");
12332
12371
  mode = "interactive";
12333
12372
  os;
12334
- constructor(os49) {
12335
- this.os = os49;
12373
+ constructor(os50) {
12374
+ this.os = os50;
12336
12375
  }
12337
12376
  /**
12338
12377
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -13112,8 +13151,8 @@ function codexCredentialLocator() {
13112
13151
  function codexLoginLauncher() {
13113
13152
  return {
13114
13153
  async ensureInstalled() {
13115
- const os49 = createOsStrategy();
13116
- return os49.findInPath("codex") !== null;
13154
+ const os50 = createOsStrategy();
13155
+ return os50.findInPath("codex") !== null;
13117
13156
  },
13118
13157
  launch() {
13119
13158
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -13136,8 +13175,8 @@ var CodexRuntimeStrategy = class {
13136
13175
  meta = getAgent("codex");
13137
13176
  mode = "interactive";
13138
13177
  os;
13139
- constructor(os49) {
13140
- this.os = os49;
13178
+ constructor(os50) {
13179
+ this.os = os50;
13141
13180
  }
13142
13181
  async prepareLaunch() {
13143
13182
  let binary = this.os.findInPath("codex");
@@ -13246,12 +13285,12 @@ var CodexRuntimeStrategy = class {
13246
13285
  });
13247
13286
  }
13248
13287
  };
13249
- function resolveNpm(os49) {
13250
- return os49.id === "win32" ? "npm.cmd" : "npm";
13288
+ function resolveNpm(os50) {
13289
+ return os50.id === "win32" ? "npm.cmd" : "npm";
13251
13290
  }
13252
- async function installCodexViaNpm(os49) {
13291
+ async function installCodexViaNpm(os50) {
13253
13292
  return new Promise((resolve7, reject) => {
13254
- const proc = (0, import_node_child_process5.spawn)(resolveNpm(os49), ["install", "-g", "@openai/codex"], {
13293
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os50), ["install", "-g", "@openai/codex"], {
13255
13294
  stdio: "inherit"
13256
13295
  });
13257
13296
  proc.on("close", (code) => {
@@ -13268,16 +13307,16 @@ async function installCodexViaNpm(os49) {
13268
13307
  });
13269
13308
  });
13270
13309
  }
13271
- function augmentNpmGlobalBin(os49) {
13310
+ function augmentNpmGlobalBin(os50) {
13272
13311
  try {
13273
- const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os49), ["prefix", "-g"], {
13312
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os50), ["prefix", "-g"], {
13274
13313
  stdio: ["ignore", "pipe", "ignore"]
13275
13314
  });
13276
13315
  if (result.status !== 0) return;
13277
13316
  const prefix = result.stdout.toString().trim();
13278
13317
  if (!prefix) return;
13279
- const binDir = os49.id === "win32" ? prefix : path24.join(prefix, "bin");
13280
- os49.augmentPath([binDir]);
13318
+ const binDir = os50.id === "win32" ? prefix : path24.join(prefix, "bin");
13319
+ os50.augmentPath([binDir]);
13281
13320
  } catch {
13282
13321
  }
13283
13322
  }
@@ -13361,9 +13400,9 @@ var import_node_child_process8 = require("child_process");
13361
13400
  // src/agents/coderabbit/installer.ts
13362
13401
  var import_node_child_process6 = require("child_process");
13363
13402
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
13364
- async function ensureCoderabbitInstalled(os49) {
13365
- if (os49.findInPath("coderabbit")) return true;
13366
- if (os49.id === "win32") {
13403
+ async function ensureCoderabbitInstalled(os50) {
13404
+ if (os50.findInPath("coderabbit")) return true;
13405
+ if (os50.id === "win32") {
13367
13406
  console.error(
13368
13407
  "\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"
13369
13408
  );
@@ -13378,8 +13417,8 @@ async function ensureCoderabbitInstalled(os49) {
13378
13417
  proc.on("error", () => resolve7(false));
13379
13418
  });
13380
13419
  if (!ok) return false;
13381
- os49.augmentPath([`${os49.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13382
- return os49.findInPath("coderabbit") !== null;
13420
+ os50.augmentPath([`${os50.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13421
+ return os50.findInPath("coderabbit") !== null;
13383
13422
  }
13384
13423
 
13385
13424
  // src/agents/coderabbit/link.ts
@@ -13414,10 +13453,10 @@ function coderabbitCredentialLocator() {
13414
13453
  validate: validateNonEmptyCredential
13415
13454
  };
13416
13455
  }
13417
- function coderabbitLoginLauncher(os49) {
13456
+ function coderabbitLoginLauncher(os50) {
13418
13457
  return {
13419
13458
  async ensureInstalled() {
13420
- return ensureCoderabbitInstalled(os49);
13459
+ return ensureCoderabbitInstalled(os50);
13421
13460
  },
13422
13461
  launch() {
13423
13462
  return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
@@ -13473,14 +13512,14 @@ function pickLine(obj) {
13473
13512
  function toHunk(raw, groupSeverity) {
13474
13513
  if (!raw || typeof raw !== "object") return null;
13475
13514
  const o = raw;
13476
- const path70 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename"])) ?? asString(pick(o, ["location"])?.path);
13477
- if (!path70) return null;
13515
+ const path71 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename"])) ?? asString(pick(o, ["location"])?.path);
13516
+ if (!path71) return null;
13478
13517
  const message = asString(pick(o, ["comment", "message", "body", "description", "summary", "markdown", "text"])) ?? "";
13479
13518
  const title = asString(pick(o, ["title", "rule", "category", "check"]));
13480
13519
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
13481
13520
  const locObj = pick(o, ["location"]) ?? o;
13482
13521
  return {
13483
- path: path70.trim(),
13522
+ path: path71.trim(),
13484
13523
  line: pickLine(o) ?? pickLine(locObj),
13485
13524
  severity,
13486
13525
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -13558,10 +13597,10 @@ function parsePlain(stdout) {
13558
13597
  for (const line of stdout.split(/\r?\n/)) {
13559
13598
  const m = line.match(HUNK_LINE_RE);
13560
13599
  if (!m) continue;
13561
- const [, path70, lineNo, sevToken, message] = m;
13562
- if (!path70 || !lineNo || !message) continue;
13600
+ const [, path71, lineNo, sevToken, message] = m;
13601
+ if (!path71 || !lineNo || !message) continue;
13563
13602
  hunks.push({
13564
- path: path70.trim(),
13603
+ path: path71.trim(),
13565
13604
  line: Number(lineNo),
13566
13605
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
13567
13606
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -13598,8 +13637,8 @@ var CoderabbitRuntimeStrategy = class {
13598
13637
  meta = getAgent("coderabbit");
13599
13638
  mode = "batch";
13600
13639
  os;
13601
- constructor(os49) {
13602
- this.os = os49;
13640
+ constructor(os50) {
13641
+ this.os = os50;
13603
13642
  }
13604
13643
  getDefaultArgs() {
13605
13644
  return ["review", "--agent"];
@@ -13834,10 +13873,10 @@ function cursorCredentialLocator() {
13834
13873
  validate: validateNonEmptyCredential
13835
13874
  };
13836
13875
  }
13837
- function cursorLoginLauncher(os49) {
13876
+ function cursorLoginLauncher(os50) {
13838
13877
  return {
13839
13878
  async ensureInstalled() {
13840
- if (os49.findInPath("cursor-agent")) return true;
13879
+ if (os50.findInPath("cursor-agent")) return true;
13841
13880
  console.error(
13842
13881
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
13843
13882
  );
@@ -13901,15 +13940,14 @@ var CursorRuntimeStrategy = class {
13901
13940
  meta = getAgent("cursor");
13902
13941
  mode = "interactive";
13903
13942
  os;
13904
- constructor(os49) {
13905
- this.os = os49;
13943
+ constructor(os50) {
13944
+ this.os = os50;
13906
13945
  }
13907
13946
  async prepareLaunch() {
13908
13947
  const binary = this.os.findInPath("cursor-agent");
13909
13948
  if (!binary) {
13910
- throw new Error(
13911
- 'Cursor Agent CLI ("cursor-agent") is not on PATH.\n Install Cursor (https://cursor.com/), enable its CLI plugin,\n then run `codeam pair` again.'
13912
- );
13949
+ const install = this.os.id === "win32" ? "Cursor Agent CLI (\"cursor-agent\") is not on PATH.\n Install it with: irm 'https://cursor.com/install?win32=true' | iex\n then run `codeam pair` again." : 'Cursor Agent CLI ("cursor-agent") is not on PATH.\n Install Cursor (https://cursor.com/), enable its CLI plugin,\n then run `codeam pair` again.';
13950
+ throw new Error(install);
13913
13951
  }
13914
13952
  const sessionId = this.mintChatId(binary);
13915
13953
  if (sessionId) {
@@ -14119,10 +14157,10 @@ function aiderCredentialLocator() {
14119
14157
  validate: validateNonEmptyCredential
14120
14158
  };
14121
14159
  }
14122
- function aiderLoginLauncher(os49) {
14160
+ function aiderLoginLauncher(os50) {
14123
14161
  return {
14124
14162
  async ensureInstalled() {
14125
- if (os49.findInPath("aider")) return true;
14163
+ if (os50.findInPath("aider")) return true;
14126
14164
  console.error(
14127
14165
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
14128
14166
  );
@@ -14132,7 +14170,7 @@ function aiderLoginLauncher(os49) {
14132
14170
  console.error(
14133
14171
  "\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"
14134
14172
  );
14135
- return (0, import_node_child_process11.spawn)(os49.id === "win32" ? "cmd.exe" : "sh", os49.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
14173
+ return (0, import_node_child_process11.spawn)(os50.id === "win32" ? "cmd.exe" : "sh", os50.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
14136
14174
  stdio: "ignore"
14137
14175
  });
14138
14176
  }
@@ -14204,8 +14242,8 @@ var AiderRuntimeStrategy = class {
14204
14242
  meta = getAgent("aider");
14205
14243
  mode = "interactive";
14206
14244
  os;
14207
- constructor(os49) {
14208
- this.os = os49;
14245
+ constructor(os50) {
14246
+ this.os = os50;
14209
14247
  }
14210
14248
  async prepareLaunch() {
14211
14249
  const binary = this.os.findInPath("aider");
@@ -14337,8 +14375,8 @@ function geminiCredentialLocator() {
14337
14375
  function geminiLoginLauncher() {
14338
14376
  return {
14339
14377
  async ensureInstalled() {
14340
- const os49 = createOsStrategy();
14341
- return os49.findInPath("gemini") !== null;
14378
+ const os50 = createOsStrategy();
14379
+ return os50.findInPath("gemini") !== null;
14342
14380
  },
14343
14381
  launch() {
14344
14382
  return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -14528,8 +14566,8 @@ var GeminiRuntimeStrategy = class {
14528
14566
  meta = getAgent("gemini");
14529
14567
  mode = "interactive";
14530
14568
  os;
14531
- constructor(os49) {
14532
- this.os = os49;
14569
+ constructor(os50) {
14570
+ this.os = os50;
14533
14571
  }
14534
14572
  async prepareLaunch() {
14535
14573
  const binary = this.os.findInPath("gemini");
@@ -14820,15 +14858,14 @@ var KimiRuntimeStrategy = class {
14820
14858
  meta = getAgent("kimi");
14821
14859
  mode = "interactive";
14822
14860
  os;
14823
- constructor(os49) {
14824
- this.os = os49;
14861
+ constructor(os50) {
14862
+ this.os = os50;
14825
14863
  }
14826
14864
  async prepareLaunch() {
14827
14865
  const binary = this.os.findInPath("kimi");
14828
14866
  if (!binary) {
14829
- throw new Error(
14830
- "Kimi Code CLI is not on PATH. Install it with:\n curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash\n Then run `codeam pair` again."
14831
- );
14867
+ const install = this.os.id === "win32" ? "Kimi Code CLI on Windows requires WSL. Install it inside WSL with:\n curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash\n then re-run `codeam pair` from WSL." : "Kimi Code CLI is not on PATH. Install it with:\n curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash\n Then run `codeam pair` again.";
14868
+ throw new Error(install);
14832
14869
  }
14833
14870
  const launch = this.os.buildLaunch(binary, []);
14834
14871
  return { cmd: launch.cmd, args: launch.args };
@@ -14935,19 +14972,19 @@ var KimiRuntimeStrategy = class {
14935
14972
 
14936
14973
  // src/agents/registry.ts
14937
14974
  var runtimeBuilders = {
14938
- claude: (os49) => new ClaudeRuntimeStrategy(os49),
14939
- codex: (os49) => new CodexRuntimeStrategy(os49),
14940
- coderabbit: (os49) => new CoderabbitRuntimeStrategy(os49),
14941
- cursor: (os49) => new CursorRuntimeStrategy(os49),
14942
- aider: (os49) => new AiderRuntimeStrategy(os49),
14943
- gemini: (os49) => new GeminiRuntimeStrategy(os49),
14944
- kimi: (os49) => new KimiRuntimeStrategy(os49)
14975
+ claude: (os50) => new ClaudeRuntimeStrategy(os50),
14976
+ codex: (os50) => new CodexRuntimeStrategy(os50),
14977
+ coderabbit: (os50) => new CoderabbitRuntimeStrategy(os50),
14978
+ cursor: (os50) => new CursorRuntimeStrategy(os50),
14979
+ aider: (os50) => new AiderRuntimeStrategy(os50),
14980
+ gemini: (os50) => new GeminiRuntimeStrategy(os50),
14981
+ kimi: (os50) => new KimiRuntimeStrategy(os50)
14945
14982
  };
14946
14983
  var deployBuilders = {
14947
14984
  claude: () => new ClaudeDeployStrategy(),
14948
14985
  codex: () => new CodexDeployStrategy()
14949
14986
  };
14950
- function createAgentStrategy(agent, os49 = createOsStrategy()) {
14987
+ function createAgentStrategy(agent, os50 = createOsStrategy()) {
14951
14988
  if (!AGENT_REGISTRY[agent]?.enabled) {
14952
14989
  throw new Error(
14953
14990
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -14957,10 +14994,10 @@ function createAgentStrategy(agent, os49 = createOsStrategy()) {
14957
14994
  if (!build) {
14958
14995
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
14959
14996
  }
14960
- return build(os49);
14997
+ return build(os50);
14961
14998
  }
14962
- function createInteractiveAgentStrategy(agent, os49 = createOsStrategy()) {
14963
- const s = createAgentStrategy(agent, os49);
14999
+ function createInteractiveAgentStrategy(agent, os50 = createOsStrategy()) {
15000
+ const s = createAgentStrategy(agent, os50);
14964
15001
  if (s.mode !== "interactive") {
14965
15002
  throw new Error(
14966
15003
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -15359,21 +15396,261 @@ async function linkDryRunPreflight(ctx) {
15359
15396
  process.exit(1);
15360
15397
  }
15361
15398
 
15399
+ // src/agents/coderabbit/configure.ts
15400
+ var import_node_child_process14 = require("child_process");
15401
+
15402
+ // src/agents/coderabbit/oauth.ts
15403
+ var fs31 = __toESM(require("fs"));
15404
+ var os27 = __toESM(require("os"));
15405
+ var path35 = __toESM(require("path"));
15406
+ function parseCoderabbitAuthEvent(line) {
15407
+ const l = line.trim();
15408
+ if (!l || l[0] !== "{") return null;
15409
+ let rec;
15410
+ try {
15411
+ rec = JSON.parse(l);
15412
+ } catch {
15413
+ return null;
15414
+ }
15415
+ if (rec.type === "error" || rec.status === "authentication_failed" || rec.status === "automatic_login_failed") {
15416
+ return { kind: "failed", message: rec.message ?? "CodeRabbit authentication failed" };
15417
+ }
15418
+ switch (rec.status) {
15419
+ case "starting_login":
15420
+ return { kind: "starting" };
15421
+ case "awaiting_browser_auth":
15422
+ return rec.authUrl ? { kind: "awaiting_browser", authUrl: rec.authUrl, fallbackAuthUrl: rec.fallbackAuthUrl } : { kind: "other", status: rec.status };
15423
+ case "processing_callback":
15424
+ return { kind: "processing_callback" };
15425
+ case "fetching_user":
15426
+ return { kind: "fetching_user" };
15427
+ case "authenticated":
15428
+ return {
15429
+ kind: "authenticated",
15430
+ user: rec.user ? { name: rec.user.name, email: rec.user.email, username: rec.user.username ?? rec.user.user_name } : void 0,
15431
+ authType: rec.authType,
15432
+ provider: rec.provider,
15433
+ org: rec.currentOrg?.name
15434
+ };
15435
+ case "not_authenticated":
15436
+ return { kind: "unauthenticated" };
15437
+ default:
15438
+ return rec.status ? { kind: "other", status: rec.status } : null;
15439
+ }
15440
+ }
15441
+ function runCoderabbitOAuthLogin(deps) {
15442
+ const timeoutMs = deps.timeoutMs ?? 18e4;
15443
+ return new Promise((resolve7) => {
15444
+ let settled = false;
15445
+ let stdout = "";
15446
+ let last = null;
15447
+ const finish = (r) => {
15448
+ if (settled) return;
15449
+ settled = true;
15450
+ clearTimeout(timer);
15451
+ try {
15452
+ child.kill("SIGKILL");
15453
+ } catch {
15454
+ }
15455
+ resolve7(r);
15456
+ };
15457
+ let child;
15458
+ try {
15459
+ child = deps.spawn("coderabbit", ["auth", "login", "--agent"]);
15460
+ } catch (err) {
15461
+ resolve7({ ok: false, error: err instanceof Error ? err.message : "spawn failed" });
15462
+ return;
15463
+ }
15464
+ const timer = setTimeout(
15465
+ () => finish({ ok: false, error: "CodeRabbit login timed out" }),
15466
+ timeoutMs
15467
+ );
15468
+ const onLine = (line) => {
15469
+ const e = parseCoderabbitAuthEvent(line);
15470
+ if (!e) return;
15471
+ deps.onEvent?.(e);
15472
+ if (e.kind === "authenticated") {
15473
+ last = e;
15474
+ finish({ ok: true, user: e.user, authType: e.authType, provider: e.provider, org: e.org });
15475
+ } else if (e.kind === "failed") {
15476
+ finish({ ok: false, error: e.message });
15477
+ }
15478
+ };
15479
+ child.stdout?.on("data", (b) => {
15480
+ stdout += b.toString();
15481
+ let nl;
15482
+ while ((nl = stdout.indexOf("\n")) >= 0) {
15483
+ onLine(stdout.slice(0, nl));
15484
+ stdout = stdout.slice(nl + 1);
15485
+ }
15486
+ });
15487
+ child.on("error", (err) => finish({ ok: false, error: err.message }));
15488
+ child.on("exit", () => {
15489
+ if (stdout.trim()) onLine(stdout);
15490
+ finish(
15491
+ last ? { ok: true, user: last.user, authType: last.authType, provider: last.provider, org: last.org } : { ok: false, error: "CodeRabbit login exited before authenticating" }
15492
+ );
15493
+ });
15494
+ });
15495
+ }
15496
+ function coderabbitDir(home) {
15497
+ return path35.join(home ?? os27.homedir(), ".coderabbit");
15498
+ }
15499
+ var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
15500
+ function snapshotCredentialDir(home) {
15501
+ const dir = coderabbitDir(home);
15502
+ const snap = {};
15503
+ let entries;
15504
+ try {
15505
+ entries = fs31.readdirSync(dir, { withFileTypes: true });
15506
+ } catch {
15507
+ return snap;
15508
+ }
15509
+ for (const e of entries) {
15510
+ if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
15511
+ try {
15512
+ const st3 = fs31.statSync(path35.join(dir, e.name));
15513
+ snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
15514
+ } catch {
15515
+ }
15516
+ }
15517
+ return snap;
15518
+ }
15519
+ function diffCapturedCredential(before, home) {
15520
+ const dir = coderabbitDir(home);
15521
+ const after = snapshotCredentialDir(home);
15522
+ let best = null;
15523
+ for (const [file, fp] of Object.entries(after)) {
15524
+ if (before[file] === fp) continue;
15525
+ const mtime = Number(fp.split(":")[0]);
15526
+ if (!best || mtime > best.mtime) best = { file, mtime };
15527
+ }
15528
+ if (!best) return null;
15529
+ try {
15530
+ return { file: best.file, contents: fs31.readFileSync(path35.join(dir, best.file), "utf8") };
15531
+ } catch {
15532
+ return null;
15533
+ }
15534
+ }
15535
+
15536
+ // src/agents/coderabbit/configure.ts
15537
+ function defaultIsLoggedIn() {
15538
+ const r = (0, import_node_child_process14.spawnSync)("coderabbit", ["auth", "status", "--agent"], {
15539
+ encoding: "utf8",
15540
+ timeout: 15e3
15541
+ });
15542
+ if (r.error || typeof r.stdout !== "string") return false;
15543
+ for (const line of r.stdout.split("\n")) {
15544
+ const l = line.trim();
15545
+ if (!l.startsWith("{")) continue;
15546
+ try {
15547
+ const rec = JSON.parse(l);
15548
+ if (rec.authenticated === true || rec.status === "authenticated") return true;
15549
+ if (rec.authenticated === false || rec.status === "not_authenticated") return false;
15550
+ } catch {
15551
+ }
15552
+ }
15553
+ return false;
15554
+ }
15555
+ async function configureCoderabbit(input, deps = {}) {
15556
+ const os50 = deps.os ?? createOsStrategy();
15557
+ const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
15558
+ const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
15559
+ const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
15560
+ const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
15561
+ const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
15562
+ const installed = os50.findInPath("coderabbit") !== null;
15563
+ const base = () => ({
15564
+ action: input.action,
15565
+ supported: true,
15566
+ installed: os50.findInPath("coderabbit") !== null,
15567
+ loggedIn: false
15568
+ });
15569
+ if (input.action === "status") {
15570
+ const res2 = base();
15571
+ res2.loggedIn = res2.installed ? isLoggedIn() : false;
15572
+ res2.linked = res2.loggedIn;
15573
+ return res2;
15574
+ }
15575
+ if (input.action === "link_apikey") {
15576
+ const res2 = base();
15577
+ const key = (input.apiKey ?? "").trim();
15578
+ if (!key) return { ...res2, error: "No API key provided" };
15579
+ const stored = deps.uploadCredential ? await deps.uploadCredential("api_key", key) : false;
15580
+ return { ...res2, linked: stored, error: stored ? void 0 : "Failed to store API key" };
15581
+ }
15582
+ if (input.action === "link_oauth") {
15583
+ const res2 = base();
15584
+ if (!installed) {
15585
+ const ok = await ensureInstalled(os50);
15586
+ res2.installed = ok;
15587
+ if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
15588
+ }
15589
+ const before = snapshot();
15590
+ const login = await runOAuth({
15591
+ spawn: (cmd, args2) => (0, import_node_child_process14.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"] }),
15592
+ onEvent: deps.onEvent
15593
+ });
15594
+ if (!login.ok) {
15595
+ return { ...res2, loggedIn: false, linked: false, error: login.error ?? "CodeRabbit login failed" };
15596
+ }
15597
+ const cred = capture2(before);
15598
+ if (!cred) {
15599
+ return {
15600
+ ...res2,
15601
+ installed: true,
15602
+ loggedIn: true,
15603
+ linked: false,
15604
+ user: login.user,
15605
+ provider: login.provider,
15606
+ org: login.org,
15607
+ error: "Signed in, but the credential could not be captured for reuse"
15608
+ };
15609
+ }
15610
+ const blob = JSON.stringify({ file: cred.file, contents: cred.contents });
15611
+ const stored = deps.uploadCredential ? await deps.uploadCredential("oauth", blob) : false;
15612
+ return {
15613
+ ...res2,
15614
+ installed: true,
15615
+ loggedIn: true,
15616
+ linked: stored,
15617
+ user: login.user,
15618
+ provider: login.provider,
15619
+ org: login.org,
15620
+ ...stored ? {} : { error: "Signed in, but storing the credential failed" }
15621
+ };
15622
+ }
15623
+ const res = base();
15624
+ if (!res.installed) {
15625
+ const ok = await ensureInstalled(os50);
15626
+ res.installed = ok;
15627
+ if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
15628
+ }
15629
+ if (!deps.runReview) return { ...res, error: "No reviewer available" };
15630
+ const out2 = await deps.runReview(input.review ?? {});
15631
+ return {
15632
+ ...res,
15633
+ loggedIn: true,
15634
+ review: { markdown: out2.markdown, hunks: out2.hunks, stats: out2.stats },
15635
+ ...out2.stats && typeof out2.stats.error === "string" ? { error: String(out2.stats.error) } : {}
15636
+ };
15637
+ }
15638
+
15362
15639
  // src/commands/host-agent.ts
15363
- var import_node_child_process21 = require("child_process");
15364
- var os34 = __toESM(require("os"));
15365
- var fs40 = __toESM(require("fs"));
15366
- var path42 = __toESM(require("path"));
15640
+ var import_node_child_process23 = require("child_process");
15641
+ var os35 = __toESM(require("os"));
15642
+ var fs41 = __toESM(require("fs"));
15643
+ var path43 = __toESM(require("path"));
15367
15644
 
15368
15645
  // src/commands/host/host-client.ts
15369
- var fs32 = __toESM(require("fs"));
15370
- var os28 = __toESM(require("os"));
15371
- var path35 = __toESM(require("path"));
15646
+ var fs33 = __toESM(require("fs"));
15647
+ var os29 = __toESM(require("os"));
15648
+ var path36 = __toESM(require("path"));
15372
15649
 
15373
15650
  // src/lib/restrict-to-owner.ts
15374
15651
  var import_node_fs5 = __toESM(require("fs"));
15375
15652
  var import_node_os4 = __toESM(require("os"));
15376
- var import_node_child_process14 = require("child_process");
15653
+ var import_node_child_process15 = require("child_process");
15377
15654
  var BROAD_WINDOWS_SIDS = [
15378
15655
  "*S-1-1-0",
15379
15656
  "*S-1-5-11",
@@ -15385,7 +15662,7 @@ function restrictToOwner(filePath) {
15385
15662
  try {
15386
15663
  if (process.platform === "win32") {
15387
15664
  const username = import_node_os4.default.userInfo().username;
15388
- (0, import_node_child_process14.execFileSync)(
15665
+ (0, import_node_child_process15.execFileSync)(
15389
15666
  "icacls",
15390
15667
  [
15391
15668
  filePath,
@@ -15407,7 +15684,7 @@ function restrictToOwner(filePath) {
15407
15684
  function sampleCpuTimes() {
15408
15685
  let idle = 0;
15409
15686
  let total = 0;
15410
- for (const cpu of os28.cpus()) {
15687
+ for (const cpu of os29.cpus()) {
15411
15688
  const t2 = cpu.times;
15412
15689
  idle += t2.idle;
15413
15690
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -15426,8 +15703,8 @@ var MetricsCollector = class {
15426
15703
  const prev = this.prevCpu;
15427
15704
  this.prevCpu = current;
15428
15705
  if (!prev) {
15429
- const cores = os28.cpus().length || 1;
15430
- const proxy = os28.loadavg()[0] / cores * 100;
15706
+ const cores = os29.cpus().length || 1;
15707
+ const proxy = os29.loadavg()[0] / cores * 100;
15431
15708
  return Math.min(100, Math.max(0, Math.round(proxy)));
15432
15709
  }
15433
15710
  const idleDelta = current.idle - prev.idle;
@@ -15440,8 +15717,8 @@ var MetricsCollector = class {
15440
15717
  collect() {
15441
15718
  return {
15442
15719
  cpuPct: this.cpuPct(),
15443
- ramUsedMb: Math.round((os28.totalmem() - os28.freemem()) / 1048576),
15444
- ramTotalMb: Math.round(os28.totalmem() / 1048576),
15720
+ ramUsedMb: Math.round((os29.totalmem() - os29.freemem()) / 1048576),
15721
+ ramTotalMb: Math.round(os29.totalmem() / 1048576),
15445
15722
  latencyMs: this.lastLatencyMs
15446
15723
  };
15447
15724
  }
@@ -15450,19 +15727,19 @@ function apiBase() {
15450
15727
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
15451
15728
  }
15452
15729
  function hostIdentityPath() {
15453
- return path35.join(os28.homedir(), ".codeam", "host-agent.json");
15730
+ return path36.join(os29.homedir(), ".codeam", "host-agent.json");
15454
15731
  }
15455
15732
  function collectOsInfo() {
15456
15733
  return {
15457
- distro: os28.platform(),
15458
- arch: os28.arch(),
15459
- kernel: os28.release(),
15734
+ distro: os29.platform(),
15735
+ arch: os29.arch(),
15736
+ kernel: os29.release(),
15460
15737
  nodeVersion: process.versions.node
15461
15738
  };
15462
15739
  }
15463
15740
  function loadHostIdentity() {
15464
15741
  try {
15465
- const raw = fs32.readFileSync(hostIdentityPath(), "utf8");
15742
+ const raw = fs33.readFileSync(hostIdentityPath(), "utf8");
15466
15743
  const parsed = JSON.parse(raw);
15467
15744
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
15468
15745
  const p2 = parsed;
@@ -15475,8 +15752,8 @@ function loadHostIdentity() {
15475
15752
  }
15476
15753
  function saveHostIdentity(identity) {
15477
15754
  const file = hostIdentityPath();
15478
- fs32.mkdirSync(path35.dirname(file), { recursive: true, mode: 448 });
15479
- fs32.writeFileSync(file, JSON.stringify(identity, null, 2), {
15755
+ fs33.mkdirSync(path36.dirname(file), { recursive: true, mode: 448 });
15756
+ fs33.writeFileSync(file, JSON.stringify(identity, null, 2), {
15480
15757
  encoding: "utf8",
15481
15758
  mode: 384
15482
15759
  });
@@ -15521,7 +15798,7 @@ function isTerminalEnrollError(err) {
15521
15798
  }
15522
15799
  function deleteHostIdentity() {
15523
15800
  try {
15524
- fs32.rmSync(hostIdentityPath(), { force: true });
15801
+ fs33.rmSync(hostIdentityPath(), { force: true });
15525
15802
  } catch {
15526
15803
  }
15527
15804
  }
@@ -15644,17 +15921,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
15644
15921
  }
15645
15922
 
15646
15923
  // src/commands/host/workspace.ts
15647
- var fs33 = __toESM(require("fs"));
15648
- var os29 = __toESM(require("os"));
15649
- var path36 = __toESM(require("path"));
15650
- var import_node_child_process15 = require("child_process");
15924
+ var fs34 = __toESM(require("fs"));
15925
+ var os30 = __toESM(require("os"));
15926
+ var path37 = __toESM(require("path"));
15927
+ var import_node_child_process16 = require("child_process");
15651
15928
  var import_node_util4 = require("util");
15652
- var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process15.execFile);
15929
+ var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process16.execFile);
15653
15930
  function isAbsolutePathTarget(target) {
15654
- return path36.isAbsolute(target);
15931
+ return path37.isAbsolute(target);
15655
15932
  }
15656
15933
  function selfHostedWorkspaceRoot() {
15657
- return path36.join(os29.homedir(), ".codeam", "self-hosted");
15934
+ return path37.join(os30.homedir(), ".codeam", "self-hosted");
15658
15935
  }
15659
15936
  function nonInteractiveGitEnv() {
15660
15937
  return {
@@ -15707,13 +15984,13 @@ async function fetchGithubIdentity(token) {
15707
15984
  async function configureGitCredentials(dest, repoRef, cloneToken) {
15708
15985
  const gh = githubOwnerRepo(repoRef.trim());
15709
15986
  if (!gh || !cloneToken) return;
15710
- const credFile = path36.join(dest, ".git", "codeam-credentials");
15711
- fs33.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
15987
+ const credFile = path37.join(dest, ".git", "codeam-credentials");
15988
+ fs34.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
15712
15989
  `, { mode: 384 });
15713
15990
  restrictToOwner(credFile);
15714
15991
  const env = nonInteractiveGitEnv();
15715
15992
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
15716
- const credFilePosix = credFile.split(path36.sep).join("/");
15993
+ const credFilePosix = credFile.split(path37.sep).join("/");
15717
15994
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
15718
15995
  });
15719
15996
  await git2([
@@ -15749,17 +16026,17 @@ function maskToken(text, cloneToken) {
15749
16026
  }
15750
16027
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
15751
16028
  if (isAbsolutePathTarget(repoOrPath)) {
15752
- if (!fs33.existsSync(repoOrPath)) {
16029
+ if (!fs34.existsSync(repoOrPath)) {
15753
16030
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
15754
16031
  }
15755
16032
  return repoOrPath;
15756
16033
  }
15757
- const dest = path36.join(selfHostedWorkspaceRoot(), deployId);
15758
- if (fs33.existsSync(path36.join(dest, ".git"))) {
16034
+ const dest = path37.join(selfHostedWorkspaceRoot(), deployId);
16035
+ if (fs34.existsSync(path37.join(dest, ".git"))) {
15759
16036
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
15760
16037
  return dest;
15761
16038
  }
15762
- fs33.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
16039
+ fs34.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
15763
16040
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
15764
16041
  try {
15765
16042
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -15776,9 +16053,10 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
15776
16053
  }
15777
16054
 
15778
16055
  // src/commands/host/agent-provisioning.ts
15779
- var fs34 = __toESM(require("fs"));
15780
- var os30 = __toESM(require("os"));
15781
- var path37 = __toESM(require("path"));
16056
+ var fs35 = __toESM(require("fs"));
16057
+ var os31 = __toESM(require("os"));
16058
+ var path38 = __toESM(require("path"));
16059
+ var import_node_child_process17 = require("child_process");
15782
16060
  var PUBLIC_TO_INTERNAL_AGENT = {
15783
16061
  claude_code: "claude",
15784
16062
  claude: "claude",
@@ -15794,22 +16072,22 @@ function toInternalAgentId(publicAgentId) {
15794
16072
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
15795
16073
  }
15796
16074
  function ensureDir(dir) {
15797
- fs34.mkdirSync(dir, { recursive: true, mode: 448 });
16075
+ fs35.mkdirSync(dir, { recursive: true, mode: 448 });
15798
16076
  }
15799
16077
  function writeFile0600(filePath, contents) {
15800
- ensureDir(path37.dirname(filePath));
15801
- fs34.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
16078
+ ensureDir(path38.dirname(filePath));
16079
+ fs35.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
15802
16080
  restrictToOwner(filePath);
15803
16081
  }
15804
16082
  function rmIfExists(filePath) {
15805
16083
  try {
15806
- fs34.rmSync(filePath, { force: true });
16084
+ fs35.rmSync(filePath, { force: true });
15807
16085
  } catch {
15808
16086
  }
15809
16087
  }
15810
16088
  var claudeProvisioner = {
15811
16089
  write(auth, home) {
15812
- const credentialsJson = path37.join(home, ".claude", ".credentials.json");
16090
+ const credentialsJson = path38.join(home, ".claude", ".credentials.json");
15813
16091
  if (auth.kind === "api_key") {
15814
16092
  rmIfExists(credentialsJson);
15815
16093
  return { ANTHROPIC_API_KEY: auth.value };
@@ -15821,8 +16099,8 @@ var claudeProvisioner = {
15821
16099
  } else {
15822
16100
  rmIfExists(credentialsJson);
15823
16101
  }
15824
- const claudeJson = path37.join(home, ".claude.json");
15825
- if (!fs34.existsSync(claudeJson)) {
16102
+ const claudeJson = path38.join(home, ".claude.json");
16103
+ if (!fs35.existsSync(claudeJson)) {
15826
16104
  writeFile0600(
15827
16105
  claudeJson,
15828
16106
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -15833,7 +16111,7 @@ var claudeProvisioner = {
15833
16111
  };
15834
16112
  var codexProvisioner = {
15835
16113
  write(auth, home) {
15836
- const authJson = path37.join(home, ".codex", "auth.json");
16114
+ const authJson = path38.join(home, ".codex", "auth.json");
15837
16115
  if (auth.kind === "api_key") {
15838
16116
  rmIfExists(authJson);
15839
16117
  return { OPENAI_API_KEY: auth.value };
@@ -15844,8 +16122,8 @@ var codexProvisioner = {
15844
16122
  };
15845
16123
  var geminiProvisioner = {
15846
16124
  write(auth, home) {
15847
- const settingsJson = path37.join(home, ".gemini", "settings.json");
15848
- const oauthCreds = path37.join(home, ".gemini", "oauth_creds.json");
16125
+ const settingsJson = path38.join(home, ".gemini", "settings.json");
16126
+ const oauthCreds = path38.join(home, ".gemini", "oauth_creds.json");
15849
16127
  if (auth.kind === "api_key") {
15850
16128
  rmIfExists(oauthCreds);
15851
16129
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -15858,7 +16136,7 @@ var geminiProvisioner = {
15858
16136
  };
15859
16137
  var cursorProvisioner = {
15860
16138
  write(auth, home) {
15861
- const authJson = path37.join(home, ".config", "cursor", "auth.json");
16139
+ const authJson = path38.join(home, ".config", "cursor", "auth.json");
15862
16140
  if (auth.kind === "api_key") {
15863
16141
  rmIfExists(authJson);
15864
16142
  return { CURSOR_API_KEY: auth.value };
@@ -15884,14 +16162,54 @@ var cursorProvisioner = {
15884
16162
  var kimiProvisioner = {
15885
16163
  write(auth, home) {
15886
16164
  const credentialsFiles = [
15887
- path37.join(home, ".kimi", "credentials", "kimi-code.json"),
15888
- path37.join(home, ".kimi-code", "credentials", "kimi-code.json")
16165
+ path38.join(home, ".kimi", "credentials", "kimi-code.json"),
16166
+ path38.join(home, ".kimi-code", "credentials", "kimi-code.json")
15889
16167
  ];
15890
16168
  if (auth.kind === "api_key") {
15891
16169
  credentialsFiles.forEach(rmIfExists);
15892
16170
  return { KIMI_API_KEY: auth.value };
15893
16171
  }
15894
16172
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
16173
+ provisionKimiConfig(home);
16174
+ return {};
16175
+ }
16176
+ };
16177
+ function provisionKimiConfig(home) {
16178
+ try {
16179
+ const osStrat = createOsStrategy();
16180
+ const binary = osStrat.findInPath("kimi");
16181
+ if (!binary) return;
16182
+ const launch = osStrat.buildLaunch(binary, ["login"]);
16183
+ (0, import_node_child_process17.spawnSync)(launch.cmd, launch.args, {
16184
+ stdio: "ignore",
16185
+ timeout: 6e4,
16186
+ env: { ...process.env, HOME: home, USERPROFILE: home }
16187
+ });
16188
+ } catch {
16189
+ }
16190
+ }
16191
+ var coderabbitProvisioner = {
16192
+ write(auth, home) {
16193
+ const dir = path38.join(home, ".coderabbit");
16194
+ const authJson = path38.join(dir, "auth.json");
16195
+ if (auth.kind === "api_key") {
16196
+ rmIfExists(authJson);
16197
+ return { CODERABBIT_API_KEY: auth.value };
16198
+ }
16199
+ const value = auth.value.trim();
16200
+ let file = "auth.json";
16201
+ let contents = value;
16202
+ if (value.startsWith("{")) {
16203
+ try {
16204
+ const parsed = JSON.parse(value);
16205
+ if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
16206
+ file = path38.basename(parsed.file);
16207
+ contents = parsed.contents;
16208
+ }
16209
+ } catch {
16210
+ }
16211
+ }
16212
+ writeFile0600(path38.join(dir, file), contents);
15895
16213
  return {};
15896
16214
  }
15897
16215
  };
@@ -15900,7 +16218,8 @@ var PROVISIONERS = {
15900
16218
  kimi: kimiProvisioner,
15901
16219
  codex: codexProvisioner,
15902
16220
  gemini: geminiProvisioner,
15903
- cursor: cursorProvisioner
16221
+ cursor: cursorProvisioner,
16222
+ coderabbit: coderabbitProvisioner
15904
16223
  };
15905
16224
  var UnsupportedAgentError = class extends Error {
15906
16225
  agentId;
@@ -15910,7 +16229,7 @@ var UnsupportedAgentError = class extends Error {
15910
16229
  this.agentId = agentId;
15911
16230
  }
15912
16231
  };
15913
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir()) {
16232
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os31.homedir()) {
15914
16233
  const internal = toInternalAgentId(publicAgentId);
15915
16234
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
15916
16235
  const provisioner = PROVISIONERS[internal];
@@ -15919,12 +16238,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
15919
16238
  }
15920
16239
 
15921
16240
  // src/commands/host/git-tooling.ts
15922
- var import_node_child_process16 = require("child_process");
15923
- var fs35 = __toESM(require("fs"));
15924
- var os31 = __toESM(require("os"));
15925
- var path38 = __toESM(require("path"));
16241
+ var import_node_child_process18 = require("child_process");
16242
+ var fs36 = __toESM(require("fs"));
16243
+ var os32 = __toESM(require("os"));
16244
+ var path39 = __toESM(require("path"));
15926
16245
  function codeamBinDir() {
15927
- return process.env.CODEAM_BIN_DIR ?? path38.join(os31.homedir(), ".codeam", "bin");
16246
+ return process.env.CODEAM_BIN_DIR ?? path39.join(os32.homedir(), ".codeam", "bin");
15928
16247
  }
15929
16248
  var FALLBACK_GH_VERSION = "2.62.0";
15930
16249
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -15956,7 +16275,7 @@ async function download(url, dest) {
15956
16275
  const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
15957
16276
  if (!res.ok || !res.body) return false;
15958
16277
  const buf = Buffer.from(await res.arrayBuffer());
15959
- fs35.writeFileSync(dest, buf);
16278
+ fs36.writeFileSync(dest, buf);
15960
16279
  return true;
15961
16280
  } catch {
15962
16281
  return false;
@@ -15979,8 +16298,8 @@ async function ensureGhCli(runner, token, deps = {}) {
15979
16298
  const version3 = await resolveVersionFn(token);
15980
16299
  const asset = `gh_${version3}_${osToken}_${arch2}`;
15981
16300
  const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
15982
- const tmpRoot = fs35.mkdtempSync(path38.join(os31.tmpdir(), "codeam-gh-"));
15983
- const archive = path38.join(tmpRoot, `${asset}.${ext}`);
16301
+ const tmpRoot = fs36.mkdtempSync(path39.join(os32.tmpdir(), "codeam-gh-"));
16302
+ const archive = path39.join(tmpRoot, `${asset}.${ext}`);
15984
16303
  if (!await downloadFn(url, archive)) {
15985
16304
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
15986
16305
  return null;
@@ -15990,16 +16309,16 @@ async function ensureGhCli(runner, token, deps = {}) {
15990
16309
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
15991
16310
  return null;
15992
16311
  }
15993
- const extractedBin = path38.join(tmpRoot, asset, "bin", binaryName);
15994
- if (!fs35.existsSync(extractedBin)) {
16312
+ const extractedBin = path39.join(tmpRoot, asset, "bin", binaryName);
16313
+ if (!fs36.existsSync(extractedBin)) {
15995
16314
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
15996
16315
  return null;
15997
16316
  }
15998
16317
  const binDir = codeamBinDir();
15999
- fs35.mkdirSync(binDir, { recursive: true });
16000
- const target = path38.join(binDir, binaryName);
16001
- fs35.copyFileSync(extractedBin, target);
16002
- fs35.chmodSync(target, 493);
16318
+ fs36.mkdirSync(binDir, { recursive: true });
16319
+ const target = path39.join(binDir, binaryName);
16320
+ fs36.copyFileSync(extractedBin, target);
16321
+ fs36.chmodSync(target, 493);
16003
16322
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
16004
16323
  return target;
16005
16324
  } catch (e) {
@@ -16033,7 +16352,7 @@ var defaultGitToolingRunner = {
16033
16352
  which(cmd) {
16034
16353
  try {
16035
16354
  const probe = process.platform === "win32" ? "where" : "which";
16036
- (0, import_node_child_process16.execFileSync)(probe, [cmd], { stdio: "ignore" });
16355
+ (0, import_node_child_process18.execFileSync)(probe, [cmd], { stdio: "ignore" });
16037
16356
  return true;
16038
16357
  } catch {
16039
16358
  return false;
@@ -16041,7 +16360,7 @@ var defaultGitToolingRunner = {
16041
16360
  },
16042
16361
  run(cmd, args2, opts = {}) {
16043
16362
  return new Promise((resolve7) => {
16044
- const child = (0, import_node_child_process16.spawn)(cmd, args2, {
16363
+ const child = (0, import_node_child_process18.spawn)(cmd, args2, {
16045
16364
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
16046
16365
  });
16047
16366
  let stderr = "";
@@ -16195,12 +16514,12 @@ var HeadroomStatsReporter = class {
16195
16514
  };
16196
16515
 
16197
16516
  // src/commands/host/os-packages.ts
16198
- var import_node_child_process17 = require("child_process");
16517
+ var import_node_child_process19 = require("child_process");
16199
16518
  var PM_INSTALL_TIMEOUT_MS = 18e4;
16200
16519
  var defaultHeadroomRunner = {
16201
16520
  which(cmd) {
16202
16521
  try {
16203
- (0, import_node_child_process17.execFileSync)("which", [cmd], { stdio: "ignore" });
16522
+ (0, import_node_child_process19.execFileSync)("which", [cmd], { stdio: "ignore" });
16204
16523
  return true;
16205
16524
  } catch {
16206
16525
  return false;
@@ -16209,7 +16528,7 @@ var defaultHeadroomRunner = {
16209
16528
  run(cmd, args2, opts = {}) {
16210
16529
  return new Promise((resolve7) => {
16211
16530
  const spawnEnv = opts.env ?? process.env;
16212
- const child = (0, import_node_child_process17.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
16531
+ const child = (0, import_node_child_process19.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
16213
16532
  let stderrBuf = "";
16214
16533
  let stdoutBuf = "";
16215
16534
  let settled = false;
@@ -16486,23 +16805,23 @@ async function ensureModernPython(runner) {
16486
16805
  }
16487
16806
 
16488
16807
  // src/commands/host/headroom-bootstrap.ts
16489
- var fs37 = __toESM(require("fs"));
16490
- var path40 = __toESM(require("path"));
16808
+ var fs38 = __toESM(require("fs"));
16809
+ var path41 = __toESM(require("path"));
16491
16810
 
16492
16811
  // src/commands/host/headroom-config.ts
16493
- var fs36 = __toESM(require("fs"));
16494
- var os32 = __toESM(require("os"));
16495
- var path39 = __toESM(require("path"));
16812
+ var fs37 = __toESM(require("fs"));
16813
+ var os33 = __toESM(require("os"));
16814
+ var path40 = __toESM(require("path"));
16496
16815
  function headroomConfigPath() {
16497
- return path39.join(os32.homedir(), ".codeam", "headroom-config.json");
16816
+ return path40.join(os33.homedir(), ".codeam", "headroom-config.json");
16498
16817
  }
16499
16818
  function persistHeadroomConfig(config) {
16500
16819
  try {
16501
16820
  const file = headroomConfigPath();
16502
- fs36.mkdirSync(path39.dirname(file), { recursive: true, mode: 448 });
16821
+ fs37.mkdirSync(path40.dirname(file), { recursive: true, mode: 448 });
16503
16822
  const tmp = `${file}.tmp-${process.pid}`;
16504
- fs36.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
16505
- fs36.renameSync(tmp, file);
16823
+ fs37.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
16824
+ fs37.renameSync(tmp, file);
16506
16825
  restrictToOwner(file);
16507
16826
  } catch (err) {
16508
16827
  log.warn(
@@ -16512,21 +16831,21 @@ function persistHeadroomConfig(config) {
16512
16831
  }
16513
16832
  }
16514
16833
  function agentSettingsPath(kind) {
16515
- const home = os32.homedir();
16516
- if (kind === "claude") return path39.join(home, ".claude", "settings.json");
16517
- if (kind === "codex") return path39.join(home, ".codex", "auth.json");
16518
- if (kind === "copilot") return path39.join(home, ".config", "github-copilot", "hosts.json");
16834
+ const home = os33.homedir();
16835
+ if (kind === "claude") return path40.join(home, ".claude", "settings.json");
16836
+ if (kind === "codex") return path40.join(home, ".codex", "auth.json");
16837
+ if (kind === "copilot") return path40.join(home, ".config", "github-copilot", "hosts.json");
16519
16838
  return null;
16520
16839
  }
16521
16840
  function backupAgentHeadroomConfig(kind) {
16522
16841
  const src = agentSettingsPath(kind);
16523
16842
  if (!src) return;
16524
16843
  try {
16525
- if (!fs36.existsSync(src)) return;
16526
- const dest = path39.join(os32.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16527
- fs36.mkdirSync(path39.dirname(dest), { recursive: true, mode: 448 });
16528
- fs36.copyFileSync(src, dest);
16529
- fs36.chmodSync(dest, 384);
16844
+ if (!fs37.existsSync(src)) return;
16845
+ const dest = path40.join(os33.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16846
+ fs37.mkdirSync(path40.dirname(dest), { recursive: true, mode: 448 });
16847
+ fs37.copyFileSync(src, dest);
16848
+ fs37.chmodSync(dest, 384);
16530
16849
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
16531
16850
  } catch (err) {
16532
16851
  log.warn(
@@ -16538,12 +16857,12 @@ function backupAgentHeadroomConfig(kind) {
16538
16857
  function restoreAgentHeadroomConfig(kind) {
16539
16858
  const dest = agentSettingsPath(kind);
16540
16859
  if (!dest) return false;
16541
- const src = path39.join(os32.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16542
- if (!fs36.existsSync(src)) return false;
16860
+ const src = path40.join(os33.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16861
+ if (!fs37.existsSync(src)) return false;
16543
16862
  try {
16544
- fs36.mkdirSync(path39.dirname(dest), { recursive: true, mode: 448 });
16545
- fs36.copyFileSync(src, dest);
16546
- fs36.chmodSync(dest, 384);
16863
+ fs37.mkdirSync(path40.dirname(dest), { recursive: true, mode: 448 });
16864
+ fs37.copyFileSync(src, dest);
16865
+ fs37.chmodSync(dest, 384);
16547
16866
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
16548
16867
  return true;
16549
16868
  } catch (err) {
@@ -16556,7 +16875,7 @@ function restoreAgentHeadroomConfig(kind) {
16556
16875
  }
16557
16876
  function readHeadroomChildEnv() {
16558
16877
  try {
16559
- const raw = fs36.readFileSync(headroomConfigPath(), "utf8");
16878
+ const raw = fs37.readFileSync(headroomConfigPath(), "utf8");
16560
16879
  const parsed = JSON.parse(raw);
16561
16880
  if (typeof parsed !== "object" || parsed === null) return {};
16562
16881
  const o = parsed;
@@ -16592,37 +16911,37 @@ function bundledClaudeBinDir() {
16592
16911
  const roots = /* @__PURE__ */ new Set();
16593
16912
  let dir = __dirname;
16594
16913
  for (let i = 0; i < 6; i++) {
16595
- roots.add(path40.join(dir, "node_modules"));
16596
- const parent = path40.dirname(dir);
16914
+ roots.add(path41.join(dir, "node_modules"));
16915
+ const parent = path41.dirname(dir);
16597
16916
  if (parent === dir) break;
16598
16917
  dir = parent;
16599
16918
  }
16600
16919
  try {
16601
16920
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
16602
- const marker = `${path40.sep}@anthropic-ai${path40.sep}`;
16921
+ const marker = `${path41.sep}@anthropic-ai${path41.sep}`;
16603
16922
  const idx = main2.lastIndexOf(marker);
16604
16923
  if (idx !== -1) roots.add(main2.slice(0, idx));
16605
16924
  } catch {
16606
16925
  }
16607
16926
  for (const nm of roots) {
16608
- const atAnthropic = path40.join(nm, "@anthropic-ai");
16927
+ const atAnthropic = path41.join(nm, "@anthropic-ai");
16609
16928
  let entries;
16610
16929
  try {
16611
- entries = fs37.readdirSync(atAnthropic);
16930
+ entries = fs38.readdirSync(atAnthropic);
16612
16931
  } catch {
16613
16932
  continue;
16614
16933
  }
16615
16934
  for (const entry of entries) {
16616
16935
  if (!entry.startsWith("claude-agent-sdk-")) continue;
16617
- const bin = path40.join(atAnthropic, entry, "claude");
16618
- if (fs37.existsSync(bin)) return path40.dirname(bin);
16936
+ const bin = path41.join(atAnthropic, entry, "claude");
16937
+ if (fs38.existsSync(bin)) return path41.dirname(bin);
16619
16938
  }
16620
16939
  }
16621
16940
  return null;
16622
16941
  }
16623
16942
  async function getFreeDiskBytes(dir) {
16624
16943
  try {
16625
- const s = await fs37.promises.statfs(dir);
16944
+ const s = await fs38.promises.statfs(dir);
16626
16945
  return s.bsize * s.bavail;
16627
16946
  } catch {
16628
16947
  return null;
@@ -16684,7 +17003,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
16684
17003
  if (initKind === "claude") {
16685
17004
  const claudeDir = bundledClaudeBinDir();
16686
17005
  if (claudeDir) {
16687
- initEnv.PATH = `${claudeDir}${path40.delimiter}${process.env["PATH"] ?? ""}`;
17006
+ initEnv.PATH = `${claudeDir}${path41.delimiter}${process.env["PATH"] ?? ""}`;
16688
17007
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
16689
17008
  } else {
16690
17009
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -16716,26 +17035,26 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
16716
17035
  }
16717
17036
 
16718
17037
  // src/commands/host/self-update.ts
16719
- var import_node_child_process19 = require("child_process");
17038
+ var import_node_child_process21 = require("child_process");
16720
17039
 
16721
17040
  // src/lib/updateNotifier.ts
16722
- var fs38 = __toESM(require("fs"));
16723
- var os33 = __toESM(require("os"));
16724
- var path41 = __toESM(require("path"));
17041
+ var fs39 = __toESM(require("fs"));
17042
+ var os34 = __toESM(require("os"));
17043
+ var path42 = __toESM(require("path"));
16725
17044
  var https6 = __toESM(require("https"));
16726
- var import_node_child_process18 = require("child_process");
17045
+ var import_node_child_process20 = require("child_process");
16727
17046
  var import_picocolors3 = __toESM(require("picocolors"));
16728
17047
  var PKG_NAME = "codeam-cli";
16729
17048
  var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
16730
17049
  var TTL_MS = 24 * 60 * 60 * 1e3;
16731
17050
  var REQUEST_TIMEOUT_MS = 1500;
16732
17051
  function cachePath() {
16733
- const dir = path41.join(os33.homedir(), ".codeam");
16734
- return path41.join(dir, "update-check.json");
17052
+ const dir = path42.join(os34.homedir(), ".codeam");
17053
+ return path42.join(dir, "update-check.json");
16735
17054
  }
16736
17055
  function readCache() {
16737
17056
  try {
16738
- const raw = fs38.readFileSync(cachePath(), "utf8");
17057
+ const raw = fs39.readFileSync(cachePath(), "utf8");
16739
17058
  const parsed = JSON.parse(raw);
16740
17059
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
16741
17060
  return parsed;
@@ -16746,10 +17065,10 @@ function readCache() {
16746
17065
  function writeCache(cache) {
16747
17066
  try {
16748
17067
  const file = cachePath();
16749
- fs38.mkdirSync(path41.dirname(file), { recursive: true });
17068
+ fs39.mkdirSync(path42.dirname(file), { recursive: true });
16750
17069
  const tmp = `${file}.${process.pid}.tmp`;
16751
- fs38.writeFileSync(tmp, JSON.stringify(cache));
16752
- fs38.renameSync(tmp, file);
17070
+ fs39.writeFileSync(tmp, JSON.stringify(cache));
17071
+ fs39.renameSync(tmp, file);
16753
17072
  } catch {
16754
17073
  }
16755
17074
  }
@@ -16817,14 +17136,14 @@ function notifyIfStale(currentVersion, latest) {
16817
17136
  }
16818
17137
  function isLinkedInstall() {
16819
17138
  try {
16820
- const root = (0, import_node_child_process18.execSync)("npm root -g", {
17139
+ const root = (0, import_node_child_process20.execSync)("npm root -g", {
16821
17140
  encoding: "utf8",
16822
17141
  stdio: ["ignore", "pipe", "ignore"],
16823
17142
  timeout: 2e3
16824
17143
  }).trim();
16825
17144
  if (!root) return false;
16826
- const pkgPath = path41.join(root, PKG_NAME);
16827
- return fs38.lstatSync(pkgPath).isSymbolicLink();
17145
+ const pkgPath = path42.join(root, PKG_NAME);
17146
+ return fs39.lstatSync(pkgPath).isSymbolicLink();
16828
17147
  } catch {
16829
17148
  return false;
16830
17149
  }
@@ -16845,7 +17164,7 @@ function maybeAutoUpdate(currentVersion, latest) {
16845
17164
 
16846
17165
  `
16847
17166
  );
16848
- const install = (0, import_node_child_process18.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
17167
+ const install = (0, import_node_child_process20.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
16849
17168
  stdio: "inherit",
16850
17169
  env: process.env
16851
17170
  });
@@ -16860,13 +17179,13 @@ function maybeAutoUpdate(currentVersion, latest) {
16860
17179
  return;
16861
17180
  }
16862
17181
  try {
16863
- fs38.unlinkSync(cachePath());
17182
+ fs39.unlinkSync(cachePath());
16864
17183
  } catch {
16865
17184
  }
16866
17185
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
16867
17186
 
16868
17187
  `);
16869
- const child = (0, import_node_child_process18.spawnSync)("codeam", process.argv.slice(2), {
17188
+ const child = (0, import_node_child_process20.spawnSync)("codeam", process.argv.slice(2), {
16870
17189
  stdio: "inherit",
16871
17190
  env: process.env
16872
17191
  });
@@ -16876,7 +17195,7 @@ async function autoUpgradeBeforeCriticalCommand() {
16876
17195
  if (process.env.NODE_ENV === "test") return;
16877
17196
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16878
17197
  if (process.env.CI) return;
16879
- const current = true ? "2.60.23" : null;
17198
+ const current = true ? "2.60.25" : null;
16880
17199
  if (!current) return;
16881
17200
  const cache = readCache();
16882
17201
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16893,7 +17212,7 @@ function checkForUpdates() {
16893
17212
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16894
17213
  if (process.env.CI) return;
16895
17214
  if (!process.stdout.isTTY) return;
16896
- const current = true ? "2.60.23" : null;
17215
+ const current = true ? "2.60.25" : null;
16897
17216
  if (!current) return;
16898
17217
  const cache = readCache();
16899
17218
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16913,11 +17232,11 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
16913
17232
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
16914
17233
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
16915
17234
  function currentCliVersion() {
16916
- return true ? "2.60.23" : null;
17235
+ return true ? "2.60.25" : null;
16917
17236
  }
16918
17237
  function runCmd(cmd, args2, timeoutMs) {
16919
17238
  return new Promise((resolve7) => {
16920
- (0, import_node_child_process19.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
17239
+ (0, import_node_child_process21.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
16921
17240
  const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
16922
17241
  resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
16923
17242
  });
@@ -16979,19 +17298,19 @@ async function runSelfUpdate() {
16979
17298
  }
16980
17299
 
16981
17300
  // src/commands/host/teardown.ts
16982
- var import_node_child_process20 = require("child_process");
16983
- var fs39 = __toESM(require("fs"));
17301
+ var import_node_child_process22 = require("child_process");
17302
+ var fs40 = __toESM(require("fs"));
16984
17303
  var defaultDisableService = () => {
16985
17304
  try {
16986
- (0, import_node_child_process20.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
17305
+ (0, import_node_child_process22.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
16987
17306
  } catch {
16988
17307
  }
16989
17308
  };
16990
17309
  var defaultTeardownHeadroom = () => {
16991
17310
  try {
16992
- const kind = JSON.parse(fs39.readFileSync(headroomConfigPath(), "utf8")).agent;
17311
+ const kind = JSON.parse(fs40.readFileSync(headroomConfigPath(), "utf8")).agent;
16993
17312
  if (kind) {
16994
- (0, import_node_child_process20.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
17313
+ (0, import_node_child_process22.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
16995
17314
  }
16996
17315
  } catch {
16997
17316
  }
@@ -17057,8 +17376,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
17057
17376
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
17058
17377
  try {
17059
17378
  const file = headroomConfigPath();
17060
- if (!fs40.existsSync(file)) return null;
17061
- const cfg = JSON.parse(fs40.readFileSync(file, "utf8"));
17379
+ if (!fs41.existsSync(file)) return null;
17380
+ const cfg = JSON.parse(fs41.readFileSync(file, "utf8"));
17062
17381
  if (!cfg?.enabled) return null;
17063
17382
  const agent = cfg.agent ?? "claude";
17064
17383
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -17149,7 +17468,7 @@ var CONTROL_AGENT_META = {
17149
17468
  headroomWrappable: false,
17150
17469
  acp: false
17151
17470
  };
17152
- var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process21.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
17471
+ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process23.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
17153
17472
  cwd,
17154
17473
  env: { ...process.env, ...env },
17155
17474
  stdio: ["ignore", "pipe", "pipe"],
@@ -17463,9 +17782,9 @@ var HostAgentSupervisor = class {
17463
17782
  API_TIMEOUT_MS: "3000000",
17464
17783
  CODEAM_AUTO_TOKEN: payload.autoPairToken
17465
17784
  };
17466
- const houseConfigDir = path42.join(os34.homedir(), ".codeam", "house-claude");
17785
+ const houseConfigDir = path43.join(os35.homedir(), ".codeam", "house-claude");
17467
17786
  try {
17468
- fs40.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
17787
+ fs41.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
17469
17788
  } catch {
17470
17789
  }
17471
17790
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -17483,14 +17802,14 @@ var HostAgentSupervisor = class {
17483
17802
  report("installing", "installing agent CLI");
17484
17803
  await this.runAgentInstall(payload.agentInstallScript);
17485
17804
  }
17486
- const home = process.env.HOME || os34.homedir();
17805
+ const home = process.env.HOME || os35.homedir();
17487
17806
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
17488
17807
  if (payload.cloneToken) {
17489
17808
  try {
17490
17809
  report("preparing", "configuring git tooling");
17491
17810
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
17492
17811
  if (ghCmd) {
17493
- childEnv.PATH = `${codeamBinDir()}${path42.delimiter}${childEnv.PATH}`;
17812
+ childEnv.PATH = `${codeamBinDir()}${path43.delimiter}${childEnv.PATH}`;
17494
17813
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
17495
17814
  }
17496
17815
  } catch (e) {
@@ -17506,7 +17825,7 @@ var HostAgentSupervisor = class {
17506
17825
  }
17507
17826
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
17508
17827
  report("headroom", "setting up Headroom proxy");
17509
- const freeBytes = await this.getFreeDisk(os34.homedir());
17828
+ const freeBytes = await this.getFreeDisk(os35.homedir());
17510
17829
  const alreadyInstalled = this.isHeadroomInstalled();
17511
17830
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
17512
17831
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -17628,8 +17947,8 @@ var HostAgentSupervisor = class {
17628
17947
  */
17629
17948
  runAgentInstall(script) {
17630
17949
  return new Promise((resolve7) => {
17631
- const home = process.env.HOME || os34.homedir();
17632
- const child = (0, import_node_child_process21.spawn)("sh", ["-c", script], {
17950
+ const home = process.env.HOME || os35.homedir();
17951
+ const child = (0, import_node_child_process23.spawn)("sh", ["-c", script], {
17633
17952
  env: { ...process.env, HOME: home },
17634
17953
  stdio: ["ignore", "pipe", "pipe"]
17635
17954
  });
@@ -17812,9 +18131,9 @@ async function configureHeadroom(action, ctx, deps) {
17812
18131
  }
17813
18132
 
17814
18133
  // src/services/headroom/budget-relaunch.ts
17815
- var fs41 = __toESM(require("fs"));
17816
- var os35 = __toESM(require("os"));
17817
- var path43 = __toESM(require("path"));
18134
+ var fs42 = __toESM(require("fs"));
18135
+ var os36 = __toESM(require("os"));
18136
+ var path44 = __toESM(require("path"));
17818
18137
  var import_child_process13 = require("child_process");
17819
18138
  function amendDeploymentManifestBudget(manifest, budget) {
17820
18139
  const rawArgs = manifest.proxy_args ?? [];
@@ -17848,7 +18167,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
17848
18167
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
17849
18168
  }
17850
18169
  function findHeadroomDeployments(homeDir2, deps) {
17851
- const deployDir = path43.join(homeDir2, ".headroom", "deploy");
18170
+ const deployDir = path44.join(homeDir2, ".headroom", "deploy");
17852
18171
  let profiles;
17853
18172
  try {
17854
18173
  profiles = deps.readDir(deployDir);
@@ -17857,7 +18176,7 @@ function findHeadroomDeployments(homeDir2, deps) {
17857
18176
  }
17858
18177
  const results = [];
17859
18178
  for (const profile of profiles) {
17860
- const manifestPath = path43.join(deployDir, profile, "manifest.json");
18179
+ const manifestPath = path44.join(deployDir, profile, "manifest.json");
17861
18180
  let raw;
17862
18181
  try {
17863
18182
  raw = deps.readJson(manifestPath);
@@ -17889,8 +18208,8 @@ async function applyBudgetToHeadroom(budget, deps) {
17889
18208
  }
17890
18209
  function writeManifestReal(manifestPath, manifest) {
17891
18210
  const tmp = manifestPath + ".codeam.tmp";
17892
- fs41.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
17893
- fs41.renameSync(tmp, manifestPath);
18211
+ fs42.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
18212
+ fs42.renameSync(tmp, manifestPath);
17894
18213
  }
17895
18214
  function restartDeploymentReal(profile) {
17896
18215
  try {
@@ -17920,11 +18239,11 @@ function spawnProxyReal2(_budget) {
17920
18239
  });
17921
18240
  }
17922
18241
  function makeRealApplyBudgetDeps() {
17923
- const homeDir2 = os35.homedir();
18242
+ const homeDir2 = os36.homedir();
17924
18243
  return {
17925
18244
  findDeployments: () => findHeadroomDeployments(homeDir2, {
17926
- readDir: (dir) => fs41.readdirSync(dir),
17927
- readJson: (filePath) => JSON.parse(fs41.readFileSync(filePath, "utf8"))
18245
+ readDir: (dir) => fs42.readdirSync(dir),
18246
+ readJson: (filePath) => JSON.parse(fs42.readFileSync(filePath, "utf8"))
17928
18247
  }),
17929
18248
  writeManifest: writeManifestReal,
17930
18249
  restartDeployment: restartDeploymentReal,
@@ -17937,11 +18256,11 @@ function makeRealApplyBudgetDeps() {
17937
18256
  var import_child_process14 = require("child_process");
17938
18257
  var import_fs = require("fs");
17939
18258
  var import_promises = __toESM(require("fs/promises"));
17940
- var import_os7 = __toESM(require("os"));
18259
+ var import_os9 = __toESM(require("os"));
17941
18260
  var import_path4 = __toESM(require("path"));
17942
18261
  var import_promises2 = require("stream/promises");
17943
18262
  var import_which = __toESM(require("which"));
17944
- var CACHED_BINARY = import_path4.default.join(import_os7.default.homedir(), ".codeam", "bin", "cloudflared");
18263
+ var CACHED_BINARY = import_path4.default.join(import_os9.default.homedir(), ".codeam", "bin", "cloudflared");
17945
18264
  async function resolveCloudflared(opts = {}) {
17946
18265
  try {
17947
18266
  return await (0, import_which.default)("cloudflared");
@@ -18041,7 +18360,7 @@ function decodeTunnelToken(token) {
18041
18360
  }
18042
18361
  async function spawnNamedTunnel(bin, token, port) {
18043
18362
  const creds = decodeTunnelToken(token);
18044
- const credDir = import_path4.default.join(import_os7.default.homedir(), ".codeam");
18363
+ const credDir = import_path4.default.join(import_os9.default.homedir(), ".codeam");
18045
18364
  await import_promises.default.mkdir(credDir, { recursive: true });
18046
18365
  const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
18047
18366
  await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
@@ -18604,8 +18923,8 @@ function activePreviewSessionIds() {
18604
18923
 
18605
18924
  // src/services/preview/start-orchestrator.ts
18606
18925
  var import_child_process17 = require("child_process");
18607
- var fs46 = __toESM(require("fs"));
18608
- var path48 = __toESM(require("path"));
18926
+ var fs47 = __toESM(require("fs"));
18927
+ var path49 = __toESM(require("path"));
18609
18928
  var import_which2 = __toESM(require("which"));
18610
18929
  var INSTALL_TIMEOUT_MS = 5 * 6e4;
18611
18930
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -18672,8 +18991,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
18672
18991
  if (args2.length === 0) return detection;
18673
18992
  const binName = args2[0];
18674
18993
  if (binName.startsWith("-")) return detection;
18675
- const binPath = path48.join(cwd, "node_modules", ".bin", binName);
18676
- if (!fs46.existsSync(binPath)) return detection;
18994
+ const binPath = path49.join(cwd, "node_modules", ".bin", binName);
18995
+ if (!fs47.existsSync(binPath)) return detection;
18677
18996
  return {
18678
18997
  ...detection,
18679
18998
  command: binPath,
@@ -19023,9 +19342,9 @@ async function establishTunnel(ctx, dev) {
19023
19342
 
19024
19343
  // src/beads/bd-adapter.ts
19025
19344
  var import_child_process18 = require("child_process");
19026
- var fs47 = __toESM(require("fs"));
19027
- var os37 = __toESM(require("os"));
19028
- var path49 = __toESM(require("path"));
19345
+ var fs48 = __toESM(require("fs"));
19346
+ var os38 = __toESM(require("os"));
19347
+ var path50 = __toESM(require("path"));
19029
19348
  var BD_PACKAGE = "@beads/bd";
19030
19349
  function resolveBundledBdBinary() {
19031
19350
  return _resolveSeam.resolveBundled();
@@ -19037,11 +19356,11 @@ function _defaultResolveBundled() {
19037
19356
  } catch {
19038
19357
  return null;
19039
19358
  }
19040
- const binDir = path49.join(path49.dirname(pkgJsonPath), "bin");
19359
+ const binDir = path50.join(path50.dirname(pkgJsonPath), "bin");
19041
19360
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
19042
- const binaryPath = path49.join(binDir, binaryName);
19361
+ const binaryPath = path50.join(binDir, binaryName);
19043
19362
  try {
19044
- fs47.accessSync(binaryPath, fs47.constants.F_OK);
19363
+ fs48.accessSync(binaryPath, fs48.constants.F_OK);
19045
19364
  return binaryPath;
19046
19365
  } catch {
19047
19366
  return null;
@@ -19051,13 +19370,13 @@ function resolveBdOnPath() {
19051
19370
  return _resolveSeam.resolveOnPath();
19052
19371
  }
19053
19372
  function _defaultResolveOnPath() {
19054
- const dirs = (process.env.PATH ?? "").split(path49.delimiter).filter(Boolean);
19373
+ const dirs = (process.env.PATH ?? "").split(path50.delimiter).filter(Boolean);
19055
19374
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
19056
19375
  for (const dir of dirs) {
19057
19376
  for (const candidate of candidates) {
19058
- const full = path49.join(dir, candidate);
19377
+ const full = path50.join(dir, candidate);
19059
19378
  try {
19060
- fs47.accessSync(full, fs47.constants.F_OK);
19379
+ fs48.accessSync(full, fs48.constants.F_OK);
19061
19380
  return full;
19062
19381
  } catch {
19063
19382
  }
@@ -19142,7 +19461,7 @@ var BdAdapter = class {
19142
19461
  const env = { ...process.env };
19143
19462
  if (!env.HOME) {
19144
19463
  try {
19145
- const home = os37.homedir();
19464
+ const home = os38.homedir();
19146
19465
  if (home) env.HOME = home;
19147
19466
  } catch {
19148
19467
  }
@@ -19234,9 +19553,9 @@ function coerceIssue(row, projectKey) {
19234
19553
 
19235
19554
  // src/beads/provisioner.ts
19236
19555
  var import_child_process22 = require("child_process");
19237
- var fs50 = __toESM(require("fs"));
19238
- var os39 = __toESM(require("os"));
19239
- var path52 = __toESM(require("path"));
19556
+ var fs51 = __toESM(require("fs"));
19557
+ var os40 = __toESM(require("os"));
19558
+ var path53 = __toESM(require("path"));
19240
19559
 
19241
19560
  // src/beads/install-bd.ts
19242
19561
  var import_child_process19 = require("child_process");
@@ -19301,9 +19620,9 @@ async function installBd(platform3 = process.platform) {
19301
19620
 
19302
19621
  // src/beads/install-dolt.ts
19303
19622
  var import_child_process20 = require("child_process");
19304
- var fs48 = __toESM(require("fs"));
19305
- var os38 = __toESM(require("os"));
19306
- var path50 = __toESM(require("path"));
19623
+ var fs49 = __toESM(require("fs"));
19624
+ var os39 = __toESM(require("os"));
19625
+ var path51 = __toESM(require("path"));
19307
19626
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
19308
19627
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
19309
19628
  function resolveDoltInstallStrategy(platform3) {
@@ -19343,11 +19662,11 @@ function resolveDoltInstallStrategy(platform3) {
19343
19662
  }
19344
19663
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
19345
19664
  function doltPlatformTuple(platform3, arch2) {
19346
- const os49 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
19665
+ const os50 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
19347
19666
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
19348
19667
  if (!a) return null;
19349
- if (os49 === "windows" && a !== "amd64") return null;
19350
- return `${os49}-${a}`;
19668
+ if (os50 === "windows" && a !== "amd64") return null;
19669
+ return `${os50}-${a}`;
19351
19670
  }
19352
19671
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
19353
19672
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -19392,14 +19711,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
19392
19711
  return result;
19393
19712
  }
19394
19713
  var _doltPathSeam = {
19395
- homedir: () => os38.homedir(),
19714
+ homedir: () => os39.homedir(),
19396
19715
  getPath: () => process.env.PATH ?? "",
19397
19716
  setPath: (p2) => {
19398
19717
  process.env.PATH = p2;
19399
19718
  },
19400
19719
  exists: (p2) => {
19401
19720
  try {
19402
- fs48.accessSync(p2, fs48.constants.F_OK);
19721
+ fs49.accessSync(p2, fs49.constants.F_OK);
19403
19722
  return true;
19404
19723
  } catch {
19405
19724
  return false;
@@ -19410,7 +19729,7 @@ function doltBinaryNames(platform3) {
19410
19729
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
19411
19730
  }
19412
19731
  function knownDoltDirs(platform3) {
19413
- const P3 = platform3 === "win32" ? path50.win32 : path50.posix;
19732
+ const P3 = platform3 === "win32" ? path51.win32 : path51.posix;
19414
19733
  const home = _doltPathSeam.homedir();
19415
19734
  if (platform3 === "win32") {
19416
19735
  return [
@@ -19426,7 +19745,7 @@ function knownDoltDirs(platform3) {
19426
19745
  ].filter(Boolean);
19427
19746
  }
19428
19747
  function ensureDoltResolvable(platform3 = process.platform) {
19429
- const P3 = platform3 === "win32" ? path50.win32 : path50.posix;
19748
+ const P3 = platform3 === "win32" ? path51.win32 : path51.posix;
19430
19749
  const delim = platform3 === "win32" ? ";" : ":";
19431
19750
  const names = doltBinaryNames(platform3);
19432
19751
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -19562,8 +19881,8 @@ async function ensureSharedServer(adapter, options = {}) {
19562
19881
  // src/beads/project-key.ts
19563
19882
  var import_child_process21 = require("child_process");
19564
19883
  var crypto2 = __toESM(require("crypto"));
19565
- var fs49 = __toESM(require("fs"));
19566
- var path51 = __toESM(require("path"));
19884
+ var fs50 = __toESM(require("fs"));
19885
+ var path52 = __toESM(require("path"));
19567
19886
  function normalizeOrigin(raw) {
19568
19887
  const trimmed = raw.trim();
19569
19888
  if (!trimmed) return null;
@@ -19589,17 +19908,17 @@ function normalizeOrigin(raw) {
19589
19908
  return `${host2}/${pathPart}`;
19590
19909
  }
19591
19910
  function findRepoRoot(cwd) {
19592
- let dir = path51.resolve(cwd);
19911
+ let dir = path52.resolve(cwd);
19593
19912
  const seen = /* @__PURE__ */ new Set();
19594
19913
  for (let i = 0; i < 256; i++) {
19595
19914
  if (seen.has(dir)) return null;
19596
19915
  seen.add(dir);
19597
19916
  try {
19598
- const stat3 = fs49.statSync(path51.join(dir, ".git"), { throwIfNoEntry: false });
19917
+ const stat3 = fs50.statSync(path52.join(dir, ".git"), { throwIfNoEntry: false });
19599
19918
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
19600
19919
  } catch {
19601
19920
  }
19602
- const parent = path51.dirname(dir);
19921
+ const parent = path52.dirname(dir);
19603
19922
  if (parent === dir) return null;
19604
19923
  dir = parent;
19605
19924
  }
@@ -19610,7 +19929,7 @@ var _execSeam2 = {
19610
19929
  const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
19611
19930
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
19612
19931
  },
19613
- realpath: (p2) => fs49.realpathSync(p2)
19932
+ realpath: (p2) => fs50.realpathSync(p2)
19614
19933
  };
19615
19934
  function readOrigin(cwd) {
19616
19935
  try {
@@ -19639,7 +19958,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
19639
19958
  } catch {
19640
19959
  }
19641
19960
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
19642
- return { projectKey: `path:${hash}`, projectLabel: path51.basename(real) || "project" };
19961
+ return { projectKey: `path:${hash}`, projectLabel: path52.basename(real) || "project" };
19643
19962
  }
19644
19963
 
19645
19964
  // src/beads/project-prefix.ts
@@ -19684,17 +20003,17 @@ var _provisionSeam = {
19684
20003
  };
19685
20004
  var _linkSeam = {
19686
20005
  platform: () => process.platform,
19687
- homedir: () => os39.homedir(),
20006
+ homedir: () => os40.homedir(),
19688
20007
  isWritableDir: (dir) => {
19689
20008
  try {
19690
- fs50.accessSync(dir, fs50.constants.W_OK);
20009
+ fs51.accessSync(dir, fs51.constants.W_OK);
19691
20010
  return true;
19692
20011
  } catch {
19693
20012
  return false;
19694
20013
  }
19695
20014
  },
19696
20015
  ensureDir: (dir) => {
19697
- fs50.mkdirSync(dir, { recursive: true });
20016
+ fs51.mkdirSync(dir, { recursive: true });
19698
20017
  },
19699
20018
  /**
19700
20019
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -19715,9 +20034,9 @@ var _linkSeam = {
19715
20034
  * which `linkBdOntoPath` creates if missing.
19716
20035
  */
19717
20036
  cliBinDir: () => {
19718
- const pathDirs = (process.env.PATH ?? "").split(path52.delimiter).filter(Boolean);
20037
+ const pathDirs = (process.env.PATH ?? "").split(path53.delimiter).filter(Boolean);
19719
20038
  const home = _linkSeam.homedir();
19720
- const localBin = home ? path52.join(home, ".local", "bin") : null;
20039
+ const localBin = home ? path53.join(home, ".local", "bin") : null;
19721
20040
  if (localBin) {
19722
20041
  try {
19723
20042
  _linkSeam.ensureDir(localBin);
@@ -19727,16 +20046,16 @@ var _linkSeam = {
19727
20046
  const candidates = [];
19728
20047
  if (localBin) candidates.push(localBin);
19729
20048
  try {
19730
- candidates.push(path52.dirname(process.execPath));
20049
+ candidates.push(path53.dirname(process.execPath));
19731
20050
  } catch {
19732
20051
  }
19733
20052
  candidates.push("/usr/local/bin");
19734
20053
  const entry = process.argv[1];
19735
20054
  if (entry) {
19736
20055
  try {
19737
- candidates.push(path52.dirname(fs50.realpathSync(entry)));
20056
+ candidates.push(path53.dirname(fs51.realpathSync(entry)));
19738
20057
  } catch {
19739
- candidates.push(path52.dirname(entry));
20058
+ candidates.push(path53.dirname(entry));
19740
20059
  }
19741
20060
  }
19742
20061
  const onPathWritable = candidates.find(
@@ -19748,20 +20067,20 @@ var _linkSeam = {
19748
20067
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
19749
20068
  readlink: (linkPath) => {
19750
20069
  try {
19751
- return fs50.readlinkSync(linkPath);
20070
+ return fs51.readlinkSync(linkPath);
19752
20071
  } catch {
19753
20072
  return null;
19754
20073
  }
19755
20074
  },
19756
- unlink: (linkPath) => fs50.unlinkSync(linkPath),
19757
- symlink: (target, linkPath) => fs50.symlinkSync(target, linkPath)
20075
+ unlink: (linkPath) => fs51.unlinkSync(linkPath),
20076
+ symlink: (target, linkPath) => fs51.symlinkSync(target, linkPath)
19758
20077
  };
19759
20078
  function linkBdOntoPath(binaryPath) {
19760
20079
  if (_linkSeam.platform() === "win32") return;
19761
20080
  const binDir = _linkSeam.cliBinDir();
19762
20081
  if (!binDir) return;
19763
20082
  _linkSeam.ensureDir(binDir);
19764
- const linkPath = path52.join(binDir, "bd");
20083
+ const linkPath = path53.join(binDir, "bd");
19765
20084
  if (linkPath === binaryPath) return;
19766
20085
  const current = _linkSeam.readlink(linkPath);
19767
20086
  if (current === binaryPath) return;
@@ -19956,7 +20275,7 @@ function dedupeRecipes(agents) {
19956
20275
 
19957
20276
  // src/beads/watcher.ts
19958
20277
  var crypto4 = __toESM(require("crypto"));
19959
- var path53 = __toESM(require("path"));
20278
+ var path54 = __toESM(require("path"));
19960
20279
  var API_BASE6 = resolveApiBaseUrl();
19961
20280
  var DEBOUNCE_MS2 = 400;
19962
20281
  var ZERO_SUMMARY = {
@@ -19980,7 +20299,7 @@ var BeadsWatcher = class {
19980
20299
  constructor(opts) {
19981
20300
  this.opts = opts;
19982
20301
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
19983
- this.feedPath = opts.feedPath ?? path53.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
20302
+ this.feedPath = opts.feedPath ?? path54.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
19984
20303
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
19985
20304
  }
19986
20305
  opts;
@@ -20397,8 +20716,8 @@ function cleanupAttachmentTempFiles() {
20397
20716
  function saveFilesTemp(files) {
20398
20717
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
20399
20718
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
20400
- const tmpPath = path55.join(os41.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
20401
- fs52.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
20719
+ const tmpPath = path56.join(os42.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
20720
+ fs53.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
20402
20721
  pendingAttachmentFiles.add(tmpPath);
20403
20722
  return tmpPath;
20404
20723
  });
@@ -20610,9 +20929,9 @@ var listFiles = async (ctx, cmd, parsed) => {
20610
20929
  await ctx.relay.sendResult(cmd.id, "completed", result);
20611
20930
  };
20612
20931
  var envReadH = async (ctx, cmd) => {
20613
- const envPath = path55.join(process.cwd(), ".env");
20932
+ const envPath = path56.join(process.cwd(), ".env");
20614
20933
  try {
20615
- const raw = await fs52.promises.readFile(envPath, "utf8");
20934
+ const raw = await fs53.promises.readFile(envPath, "utf8");
20616
20935
  await ctx.relay.sendResult(cmd.id, "completed", {
20617
20936
  exists: true,
20618
20937
  vars: parseDotenv(raw)
@@ -20643,14 +20962,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
20643
20962
  }
20644
20963
  seen.add(v.key);
20645
20964
  }
20646
- const envPath = path55.join(process.cwd(), ".env");
20647
- const tmpPath = path55.join(process.cwd(), ".env.codeam.tmp");
20965
+ const envPath = path56.join(process.cwd(), ".env");
20966
+ const tmpPath = path56.join(process.cwd(), ".env.codeam.tmp");
20648
20967
  try {
20649
- await fs52.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
20650
- await fs52.promises.rename(tmpPath, envPath);
20968
+ await fs53.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
20969
+ await fs53.promises.rename(tmpPath, envPath);
20651
20970
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
20652
20971
  } catch (err) {
20653
- await fs52.promises.rm(tmpPath, { force: true }).catch(() => void 0);
20972
+ await fs53.promises.rm(tmpPath, { force: true }).catch(() => void 0);
20654
20973
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
20655
20974
  }
20656
20975
  };
@@ -20694,7 +21013,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20694
21013
  let configuredAgent = rawAgentId;
20695
21014
  if (!configuredAgent) {
20696
21015
  try {
20697
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21016
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20698
21017
  configuredAgent = raw.agent ?? "";
20699
21018
  } catch {
20700
21019
  }
@@ -20728,7 +21047,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20728
21047
  persist: persistHeadroomConfig,
20729
21048
  readEnabled: () => {
20730
21049
  try {
20731
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21050
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20732
21051
  return raw.enabled === true;
20733
21052
  } catch {
20734
21053
  return false;
@@ -20801,6 +21120,63 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20801
21120
  });
20802
21121
  await ctx.relay.sendResult(cmd.id, "completed", result);
20803
21122
  };
21123
+ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
21124
+ const action = parsed.action ?? "status";
21125
+ const token = ctx.pluginAuthToken;
21126
+ let emitChain = Promise.resolve();
21127
+ const emit2 = (type, payload) => {
21128
+ if (!token) return;
21129
+ emitChain = emitChain.then(
21130
+ () => postCoderabbitEvent({
21131
+ sessionId: ctx.sessionId,
21132
+ pluginId: ctx.pluginId,
21133
+ pluginAuthToken: token,
21134
+ type,
21135
+ payload
21136
+ })
21137
+ );
21138
+ };
21139
+ const result = await configureCoderabbit(
21140
+ {
21141
+ action,
21142
+ apiKey: parsed.apiKey,
21143
+ review: { changeSet: parsed.changeSet, base: parsed.base, dir: parsed.reviewDir }
21144
+ },
21145
+ {
21146
+ onEvent: (e) => {
21147
+ if (e.kind === "awaiting_browser") {
21148
+ emit2("coderabbit_progress", {
21149
+ phase: "awaiting_browser",
21150
+ authUrl: e.authUrl,
21151
+ fallbackAuthUrl: e.fallbackAuthUrl
21152
+ });
21153
+ } else {
21154
+ emit2("coderabbit_progress", { phase: e.kind });
21155
+ }
21156
+ },
21157
+ uploadCredential: token ? async (method, credential) => {
21158
+ const r = await postLinkCredential({
21159
+ agentId: "coderabbit",
21160
+ sessionId: ctx.sessionId,
21161
+ pluginId: ctx.pluginId,
21162
+ pluginAuthToken: token,
21163
+ method,
21164
+ credential
21165
+ });
21166
+ return r.ok === true;
21167
+ } : void 0,
21168
+ runReview: (input) => new CoderabbitRuntimeStrategy(createOsStrategy()).runOneShot(input)
21169
+ }
21170
+ );
21171
+ emit2("coderabbit_status", {
21172
+ installed: result.installed,
21173
+ loggedIn: result.loggedIn,
21174
+ linked: result.linked ?? false,
21175
+ ...result.error ? { error: result.error } : {}
21176
+ });
21177
+ await emitChain;
21178
+ await ctx.relay.sendResult(cmd.id, result.error && action !== "review" ? "failed" : "completed", result);
21179
+ };
20804
21180
  var headroomBudgetH = async (ctx, cmd) => {
20805
21181
  const payload = cmd.payload;
20806
21182
  let rawAgentId = ctx.agentId || (typeof payload.agentId === "string" ? payload.agentId : "");
@@ -20817,7 +21193,7 @@ var headroomBudgetH = async (ctx, cmd) => {
20817
21193
  }
20818
21194
  let headroomActive = false;
20819
21195
  try {
20820
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21196
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20821
21197
  headroomActive = raw.enabled === true;
20822
21198
  } catch {
20823
21199
  }
@@ -20827,7 +21203,7 @@ var headroomBudgetH = async (ctx, cmd) => {
20827
21203
  }
20828
21204
  let existingConfig = { enabled: true };
20829
21205
  try {
20830
- existingConfig = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21206
+ existingConfig = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20831
21207
  } catch {
20832
21208
  }
20833
21209
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -20940,13 +21316,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
20940
21316
  function buildNpmInstallInvocation(opts) {
20941
21317
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
20942
21318
  const execPath = opts?.execPath ?? process.execPath;
20943
- const exists2 = opts?.existsSync ?? fs52.existsSync;
20944
- const normalized = entryScript.split(path55.sep).join("/");
21319
+ const exists2 = opts?.existsSync ?? fs53.existsSync;
21320
+ const normalized = entryScript.split(path56.sep).join("/");
20945
21321
  const marker = "/lib/node_modules/codeam-cli/";
20946
21322
  const markerIdx = normalized.indexOf(marker);
20947
21323
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
20948
- const siblingNpm = path55.join(
20949
- path55.dirname(execPath),
21324
+ const siblingNpm = path56.join(
21325
+ path56.dirname(execPath),
20950
21326
  process.platform === "win32" ? "npm.cmd" : "npm"
20951
21327
  );
20952
21328
  const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
@@ -21518,6 +21894,7 @@ var handlers = {
21518
21894
  take_control: takeControlH,
21519
21895
  handback: handbackH,
21520
21896
  headroom_configure: headroomConfigureH,
21897
+ coderabbit_configure: coderabbitConfigureH,
21521
21898
  headroom_budget: headroomBudgetH,
21522
21899
  beads_configure: beadsConfigureH,
21523
21900
  cli_self_update: cliSelfUpdateH()
@@ -21788,11 +22165,11 @@ function resolveTokenValue(args2) {
21788
22165
  }
21789
22166
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
21790
22167
  if (fileFlag) {
21791
- const path70 = fileFlag.slice("--token-file=".length);
22168
+ const path71 = fileFlag.slice("--token-file=".length);
21792
22169
  try {
21793
- const content = fs53.readFileSync(path70, "utf8").trim();
21794
- if (content.length === 0) fail(`--token-file ${path70} is empty`);
21795
- rmIfExistsQuiet(path70);
22170
+ const content = fs54.readFileSync(path71, "utf8").trim();
22171
+ if (content.length === 0) fail(`--token-file ${path71} is empty`);
22172
+ rmIfExistsQuiet(path71);
21796
22173
  return content;
21797
22174
  } catch (err) {
21798
22175
  fail(`Could not read --token-file: ${err.message}`);
@@ -21821,7 +22198,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
21821
22198
  pluginId,
21822
22199
  ideName: "codeam-cli (codespace)",
21823
22200
  ideVersion: process.env.npm_package_version ?? "unknown",
21824
- hostname: os42.hostname(),
22201
+ hostname: os43.hostname(),
21825
22202
  codespaceName: process.env.CODESPACE_NAME ?? "",
21826
22203
  // Current git branch of the codespace's working directory, so the
21827
22204
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -21882,7 +22259,7 @@ async function claim(token, pluginId, pluginSecretHash) {
21882
22259
  }
21883
22260
  }
21884
22261
  function pairAutoLockPath() {
21885
- return path56.join(os42.homedir(), ".codeam", "pair-auto.lock");
22262
+ return path57.join(os43.homedir(), ".codeam", "pair-auto.lock");
21886
22263
  }
21887
22264
  function isLivePairAuto(pid) {
21888
22265
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -21892,7 +22269,7 @@ function isLivePairAuto(pid) {
21892
22269
  if (e.code !== "EPERM") return false;
21893
22270
  }
21894
22271
  try {
21895
- return fs53.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
22272
+ return fs54.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
21896
22273
  } catch {
21897
22274
  return true;
21898
22275
  }
@@ -21902,24 +22279,24 @@ function isLiveCodeam(pid) {
21902
22279
  }
21903
22280
  function daemonLockPath(sessionId) {
21904
22281
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
21905
- return path56.join(os42.homedir(), ".codeam", `daemon-${safe}.lock`);
22282
+ return path57.join(os43.homedir(), ".codeam", `daemon-${safe}.lock`);
21906
22283
  }
21907
22284
  function acquireDaemonLock(sessionId) {
21908
22285
  const lockPath = daemonLockPath(sessionId);
21909
22286
  try {
21910
- fs53.mkdirSync(path56.dirname(lockPath), { recursive: true });
22287
+ fs54.mkdirSync(path57.dirname(lockPath), { recursive: true });
21911
22288
  try {
21912
- fs53.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
22289
+ fs54.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21913
22290
  } catch (e) {
21914
22291
  if (e.code !== "EEXIST") throw e;
21915
- const holder = Number(fs53.readFileSync(lockPath, "utf8").trim());
22292
+ const holder = Number(fs54.readFileSync(lockPath, "utf8").trim());
21916
22293
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
21917
- fs53.writeFileSync(lockPath, String(process.pid));
22294
+ fs54.writeFileSync(lockPath, String(process.pid));
21918
22295
  }
21919
22296
  const release3 = () => {
21920
22297
  try {
21921
- if (fs53.existsSync(lockPath) && Number(fs53.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21922
- fs53.unlinkSync(lockPath);
22298
+ if (fs54.existsSync(lockPath) && Number(fs54.readFileSync(lockPath, "utf8").trim()) === process.pid) {
22299
+ fs54.unlinkSync(lockPath);
21923
22300
  }
21924
22301
  } catch {
21925
22302
  }
@@ -21941,19 +22318,19 @@ function acquireDaemonLock(sessionId) {
21941
22318
  function acquireSingletonLock() {
21942
22319
  const lockPath = pairAutoLockPath();
21943
22320
  try {
21944
- fs53.mkdirSync(path56.dirname(lockPath), { recursive: true });
22321
+ fs54.mkdirSync(path57.dirname(lockPath), { recursive: true });
21945
22322
  try {
21946
- fs53.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
22323
+ fs54.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21947
22324
  } catch (e) {
21948
22325
  if (e.code !== "EEXIST") throw e;
21949
- const holder = Number(fs53.readFileSync(lockPath, "utf8").trim());
22326
+ const holder = Number(fs54.readFileSync(lockPath, "utf8").trim());
21950
22327
  if (isLivePairAuto(holder)) return false;
21951
- fs53.writeFileSync(lockPath, String(process.pid));
22328
+ fs54.writeFileSync(lockPath, String(process.pid));
21952
22329
  }
21953
22330
  process.once("exit", () => {
21954
22331
  try {
21955
- if (fs53.existsSync(lockPath) && Number(fs53.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21956
- fs53.unlinkSync(lockPath);
22332
+ if (fs54.existsSync(lockPath) && Number(fs54.readFileSync(lockPath, "utf8").trim()) === process.pid) {
22333
+ fs54.unlinkSync(lockPath);
21957
22334
  }
21958
22335
  } catch {
21959
22336
  }
@@ -22035,7 +22412,7 @@ async function pairAuto(args2) {
22035
22412
  }
22036
22413
 
22037
22414
  // src/services/headroom/wrap-launch.ts
22038
- var import_node_child_process22 = require("child_process");
22415
+ var import_node_child_process24 = require("child_process");
22039
22416
  function wrapWithHeadroom(launch, opts) {
22040
22417
  if (!opts.enabled || !opts.headroomPresent) return launch;
22041
22418
  return {
@@ -22048,7 +22425,7 @@ var _present;
22048
22425
  function headroomPresent() {
22049
22426
  if (_present !== void 0) return Promise.resolve(_present);
22050
22427
  return new Promise((resolve7) => {
22051
- (0, import_node_child_process22.execFile)("headroom", ["--version"], (err) => {
22428
+ (0, import_node_child_process24.execFile)("headroom", ["--version"], (err) => {
22052
22429
  _present = !err;
22053
22430
  resolve7(_present);
22054
22431
  });
@@ -22398,11 +22775,11 @@ var AgentService = class _AgentService {
22398
22775
  };
22399
22776
 
22400
22777
  // src/agents/acp/adapters.ts
22401
- var path58 = __toESM(require("path"));
22778
+ var path59 = __toESM(require("path"));
22402
22779
 
22403
22780
  // src/agents/acp/agent-binary.ts
22404
22781
  var import_fs4 = __toESM(require("fs"));
22405
- var import_os8 = __toESM(require("os"));
22782
+ var import_os11 = __toESM(require("os"));
22406
22783
  var import_path8 = __toESM(require("path"));
22407
22784
  var import_child_process25 = require("child_process");
22408
22785
  function currentPlatformKey() {
@@ -22498,7 +22875,7 @@ function resolveCursorAgentBinary(deps = {}) {
22498
22875
  const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
22499
22876
  return existsSync26(exe) ? exe : null;
22500
22877
  }
22501
- const home = deps.homedir ?? import_os8.default.homedir();
22878
+ const home = deps.homedir ?? import_os11.default.homedir();
22502
22879
  const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
22503
22880
  return existsSync26(unix) ? unix : null;
22504
22881
  }
@@ -22572,7 +22949,7 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
22572
22949
  }
22573
22950
 
22574
22951
  // src/agents/kimi/installer.ts
22575
- var import_node_child_process23 = require("child_process");
22952
+ var import_node_child_process25 = require("child_process");
22576
22953
  var import_node_os6 = require("os");
22577
22954
  var import_node_path6 = require("path");
22578
22955
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
@@ -22580,7 +22957,7 @@ function kimiBinDir() {
22580
22957
  return (0, import_node_path6.join)(process.env.KIMI_CODE_HOME || (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".kimi-code"), "bin");
22581
22958
  }
22582
22959
  function kimiRuns() {
22583
- const r = (0, import_node_child_process23.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
22960
+ const r = (0, import_node_child_process25.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
22584
22961
  return !r.error && r.status === 0;
22585
22962
  }
22586
22963
  function augmentPath2() {
@@ -22590,7 +22967,7 @@ function augmentPath2() {
22590
22967
  }
22591
22968
  async function runInstaller2() {
22592
22969
  return new Promise((resolve7) => {
22593
- const proc = (0, import_node_child_process23.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
22970
+ const proc = (0, import_node_child_process25.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
22594
22971
  proc.on("close", (code) => resolve7(code === 0));
22595
22972
  proc.on("error", () => resolve7(false));
22596
22973
  });
@@ -22640,13 +23017,13 @@ function resolveBin(pkgName, binName) {
22640
23017
  try {
22641
23018
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
22642
23019
  const manifest = require_(`${pkgName}/package.json`);
22643
- const pkgDir = path58.dirname(manifestPath);
23020
+ const pkgDir = path59.dirname(manifestPath);
22644
23021
  const bin = manifest.bin;
22645
23022
  if (!bin) return null;
22646
- if (typeof bin === "string") return path58.resolve(pkgDir, bin);
23023
+ if (typeof bin === "string") return path59.resolve(pkgDir, bin);
22647
23024
  const target = binName ?? Object.keys(bin)[0];
22648
23025
  if (!target || !bin[target]) return null;
22649
- return path58.resolve(pkgDir, bin[target]);
23026
+ return path59.resolve(pkgDir, bin[target]);
22650
23027
  } catch {
22651
23028
  return null;
22652
23029
  }
@@ -22750,9 +23127,9 @@ function requiresAcp(agent) {
22750
23127
  var import_node_crypto10 = require("crypto");
22751
23128
 
22752
23129
  // src/services/history.service.ts
22753
- var fs55 = __toESM(require("fs"));
22754
- var path59 = __toESM(require("path"));
22755
- var os44 = __toESM(require("os"));
23130
+ var fs56 = __toESM(require("fs"));
23131
+ var path60 = __toESM(require("path"));
23132
+ var os45 = __toESM(require("os"));
22756
23133
  var https7 = __toESM(require("https"));
22757
23134
  var http6 = __toESM(require("http"));
22758
23135
  var import_zod2 = require("zod");
@@ -22779,7 +23156,7 @@ function parseJsonl(filePath) {
22779
23156
  const messages = [];
22780
23157
  let raw;
22781
23158
  try {
22782
- raw = fs55.readFileSync(filePath, "utf8");
23159
+ raw = fs56.readFileSync(filePath, "utf8");
22783
23160
  } catch (err) {
22784
23161
  if (err.code !== "ENOENT") {
22785
23162
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -22920,7 +23297,7 @@ var HistoryService = class _HistoryService {
22920
23297
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
22921
23298
  }
22922
23299
  get projectDir() {
22923
- return this.runtime.resolveHistoryDir(this.cwd) ?? path59.join(os44.homedir(), ".claude", "projects", encodeCwd(this.cwd));
23300
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path60.join(os45.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22924
23301
  }
22925
23302
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
22926
23303
  setCurrentConversationId(id) {
@@ -22932,7 +23309,7 @@ var HistoryService = class _HistoryService {
22932
23309
  /** Return the current message count in the active conversation. */
22933
23310
  getCurrentMessageCount() {
22934
23311
  if (!this.currentConversationId) return 0;
22935
- const filePath = path59.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23312
+ const filePath = path60.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22936
23313
  return parseJsonl(filePath).length;
22937
23314
  }
22938
23315
  /**
@@ -22943,7 +23320,7 @@ var HistoryService = class _HistoryService {
22943
23320
  const deadline = Date.now() + timeoutMs;
22944
23321
  while (Date.now() < deadline) {
22945
23322
  if (!this.currentConversationId) return null;
22946
- const filePath = path59.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23323
+ const filePath = path60.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22947
23324
  const messages = parseJsonl(filePath);
22948
23325
  if (messages.length > previousCount) {
22949
23326
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -22969,16 +23346,16 @@ var HistoryService = class _HistoryService {
22969
23346
  const dir = this.projectDir;
22970
23347
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22971
23348
  try {
22972
- const files = fs55.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
23349
+ const files = fs56.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22973
23350
  try {
22974
- const stat3 = fs55.statSync(path59.join(dir, e.name));
23351
+ const stat3 = fs56.statSync(path60.join(dir, e.name));
22975
23352
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22976
23353
  } catch {
22977
23354
  return { name: e.name, mtime: 0, birthtime: 0 };
22978
23355
  }
22979
23356
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
22980
23357
  if (files.length > 0) {
22981
- this.currentConversationId = path59.basename(files[0].name, ".jsonl");
23358
+ this.currentConversationId = path60.basename(files[0].name, ".jsonl");
22982
23359
  }
22983
23360
  } catch {
22984
23361
  }
@@ -23012,13 +23389,13 @@ var HistoryService = class _HistoryService {
23012
23389
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
23013
23390
  let entries;
23014
23391
  try {
23015
- entries = fs55.readdirSync(dir, { withFileTypes: true });
23392
+ entries = fs56.readdirSync(dir, { withFileTypes: true });
23016
23393
  } catch {
23017
23394
  return null;
23018
23395
  }
23019
23396
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
23020
23397
  try {
23021
- const stat3 = fs55.statSync(path59.join(dir, e.name));
23398
+ const stat3 = fs56.statSync(path60.join(dir, e.name));
23022
23399
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
23023
23400
  } catch {
23024
23401
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -23027,12 +23404,12 @@ var HistoryService = class _HistoryService {
23027
23404
  if (files.length === 0) return null;
23028
23405
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
23029
23406
  if (!files.some((f) => f.name === targetFile)) return null;
23030
- return this.extractUsageFromFile(path59.join(dir, targetFile));
23407
+ return this.extractUsageFromFile(path60.join(dir, targetFile));
23031
23408
  }
23032
23409
  extractUsageFromFile(filePath) {
23033
23410
  let raw;
23034
23411
  try {
23035
- raw = fs55.readFileSync(filePath, "utf8");
23412
+ raw = fs56.readFileSync(filePath, "utf8");
23036
23413
  } catch {
23037
23414
  return null;
23038
23415
  }
@@ -23077,9 +23454,9 @@ var HistoryService = class _HistoryService {
23077
23454
  let totalCost = 0;
23078
23455
  let files;
23079
23456
  try {
23080
- files = fs55.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23457
+ files = fs56.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23081
23458
  try {
23082
- return fs55.statSync(path59.join(projectDir, f)).mtimeMs >= monthStartMs;
23459
+ return fs56.statSync(path60.join(projectDir, f)).mtimeMs >= monthStartMs;
23083
23460
  } catch {
23084
23461
  return false;
23085
23462
  }
@@ -23090,7 +23467,7 @@ var HistoryService = class _HistoryService {
23090
23467
  for (const file of files) {
23091
23468
  let raw;
23092
23469
  try {
23093
- raw = fs55.readFileSync(path59.join(projectDir, file), "utf8");
23470
+ raw = fs56.readFileSync(path60.join(projectDir, file), "utf8");
23094
23471
  } catch {
23095
23472
  continue;
23096
23473
  }
@@ -23169,7 +23546,7 @@ var HistoryService = class _HistoryService {
23169
23546
  if (this.runtime.resolveHistoryFile) {
23170
23547
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
23171
23548
  }
23172
- return path59.join(this.projectDir, `${sessionId}.jsonl`);
23549
+ return path60.join(this.projectDir, `${sessionId}.jsonl`);
23173
23550
  }
23174
23551
  /**
23175
23552
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -23203,7 +23580,7 @@ var HistoryService = class _HistoryService {
23203
23580
  };
23204
23581
  });
23205
23582
  }
23206
- return parseJsonl(path59.join(this.projectDir, `${sessionId}.jsonl`));
23583
+ return parseJsonl(path60.join(this.projectDir, `${sessionId}.jsonl`));
23207
23584
  }
23208
23585
  async loadConversation(sessionId) {
23209
23586
  const messages = this.readConversation(sessionId);
@@ -23259,7 +23636,7 @@ var HistoryService = class _HistoryService {
23259
23636
  if (!filePath) return false;
23260
23637
  let mtimeMs;
23261
23638
  try {
23262
- mtimeMs = fs55.statSync(filePath).mtimeMs;
23639
+ mtimeMs = fs56.statSync(filePath).mtimeMs;
23263
23640
  } catch {
23264
23641
  return false;
23265
23642
  }
@@ -23327,11 +23704,11 @@ var HistoryService = class _HistoryService {
23327
23704
  };
23328
23705
 
23329
23706
  // src/agents/acp/client.ts
23330
- var import_node_child_process24 = require("child_process");
23331
- var fs56 = __toESM(require("fs/promises"));
23707
+ var import_node_child_process26 = require("child_process");
23708
+ var fs57 = __toESM(require("fs/promises"));
23332
23709
  var fsSync = __toESM(require("fs"));
23333
- var os45 = __toESM(require("os"));
23334
- var path60 = __toESM(require("path"));
23710
+ var os46 = __toESM(require("os"));
23711
+ var path61 = __toESM(require("path"));
23335
23712
  var import_node_stream = require("stream");
23336
23713
 
23337
23714
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -25931,7 +26308,7 @@ var AcpClient = class {
25931
26308
  "acpClient",
25932
26309
  `spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
25933
26310
  );
25934
- const child = (0, import_node_child_process24.spawn)(adapter.command, adapter.args, {
26311
+ const child = (0, import_node_child_process26.spawn)(adapter.command, adapter.args, {
25935
26312
  cwd,
25936
26313
  // extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
25937
26314
  // re-spawn) layers over process.env; PATH stays last so the augmented
@@ -26245,7 +26622,7 @@ var AcpClient = class {
26245
26622
  },
26246
26623
  readTextFile: async (params) => {
26247
26624
  try {
26248
- const content = await fs56.readFile(params.path, "utf8");
26625
+ const content = await fs57.readFile(params.path, "utf8");
26249
26626
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
26250
26627
  } catch (err) {
26251
26628
  const code = err.code;
@@ -26265,7 +26642,7 @@ var AcpClient = class {
26265
26642
  },
26266
26643
  writeTextFile: async (params) => {
26267
26644
  try {
26268
- await fs56.writeFile(params.path, params.content, "utf8");
26645
+ await fs57.writeFile(params.path, params.content, "utf8");
26269
26646
  return {};
26270
26647
  } catch (err) {
26271
26648
  const code = err.code;
@@ -26314,29 +26691,29 @@ function applyLineRange(content, line, limit) {
26314
26691
  return { content: lines.slice(start2, end).join("\n") };
26315
26692
  }
26316
26693
  function knownAgentBinaryDirs() {
26317
- const home = os45.homedir();
26694
+ const home = os46.homedir();
26318
26695
  const out2 = [];
26319
26696
  out2.push("/tmp/codeam-node20/bin");
26320
26697
  for (const root of [
26321
26698
  "/usr/local/share/nvm/versions/node",
26322
- path60.join(home, ".nvm/versions/node")
26699
+ path61.join(home, ".nvm/versions/node")
26323
26700
  ]) {
26324
26701
  try {
26325
26702
  for (const child of fsSync.readdirSync(root)) {
26326
- out2.push(path60.join(root, child, "bin"));
26703
+ out2.push(path61.join(root, child, "bin"));
26327
26704
  }
26328
26705
  } catch {
26329
26706
  }
26330
26707
  }
26331
- out2.push(path60.join(home, ".volta/bin"));
26708
+ out2.push(path61.join(home, ".volta/bin"));
26332
26709
  out2.push("/usr/local/bin");
26333
26710
  out2.push("/usr/bin");
26334
- out2.push(path60.join(home, ".local/bin"));
26335
- out2.push(path60.join(home, "bin"));
26711
+ out2.push(path61.join(home, ".local/bin"));
26712
+ out2.push(path61.join(home, "bin"));
26336
26713
  if (process.platform === "win32") {
26337
26714
  const { LOCALAPPDATA, APPDATA } = process.env;
26338
- if (LOCALAPPDATA) out2.push(path60.join(LOCALAPPDATA, "cursor-agent"));
26339
- if (APPDATA) out2.push(path60.join(APPDATA, "npm"));
26715
+ if (LOCALAPPDATA) out2.push(path61.join(LOCALAPPDATA, "cursor-agent"));
26716
+ if (APPDATA) out2.push(path61.join(APPDATA, "npm"));
26340
26717
  }
26341
26718
  return out2.filter((p2) => {
26342
26719
  try {
@@ -26348,7 +26725,7 @@ function knownAgentBinaryDirs() {
26348
26725
  }
26349
26726
  function expandPathForAgentBinaries(existingPath) {
26350
26727
  const existing = new Set(
26351
- existingPath.split(path60.delimiter).filter((p2) => p2.length > 0)
26728
+ existingPath.split(path61.delimiter).filter((p2) => p2.length > 0)
26352
26729
  );
26353
26730
  const additions = [];
26354
26731
  for (const dir of knownAgentBinaryDirs()) {
@@ -26358,7 +26735,7 @@ function expandPathForAgentBinaries(existingPath) {
26358
26735
  }
26359
26736
  }
26360
26737
  if (additions.length === 0) return existingPath;
26361
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path60.delimiter);
26738
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path61.delimiter);
26362
26739
  }
26363
26740
 
26364
26741
  // src/agents/acp/headroom-budget-proxy.ts
@@ -26369,12 +26746,12 @@ function buildRelaunchProxyEnv(baseEnv) {
26369
26746
  return env;
26370
26747
  }
26371
26748
  var relaunchProxyWithoutBudget = async () => {
26372
- const { spawn: spawn40 } = await import("child_process");
26749
+ const { spawn: spawn41 } = await import("child_process");
26373
26750
  killHeadroomProxy();
26374
26751
  await new Promise((r) => setTimeout(r, 500));
26375
26752
  const proxyEnv = buildRelaunchProxyEnv(process.env);
26376
26753
  try {
26377
- const proxy = spawn40(
26754
+ const proxy = spawn41(
26378
26755
  "headroom",
26379
26756
  ["proxy", "--port", "8787"],
26380
26757
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -26840,15 +27217,15 @@ function commonPrefixLength(a, b) {
26840
27217
 
26841
27218
  // src/agents/acp/onboarding.ts
26842
27219
  var import_child_process26 = require("child_process");
26843
- var fs57 = __toESM(require("fs"));
26844
- var os46 = __toESM(require("os"));
26845
- var path61 = __toESM(require("path"));
27220
+ var fs58 = __toESM(require("fs"));
27221
+ var os47 = __toESM(require("os"));
27222
+ var path62 = __toESM(require("path"));
26846
27223
  var _onboardingSeam = {
26847
- markerPath: (sessionId) => path61.join(os46.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
26848
- exists: (p2) => fs57.existsSync(p2),
27224
+ markerPath: (sessionId) => path62.join(os47.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
27225
+ exists: (p2) => fs58.existsSync(p2),
26849
27226
  write: (p2) => {
26850
- fs57.mkdirSync(path61.dirname(p2), { recursive: true });
26851
- fs57.writeFileSync(p2, "");
27227
+ fs58.mkdirSync(path62.dirname(p2), { recursive: true });
27228
+ fs58.writeFileSync(p2, "");
26852
27229
  },
26853
27230
  disabled: () => {
26854
27231
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -26885,7 +27262,7 @@ function resolveRepoName(cwd) {
26885
27262
  if (name) return name;
26886
27263
  }
26887
27264
  }
26888
- const base = path61.basename(cwd || "");
27265
+ const base = path62.basename(cwd || "");
26889
27266
  if (base && !isUuid(base)) return base;
26890
27267
  return "this project";
26891
27268
  }
@@ -27137,8 +27514,8 @@ var import_crypto5 = require("crypto");
27137
27514
 
27138
27515
  // src/services/turn-files/git-changeset.ts
27139
27516
  var import_child_process27 = require("child_process");
27140
- var fs58 = __toESM(require("fs/promises"));
27141
- var path62 = __toESM(require("path"));
27517
+ var fs59 = __toESM(require("fs/promises"));
27518
+ var path63 = __toESM(require("path"));
27142
27519
  async function collectRepoChangeset(opts) {
27143
27520
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
27144
27521
  if (status2 === null) return null;
@@ -27156,7 +27533,7 @@ async function collectRepoChangeset(opts) {
27156
27533
  let stats;
27157
27534
  if (row.fileStatus === "added" && numstatEntry === void 0) {
27158
27535
  const lineCount = await readUntrackedLineCount(
27159
- path62.join(opts.repoRoot, row.filePath)
27536
+ path63.join(opts.repoRoot, row.filePath)
27160
27537
  );
27161
27538
  stats = { added: lineCount, removed: 0 };
27162
27539
  } else {
@@ -27187,7 +27564,7 @@ function readUntrackedLineCount(absPath) {
27187
27564
  }
27188
27565
  async function defaultReadUntrackedLineCount(absPath) {
27189
27566
  try {
27190
- const content = await fs58.readFile(absPath, "utf8");
27567
+ const content = await fs59.readFile(absPath, "utf8");
27191
27568
  let count = 0;
27192
27569
  let pos = -1;
27193
27570
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -27279,7 +27656,7 @@ function defaultRunGit(cwd, args2) {
27279
27656
  });
27280
27657
  }
27281
27658
  async function discoverRepos(workingDir, maxDepth = 4) {
27282
- const fs63 = await import("fs/promises");
27659
+ const fs64 = await import("fs/promises");
27283
27660
  const out2 = [];
27284
27661
  await walk(workingDir, 0);
27285
27662
  return out2;
@@ -27287,7 +27664,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27287
27664
  if (depth > maxDepth) return;
27288
27665
  let entries = [];
27289
27666
  try {
27290
- const dirents = await fs63.readdir(dir, { withFileTypes: true });
27667
+ const dirents = await fs64.readdir(dir, { withFileTypes: true });
27291
27668
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
27292
27669
  } catch {
27293
27670
  return;
@@ -27298,8 +27675,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27298
27675
  if (hasGit) {
27299
27676
  out2.push({
27300
27677
  repoRoot: dir,
27301
- repoPath: path62.relative(workingDir, dir),
27302
- repoName: path62.basename(dir)
27678
+ repoPath: path63.relative(workingDir, dir),
27679
+ repoName: path63.basename(dir)
27303
27680
  });
27304
27681
  return;
27305
27682
  }
@@ -27307,15 +27684,15 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27307
27684
  if (!entry.isDirectory) continue;
27308
27685
  if (entry.name === "node_modules") continue;
27309
27686
  if (entry.name === "dist" || entry.name === "build") continue;
27310
- await walk(path62.join(dir, entry.name), depth + 1);
27687
+ await walk(path63.join(dir, entry.name), depth + 1);
27311
27688
  }
27312
27689
  }
27313
27690
  }
27314
27691
 
27315
27692
  // src/services/turn-files/files-outbox.ts
27316
- var fs59 = __toESM(require("fs/promises"));
27317
- var path63 = __toESM(require("path"));
27318
- var import_os9 = require("os");
27693
+ var fs60 = __toESM(require("fs/promises"));
27694
+ var path64 = __toESM(require("path"));
27695
+ var import_os12 = require("os");
27319
27696
  var HOME_OUTBOX_DIR = ".codeam/outbox";
27320
27697
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
27321
27698
  var BACKOFF_STEPS_MS = [
@@ -27347,16 +27724,16 @@ var FilesOutbox = class {
27347
27724
  backoffIndex = 0;
27348
27725
  stopped = false;
27349
27726
  constructor(opts) {
27350
- const base = opts.baseDir ?? path63.join(homeDir(), HOME_OUTBOX_DIR);
27351
- this.filePath = path63.join(base, `${opts.sessionId}.jsonl`);
27727
+ const base = opts.baseDir ?? path64.join(homeDir(), HOME_OUTBOX_DIR);
27728
+ this.filePath = path64.join(base, `${opts.sessionId}.jsonl`);
27352
27729
  this.post = opts.post;
27353
27730
  this.autoSchedule = opts.autoSchedule !== false;
27354
27731
  }
27355
27732
  /** Persist the entry to disk and trigger a flush. Returns once the
27356
27733
  * line is durable on disk (not once the POST succeeds). */
27357
27734
  async enqueue(entry) {
27358
- await fs59.mkdir(path63.dirname(this.filePath), { recursive: true });
27359
- await fs59.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
27735
+ await fs60.mkdir(path64.dirname(this.filePath), { recursive: true });
27736
+ await fs60.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
27360
27737
  this.backoffIndex = 0;
27361
27738
  if (this.autoSchedule) this.scheduleFlush(0);
27362
27739
  }
@@ -27445,7 +27822,7 @@ var FilesOutbox = class {
27445
27822
  async readAll() {
27446
27823
  let raw = "";
27447
27824
  try {
27448
- raw = await fs59.readFile(this.filePath, "utf8");
27825
+ raw = await fs60.readFile(this.filePath, "utf8");
27449
27826
  } catch {
27450
27827
  return [];
27451
27828
  }
@@ -27469,12 +27846,12 @@ var FilesOutbox = class {
27469
27846
  async rewrite(entries) {
27470
27847
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
27471
27848
  if (entries.length === 0) {
27472
- await fs59.unlink(this.filePath).catch(() => void 0);
27849
+ await fs60.unlink(this.filePath).catch(() => void 0);
27473
27850
  return;
27474
27851
  }
27475
27852
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
27476
- await fs59.writeFile(tmpPath, payload, "utf8");
27477
- await fs59.rename(tmpPath, this.filePath);
27853
+ await fs60.writeFile(tmpPath, payload, "utf8");
27854
+ await fs60.rename(tmpPath, this.filePath);
27478
27855
  }
27479
27856
  };
27480
27857
  function applyJitter(ms) {
@@ -27482,7 +27859,7 @@ function applyJitter(ms) {
27482
27859
  return Math.round(ms * factor);
27483
27860
  }
27484
27861
  function homeDir() {
27485
- return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os9.tmpdir)();
27862
+ return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os12.tmpdir)();
27486
27863
  }
27487
27864
 
27488
27865
  // src/services/turn-files/turn-file-aggregator.ts
@@ -30579,7 +30956,7 @@ var AcpDriver = class {
30579
30956
  };
30580
30957
 
30581
30958
  // src/baton/transcript-mirror.ts
30582
- var fs60 = __toESM(require("fs"));
30959
+ var fs61 = __toESM(require("fs"));
30583
30960
  var TranscriptMirror = class {
30584
30961
  constructor(deps) {
30585
30962
  this.deps = deps;
@@ -30646,7 +31023,7 @@ var TranscriptMirror = class {
30646
31023
  }
30647
31024
  };
30648
31025
  function defaultWatch(file, onChange) {
30649
- const w3 = fs60.watch(file, { persistent: false }, () => onChange());
31026
+ const w3 = fs61.watch(file, { persistent: false }, () => onChange());
30650
31027
  return () => w3.close();
30651
31028
  }
30652
31029
 
@@ -30898,15 +31275,15 @@ function toEpochMs(ts) {
30898
31275
  }
30899
31276
 
30900
31277
  // src/agents/claude/onboarding.ts
30901
- var fs61 = __toESM(require("fs"));
30902
- var os47 = __toESM(require("os"));
30903
- var path64 = __toESM(require("path"));
31278
+ var fs62 = __toESM(require("fs"));
31279
+ var os48 = __toESM(require("os"));
31280
+ var path65 = __toESM(require("path"));
30904
31281
  function ensureClaudeOnboarded() {
30905
31282
  try {
30906
- const file = path64.join(os47.homedir(), ".claude.json");
31283
+ const file = path65.join(os48.homedir(), ".claude.json");
30907
31284
  let config = {};
30908
31285
  try {
30909
- config = JSON.parse(fs61.readFileSync(file, "utf8"));
31286
+ config = JSON.parse(fs62.readFileSync(file, "utf8"));
30910
31287
  } catch {
30911
31288
  }
30912
31289
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -30917,8 +31294,8 @@ function ensureClaudeOnboarded() {
30917
31294
  if (typeof config.lastOnboardingVersion !== "string") {
30918
31295
  config.lastOnboardingVersion = "2.1.177";
30919
31296
  }
30920
- fs61.mkdirSync(path64.dirname(file), { recursive: true });
30921
- fs61.writeFileSync(file, JSON.stringify(config, null, 2));
31297
+ fs62.mkdirSync(path65.dirname(file), { recursive: true });
31298
+ fs62.writeFileSync(file, JSON.stringify(config, null, 2));
30922
31299
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
30923
31300
  } catch (err) {
30924
31301
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -31592,7 +31969,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
31592
31969
  var import_child_process28 = require("child_process");
31593
31970
  var import_util4 = require("util");
31594
31971
  var import_picocolors9 = __toESM(require("picocolors"));
31595
- var path65 = __toESM(require("path"));
31972
+ var path66 = __toESM(require("path"));
31596
31973
  var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
31597
31974
  var MAX_BUFFER = 8 * 1024 * 1024;
31598
31975
  function resetStdinForChild() {
@@ -32081,7 +32458,7 @@ var GitHubCodespacesProvider = class {
32081
32458
  });
32082
32459
  }
32083
32460
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32084
- const remoteDir = path65.posix.dirname(remotePath);
32461
+ const remoteDir = path66.posix.dirname(remotePath);
32085
32462
  const parts = [
32086
32463
  `mkdir -p ${shellQuote(remoteDir)}`,
32087
32464
  `cat > ${shellQuote(remotePath)}`
@@ -32151,7 +32528,7 @@ function shellQuote(s) {
32151
32528
  // src/services/providers/gitpod.ts
32152
32529
  var import_child_process29 = require("child_process");
32153
32530
  var import_util5 = require("util");
32154
- var path66 = __toESM(require("path"));
32531
+ var path67 = __toESM(require("path"));
32155
32532
  var import_picocolors10 = __toESM(require("picocolors"));
32156
32533
  var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
32157
32534
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -32391,7 +32768,7 @@ var GitpodProvider = class {
32391
32768
  });
32392
32769
  }
32393
32770
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32394
- const remoteDir = path66.posix.dirname(remotePath);
32771
+ const remoteDir = path67.posix.dirname(remotePath);
32395
32772
  const parts = [
32396
32773
  `mkdir -p ${shellQuote2(remoteDir)}`,
32397
32774
  `cat > ${shellQuote2(remotePath)}`
@@ -32427,7 +32804,7 @@ function shellQuote2(s) {
32427
32804
  // src/services/providers/gitlab-workspaces.ts
32428
32805
  var import_child_process30 = require("child_process");
32429
32806
  var import_util6 = require("util");
32430
- var path67 = __toESM(require("path"));
32807
+ var path68 = __toESM(require("path"));
32431
32808
  var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
32432
32809
  var MAX_BUFFER3 = 8 * 1024 * 1024;
32433
32810
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -32687,7 +33064,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
32687
33064
  }
32688
33065
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32689
33066
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
32690
- const remoteDir = path67.posix.dirname(remotePath);
33067
+ const remoteDir = path68.posix.dirname(remotePath);
32691
33068
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
32692
33069
  if (options.mode != null) {
32693
33070
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -32755,7 +33132,7 @@ function shellQuote3(s) {
32755
33132
  // src/services/providers/railway.ts
32756
33133
  var import_child_process31 = require("child_process");
32757
33134
  var import_util7 = require("util");
32758
- var path68 = __toESM(require("path"));
33135
+ var path69 = __toESM(require("path"));
32759
33136
  var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
32760
33137
  var MAX_BUFFER4 = 8 * 1024 * 1024;
32761
33138
  function resetStdinForChild4() {
@@ -32991,7 +33368,7 @@ var RailwayProvider = class {
32991
33368
  if (!projectId || !serviceId) {
32992
33369
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
32993
33370
  }
32994
- const remoteDir = path68.posix.dirname(remotePath);
33371
+ const remoteDir = path69.posix.dirname(remotePath);
32995
33372
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
32996
33373
  if (options.mode != null) {
32997
33374
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -33637,8 +34014,8 @@ async function invite() {
33637
34014
  var import_node_dns = require("dns");
33638
34015
  var import_node_util5 = require("util");
33639
34016
  var import_node_crypto12 = require("crypto");
33640
- var fs62 = __toESM(require("fs"));
33641
- var path69 = __toESM(require("path"));
34017
+ var fs63 = __toESM(require("fs"));
34018
+ var path70 = __toESM(require("path"));
33642
34019
  var import_picocolors14 = __toESM(require("picocolors"));
33643
34020
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
33644
34021
  async function checkDns(apiBase2) {
@@ -33694,13 +34071,13 @@ async function checkHealth(apiBase2) {
33694
34071
  }
33695
34072
  }
33696
34073
  function checkConfigDir() {
33697
- const dir = path69.join(require("os").homedir(), ".codeam");
34074
+ const dir = path70.join(require("os").homedir(), ".codeam");
33698
34075
  try {
33699
- fs62.mkdirSync(dir, { recursive: true, mode: 448 });
33700
- const probe = path69.join(dir, ".doctor-probe");
33701
- fs62.writeFileSync(probe, "ok", { mode: 384 });
33702
- const read2 = fs62.readFileSync(probe, "utf8");
33703
- fs62.unlinkSync(probe);
34076
+ fs63.mkdirSync(dir, { recursive: true, mode: 448 });
34077
+ const probe = path70.join(dir, ".doctor-probe");
34078
+ fs63.writeFileSync(probe, "ok", { mode: 384 });
34079
+ const read2 = fs63.readFileSync(probe, "utf8");
34080
+ fs63.unlinkSync(probe);
33704
34081
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
33705
34082
  return {
33706
34083
  id: "config-dir",
@@ -33740,9 +34117,9 @@ function checkSessions() {
33740
34117
  }
33741
34118
  }
33742
34119
  function checkAgentBinaries() {
33743
- const os49 = createOsStrategy();
34120
+ const os50 = createOsStrategy();
33744
34121
  return getEnabledAgents().map((meta) => {
33745
- const found = os49.findInPath(meta.binaryName);
34122
+ const found = os50.findInPath(meta.binaryName);
33746
34123
  return {
33747
34124
  id: `agent-${meta.id}`,
33748
34125
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -33764,7 +34141,7 @@ function checkNodePty() {
33764
34141
  detail: "not required on this platform"
33765
34142
  };
33766
34143
  }
33767
- const vendoredPath = path69.join(__dirname, "vendor", "node-pty");
34144
+ const vendoredPath = path70.join(__dirname, "vendor", "node-pty");
33768
34145
  for (const target of [vendoredPath, "node-pty"]) {
33769
34146
  try {
33770
34147
  require(target);
@@ -33806,7 +34183,7 @@ function checkChokidar() {
33806
34183
  }
33807
34184
  async function doctor(args2 = []) {
33808
34185
  const json = args2.includes("--json");
33809
- const cliVersion = true ? "2.60.23" : "0.0.0-dev";
34186
+ const cliVersion = true ? "2.60.25" : "0.0.0-dev";
33810
34187
  const apiBase2 = resolveApiBaseUrl();
33811
34188
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
33812
34189
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -34005,7 +34382,7 @@ async function completion(args2) {
34005
34382
  // src/commands/version.ts
34006
34383
  var import_picocolors15 = __toESM(require("picocolors"));
34007
34384
  function version2() {
34008
- const v = true ? "2.60.23" : "unknown";
34385
+ const v = true ? "2.60.25" : "unknown";
34009
34386
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
34010
34387
  }
34011
34388
 
@@ -34154,10 +34531,10 @@ var EXIT_CODE_NAMES = {
34154
34531
  };
34155
34532
 
34156
34533
  // src/index.ts
34157
- var os48 = __toESM(require("os"));
34534
+ var os49 = __toESM(require("os"));
34158
34535
  if (!process.env.HOME) {
34159
34536
  try {
34160
- const home = os48.homedir();
34537
+ const home = os49.homedir();
34161
34538
  if (home) process.env.HOME = home;
34162
34539
  } catch {
34163
34540
  }