codeam-cli 2.60.23 → 2.60.24

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 +798 -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.24" : "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.24",
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.24" ? { ideVersion: "2.60.24" } : {}
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_process22 = 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,9 @@ 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"));
15782
16059
  var PUBLIC_TO_INTERNAL_AGENT = {
15783
16060
  claude_code: "claude",
15784
16061
  claude: "claude",
@@ -15794,22 +16071,22 @@ function toInternalAgentId(publicAgentId) {
15794
16071
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
15795
16072
  }
15796
16073
  function ensureDir(dir) {
15797
- fs34.mkdirSync(dir, { recursive: true, mode: 448 });
16074
+ fs35.mkdirSync(dir, { recursive: true, mode: 448 });
15798
16075
  }
15799
16076
  function writeFile0600(filePath, contents) {
15800
- ensureDir(path37.dirname(filePath));
15801
- fs34.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
16077
+ ensureDir(path38.dirname(filePath));
16078
+ fs35.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
15802
16079
  restrictToOwner(filePath);
15803
16080
  }
15804
16081
  function rmIfExists(filePath) {
15805
16082
  try {
15806
- fs34.rmSync(filePath, { force: true });
16083
+ fs35.rmSync(filePath, { force: true });
15807
16084
  } catch {
15808
16085
  }
15809
16086
  }
15810
16087
  var claudeProvisioner = {
15811
16088
  write(auth, home) {
15812
- const credentialsJson = path37.join(home, ".claude", ".credentials.json");
16089
+ const credentialsJson = path38.join(home, ".claude", ".credentials.json");
15813
16090
  if (auth.kind === "api_key") {
15814
16091
  rmIfExists(credentialsJson);
15815
16092
  return { ANTHROPIC_API_KEY: auth.value };
@@ -15821,8 +16098,8 @@ var claudeProvisioner = {
15821
16098
  } else {
15822
16099
  rmIfExists(credentialsJson);
15823
16100
  }
15824
- const claudeJson = path37.join(home, ".claude.json");
15825
- if (!fs34.existsSync(claudeJson)) {
16101
+ const claudeJson = path38.join(home, ".claude.json");
16102
+ if (!fs35.existsSync(claudeJson)) {
15826
16103
  writeFile0600(
15827
16104
  claudeJson,
15828
16105
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -15833,7 +16110,7 @@ var claudeProvisioner = {
15833
16110
  };
15834
16111
  var codexProvisioner = {
15835
16112
  write(auth, home) {
15836
- const authJson = path37.join(home, ".codex", "auth.json");
16113
+ const authJson = path38.join(home, ".codex", "auth.json");
15837
16114
  if (auth.kind === "api_key") {
15838
16115
  rmIfExists(authJson);
15839
16116
  return { OPENAI_API_KEY: auth.value };
@@ -15844,8 +16121,8 @@ var codexProvisioner = {
15844
16121
  };
15845
16122
  var geminiProvisioner = {
15846
16123
  write(auth, home) {
15847
- const settingsJson = path37.join(home, ".gemini", "settings.json");
15848
- const oauthCreds = path37.join(home, ".gemini", "oauth_creds.json");
16124
+ const settingsJson = path38.join(home, ".gemini", "settings.json");
16125
+ const oauthCreds = path38.join(home, ".gemini", "oauth_creds.json");
15849
16126
  if (auth.kind === "api_key") {
15850
16127
  rmIfExists(oauthCreds);
15851
16128
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -15858,7 +16135,7 @@ var geminiProvisioner = {
15858
16135
  };
15859
16136
  var cursorProvisioner = {
15860
16137
  write(auth, home) {
15861
- const authJson = path37.join(home, ".config", "cursor", "auth.json");
16138
+ const authJson = path38.join(home, ".config", "cursor", "auth.json");
15862
16139
  if (auth.kind === "api_key") {
15863
16140
  rmIfExists(authJson);
15864
16141
  return { CURSOR_API_KEY: auth.value };
@@ -15884,8 +16161,8 @@ var cursorProvisioner = {
15884
16161
  var kimiProvisioner = {
15885
16162
  write(auth, home) {
15886
16163
  const credentialsFiles = [
15887
- path37.join(home, ".kimi", "credentials", "kimi-code.json"),
15888
- path37.join(home, ".kimi-code", "credentials", "kimi-code.json")
16164
+ path38.join(home, ".kimi", "credentials", "kimi-code.json"),
16165
+ path38.join(home, ".kimi-code", "credentials", "kimi-code.json")
15889
16166
  ];
15890
16167
  if (auth.kind === "api_key") {
15891
16168
  credentialsFiles.forEach(rmIfExists);
@@ -15895,12 +16172,38 @@ var kimiProvisioner = {
15895
16172
  return {};
15896
16173
  }
15897
16174
  };
16175
+ var coderabbitProvisioner = {
16176
+ write(auth, home) {
16177
+ const dir = path38.join(home, ".coderabbit");
16178
+ const authJson = path38.join(dir, "auth.json");
16179
+ if (auth.kind === "api_key") {
16180
+ rmIfExists(authJson);
16181
+ return { CODERABBIT_API_KEY: auth.value };
16182
+ }
16183
+ const value = auth.value.trim();
16184
+ let file = "auth.json";
16185
+ let contents = value;
16186
+ if (value.startsWith("{")) {
16187
+ try {
16188
+ const parsed = JSON.parse(value);
16189
+ if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
16190
+ file = path38.basename(parsed.file);
16191
+ contents = parsed.contents;
16192
+ }
16193
+ } catch {
16194
+ }
16195
+ }
16196
+ writeFile0600(path38.join(dir, file), contents);
16197
+ return {};
16198
+ }
16199
+ };
15898
16200
  var PROVISIONERS = {
15899
16201
  claude: claudeProvisioner,
15900
16202
  kimi: kimiProvisioner,
15901
16203
  codex: codexProvisioner,
15902
16204
  gemini: geminiProvisioner,
15903
- cursor: cursorProvisioner
16205
+ cursor: cursorProvisioner,
16206
+ coderabbit: coderabbitProvisioner
15904
16207
  };
15905
16208
  var UnsupportedAgentError = class extends Error {
15906
16209
  agentId;
@@ -15910,7 +16213,7 @@ var UnsupportedAgentError = class extends Error {
15910
16213
  this.agentId = agentId;
15911
16214
  }
15912
16215
  };
15913
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir()) {
16216
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os31.homedir()) {
15914
16217
  const internal = toInternalAgentId(publicAgentId);
15915
16218
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
15916
16219
  const provisioner = PROVISIONERS[internal];
@@ -15919,12 +16222,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
15919
16222
  }
15920
16223
 
15921
16224
  // 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"));
16225
+ var import_node_child_process17 = require("child_process");
16226
+ var fs36 = __toESM(require("fs"));
16227
+ var os32 = __toESM(require("os"));
16228
+ var path39 = __toESM(require("path"));
15926
16229
  function codeamBinDir() {
15927
- return process.env.CODEAM_BIN_DIR ?? path38.join(os31.homedir(), ".codeam", "bin");
16230
+ return process.env.CODEAM_BIN_DIR ?? path39.join(os32.homedir(), ".codeam", "bin");
15928
16231
  }
15929
16232
  var FALLBACK_GH_VERSION = "2.62.0";
15930
16233
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -15956,7 +16259,7 @@ async function download(url, dest) {
15956
16259
  const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
15957
16260
  if (!res.ok || !res.body) return false;
15958
16261
  const buf = Buffer.from(await res.arrayBuffer());
15959
- fs35.writeFileSync(dest, buf);
16262
+ fs36.writeFileSync(dest, buf);
15960
16263
  return true;
15961
16264
  } catch {
15962
16265
  return false;
@@ -15979,8 +16282,8 @@ async function ensureGhCli(runner, token, deps = {}) {
15979
16282
  const version3 = await resolveVersionFn(token);
15980
16283
  const asset = `gh_${version3}_${osToken}_${arch2}`;
15981
16284
  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}`);
16285
+ const tmpRoot = fs36.mkdtempSync(path39.join(os32.tmpdir(), "codeam-gh-"));
16286
+ const archive = path39.join(tmpRoot, `${asset}.${ext}`);
15984
16287
  if (!await downloadFn(url, archive)) {
15985
16288
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
15986
16289
  return null;
@@ -15990,16 +16293,16 @@ async function ensureGhCli(runner, token, deps = {}) {
15990
16293
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
15991
16294
  return null;
15992
16295
  }
15993
- const extractedBin = path38.join(tmpRoot, asset, "bin", binaryName);
15994
- if (!fs35.existsSync(extractedBin)) {
16296
+ const extractedBin = path39.join(tmpRoot, asset, "bin", binaryName);
16297
+ if (!fs36.existsSync(extractedBin)) {
15995
16298
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
15996
16299
  return null;
15997
16300
  }
15998
16301
  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);
16302
+ fs36.mkdirSync(binDir, { recursive: true });
16303
+ const target = path39.join(binDir, binaryName);
16304
+ fs36.copyFileSync(extractedBin, target);
16305
+ fs36.chmodSync(target, 493);
16003
16306
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
16004
16307
  return target;
16005
16308
  } catch (e) {
@@ -16033,7 +16336,7 @@ var defaultGitToolingRunner = {
16033
16336
  which(cmd) {
16034
16337
  try {
16035
16338
  const probe = process.platform === "win32" ? "where" : "which";
16036
- (0, import_node_child_process16.execFileSync)(probe, [cmd], { stdio: "ignore" });
16339
+ (0, import_node_child_process17.execFileSync)(probe, [cmd], { stdio: "ignore" });
16037
16340
  return true;
16038
16341
  } catch {
16039
16342
  return false;
@@ -16041,7 +16344,7 @@ var defaultGitToolingRunner = {
16041
16344
  },
16042
16345
  run(cmd, args2, opts = {}) {
16043
16346
  return new Promise((resolve7) => {
16044
- const child = (0, import_node_child_process16.spawn)(cmd, args2, {
16347
+ const child = (0, import_node_child_process17.spawn)(cmd, args2, {
16045
16348
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
16046
16349
  });
16047
16350
  let stderr = "";
@@ -16195,12 +16498,12 @@ var HeadroomStatsReporter = class {
16195
16498
  };
16196
16499
 
16197
16500
  // src/commands/host/os-packages.ts
16198
- var import_node_child_process17 = require("child_process");
16501
+ var import_node_child_process18 = require("child_process");
16199
16502
  var PM_INSTALL_TIMEOUT_MS = 18e4;
16200
16503
  var defaultHeadroomRunner = {
16201
16504
  which(cmd) {
16202
16505
  try {
16203
- (0, import_node_child_process17.execFileSync)("which", [cmd], { stdio: "ignore" });
16506
+ (0, import_node_child_process18.execFileSync)("which", [cmd], { stdio: "ignore" });
16204
16507
  return true;
16205
16508
  } catch {
16206
16509
  return false;
@@ -16209,7 +16512,7 @@ var defaultHeadroomRunner = {
16209
16512
  run(cmd, args2, opts = {}) {
16210
16513
  return new Promise((resolve7) => {
16211
16514
  const spawnEnv = opts.env ?? process.env;
16212
- const child = (0, import_node_child_process17.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
16515
+ const child = (0, import_node_child_process18.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
16213
16516
  let stderrBuf = "";
16214
16517
  let stdoutBuf = "";
16215
16518
  let settled = false;
@@ -16486,23 +16789,23 @@ async function ensureModernPython(runner) {
16486
16789
  }
16487
16790
 
16488
16791
  // src/commands/host/headroom-bootstrap.ts
16489
- var fs37 = __toESM(require("fs"));
16490
- var path40 = __toESM(require("path"));
16792
+ var fs38 = __toESM(require("fs"));
16793
+ var path41 = __toESM(require("path"));
16491
16794
 
16492
16795
  // src/commands/host/headroom-config.ts
16493
- var fs36 = __toESM(require("fs"));
16494
- var os32 = __toESM(require("os"));
16495
- var path39 = __toESM(require("path"));
16796
+ var fs37 = __toESM(require("fs"));
16797
+ var os33 = __toESM(require("os"));
16798
+ var path40 = __toESM(require("path"));
16496
16799
  function headroomConfigPath() {
16497
- return path39.join(os32.homedir(), ".codeam", "headroom-config.json");
16800
+ return path40.join(os33.homedir(), ".codeam", "headroom-config.json");
16498
16801
  }
16499
16802
  function persistHeadroomConfig(config) {
16500
16803
  try {
16501
16804
  const file = headroomConfigPath();
16502
- fs36.mkdirSync(path39.dirname(file), { recursive: true, mode: 448 });
16805
+ fs37.mkdirSync(path40.dirname(file), { recursive: true, mode: 448 });
16503
16806
  const tmp = `${file}.tmp-${process.pid}`;
16504
- fs36.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
16505
- fs36.renameSync(tmp, file);
16807
+ fs37.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
16808
+ fs37.renameSync(tmp, file);
16506
16809
  restrictToOwner(file);
16507
16810
  } catch (err) {
16508
16811
  log.warn(
@@ -16512,21 +16815,21 @@ function persistHeadroomConfig(config) {
16512
16815
  }
16513
16816
  }
16514
16817
  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");
16818
+ const home = os33.homedir();
16819
+ if (kind === "claude") return path40.join(home, ".claude", "settings.json");
16820
+ if (kind === "codex") return path40.join(home, ".codex", "auth.json");
16821
+ if (kind === "copilot") return path40.join(home, ".config", "github-copilot", "hosts.json");
16519
16822
  return null;
16520
16823
  }
16521
16824
  function backupAgentHeadroomConfig(kind) {
16522
16825
  const src = agentSettingsPath(kind);
16523
16826
  if (!src) return;
16524
16827
  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);
16828
+ if (!fs37.existsSync(src)) return;
16829
+ const dest = path40.join(os33.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16830
+ fs37.mkdirSync(path40.dirname(dest), { recursive: true, mode: 448 });
16831
+ fs37.copyFileSync(src, dest);
16832
+ fs37.chmodSync(dest, 384);
16530
16833
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
16531
16834
  } catch (err) {
16532
16835
  log.warn(
@@ -16538,12 +16841,12 @@ function backupAgentHeadroomConfig(kind) {
16538
16841
  function restoreAgentHeadroomConfig(kind) {
16539
16842
  const dest = agentSettingsPath(kind);
16540
16843
  if (!dest) return false;
16541
- const src = path39.join(os32.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16542
- if (!fs36.existsSync(src)) return false;
16844
+ const src = path40.join(os33.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16845
+ if (!fs37.existsSync(src)) return false;
16543
16846
  try {
16544
- fs36.mkdirSync(path39.dirname(dest), { recursive: true, mode: 448 });
16545
- fs36.copyFileSync(src, dest);
16546
- fs36.chmodSync(dest, 384);
16847
+ fs37.mkdirSync(path40.dirname(dest), { recursive: true, mode: 448 });
16848
+ fs37.copyFileSync(src, dest);
16849
+ fs37.chmodSync(dest, 384);
16547
16850
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
16548
16851
  return true;
16549
16852
  } catch (err) {
@@ -16556,7 +16859,7 @@ function restoreAgentHeadroomConfig(kind) {
16556
16859
  }
16557
16860
  function readHeadroomChildEnv() {
16558
16861
  try {
16559
- const raw = fs36.readFileSync(headroomConfigPath(), "utf8");
16862
+ const raw = fs37.readFileSync(headroomConfigPath(), "utf8");
16560
16863
  const parsed = JSON.parse(raw);
16561
16864
  if (typeof parsed !== "object" || parsed === null) return {};
16562
16865
  const o = parsed;
@@ -16592,37 +16895,37 @@ function bundledClaudeBinDir() {
16592
16895
  const roots = /* @__PURE__ */ new Set();
16593
16896
  let dir = __dirname;
16594
16897
  for (let i = 0; i < 6; i++) {
16595
- roots.add(path40.join(dir, "node_modules"));
16596
- const parent = path40.dirname(dir);
16898
+ roots.add(path41.join(dir, "node_modules"));
16899
+ const parent = path41.dirname(dir);
16597
16900
  if (parent === dir) break;
16598
16901
  dir = parent;
16599
16902
  }
16600
16903
  try {
16601
16904
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
16602
- const marker = `${path40.sep}@anthropic-ai${path40.sep}`;
16905
+ const marker = `${path41.sep}@anthropic-ai${path41.sep}`;
16603
16906
  const idx = main2.lastIndexOf(marker);
16604
16907
  if (idx !== -1) roots.add(main2.slice(0, idx));
16605
16908
  } catch {
16606
16909
  }
16607
16910
  for (const nm of roots) {
16608
- const atAnthropic = path40.join(nm, "@anthropic-ai");
16911
+ const atAnthropic = path41.join(nm, "@anthropic-ai");
16609
16912
  let entries;
16610
16913
  try {
16611
- entries = fs37.readdirSync(atAnthropic);
16914
+ entries = fs38.readdirSync(atAnthropic);
16612
16915
  } catch {
16613
16916
  continue;
16614
16917
  }
16615
16918
  for (const entry of entries) {
16616
16919
  if (!entry.startsWith("claude-agent-sdk-")) continue;
16617
- const bin = path40.join(atAnthropic, entry, "claude");
16618
- if (fs37.existsSync(bin)) return path40.dirname(bin);
16920
+ const bin = path41.join(atAnthropic, entry, "claude");
16921
+ if (fs38.existsSync(bin)) return path41.dirname(bin);
16619
16922
  }
16620
16923
  }
16621
16924
  return null;
16622
16925
  }
16623
16926
  async function getFreeDiskBytes(dir) {
16624
16927
  try {
16625
- const s = await fs37.promises.statfs(dir);
16928
+ const s = await fs38.promises.statfs(dir);
16626
16929
  return s.bsize * s.bavail;
16627
16930
  } catch {
16628
16931
  return null;
@@ -16684,7 +16987,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
16684
16987
  if (initKind === "claude") {
16685
16988
  const claudeDir = bundledClaudeBinDir();
16686
16989
  if (claudeDir) {
16687
- initEnv.PATH = `${claudeDir}${path40.delimiter}${process.env["PATH"] ?? ""}`;
16990
+ initEnv.PATH = `${claudeDir}${path41.delimiter}${process.env["PATH"] ?? ""}`;
16688
16991
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
16689
16992
  } else {
16690
16993
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -16716,26 +17019,26 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
16716
17019
  }
16717
17020
 
16718
17021
  // src/commands/host/self-update.ts
16719
- var import_node_child_process19 = require("child_process");
17022
+ var import_node_child_process20 = require("child_process");
16720
17023
 
16721
17024
  // src/lib/updateNotifier.ts
16722
- var fs38 = __toESM(require("fs"));
16723
- var os33 = __toESM(require("os"));
16724
- var path41 = __toESM(require("path"));
17025
+ var fs39 = __toESM(require("fs"));
17026
+ var os34 = __toESM(require("os"));
17027
+ var path42 = __toESM(require("path"));
16725
17028
  var https6 = __toESM(require("https"));
16726
- var import_node_child_process18 = require("child_process");
17029
+ var import_node_child_process19 = require("child_process");
16727
17030
  var import_picocolors3 = __toESM(require("picocolors"));
16728
17031
  var PKG_NAME = "codeam-cli";
16729
17032
  var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
16730
17033
  var TTL_MS = 24 * 60 * 60 * 1e3;
16731
17034
  var REQUEST_TIMEOUT_MS = 1500;
16732
17035
  function cachePath() {
16733
- const dir = path41.join(os33.homedir(), ".codeam");
16734
- return path41.join(dir, "update-check.json");
17036
+ const dir = path42.join(os34.homedir(), ".codeam");
17037
+ return path42.join(dir, "update-check.json");
16735
17038
  }
16736
17039
  function readCache() {
16737
17040
  try {
16738
- const raw = fs38.readFileSync(cachePath(), "utf8");
17041
+ const raw = fs39.readFileSync(cachePath(), "utf8");
16739
17042
  const parsed = JSON.parse(raw);
16740
17043
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
16741
17044
  return parsed;
@@ -16746,10 +17049,10 @@ function readCache() {
16746
17049
  function writeCache(cache) {
16747
17050
  try {
16748
17051
  const file = cachePath();
16749
- fs38.mkdirSync(path41.dirname(file), { recursive: true });
17052
+ fs39.mkdirSync(path42.dirname(file), { recursive: true });
16750
17053
  const tmp = `${file}.${process.pid}.tmp`;
16751
- fs38.writeFileSync(tmp, JSON.stringify(cache));
16752
- fs38.renameSync(tmp, file);
17054
+ fs39.writeFileSync(tmp, JSON.stringify(cache));
17055
+ fs39.renameSync(tmp, file);
16753
17056
  } catch {
16754
17057
  }
16755
17058
  }
@@ -16817,14 +17120,14 @@ function notifyIfStale(currentVersion, latest) {
16817
17120
  }
16818
17121
  function isLinkedInstall() {
16819
17122
  try {
16820
- const root = (0, import_node_child_process18.execSync)("npm root -g", {
17123
+ const root = (0, import_node_child_process19.execSync)("npm root -g", {
16821
17124
  encoding: "utf8",
16822
17125
  stdio: ["ignore", "pipe", "ignore"],
16823
17126
  timeout: 2e3
16824
17127
  }).trim();
16825
17128
  if (!root) return false;
16826
- const pkgPath = path41.join(root, PKG_NAME);
16827
- return fs38.lstatSync(pkgPath).isSymbolicLink();
17129
+ const pkgPath = path42.join(root, PKG_NAME);
17130
+ return fs39.lstatSync(pkgPath).isSymbolicLink();
16828
17131
  } catch {
16829
17132
  return false;
16830
17133
  }
@@ -16845,7 +17148,7 @@ function maybeAutoUpdate(currentVersion, latest) {
16845
17148
 
16846
17149
  `
16847
17150
  );
16848
- const install = (0, import_node_child_process18.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
17151
+ const install = (0, import_node_child_process19.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
16849
17152
  stdio: "inherit",
16850
17153
  env: process.env
16851
17154
  });
@@ -16860,13 +17163,13 @@ function maybeAutoUpdate(currentVersion, latest) {
16860
17163
  return;
16861
17164
  }
16862
17165
  try {
16863
- fs38.unlinkSync(cachePath());
17166
+ fs39.unlinkSync(cachePath());
16864
17167
  } catch {
16865
17168
  }
16866
17169
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
16867
17170
 
16868
17171
  `);
16869
- const child = (0, import_node_child_process18.spawnSync)("codeam", process.argv.slice(2), {
17172
+ const child = (0, import_node_child_process19.spawnSync)("codeam", process.argv.slice(2), {
16870
17173
  stdio: "inherit",
16871
17174
  env: process.env
16872
17175
  });
@@ -16876,7 +17179,7 @@ async function autoUpgradeBeforeCriticalCommand() {
16876
17179
  if (process.env.NODE_ENV === "test") return;
16877
17180
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16878
17181
  if (process.env.CI) return;
16879
- const current = true ? "2.60.23" : null;
17182
+ const current = true ? "2.60.24" : null;
16880
17183
  if (!current) return;
16881
17184
  const cache = readCache();
16882
17185
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16893,7 +17196,7 @@ function checkForUpdates() {
16893
17196
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16894
17197
  if (process.env.CI) return;
16895
17198
  if (!process.stdout.isTTY) return;
16896
- const current = true ? "2.60.23" : null;
17199
+ const current = true ? "2.60.24" : null;
16897
17200
  if (!current) return;
16898
17201
  const cache = readCache();
16899
17202
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16913,11 +17216,11 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
16913
17216
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
16914
17217
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
16915
17218
  function currentCliVersion() {
16916
- return true ? "2.60.23" : null;
17219
+ return true ? "2.60.24" : null;
16917
17220
  }
16918
17221
  function runCmd(cmd, args2, timeoutMs) {
16919
17222
  return new Promise((resolve7) => {
16920
- (0, import_node_child_process19.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
17223
+ (0, import_node_child_process20.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
16921
17224
  const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
16922
17225
  resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
16923
17226
  });
@@ -16979,19 +17282,19 @@ async function runSelfUpdate() {
16979
17282
  }
16980
17283
 
16981
17284
  // src/commands/host/teardown.ts
16982
- var import_node_child_process20 = require("child_process");
16983
- var fs39 = __toESM(require("fs"));
17285
+ var import_node_child_process21 = require("child_process");
17286
+ var fs40 = __toESM(require("fs"));
16984
17287
  var defaultDisableService = () => {
16985
17288
  try {
16986
- (0, import_node_child_process20.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
17289
+ (0, import_node_child_process21.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
16987
17290
  } catch {
16988
17291
  }
16989
17292
  };
16990
17293
  var defaultTeardownHeadroom = () => {
16991
17294
  try {
16992
- const kind = JSON.parse(fs39.readFileSync(headroomConfigPath(), "utf8")).agent;
17295
+ const kind = JSON.parse(fs40.readFileSync(headroomConfigPath(), "utf8")).agent;
16993
17296
  if (kind) {
16994
- (0, import_node_child_process20.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
17297
+ (0, import_node_child_process21.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
16995
17298
  }
16996
17299
  } catch {
16997
17300
  }
@@ -17057,8 +17360,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
17057
17360
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
17058
17361
  try {
17059
17362
  const file = headroomConfigPath();
17060
- if (!fs40.existsSync(file)) return null;
17061
- const cfg = JSON.parse(fs40.readFileSync(file, "utf8"));
17363
+ if (!fs41.existsSync(file)) return null;
17364
+ const cfg = JSON.parse(fs41.readFileSync(file, "utf8"));
17062
17365
  if (!cfg?.enabled) return null;
17063
17366
  const agent = cfg.agent ?? "claude";
17064
17367
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -17149,7 +17452,7 @@ var CONTROL_AGENT_META = {
17149
17452
  headroomWrappable: false,
17150
17453
  acp: false
17151
17454
  };
17152
- var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process21.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
17455
+ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process22.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
17153
17456
  cwd,
17154
17457
  env: { ...process.env, ...env },
17155
17458
  stdio: ["ignore", "pipe", "pipe"],
@@ -17463,9 +17766,9 @@ var HostAgentSupervisor = class {
17463
17766
  API_TIMEOUT_MS: "3000000",
17464
17767
  CODEAM_AUTO_TOKEN: payload.autoPairToken
17465
17768
  };
17466
- const houseConfigDir = path42.join(os34.homedir(), ".codeam", "house-claude");
17769
+ const houseConfigDir = path43.join(os35.homedir(), ".codeam", "house-claude");
17467
17770
  try {
17468
- fs40.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
17771
+ fs41.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
17469
17772
  } catch {
17470
17773
  }
17471
17774
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -17483,14 +17786,14 @@ var HostAgentSupervisor = class {
17483
17786
  report("installing", "installing agent CLI");
17484
17787
  await this.runAgentInstall(payload.agentInstallScript);
17485
17788
  }
17486
- const home = process.env.HOME || os34.homedir();
17789
+ const home = process.env.HOME || os35.homedir();
17487
17790
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
17488
17791
  if (payload.cloneToken) {
17489
17792
  try {
17490
17793
  report("preparing", "configuring git tooling");
17491
17794
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
17492
17795
  if (ghCmd) {
17493
- childEnv.PATH = `${codeamBinDir()}${path42.delimiter}${childEnv.PATH}`;
17796
+ childEnv.PATH = `${codeamBinDir()}${path43.delimiter}${childEnv.PATH}`;
17494
17797
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
17495
17798
  }
17496
17799
  } catch (e) {
@@ -17506,7 +17809,7 @@ var HostAgentSupervisor = class {
17506
17809
  }
17507
17810
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
17508
17811
  report("headroom", "setting up Headroom proxy");
17509
- const freeBytes = await this.getFreeDisk(os34.homedir());
17812
+ const freeBytes = await this.getFreeDisk(os35.homedir());
17510
17813
  const alreadyInstalled = this.isHeadroomInstalled();
17511
17814
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
17512
17815
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -17628,8 +17931,8 @@ var HostAgentSupervisor = class {
17628
17931
  */
17629
17932
  runAgentInstall(script) {
17630
17933
  return new Promise((resolve7) => {
17631
- const home = process.env.HOME || os34.homedir();
17632
- const child = (0, import_node_child_process21.spawn)("sh", ["-c", script], {
17934
+ const home = process.env.HOME || os35.homedir();
17935
+ const child = (0, import_node_child_process22.spawn)("sh", ["-c", script], {
17633
17936
  env: { ...process.env, HOME: home },
17634
17937
  stdio: ["ignore", "pipe", "pipe"]
17635
17938
  });
@@ -17812,9 +18115,9 @@ async function configureHeadroom(action, ctx, deps) {
17812
18115
  }
17813
18116
 
17814
18117
  // src/services/headroom/budget-relaunch.ts
17815
- var fs41 = __toESM(require("fs"));
17816
- var os35 = __toESM(require("os"));
17817
- var path43 = __toESM(require("path"));
18118
+ var fs42 = __toESM(require("fs"));
18119
+ var os36 = __toESM(require("os"));
18120
+ var path44 = __toESM(require("path"));
17818
18121
  var import_child_process13 = require("child_process");
17819
18122
  function amendDeploymentManifestBudget(manifest, budget) {
17820
18123
  const rawArgs = manifest.proxy_args ?? [];
@@ -17848,7 +18151,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
17848
18151
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
17849
18152
  }
17850
18153
  function findHeadroomDeployments(homeDir2, deps) {
17851
- const deployDir = path43.join(homeDir2, ".headroom", "deploy");
18154
+ const deployDir = path44.join(homeDir2, ".headroom", "deploy");
17852
18155
  let profiles;
17853
18156
  try {
17854
18157
  profiles = deps.readDir(deployDir);
@@ -17857,7 +18160,7 @@ function findHeadroomDeployments(homeDir2, deps) {
17857
18160
  }
17858
18161
  const results = [];
17859
18162
  for (const profile of profiles) {
17860
- const manifestPath = path43.join(deployDir, profile, "manifest.json");
18163
+ const manifestPath = path44.join(deployDir, profile, "manifest.json");
17861
18164
  let raw;
17862
18165
  try {
17863
18166
  raw = deps.readJson(manifestPath);
@@ -17889,8 +18192,8 @@ async function applyBudgetToHeadroom(budget, deps) {
17889
18192
  }
17890
18193
  function writeManifestReal(manifestPath, manifest) {
17891
18194
  const tmp = manifestPath + ".codeam.tmp";
17892
- fs41.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
17893
- fs41.renameSync(tmp, manifestPath);
18195
+ fs42.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
18196
+ fs42.renameSync(tmp, manifestPath);
17894
18197
  }
17895
18198
  function restartDeploymentReal(profile) {
17896
18199
  try {
@@ -17920,11 +18223,11 @@ function spawnProxyReal2(_budget) {
17920
18223
  });
17921
18224
  }
17922
18225
  function makeRealApplyBudgetDeps() {
17923
- const homeDir2 = os35.homedir();
18226
+ const homeDir2 = os36.homedir();
17924
18227
  return {
17925
18228
  findDeployments: () => findHeadroomDeployments(homeDir2, {
17926
- readDir: (dir) => fs41.readdirSync(dir),
17927
- readJson: (filePath) => JSON.parse(fs41.readFileSync(filePath, "utf8"))
18229
+ readDir: (dir) => fs42.readdirSync(dir),
18230
+ readJson: (filePath) => JSON.parse(fs42.readFileSync(filePath, "utf8"))
17928
18231
  }),
17929
18232
  writeManifest: writeManifestReal,
17930
18233
  restartDeployment: restartDeploymentReal,
@@ -17937,11 +18240,11 @@ function makeRealApplyBudgetDeps() {
17937
18240
  var import_child_process14 = require("child_process");
17938
18241
  var import_fs = require("fs");
17939
18242
  var import_promises = __toESM(require("fs/promises"));
17940
- var import_os7 = __toESM(require("os"));
18243
+ var import_os8 = __toESM(require("os"));
17941
18244
  var import_path4 = __toESM(require("path"));
17942
18245
  var import_promises2 = require("stream/promises");
17943
18246
  var import_which = __toESM(require("which"));
17944
- var CACHED_BINARY = import_path4.default.join(import_os7.default.homedir(), ".codeam", "bin", "cloudflared");
18247
+ var CACHED_BINARY = import_path4.default.join(import_os8.default.homedir(), ".codeam", "bin", "cloudflared");
17945
18248
  async function resolveCloudflared(opts = {}) {
17946
18249
  try {
17947
18250
  return await (0, import_which.default)("cloudflared");
@@ -18041,7 +18344,7 @@ function decodeTunnelToken(token) {
18041
18344
  }
18042
18345
  async function spawnNamedTunnel(bin, token, port) {
18043
18346
  const creds = decodeTunnelToken(token);
18044
- const credDir = import_path4.default.join(import_os7.default.homedir(), ".codeam");
18347
+ const credDir = import_path4.default.join(import_os8.default.homedir(), ".codeam");
18045
18348
  await import_promises.default.mkdir(credDir, { recursive: true });
18046
18349
  const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
18047
18350
  await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
@@ -18604,8 +18907,8 @@ function activePreviewSessionIds() {
18604
18907
 
18605
18908
  // src/services/preview/start-orchestrator.ts
18606
18909
  var import_child_process17 = require("child_process");
18607
- var fs46 = __toESM(require("fs"));
18608
- var path48 = __toESM(require("path"));
18910
+ var fs47 = __toESM(require("fs"));
18911
+ var path49 = __toESM(require("path"));
18609
18912
  var import_which2 = __toESM(require("which"));
18610
18913
  var INSTALL_TIMEOUT_MS = 5 * 6e4;
18611
18914
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -18672,8 +18975,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
18672
18975
  if (args2.length === 0) return detection;
18673
18976
  const binName = args2[0];
18674
18977
  if (binName.startsWith("-")) return detection;
18675
- const binPath = path48.join(cwd, "node_modules", ".bin", binName);
18676
- if (!fs46.existsSync(binPath)) return detection;
18978
+ const binPath = path49.join(cwd, "node_modules", ".bin", binName);
18979
+ if (!fs47.existsSync(binPath)) return detection;
18677
18980
  return {
18678
18981
  ...detection,
18679
18982
  command: binPath,
@@ -19023,9 +19326,9 @@ async function establishTunnel(ctx, dev) {
19023
19326
 
19024
19327
  // src/beads/bd-adapter.ts
19025
19328
  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"));
19329
+ var fs48 = __toESM(require("fs"));
19330
+ var os38 = __toESM(require("os"));
19331
+ var path50 = __toESM(require("path"));
19029
19332
  var BD_PACKAGE = "@beads/bd";
19030
19333
  function resolveBundledBdBinary() {
19031
19334
  return _resolveSeam.resolveBundled();
@@ -19037,11 +19340,11 @@ function _defaultResolveBundled() {
19037
19340
  } catch {
19038
19341
  return null;
19039
19342
  }
19040
- const binDir = path49.join(path49.dirname(pkgJsonPath), "bin");
19343
+ const binDir = path50.join(path50.dirname(pkgJsonPath), "bin");
19041
19344
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
19042
- const binaryPath = path49.join(binDir, binaryName);
19345
+ const binaryPath = path50.join(binDir, binaryName);
19043
19346
  try {
19044
- fs47.accessSync(binaryPath, fs47.constants.F_OK);
19347
+ fs48.accessSync(binaryPath, fs48.constants.F_OK);
19045
19348
  return binaryPath;
19046
19349
  } catch {
19047
19350
  return null;
@@ -19051,13 +19354,13 @@ function resolveBdOnPath() {
19051
19354
  return _resolveSeam.resolveOnPath();
19052
19355
  }
19053
19356
  function _defaultResolveOnPath() {
19054
- const dirs = (process.env.PATH ?? "").split(path49.delimiter).filter(Boolean);
19357
+ const dirs = (process.env.PATH ?? "").split(path50.delimiter).filter(Boolean);
19055
19358
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
19056
19359
  for (const dir of dirs) {
19057
19360
  for (const candidate of candidates) {
19058
- const full = path49.join(dir, candidate);
19361
+ const full = path50.join(dir, candidate);
19059
19362
  try {
19060
- fs47.accessSync(full, fs47.constants.F_OK);
19363
+ fs48.accessSync(full, fs48.constants.F_OK);
19061
19364
  return full;
19062
19365
  } catch {
19063
19366
  }
@@ -19142,7 +19445,7 @@ var BdAdapter = class {
19142
19445
  const env = { ...process.env };
19143
19446
  if (!env.HOME) {
19144
19447
  try {
19145
- const home = os37.homedir();
19448
+ const home = os38.homedir();
19146
19449
  if (home) env.HOME = home;
19147
19450
  } catch {
19148
19451
  }
@@ -19234,9 +19537,9 @@ function coerceIssue(row, projectKey) {
19234
19537
 
19235
19538
  // src/beads/provisioner.ts
19236
19539
  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"));
19540
+ var fs51 = __toESM(require("fs"));
19541
+ var os40 = __toESM(require("os"));
19542
+ var path53 = __toESM(require("path"));
19240
19543
 
19241
19544
  // src/beads/install-bd.ts
19242
19545
  var import_child_process19 = require("child_process");
@@ -19301,9 +19604,9 @@ async function installBd(platform3 = process.platform) {
19301
19604
 
19302
19605
  // src/beads/install-dolt.ts
19303
19606
  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"));
19607
+ var fs49 = __toESM(require("fs"));
19608
+ var os39 = __toESM(require("os"));
19609
+ var path51 = __toESM(require("path"));
19307
19610
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
19308
19611
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
19309
19612
  function resolveDoltInstallStrategy(platform3) {
@@ -19343,11 +19646,11 @@ function resolveDoltInstallStrategy(platform3) {
19343
19646
  }
19344
19647
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
19345
19648
  function doltPlatformTuple(platform3, arch2) {
19346
- const os49 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
19649
+ const os50 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
19347
19650
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
19348
19651
  if (!a) return null;
19349
- if (os49 === "windows" && a !== "amd64") return null;
19350
- return `${os49}-${a}`;
19652
+ if (os50 === "windows" && a !== "amd64") return null;
19653
+ return `${os50}-${a}`;
19351
19654
  }
19352
19655
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
19353
19656
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -19392,14 +19695,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
19392
19695
  return result;
19393
19696
  }
19394
19697
  var _doltPathSeam = {
19395
- homedir: () => os38.homedir(),
19698
+ homedir: () => os39.homedir(),
19396
19699
  getPath: () => process.env.PATH ?? "",
19397
19700
  setPath: (p2) => {
19398
19701
  process.env.PATH = p2;
19399
19702
  },
19400
19703
  exists: (p2) => {
19401
19704
  try {
19402
- fs48.accessSync(p2, fs48.constants.F_OK);
19705
+ fs49.accessSync(p2, fs49.constants.F_OK);
19403
19706
  return true;
19404
19707
  } catch {
19405
19708
  return false;
@@ -19410,7 +19713,7 @@ function doltBinaryNames(platform3) {
19410
19713
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
19411
19714
  }
19412
19715
  function knownDoltDirs(platform3) {
19413
- const P3 = platform3 === "win32" ? path50.win32 : path50.posix;
19716
+ const P3 = platform3 === "win32" ? path51.win32 : path51.posix;
19414
19717
  const home = _doltPathSeam.homedir();
19415
19718
  if (platform3 === "win32") {
19416
19719
  return [
@@ -19426,7 +19729,7 @@ function knownDoltDirs(platform3) {
19426
19729
  ].filter(Boolean);
19427
19730
  }
19428
19731
  function ensureDoltResolvable(platform3 = process.platform) {
19429
- const P3 = platform3 === "win32" ? path50.win32 : path50.posix;
19732
+ const P3 = platform3 === "win32" ? path51.win32 : path51.posix;
19430
19733
  const delim = platform3 === "win32" ? ";" : ":";
19431
19734
  const names = doltBinaryNames(platform3);
19432
19735
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -19562,8 +19865,8 @@ async function ensureSharedServer(adapter, options = {}) {
19562
19865
  // src/beads/project-key.ts
19563
19866
  var import_child_process21 = require("child_process");
19564
19867
  var crypto2 = __toESM(require("crypto"));
19565
- var fs49 = __toESM(require("fs"));
19566
- var path51 = __toESM(require("path"));
19868
+ var fs50 = __toESM(require("fs"));
19869
+ var path52 = __toESM(require("path"));
19567
19870
  function normalizeOrigin(raw) {
19568
19871
  const trimmed = raw.trim();
19569
19872
  if (!trimmed) return null;
@@ -19589,17 +19892,17 @@ function normalizeOrigin(raw) {
19589
19892
  return `${host2}/${pathPart}`;
19590
19893
  }
19591
19894
  function findRepoRoot(cwd) {
19592
- let dir = path51.resolve(cwd);
19895
+ let dir = path52.resolve(cwd);
19593
19896
  const seen = /* @__PURE__ */ new Set();
19594
19897
  for (let i = 0; i < 256; i++) {
19595
19898
  if (seen.has(dir)) return null;
19596
19899
  seen.add(dir);
19597
19900
  try {
19598
- const stat3 = fs49.statSync(path51.join(dir, ".git"), { throwIfNoEntry: false });
19901
+ const stat3 = fs50.statSync(path52.join(dir, ".git"), { throwIfNoEntry: false });
19599
19902
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
19600
19903
  } catch {
19601
19904
  }
19602
- const parent = path51.dirname(dir);
19905
+ const parent = path52.dirname(dir);
19603
19906
  if (parent === dir) return null;
19604
19907
  dir = parent;
19605
19908
  }
@@ -19610,7 +19913,7 @@ var _execSeam2 = {
19610
19913
  const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
19611
19914
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
19612
19915
  },
19613
- realpath: (p2) => fs49.realpathSync(p2)
19916
+ realpath: (p2) => fs50.realpathSync(p2)
19614
19917
  };
19615
19918
  function readOrigin(cwd) {
19616
19919
  try {
@@ -19639,7 +19942,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
19639
19942
  } catch {
19640
19943
  }
19641
19944
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
19642
- return { projectKey: `path:${hash}`, projectLabel: path51.basename(real) || "project" };
19945
+ return { projectKey: `path:${hash}`, projectLabel: path52.basename(real) || "project" };
19643
19946
  }
19644
19947
 
19645
19948
  // src/beads/project-prefix.ts
@@ -19684,17 +19987,17 @@ var _provisionSeam = {
19684
19987
  };
19685
19988
  var _linkSeam = {
19686
19989
  platform: () => process.platform,
19687
- homedir: () => os39.homedir(),
19990
+ homedir: () => os40.homedir(),
19688
19991
  isWritableDir: (dir) => {
19689
19992
  try {
19690
- fs50.accessSync(dir, fs50.constants.W_OK);
19993
+ fs51.accessSync(dir, fs51.constants.W_OK);
19691
19994
  return true;
19692
19995
  } catch {
19693
19996
  return false;
19694
19997
  }
19695
19998
  },
19696
19999
  ensureDir: (dir) => {
19697
- fs50.mkdirSync(dir, { recursive: true });
20000
+ fs51.mkdirSync(dir, { recursive: true });
19698
20001
  },
19699
20002
  /**
19700
20003
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -19715,9 +20018,9 @@ var _linkSeam = {
19715
20018
  * which `linkBdOntoPath` creates if missing.
19716
20019
  */
19717
20020
  cliBinDir: () => {
19718
- const pathDirs = (process.env.PATH ?? "").split(path52.delimiter).filter(Boolean);
20021
+ const pathDirs = (process.env.PATH ?? "").split(path53.delimiter).filter(Boolean);
19719
20022
  const home = _linkSeam.homedir();
19720
- const localBin = home ? path52.join(home, ".local", "bin") : null;
20023
+ const localBin = home ? path53.join(home, ".local", "bin") : null;
19721
20024
  if (localBin) {
19722
20025
  try {
19723
20026
  _linkSeam.ensureDir(localBin);
@@ -19727,16 +20030,16 @@ var _linkSeam = {
19727
20030
  const candidates = [];
19728
20031
  if (localBin) candidates.push(localBin);
19729
20032
  try {
19730
- candidates.push(path52.dirname(process.execPath));
20033
+ candidates.push(path53.dirname(process.execPath));
19731
20034
  } catch {
19732
20035
  }
19733
20036
  candidates.push("/usr/local/bin");
19734
20037
  const entry = process.argv[1];
19735
20038
  if (entry) {
19736
20039
  try {
19737
- candidates.push(path52.dirname(fs50.realpathSync(entry)));
20040
+ candidates.push(path53.dirname(fs51.realpathSync(entry)));
19738
20041
  } catch {
19739
- candidates.push(path52.dirname(entry));
20042
+ candidates.push(path53.dirname(entry));
19740
20043
  }
19741
20044
  }
19742
20045
  const onPathWritable = candidates.find(
@@ -19748,20 +20051,20 @@ var _linkSeam = {
19748
20051
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
19749
20052
  readlink: (linkPath) => {
19750
20053
  try {
19751
- return fs50.readlinkSync(linkPath);
20054
+ return fs51.readlinkSync(linkPath);
19752
20055
  } catch {
19753
20056
  return null;
19754
20057
  }
19755
20058
  },
19756
- unlink: (linkPath) => fs50.unlinkSync(linkPath),
19757
- symlink: (target, linkPath) => fs50.symlinkSync(target, linkPath)
20059
+ unlink: (linkPath) => fs51.unlinkSync(linkPath),
20060
+ symlink: (target, linkPath) => fs51.symlinkSync(target, linkPath)
19758
20061
  };
19759
20062
  function linkBdOntoPath(binaryPath) {
19760
20063
  if (_linkSeam.platform() === "win32") return;
19761
20064
  const binDir = _linkSeam.cliBinDir();
19762
20065
  if (!binDir) return;
19763
20066
  _linkSeam.ensureDir(binDir);
19764
- const linkPath = path52.join(binDir, "bd");
20067
+ const linkPath = path53.join(binDir, "bd");
19765
20068
  if (linkPath === binaryPath) return;
19766
20069
  const current = _linkSeam.readlink(linkPath);
19767
20070
  if (current === binaryPath) return;
@@ -19956,7 +20259,7 @@ function dedupeRecipes(agents) {
19956
20259
 
19957
20260
  // src/beads/watcher.ts
19958
20261
  var crypto4 = __toESM(require("crypto"));
19959
- var path53 = __toESM(require("path"));
20262
+ var path54 = __toESM(require("path"));
19960
20263
  var API_BASE6 = resolveApiBaseUrl();
19961
20264
  var DEBOUNCE_MS2 = 400;
19962
20265
  var ZERO_SUMMARY = {
@@ -19980,7 +20283,7 @@ var BeadsWatcher = class {
19980
20283
  constructor(opts) {
19981
20284
  this.opts = opts;
19982
20285
  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");
20286
+ this.feedPath = opts.feedPath ?? path54.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
19984
20287
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
19985
20288
  }
19986
20289
  opts;
@@ -20397,8 +20700,8 @@ function cleanupAttachmentTempFiles() {
20397
20700
  function saveFilesTemp(files) {
20398
20701
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
20399
20702
  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"));
20703
+ const tmpPath = path56.join(os42.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
20704
+ fs53.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
20402
20705
  pendingAttachmentFiles.add(tmpPath);
20403
20706
  return tmpPath;
20404
20707
  });
@@ -20610,9 +20913,9 @@ var listFiles = async (ctx, cmd, parsed) => {
20610
20913
  await ctx.relay.sendResult(cmd.id, "completed", result);
20611
20914
  };
20612
20915
  var envReadH = async (ctx, cmd) => {
20613
- const envPath = path55.join(process.cwd(), ".env");
20916
+ const envPath = path56.join(process.cwd(), ".env");
20614
20917
  try {
20615
- const raw = await fs52.promises.readFile(envPath, "utf8");
20918
+ const raw = await fs53.promises.readFile(envPath, "utf8");
20616
20919
  await ctx.relay.sendResult(cmd.id, "completed", {
20617
20920
  exists: true,
20618
20921
  vars: parseDotenv(raw)
@@ -20643,14 +20946,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
20643
20946
  }
20644
20947
  seen.add(v.key);
20645
20948
  }
20646
- const envPath = path55.join(process.cwd(), ".env");
20647
- const tmpPath = path55.join(process.cwd(), ".env.codeam.tmp");
20949
+ const envPath = path56.join(process.cwd(), ".env");
20950
+ const tmpPath = path56.join(process.cwd(), ".env.codeam.tmp");
20648
20951
  try {
20649
- await fs52.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
20650
- await fs52.promises.rename(tmpPath, envPath);
20952
+ await fs53.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
20953
+ await fs53.promises.rename(tmpPath, envPath);
20651
20954
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
20652
20955
  } catch (err) {
20653
- await fs52.promises.rm(tmpPath, { force: true }).catch(() => void 0);
20956
+ await fs53.promises.rm(tmpPath, { force: true }).catch(() => void 0);
20654
20957
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
20655
20958
  }
20656
20959
  };
@@ -20694,7 +20997,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20694
20997
  let configuredAgent = rawAgentId;
20695
20998
  if (!configuredAgent) {
20696
20999
  try {
20697
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21000
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20698
21001
  configuredAgent = raw.agent ?? "";
20699
21002
  } catch {
20700
21003
  }
@@ -20728,7 +21031,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20728
21031
  persist: persistHeadroomConfig,
20729
21032
  readEnabled: () => {
20730
21033
  try {
20731
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21034
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20732
21035
  return raw.enabled === true;
20733
21036
  } catch {
20734
21037
  return false;
@@ -20801,6 +21104,63 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20801
21104
  });
20802
21105
  await ctx.relay.sendResult(cmd.id, "completed", result);
20803
21106
  };
21107
+ var coderabbitConfigureH = async (ctx, cmd, parsed) => {
21108
+ const action = parsed.action ?? "status";
21109
+ const token = ctx.pluginAuthToken;
21110
+ let emitChain = Promise.resolve();
21111
+ const emit2 = (type, payload) => {
21112
+ if (!token) return;
21113
+ emitChain = emitChain.then(
21114
+ () => postCoderabbitEvent({
21115
+ sessionId: ctx.sessionId,
21116
+ pluginId: ctx.pluginId,
21117
+ pluginAuthToken: token,
21118
+ type,
21119
+ payload
21120
+ })
21121
+ );
21122
+ };
21123
+ const result = await configureCoderabbit(
21124
+ {
21125
+ action,
21126
+ apiKey: parsed.apiKey,
21127
+ review: { changeSet: parsed.changeSet, base: parsed.base, dir: parsed.reviewDir }
21128
+ },
21129
+ {
21130
+ onEvent: (e) => {
21131
+ if (e.kind === "awaiting_browser") {
21132
+ emit2("coderabbit_progress", {
21133
+ phase: "awaiting_browser",
21134
+ authUrl: e.authUrl,
21135
+ fallbackAuthUrl: e.fallbackAuthUrl
21136
+ });
21137
+ } else {
21138
+ emit2("coderabbit_progress", { phase: e.kind });
21139
+ }
21140
+ },
21141
+ uploadCredential: token ? async (method, credential) => {
21142
+ const r = await postLinkCredential({
21143
+ agentId: "coderabbit",
21144
+ sessionId: ctx.sessionId,
21145
+ pluginId: ctx.pluginId,
21146
+ pluginAuthToken: token,
21147
+ method,
21148
+ credential
21149
+ });
21150
+ return r.ok === true;
21151
+ } : void 0,
21152
+ runReview: (input) => new CoderabbitRuntimeStrategy(createOsStrategy()).runOneShot(input)
21153
+ }
21154
+ );
21155
+ emit2("coderabbit_status", {
21156
+ installed: result.installed,
21157
+ loggedIn: result.loggedIn,
21158
+ linked: result.linked ?? false,
21159
+ ...result.error ? { error: result.error } : {}
21160
+ });
21161
+ await emitChain;
21162
+ await ctx.relay.sendResult(cmd.id, result.error && action !== "review" ? "failed" : "completed", result);
21163
+ };
20804
21164
  var headroomBudgetH = async (ctx, cmd) => {
20805
21165
  const payload = cmd.payload;
20806
21166
  let rawAgentId = ctx.agentId || (typeof payload.agentId === "string" ? payload.agentId : "");
@@ -20817,7 +21177,7 @@ var headroomBudgetH = async (ctx, cmd) => {
20817
21177
  }
20818
21178
  let headroomActive = false;
20819
21179
  try {
20820
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21180
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20821
21181
  headroomActive = raw.enabled === true;
20822
21182
  } catch {
20823
21183
  }
@@ -20827,7 +21187,7 @@ var headroomBudgetH = async (ctx, cmd) => {
20827
21187
  }
20828
21188
  let existingConfig = { enabled: true };
20829
21189
  try {
20830
- existingConfig = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21190
+ existingConfig = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20831
21191
  } catch {
20832
21192
  }
20833
21193
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -20940,13 +21300,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
20940
21300
  function buildNpmInstallInvocation(opts) {
20941
21301
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
20942
21302
  const execPath = opts?.execPath ?? process.execPath;
20943
- const exists2 = opts?.existsSync ?? fs52.existsSync;
20944
- const normalized = entryScript.split(path55.sep).join("/");
21303
+ const exists2 = opts?.existsSync ?? fs53.existsSync;
21304
+ const normalized = entryScript.split(path56.sep).join("/");
20945
21305
  const marker = "/lib/node_modules/codeam-cli/";
20946
21306
  const markerIdx = normalized.indexOf(marker);
20947
21307
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
20948
- const siblingNpm = path55.join(
20949
- path55.dirname(execPath),
21308
+ const siblingNpm = path56.join(
21309
+ path56.dirname(execPath),
20950
21310
  process.platform === "win32" ? "npm.cmd" : "npm"
20951
21311
  );
20952
21312
  const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
@@ -21518,6 +21878,7 @@ var handlers = {
21518
21878
  take_control: takeControlH,
21519
21879
  handback: handbackH,
21520
21880
  headroom_configure: headroomConfigureH,
21881
+ coderabbit_configure: coderabbitConfigureH,
21521
21882
  headroom_budget: headroomBudgetH,
21522
21883
  beads_configure: beadsConfigureH,
21523
21884
  cli_self_update: cliSelfUpdateH()
@@ -21788,11 +22149,11 @@ function resolveTokenValue(args2) {
21788
22149
  }
21789
22150
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
21790
22151
  if (fileFlag) {
21791
- const path70 = fileFlag.slice("--token-file=".length);
22152
+ const path71 = fileFlag.slice("--token-file=".length);
21792
22153
  try {
21793
- const content = fs53.readFileSync(path70, "utf8").trim();
21794
- if (content.length === 0) fail(`--token-file ${path70} is empty`);
21795
- rmIfExistsQuiet(path70);
22154
+ const content = fs54.readFileSync(path71, "utf8").trim();
22155
+ if (content.length === 0) fail(`--token-file ${path71} is empty`);
22156
+ rmIfExistsQuiet(path71);
21796
22157
  return content;
21797
22158
  } catch (err) {
21798
22159
  fail(`Could not read --token-file: ${err.message}`);
@@ -21821,7 +22182,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
21821
22182
  pluginId,
21822
22183
  ideName: "codeam-cli (codespace)",
21823
22184
  ideVersion: process.env.npm_package_version ?? "unknown",
21824
- hostname: os42.hostname(),
22185
+ hostname: os43.hostname(),
21825
22186
  codespaceName: process.env.CODESPACE_NAME ?? "",
21826
22187
  // Current git branch of the codespace's working directory, so the
21827
22188
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -21882,7 +22243,7 @@ async function claim(token, pluginId, pluginSecretHash) {
21882
22243
  }
21883
22244
  }
21884
22245
  function pairAutoLockPath() {
21885
- return path56.join(os42.homedir(), ".codeam", "pair-auto.lock");
22246
+ return path57.join(os43.homedir(), ".codeam", "pair-auto.lock");
21886
22247
  }
21887
22248
  function isLivePairAuto(pid) {
21888
22249
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -21892,7 +22253,7 @@ function isLivePairAuto(pid) {
21892
22253
  if (e.code !== "EPERM") return false;
21893
22254
  }
21894
22255
  try {
21895
- return fs53.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
22256
+ return fs54.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
21896
22257
  } catch {
21897
22258
  return true;
21898
22259
  }
@@ -21902,24 +22263,24 @@ function isLiveCodeam(pid) {
21902
22263
  }
21903
22264
  function daemonLockPath(sessionId) {
21904
22265
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
21905
- return path56.join(os42.homedir(), ".codeam", `daemon-${safe}.lock`);
22266
+ return path57.join(os43.homedir(), ".codeam", `daemon-${safe}.lock`);
21906
22267
  }
21907
22268
  function acquireDaemonLock(sessionId) {
21908
22269
  const lockPath = daemonLockPath(sessionId);
21909
22270
  try {
21910
- fs53.mkdirSync(path56.dirname(lockPath), { recursive: true });
22271
+ fs54.mkdirSync(path57.dirname(lockPath), { recursive: true });
21911
22272
  try {
21912
- fs53.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
22273
+ fs54.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21913
22274
  } catch (e) {
21914
22275
  if (e.code !== "EEXIST") throw e;
21915
- const holder = Number(fs53.readFileSync(lockPath, "utf8").trim());
22276
+ const holder = Number(fs54.readFileSync(lockPath, "utf8").trim());
21916
22277
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
21917
- fs53.writeFileSync(lockPath, String(process.pid));
22278
+ fs54.writeFileSync(lockPath, String(process.pid));
21918
22279
  }
21919
22280
  const release3 = () => {
21920
22281
  try {
21921
- if (fs53.existsSync(lockPath) && Number(fs53.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21922
- fs53.unlinkSync(lockPath);
22282
+ if (fs54.existsSync(lockPath) && Number(fs54.readFileSync(lockPath, "utf8").trim()) === process.pid) {
22283
+ fs54.unlinkSync(lockPath);
21923
22284
  }
21924
22285
  } catch {
21925
22286
  }
@@ -21941,19 +22302,19 @@ function acquireDaemonLock(sessionId) {
21941
22302
  function acquireSingletonLock() {
21942
22303
  const lockPath = pairAutoLockPath();
21943
22304
  try {
21944
- fs53.mkdirSync(path56.dirname(lockPath), { recursive: true });
22305
+ fs54.mkdirSync(path57.dirname(lockPath), { recursive: true });
21945
22306
  try {
21946
- fs53.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
22307
+ fs54.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21947
22308
  } catch (e) {
21948
22309
  if (e.code !== "EEXIST") throw e;
21949
- const holder = Number(fs53.readFileSync(lockPath, "utf8").trim());
22310
+ const holder = Number(fs54.readFileSync(lockPath, "utf8").trim());
21950
22311
  if (isLivePairAuto(holder)) return false;
21951
- fs53.writeFileSync(lockPath, String(process.pid));
22312
+ fs54.writeFileSync(lockPath, String(process.pid));
21952
22313
  }
21953
22314
  process.once("exit", () => {
21954
22315
  try {
21955
- if (fs53.existsSync(lockPath) && Number(fs53.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21956
- fs53.unlinkSync(lockPath);
22316
+ if (fs54.existsSync(lockPath) && Number(fs54.readFileSync(lockPath, "utf8").trim()) === process.pid) {
22317
+ fs54.unlinkSync(lockPath);
21957
22318
  }
21958
22319
  } catch {
21959
22320
  }
@@ -22035,7 +22396,7 @@ async function pairAuto(args2) {
22035
22396
  }
22036
22397
 
22037
22398
  // src/services/headroom/wrap-launch.ts
22038
- var import_node_child_process22 = require("child_process");
22399
+ var import_node_child_process23 = require("child_process");
22039
22400
  function wrapWithHeadroom(launch, opts) {
22040
22401
  if (!opts.enabled || !opts.headroomPresent) return launch;
22041
22402
  return {
@@ -22048,7 +22409,7 @@ var _present;
22048
22409
  function headroomPresent() {
22049
22410
  if (_present !== void 0) return Promise.resolve(_present);
22050
22411
  return new Promise((resolve7) => {
22051
- (0, import_node_child_process22.execFile)("headroom", ["--version"], (err) => {
22412
+ (0, import_node_child_process23.execFile)("headroom", ["--version"], (err) => {
22052
22413
  _present = !err;
22053
22414
  resolve7(_present);
22054
22415
  });
@@ -22398,11 +22759,11 @@ var AgentService = class _AgentService {
22398
22759
  };
22399
22760
 
22400
22761
  // src/agents/acp/adapters.ts
22401
- var path58 = __toESM(require("path"));
22762
+ var path59 = __toESM(require("path"));
22402
22763
 
22403
22764
  // src/agents/acp/agent-binary.ts
22404
22765
  var import_fs4 = __toESM(require("fs"));
22405
- var import_os8 = __toESM(require("os"));
22766
+ var import_os10 = __toESM(require("os"));
22406
22767
  var import_path8 = __toESM(require("path"));
22407
22768
  var import_child_process25 = require("child_process");
22408
22769
  function currentPlatformKey() {
@@ -22498,7 +22859,7 @@ function resolveCursorAgentBinary(deps = {}) {
22498
22859
  const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
22499
22860
  return existsSync26(exe) ? exe : null;
22500
22861
  }
22501
- const home = deps.homedir ?? import_os8.default.homedir();
22862
+ const home = deps.homedir ?? import_os10.default.homedir();
22502
22863
  const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
22503
22864
  return existsSync26(unix) ? unix : null;
22504
22865
  }
@@ -22572,7 +22933,7 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
22572
22933
  }
22573
22934
 
22574
22935
  // src/agents/kimi/installer.ts
22575
- var import_node_child_process23 = require("child_process");
22936
+ var import_node_child_process24 = require("child_process");
22576
22937
  var import_node_os6 = require("os");
22577
22938
  var import_node_path6 = require("path");
22578
22939
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
@@ -22580,7 +22941,7 @@ function kimiBinDir() {
22580
22941
  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
22942
  }
22582
22943
  function kimiRuns() {
22583
- const r = (0, import_node_child_process23.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
22944
+ const r = (0, import_node_child_process24.spawnSync)("kimi", ["--version"], { stdio: "ignore", timeout: 15e3 });
22584
22945
  return !r.error && r.status === 0;
22585
22946
  }
22586
22947
  function augmentPath2() {
@@ -22590,7 +22951,7 @@ function augmentPath2() {
22590
22951
  }
22591
22952
  async function runInstaller2() {
22592
22953
  return new Promise((resolve7) => {
22593
- const proc = (0, import_node_child_process23.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
22954
+ const proc = (0, import_node_child_process24.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL2} | bash`], { stdio: "inherit" });
22594
22955
  proc.on("close", (code) => resolve7(code === 0));
22595
22956
  proc.on("error", () => resolve7(false));
22596
22957
  });
@@ -22640,13 +23001,13 @@ function resolveBin(pkgName, binName) {
22640
23001
  try {
22641
23002
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
22642
23003
  const manifest = require_(`${pkgName}/package.json`);
22643
- const pkgDir = path58.dirname(manifestPath);
23004
+ const pkgDir = path59.dirname(manifestPath);
22644
23005
  const bin = manifest.bin;
22645
23006
  if (!bin) return null;
22646
- if (typeof bin === "string") return path58.resolve(pkgDir, bin);
23007
+ if (typeof bin === "string") return path59.resolve(pkgDir, bin);
22647
23008
  const target = binName ?? Object.keys(bin)[0];
22648
23009
  if (!target || !bin[target]) return null;
22649
- return path58.resolve(pkgDir, bin[target]);
23010
+ return path59.resolve(pkgDir, bin[target]);
22650
23011
  } catch {
22651
23012
  return null;
22652
23013
  }
@@ -22750,9 +23111,9 @@ function requiresAcp(agent) {
22750
23111
  var import_node_crypto10 = require("crypto");
22751
23112
 
22752
23113
  // src/services/history.service.ts
22753
- var fs55 = __toESM(require("fs"));
22754
- var path59 = __toESM(require("path"));
22755
- var os44 = __toESM(require("os"));
23114
+ var fs56 = __toESM(require("fs"));
23115
+ var path60 = __toESM(require("path"));
23116
+ var os45 = __toESM(require("os"));
22756
23117
  var https7 = __toESM(require("https"));
22757
23118
  var http6 = __toESM(require("http"));
22758
23119
  var import_zod2 = require("zod");
@@ -22779,7 +23140,7 @@ function parseJsonl(filePath) {
22779
23140
  const messages = [];
22780
23141
  let raw;
22781
23142
  try {
22782
- raw = fs55.readFileSync(filePath, "utf8");
23143
+ raw = fs56.readFileSync(filePath, "utf8");
22783
23144
  } catch (err) {
22784
23145
  if (err.code !== "ENOENT") {
22785
23146
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -22920,7 +23281,7 @@ var HistoryService = class _HistoryService {
22920
23281
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
22921
23282
  }
22922
23283
  get projectDir() {
22923
- return this.runtime.resolveHistoryDir(this.cwd) ?? path59.join(os44.homedir(), ".claude", "projects", encodeCwd(this.cwd));
23284
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path60.join(os45.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22924
23285
  }
22925
23286
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
22926
23287
  setCurrentConversationId(id) {
@@ -22932,7 +23293,7 @@ var HistoryService = class _HistoryService {
22932
23293
  /** Return the current message count in the active conversation. */
22933
23294
  getCurrentMessageCount() {
22934
23295
  if (!this.currentConversationId) return 0;
22935
- const filePath = path59.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23296
+ const filePath = path60.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22936
23297
  return parseJsonl(filePath).length;
22937
23298
  }
22938
23299
  /**
@@ -22943,7 +23304,7 @@ var HistoryService = class _HistoryService {
22943
23304
  const deadline = Date.now() + timeoutMs;
22944
23305
  while (Date.now() < deadline) {
22945
23306
  if (!this.currentConversationId) return null;
22946
- const filePath = path59.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23307
+ const filePath = path60.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22947
23308
  const messages = parseJsonl(filePath);
22948
23309
  if (messages.length > previousCount) {
22949
23310
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -22969,16 +23330,16 @@ var HistoryService = class _HistoryService {
22969
23330
  const dir = this.projectDir;
22970
23331
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22971
23332
  try {
22972
- const files = fs55.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
23333
+ const files = fs56.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22973
23334
  try {
22974
- const stat3 = fs55.statSync(path59.join(dir, e.name));
23335
+ const stat3 = fs56.statSync(path60.join(dir, e.name));
22975
23336
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22976
23337
  } catch {
22977
23338
  return { name: e.name, mtime: 0, birthtime: 0 };
22978
23339
  }
22979
23340
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
22980
23341
  if (files.length > 0) {
22981
- this.currentConversationId = path59.basename(files[0].name, ".jsonl");
23342
+ this.currentConversationId = path60.basename(files[0].name, ".jsonl");
22982
23343
  }
22983
23344
  } catch {
22984
23345
  }
@@ -23012,13 +23373,13 @@ var HistoryService = class _HistoryService {
23012
23373
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
23013
23374
  let entries;
23014
23375
  try {
23015
- entries = fs55.readdirSync(dir, { withFileTypes: true });
23376
+ entries = fs56.readdirSync(dir, { withFileTypes: true });
23016
23377
  } catch {
23017
23378
  return null;
23018
23379
  }
23019
23380
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
23020
23381
  try {
23021
- const stat3 = fs55.statSync(path59.join(dir, e.name));
23382
+ const stat3 = fs56.statSync(path60.join(dir, e.name));
23022
23383
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
23023
23384
  } catch {
23024
23385
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -23027,12 +23388,12 @@ var HistoryService = class _HistoryService {
23027
23388
  if (files.length === 0) return null;
23028
23389
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
23029
23390
  if (!files.some((f) => f.name === targetFile)) return null;
23030
- return this.extractUsageFromFile(path59.join(dir, targetFile));
23391
+ return this.extractUsageFromFile(path60.join(dir, targetFile));
23031
23392
  }
23032
23393
  extractUsageFromFile(filePath) {
23033
23394
  let raw;
23034
23395
  try {
23035
- raw = fs55.readFileSync(filePath, "utf8");
23396
+ raw = fs56.readFileSync(filePath, "utf8");
23036
23397
  } catch {
23037
23398
  return null;
23038
23399
  }
@@ -23077,9 +23438,9 @@ var HistoryService = class _HistoryService {
23077
23438
  let totalCost = 0;
23078
23439
  let files;
23079
23440
  try {
23080
- files = fs55.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23441
+ files = fs56.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23081
23442
  try {
23082
- return fs55.statSync(path59.join(projectDir, f)).mtimeMs >= monthStartMs;
23443
+ return fs56.statSync(path60.join(projectDir, f)).mtimeMs >= monthStartMs;
23083
23444
  } catch {
23084
23445
  return false;
23085
23446
  }
@@ -23090,7 +23451,7 @@ var HistoryService = class _HistoryService {
23090
23451
  for (const file of files) {
23091
23452
  let raw;
23092
23453
  try {
23093
- raw = fs55.readFileSync(path59.join(projectDir, file), "utf8");
23454
+ raw = fs56.readFileSync(path60.join(projectDir, file), "utf8");
23094
23455
  } catch {
23095
23456
  continue;
23096
23457
  }
@@ -23169,7 +23530,7 @@ var HistoryService = class _HistoryService {
23169
23530
  if (this.runtime.resolveHistoryFile) {
23170
23531
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
23171
23532
  }
23172
- return path59.join(this.projectDir, `${sessionId}.jsonl`);
23533
+ return path60.join(this.projectDir, `${sessionId}.jsonl`);
23173
23534
  }
23174
23535
  /**
23175
23536
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -23203,7 +23564,7 @@ var HistoryService = class _HistoryService {
23203
23564
  };
23204
23565
  });
23205
23566
  }
23206
- return parseJsonl(path59.join(this.projectDir, `${sessionId}.jsonl`));
23567
+ return parseJsonl(path60.join(this.projectDir, `${sessionId}.jsonl`));
23207
23568
  }
23208
23569
  async loadConversation(sessionId) {
23209
23570
  const messages = this.readConversation(sessionId);
@@ -23259,7 +23620,7 @@ var HistoryService = class _HistoryService {
23259
23620
  if (!filePath) return false;
23260
23621
  let mtimeMs;
23261
23622
  try {
23262
- mtimeMs = fs55.statSync(filePath).mtimeMs;
23623
+ mtimeMs = fs56.statSync(filePath).mtimeMs;
23263
23624
  } catch {
23264
23625
  return false;
23265
23626
  }
@@ -23327,11 +23688,11 @@ var HistoryService = class _HistoryService {
23327
23688
  };
23328
23689
 
23329
23690
  // src/agents/acp/client.ts
23330
- var import_node_child_process24 = require("child_process");
23331
- var fs56 = __toESM(require("fs/promises"));
23691
+ var import_node_child_process25 = require("child_process");
23692
+ var fs57 = __toESM(require("fs/promises"));
23332
23693
  var fsSync = __toESM(require("fs"));
23333
- var os45 = __toESM(require("os"));
23334
- var path60 = __toESM(require("path"));
23694
+ var os46 = __toESM(require("os"));
23695
+ var path61 = __toESM(require("path"));
23335
23696
  var import_node_stream = require("stream");
23336
23697
 
23337
23698
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -25931,7 +26292,7 @@ var AcpClient = class {
25931
26292
  "acpClient",
25932
26293
  `spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
25933
26294
  );
25934
- const child = (0, import_node_child_process24.spawn)(adapter.command, adapter.args, {
26295
+ const child = (0, import_node_child_process25.spawn)(adapter.command, adapter.args, {
25935
26296
  cwd,
25936
26297
  // extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
25937
26298
  // re-spawn) layers over process.env; PATH stays last so the augmented
@@ -26245,7 +26606,7 @@ var AcpClient = class {
26245
26606
  },
26246
26607
  readTextFile: async (params) => {
26247
26608
  try {
26248
- const content = await fs56.readFile(params.path, "utf8");
26609
+ const content = await fs57.readFile(params.path, "utf8");
26249
26610
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
26250
26611
  } catch (err) {
26251
26612
  const code = err.code;
@@ -26265,7 +26626,7 @@ var AcpClient = class {
26265
26626
  },
26266
26627
  writeTextFile: async (params) => {
26267
26628
  try {
26268
- await fs56.writeFile(params.path, params.content, "utf8");
26629
+ await fs57.writeFile(params.path, params.content, "utf8");
26269
26630
  return {};
26270
26631
  } catch (err) {
26271
26632
  const code = err.code;
@@ -26314,29 +26675,29 @@ function applyLineRange(content, line, limit) {
26314
26675
  return { content: lines.slice(start2, end).join("\n") };
26315
26676
  }
26316
26677
  function knownAgentBinaryDirs() {
26317
- const home = os45.homedir();
26678
+ const home = os46.homedir();
26318
26679
  const out2 = [];
26319
26680
  out2.push("/tmp/codeam-node20/bin");
26320
26681
  for (const root of [
26321
26682
  "/usr/local/share/nvm/versions/node",
26322
- path60.join(home, ".nvm/versions/node")
26683
+ path61.join(home, ".nvm/versions/node")
26323
26684
  ]) {
26324
26685
  try {
26325
26686
  for (const child of fsSync.readdirSync(root)) {
26326
- out2.push(path60.join(root, child, "bin"));
26687
+ out2.push(path61.join(root, child, "bin"));
26327
26688
  }
26328
26689
  } catch {
26329
26690
  }
26330
26691
  }
26331
- out2.push(path60.join(home, ".volta/bin"));
26692
+ out2.push(path61.join(home, ".volta/bin"));
26332
26693
  out2.push("/usr/local/bin");
26333
26694
  out2.push("/usr/bin");
26334
- out2.push(path60.join(home, ".local/bin"));
26335
- out2.push(path60.join(home, "bin"));
26695
+ out2.push(path61.join(home, ".local/bin"));
26696
+ out2.push(path61.join(home, "bin"));
26336
26697
  if (process.platform === "win32") {
26337
26698
  const { LOCALAPPDATA, APPDATA } = process.env;
26338
- if (LOCALAPPDATA) out2.push(path60.join(LOCALAPPDATA, "cursor-agent"));
26339
- if (APPDATA) out2.push(path60.join(APPDATA, "npm"));
26699
+ if (LOCALAPPDATA) out2.push(path61.join(LOCALAPPDATA, "cursor-agent"));
26700
+ if (APPDATA) out2.push(path61.join(APPDATA, "npm"));
26340
26701
  }
26341
26702
  return out2.filter((p2) => {
26342
26703
  try {
@@ -26348,7 +26709,7 @@ function knownAgentBinaryDirs() {
26348
26709
  }
26349
26710
  function expandPathForAgentBinaries(existingPath) {
26350
26711
  const existing = new Set(
26351
- existingPath.split(path60.delimiter).filter((p2) => p2.length > 0)
26712
+ existingPath.split(path61.delimiter).filter((p2) => p2.length > 0)
26352
26713
  );
26353
26714
  const additions = [];
26354
26715
  for (const dir of knownAgentBinaryDirs()) {
@@ -26358,7 +26719,7 @@ function expandPathForAgentBinaries(existingPath) {
26358
26719
  }
26359
26720
  }
26360
26721
  if (additions.length === 0) return existingPath;
26361
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path60.delimiter);
26722
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path61.delimiter);
26362
26723
  }
26363
26724
 
26364
26725
  // src/agents/acp/headroom-budget-proxy.ts
@@ -26369,12 +26730,12 @@ function buildRelaunchProxyEnv(baseEnv) {
26369
26730
  return env;
26370
26731
  }
26371
26732
  var relaunchProxyWithoutBudget = async () => {
26372
- const { spawn: spawn40 } = await import("child_process");
26733
+ const { spawn: spawn41 } = await import("child_process");
26373
26734
  killHeadroomProxy();
26374
26735
  await new Promise((r) => setTimeout(r, 500));
26375
26736
  const proxyEnv = buildRelaunchProxyEnv(process.env);
26376
26737
  try {
26377
- const proxy = spawn40(
26738
+ const proxy = spawn41(
26378
26739
  "headroom",
26379
26740
  ["proxy", "--port", "8787"],
26380
26741
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -26840,15 +27201,15 @@ function commonPrefixLength(a, b) {
26840
27201
 
26841
27202
  // src/agents/acp/onboarding.ts
26842
27203
  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"));
27204
+ var fs58 = __toESM(require("fs"));
27205
+ var os47 = __toESM(require("os"));
27206
+ var path62 = __toESM(require("path"));
26846
27207
  var _onboardingSeam = {
26847
- markerPath: (sessionId) => path61.join(os46.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
26848
- exists: (p2) => fs57.existsSync(p2),
27208
+ markerPath: (sessionId) => path62.join(os47.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
27209
+ exists: (p2) => fs58.existsSync(p2),
26849
27210
  write: (p2) => {
26850
- fs57.mkdirSync(path61.dirname(p2), { recursive: true });
26851
- fs57.writeFileSync(p2, "");
27211
+ fs58.mkdirSync(path62.dirname(p2), { recursive: true });
27212
+ fs58.writeFileSync(p2, "");
26852
27213
  },
26853
27214
  disabled: () => {
26854
27215
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -26885,7 +27246,7 @@ function resolveRepoName(cwd) {
26885
27246
  if (name) return name;
26886
27247
  }
26887
27248
  }
26888
- const base = path61.basename(cwd || "");
27249
+ const base = path62.basename(cwd || "");
26889
27250
  if (base && !isUuid(base)) return base;
26890
27251
  return "this project";
26891
27252
  }
@@ -27137,8 +27498,8 @@ var import_crypto5 = require("crypto");
27137
27498
 
27138
27499
  // src/services/turn-files/git-changeset.ts
27139
27500
  var import_child_process27 = require("child_process");
27140
- var fs58 = __toESM(require("fs/promises"));
27141
- var path62 = __toESM(require("path"));
27501
+ var fs59 = __toESM(require("fs/promises"));
27502
+ var path63 = __toESM(require("path"));
27142
27503
  async function collectRepoChangeset(opts) {
27143
27504
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
27144
27505
  if (status2 === null) return null;
@@ -27156,7 +27517,7 @@ async function collectRepoChangeset(opts) {
27156
27517
  let stats;
27157
27518
  if (row.fileStatus === "added" && numstatEntry === void 0) {
27158
27519
  const lineCount = await readUntrackedLineCount(
27159
- path62.join(opts.repoRoot, row.filePath)
27520
+ path63.join(opts.repoRoot, row.filePath)
27160
27521
  );
27161
27522
  stats = { added: lineCount, removed: 0 };
27162
27523
  } else {
@@ -27187,7 +27548,7 @@ function readUntrackedLineCount(absPath) {
27187
27548
  }
27188
27549
  async function defaultReadUntrackedLineCount(absPath) {
27189
27550
  try {
27190
- const content = await fs58.readFile(absPath, "utf8");
27551
+ const content = await fs59.readFile(absPath, "utf8");
27191
27552
  let count = 0;
27192
27553
  let pos = -1;
27193
27554
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -27279,7 +27640,7 @@ function defaultRunGit(cwd, args2) {
27279
27640
  });
27280
27641
  }
27281
27642
  async function discoverRepos(workingDir, maxDepth = 4) {
27282
- const fs63 = await import("fs/promises");
27643
+ const fs64 = await import("fs/promises");
27283
27644
  const out2 = [];
27284
27645
  await walk(workingDir, 0);
27285
27646
  return out2;
@@ -27287,7 +27648,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27287
27648
  if (depth > maxDepth) return;
27288
27649
  let entries = [];
27289
27650
  try {
27290
- const dirents = await fs63.readdir(dir, { withFileTypes: true });
27651
+ const dirents = await fs64.readdir(dir, { withFileTypes: true });
27291
27652
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
27292
27653
  } catch {
27293
27654
  return;
@@ -27298,8 +27659,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27298
27659
  if (hasGit) {
27299
27660
  out2.push({
27300
27661
  repoRoot: dir,
27301
- repoPath: path62.relative(workingDir, dir),
27302
- repoName: path62.basename(dir)
27662
+ repoPath: path63.relative(workingDir, dir),
27663
+ repoName: path63.basename(dir)
27303
27664
  });
27304
27665
  return;
27305
27666
  }
@@ -27307,15 +27668,15 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27307
27668
  if (!entry.isDirectory) continue;
27308
27669
  if (entry.name === "node_modules") continue;
27309
27670
  if (entry.name === "dist" || entry.name === "build") continue;
27310
- await walk(path62.join(dir, entry.name), depth + 1);
27671
+ await walk(path63.join(dir, entry.name), depth + 1);
27311
27672
  }
27312
27673
  }
27313
27674
  }
27314
27675
 
27315
27676
  // 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");
27677
+ var fs60 = __toESM(require("fs/promises"));
27678
+ var path64 = __toESM(require("path"));
27679
+ var import_os11 = require("os");
27319
27680
  var HOME_OUTBOX_DIR = ".codeam/outbox";
27320
27681
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
27321
27682
  var BACKOFF_STEPS_MS = [
@@ -27347,16 +27708,16 @@ var FilesOutbox = class {
27347
27708
  backoffIndex = 0;
27348
27709
  stopped = false;
27349
27710
  constructor(opts) {
27350
- const base = opts.baseDir ?? path63.join(homeDir(), HOME_OUTBOX_DIR);
27351
- this.filePath = path63.join(base, `${opts.sessionId}.jsonl`);
27711
+ const base = opts.baseDir ?? path64.join(homeDir(), HOME_OUTBOX_DIR);
27712
+ this.filePath = path64.join(base, `${opts.sessionId}.jsonl`);
27352
27713
  this.post = opts.post;
27353
27714
  this.autoSchedule = opts.autoSchedule !== false;
27354
27715
  }
27355
27716
  /** Persist the entry to disk and trigger a flush. Returns once the
27356
27717
  * line is durable on disk (not once the POST succeeds). */
27357
27718
  async enqueue(entry) {
27358
- await fs59.mkdir(path63.dirname(this.filePath), { recursive: true });
27359
- await fs59.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
27719
+ await fs60.mkdir(path64.dirname(this.filePath), { recursive: true });
27720
+ await fs60.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
27360
27721
  this.backoffIndex = 0;
27361
27722
  if (this.autoSchedule) this.scheduleFlush(0);
27362
27723
  }
@@ -27445,7 +27806,7 @@ var FilesOutbox = class {
27445
27806
  async readAll() {
27446
27807
  let raw = "";
27447
27808
  try {
27448
- raw = await fs59.readFile(this.filePath, "utf8");
27809
+ raw = await fs60.readFile(this.filePath, "utf8");
27449
27810
  } catch {
27450
27811
  return [];
27451
27812
  }
@@ -27469,12 +27830,12 @@ var FilesOutbox = class {
27469
27830
  async rewrite(entries) {
27470
27831
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
27471
27832
  if (entries.length === 0) {
27472
- await fs59.unlink(this.filePath).catch(() => void 0);
27833
+ await fs60.unlink(this.filePath).catch(() => void 0);
27473
27834
  return;
27474
27835
  }
27475
27836
  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);
27837
+ await fs60.writeFile(tmpPath, payload, "utf8");
27838
+ await fs60.rename(tmpPath, this.filePath);
27478
27839
  }
27479
27840
  };
27480
27841
  function applyJitter(ms) {
@@ -27482,7 +27843,7 @@ function applyJitter(ms) {
27482
27843
  return Math.round(ms * factor);
27483
27844
  }
27484
27845
  function homeDir() {
27485
- return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os9.tmpdir)();
27846
+ return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os11.tmpdir)();
27486
27847
  }
27487
27848
 
27488
27849
  // src/services/turn-files/turn-file-aggregator.ts
@@ -30579,7 +30940,7 @@ var AcpDriver = class {
30579
30940
  };
30580
30941
 
30581
30942
  // src/baton/transcript-mirror.ts
30582
- var fs60 = __toESM(require("fs"));
30943
+ var fs61 = __toESM(require("fs"));
30583
30944
  var TranscriptMirror = class {
30584
30945
  constructor(deps) {
30585
30946
  this.deps = deps;
@@ -30646,7 +31007,7 @@ var TranscriptMirror = class {
30646
31007
  }
30647
31008
  };
30648
31009
  function defaultWatch(file, onChange) {
30649
- const w3 = fs60.watch(file, { persistent: false }, () => onChange());
31010
+ const w3 = fs61.watch(file, { persistent: false }, () => onChange());
30650
31011
  return () => w3.close();
30651
31012
  }
30652
31013
 
@@ -30898,15 +31259,15 @@ function toEpochMs(ts) {
30898
31259
  }
30899
31260
 
30900
31261
  // src/agents/claude/onboarding.ts
30901
- var fs61 = __toESM(require("fs"));
30902
- var os47 = __toESM(require("os"));
30903
- var path64 = __toESM(require("path"));
31262
+ var fs62 = __toESM(require("fs"));
31263
+ var os48 = __toESM(require("os"));
31264
+ var path65 = __toESM(require("path"));
30904
31265
  function ensureClaudeOnboarded() {
30905
31266
  try {
30906
- const file = path64.join(os47.homedir(), ".claude.json");
31267
+ const file = path65.join(os48.homedir(), ".claude.json");
30907
31268
  let config = {};
30908
31269
  try {
30909
- config = JSON.parse(fs61.readFileSync(file, "utf8"));
31270
+ config = JSON.parse(fs62.readFileSync(file, "utf8"));
30910
31271
  } catch {
30911
31272
  }
30912
31273
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -30917,8 +31278,8 @@ function ensureClaudeOnboarded() {
30917
31278
  if (typeof config.lastOnboardingVersion !== "string") {
30918
31279
  config.lastOnboardingVersion = "2.1.177";
30919
31280
  }
30920
- fs61.mkdirSync(path64.dirname(file), { recursive: true });
30921
- fs61.writeFileSync(file, JSON.stringify(config, null, 2));
31281
+ fs62.mkdirSync(path65.dirname(file), { recursive: true });
31282
+ fs62.writeFileSync(file, JSON.stringify(config, null, 2));
30922
31283
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
30923
31284
  } catch (err) {
30924
31285
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -31592,7 +31953,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
31592
31953
  var import_child_process28 = require("child_process");
31593
31954
  var import_util4 = require("util");
31594
31955
  var import_picocolors9 = __toESM(require("picocolors"));
31595
- var path65 = __toESM(require("path"));
31956
+ var path66 = __toESM(require("path"));
31596
31957
  var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
31597
31958
  var MAX_BUFFER = 8 * 1024 * 1024;
31598
31959
  function resetStdinForChild() {
@@ -32081,7 +32442,7 @@ var GitHubCodespacesProvider = class {
32081
32442
  });
32082
32443
  }
32083
32444
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32084
- const remoteDir = path65.posix.dirname(remotePath);
32445
+ const remoteDir = path66.posix.dirname(remotePath);
32085
32446
  const parts = [
32086
32447
  `mkdir -p ${shellQuote(remoteDir)}`,
32087
32448
  `cat > ${shellQuote(remotePath)}`
@@ -32151,7 +32512,7 @@ function shellQuote(s) {
32151
32512
  // src/services/providers/gitpod.ts
32152
32513
  var import_child_process29 = require("child_process");
32153
32514
  var import_util5 = require("util");
32154
- var path66 = __toESM(require("path"));
32515
+ var path67 = __toESM(require("path"));
32155
32516
  var import_picocolors10 = __toESM(require("picocolors"));
32156
32517
  var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
32157
32518
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -32391,7 +32752,7 @@ var GitpodProvider = class {
32391
32752
  });
32392
32753
  }
32393
32754
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32394
- const remoteDir = path66.posix.dirname(remotePath);
32755
+ const remoteDir = path67.posix.dirname(remotePath);
32395
32756
  const parts = [
32396
32757
  `mkdir -p ${shellQuote2(remoteDir)}`,
32397
32758
  `cat > ${shellQuote2(remotePath)}`
@@ -32427,7 +32788,7 @@ function shellQuote2(s) {
32427
32788
  // src/services/providers/gitlab-workspaces.ts
32428
32789
  var import_child_process30 = require("child_process");
32429
32790
  var import_util6 = require("util");
32430
- var path67 = __toESM(require("path"));
32791
+ var path68 = __toESM(require("path"));
32431
32792
  var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
32432
32793
  var MAX_BUFFER3 = 8 * 1024 * 1024;
32433
32794
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -32687,7 +33048,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
32687
33048
  }
32688
33049
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32689
33050
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
32690
- const remoteDir = path67.posix.dirname(remotePath);
33051
+ const remoteDir = path68.posix.dirname(remotePath);
32691
33052
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
32692
33053
  if (options.mode != null) {
32693
33054
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -32755,7 +33116,7 @@ function shellQuote3(s) {
32755
33116
  // src/services/providers/railway.ts
32756
33117
  var import_child_process31 = require("child_process");
32757
33118
  var import_util7 = require("util");
32758
- var path68 = __toESM(require("path"));
33119
+ var path69 = __toESM(require("path"));
32759
33120
  var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
32760
33121
  var MAX_BUFFER4 = 8 * 1024 * 1024;
32761
33122
  function resetStdinForChild4() {
@@ -32991,7 +33352,7 @@ var RailwayProvider = class {
32991
33352
  if (!projectId || !serviceId) {
32992
33353
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
32993
33354
  }
32994
- const remoteDir = path68.posix.dirname(remotePath);
33355
+ const remoteDir = path69.posix.dirname(remotePath);
32995
33356
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
32996
33357
  if (options.mode != null) {
32997
33358
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -33637,8 +33998,8 @@ async function invite() {
33637
33998
  var import_node_dns = require("dns");
33638
33999
  var import_node_util5 = require("util");
33639
34000
  var import_node_crypto12 = require("crypto");
33640
- var fs62 = __toESM(require("fs"));
33641
- var path69 = __toESM(require("path"));
34001
+ var fs63 = __toESM(require("fs"));
34002
+ var path70 = __toESM(require("path"));
33642
34003
  var import_picocolors14 = __toESM(require("picocolors"));
33643
34004
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
33644
34005
  async function checkDns(apiBase2) {
@@ -33694,13 +34055,13 @@ async function checkHealth(apiBase2) {
33694
34055
  }
33695
34056
  }
33696
34057
  function checkConfigDir() {
33697
- const dir = path69.join(require("os").homedir(), ".codeam");
34058
+ const dir = path70.join(require("os").homedir(), ".codeam");
33698
34059
  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);
34060
+ fs63.mkdirSync(dir, { recursive: true, mode: 448 });
34061
+ const probe = path70.join(dir, ".doctor-probe");
34062
+ fs63.writeFileSync(probe, "ok", { mode: 384 });
34063
+ const read2 = fs63.readFileSync(probe, "utf8");
34064
+ fs63.unlinkSync(probe);
33704
34065
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
33705
34066
  return {
33706
34067
  id: "config-dir",
@@ -33740,9 +34101,9 @@ function checkSessions() {
33740
34101
  }
33741
34102
  }
33742
34103
  function checkAgentBinaries() {
33743
- const os49 = createOsStrategy();
34104
+ const os50 = createOsStrategy();
33744
34105
  return getEnabledAgents().map((meta) => {
33745
- const found = os49.findInPath(meta.binaryName);
34106
+ const found = os50.findInPath(meta.binaryName);
33746
34107
  return {
33747
34108
  id: `agent-${meta.id}`,
33748
34109
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -33764,7 +34125,7 @@ function checkNodePty() {
33764
34125
  detail: "not required on this platform"
33765
34126
  };
33766
34127
  }
33767
- const vendoredPath = path69.join(__dirname, "vendor", "node-pty");
34128
+ const vendoredPath = path70.join(__dirname, "vendor", "node-pty");
33768
34129
  for (const target of [vendoredPath, "node-pty"]) {
33769
34130
  try {
33770
34131
  require(target);
@@ -33806,7 +34167,7 @@ function checkChokidar() {
33806
34167
  }
33807
34168
  async function doctor(args2 = []) {
33808
34169
  const json = args2.includes("--json");
33809
- const cliVersion = true ? "2.60.23" : "0.0.0-dev";
34170
+ const cliVersion = true ? "2.60.24" : "0.0.0-dev";
33810
34171
  const apiBase2 = resolveApiBaseUrl();
33811
34172
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
33812
34173
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -34005,7 +34366,7 @@ async function completion(args2) {
34005
34366
  // src/commands/version.ts
34006
34367
  var import_picocolors15 = __toESM(require("picocolors"));
34007
34368
  function version2() {
34008
- const v = true ? "2.60.23" : "unknown";
34369
+ const v = true ? "2.60.24" : "unknown";
34009
34370
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
34010
34371
  }
34011
34372
 
@@ -34154,10 +34515,10 @@ var EXIT_CODE_NAMES = {
34154
34515
  };
34155
34516
 
34156
34517
  // src/index.ts
34157
- var os48 = __toESM(require("os"));
34518
+ var os49 = __toESM(require("os"));
34158
34519
  if (!process.env.HOME) {
34159
34520
  try {
34160
- const home = os48.homedir();
34521
+ const home = os49.homedir();
34161
34522
  if (home) process.env.HOME = home;
34162
34523
  } catch {
34163
34524
  }