codeam-cli 2.60.22 → 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 +18 -0
  2. package/dist/index.js +957 -453
  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.22" : "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.22",
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.22" ? { ideVersion: "2.60.22" } : {}
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,13 +13453,13 @@ 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
- return (0, import_node_child_process7.spawn)("coderabbit", ["login"], { stdio: "inherit" });
13462
+ return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
13424
13463
  }
13425
13464
  };
13426
13465
  }
@@ -13429,31 +13468,166 @@ function coderabbitLoginLauncher(os49) {
13429
13468
  var HUNK_LINE_RE = /^([^\s:][^:]*?):(\d+)[\s:—-]+(?:\[?(info|warn|warning|error|critical)\]?[:\s—-]+)?(.+)$/i;
13430
13469
  var SEVERITY_MAP = {
13431
13470
  info: "info",
13471
+ note: "info",
13472
+ low: "info",
13473
+ minor: "info",
13432
13474
  warn: "warn",
13433
13475
  warning: "warn",
13476
+ medium: "warn",
13477
+ major: "warn",
13434
13478
  error: "error",
13435
- critical: "error"
13479
+ critical: "error",
13480
+ high: "error",
13481
+ blocker: "error"
13436
13482
  };
13437
- function parseReview(stdout) {
13483
+ function normSeverity(v) {
13484
+ if (typeof v !== "string") return void 0;
13485
+ return SEVERITY_MAP[v.trim().toLowerCase()];
13486
+ }
13487
+ function pick(obj, keys) {
13488
+ for (const k2 of keys) {
13489
+ if (obj[k2] !== void 0 && obj[k2] !== null) return obj[k2];
13490
+ }
13491
+ return void 0;
13492
+ }
13493
+ function asString(v) {
13494
+ return typeof v === "string" && v.trim().length > 0 ? v : void 0;
13495
+ }
13496
+ function pickLine(obj) {
13497
+ const direct = pick(obj, ["line", "start_line", "startLine", "line_number", "lineNumber"]);
13498
+ if (typeof direct === "number") return direct;
13499
+ if (typeof direct === "string" && /^\d+$/.test(direct)) return Number(direct);
13500
+ const range = pick(obj, ["line_range", "lineRange", "range", "lines"]);
13501
+ if (Array.isArray(range) && typeof range[0] === "number") return range[0];
13502
+ if (range && typeof range === "object") {
13503
+ const start2 = pick(range, ["start", "begin", "from"]);
13504
+ if (typeof start2 === "number") return start2;
13505
+ if (start2 && typeof start2 === "object") {
13506
+ const l = start2.line;
13507
+ if (typeof l === "number") return l;
13508
+ }
13509
+ }
13510
+ return void 0;
13511
+ }
13512
+ function toHunk(raw, groupSeverity) {
13513
+ if (!raw || typeof raw !== "object") return null;
13514
+ const o = raw;
13515
+ const path71 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename"])) ?? asString(pick(o, ["location"])?.path);
13516
+ if (!path71) return null;
13517
+ const message = asString(pick(o, ["comment", "message", "body", "description", "summary", "markdown", "text"])) ?? "";
13518
+ const title = asString(pick(o, ["title", "rule", "category", "check"]));
13519
+ const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
13520
+ const locObj = pick(o, ["location"]) ?? o;
13521
+ return {
13522
+ path: path71.trim(),
13523
+ line: pickLine(o) ?? pickLine(locObj),
13524
+ severity,
13525
+ message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
13526
+ };
13527
+ }
13528
+ function findingsFrom(value) {
13529
+ const out2 = [];
13530
+ if (!value || typeof value !== "object") return out2;
13531
+ const root = value;
13532
+ const flat = pick(root, ["findings", "comments", "issues", "results", "review_comments", "reviewComments"]);
13533
+ if (Array.isArray(flat)) {
13534
+ for (const f of flat) {
13535
+ const h = toHunk(f);
13536
+ if (h) out2.push(h);
13537
+ }
13538
+ }
13539
+ const grouped = flat && !Array.isArray(flat) ? flat : root;
13540
+ for (const sev of ["critical", "warning", "warn", "error", "info", "note"]) {
13541
+ const bucket = grouped[sev];
13542
+ if (Array.isArray(bucket)) {
13543
+ for (const f of bucket) {
13544
+ const h = toHunk(f, sev);
13545
+ if (h) out2.push(h);
13546
+ }
13547
+ }
13548
+ }
13549
+ return out2;
13550
+ }
13551
+ function errorFrom(obj) {
13552
+ if (obj.type !== "error") return void 0;
13553
+ return asString(pick(obj, ["message", "error"]));
13554
+ }
13555
+ function isControlEvent(obj) {
13556
+ return obj.type === "review_context" || obj.type === "status" || obj.type === "progress" || obj.type === "error";
13557
+ }
13558
+ function parseStructured(stdout) {
13559
+ const trimmed = stdout.trim();
13560
+ if (!trimmed || trimmed[0] !== "{" && trimmed[0] !== "[") return null;
13561
+ try {
13562
+ const doc = JSON.parse(trimmed);
13563
+ const hunks2 = findingsFrom(Array.isArray(doc) ? { findings: doc } : doc);
13564
+ const summary2 = asString(
13565
+ pick(Array.isArray(doc) ? {} : doc, ["summary", "markdown", "report", "overview"])
13566
+ );
13567
+ if (hunks2.length > 0 || summary2) return { hunks: hunks2, summary: summary2 };
13568
+ } catch {
13569
+ }
13438
13570
  const hunks = [];
13439
- const lines = stdout.split(/\r?\n/);
13440
- for (const line of lines) {
13571
+ let summary;
13572
+ let error;
13573
+ let sawJson = false;
13574
+ for (const line of trimmed.split(/\r?\n/)) {
13575
+ const l = line.trim();
13576
+ if (!l || l[0] !== "{" && l[0] !== "[") continue;
13577
+ try {
13578
+ const obj = JSON.parse(l);
13579
+ sawJson = true;
13580
+ const rec = Array.isArray(obj) ? {} : obj;
13581
+ error ??= errorFrom(rec);
13582
+ if (isControlEvent(rec)) continue;
13583
+ const found = findingsFrom(Array.isArray(obj) ? { findings: obj } : obj);
13584
+ if (found.length > 0) hunks.push(...found);
13585
+ else {
13586
+ const single = toHunk(obj);
13587
+ if (single) hunks.push(single);
13588
+ }
13589
+ summary ??= asString(pick(rec, ["summary", "markdown", "report"]));
13590
+ } catch {
13591
+ }
13592
+ }
13593
+ return sawJson ? { hunks, summary, error } : null;
13594
+ }
13595
+ function parsePlain(stdout) {
13596
+ const hunks = [];
13597
+ for (const line of stdout.split(/\r?\n/)) {
13441
13598
  const m = line.match(HUNK_LINE_RE);
13442
13599
  if (!m) continue;
13443
- const [, path70, lineNo, sevToken, message] = m;
13444
- if (!path70 || !lineNo || !message) continue;
13445
- const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
13600
+ const [, path71, lineNo, sevToken, message] = m;
13601
+ if (!path71 || !lineNo || !message) continue;
13446
13602
  hunks.push({
13447
- path: path70.trim(),
13603
+ path: path71.trim(),
13448
13604
  line: Number(lineNo),
13449
13605
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
13450
- message: cleanedMessage
13606
+ message: message.trim().replace(/^[*-]\s+/, "")
13451
13607
  });
13452
13608
  }
13609
+ return hunks;
13610
+ }
13611
+ function severityCounts(hunks) {
13612
+ const c2 = { error: 0, warn: 0, info: 0 };
13613
+ for (const h of hunks) if (h.severity) c2[h.severity] += 1;
13614
+ return c2;
13615
+ }
13616
+ function parseReview(stdout) {
13617
+ const structured = parseStructured(stdout);
13618
+ const hunks = structured && structured.hunks.length > 0 ? structured.hunks : parsePlain(stdout);
13619
+ const counts = severityCounts(hunks);
13620
+ const markdown = (structured?.summary ?? (hunks.length === 0 && structured?.error ? structured.error : stdout)).trim();
13453
13621
  return {
13454
- markdown: stdout.trim(),
13622
+ markdown,
13455
13623
  hunks,
13456
- stats: { linesReviewed: lines.length, hunkCount: hunks.length }
13624
+ stats: {
13625
+ findingCount: hunks.length,
13626
+ critical: counts.error,
13627
+ warning: counts.warn,
13628
+ info: counts.info,
13629
+ ...structured?.error ? { error: structured.error } : {}
13630
+ }
13457
13631
  };
13458
13632
  }
13459
13633
 
@@ -13463,11 +13637,11 @@ var CoderabbitRuntimeStrategy = class {
13463
13637
  meta = getAgent("coderabbit");
13464
13638
  mode = "batch";
13465
13639
  os;
13466
- constructor(os49) {
13467
- this.os = os49;
13640
+ constructor(os50) {
13641
+ this.os = os50;
13468
13642
  }
13469
13643
  getDefaultArgs() {
13470
- return ["review"];
13644
+ return ["review", "--agent"];
13471
13645
  }
13472
13646
  async prepareInvocation(input) {
13473
13647
  const binary = this.os.findInPath(this.meta.binaryName);
@@ -13476,14 +13650,12 @@ var CoderabbitRuntimeStrategy = class {
13476
13650
  `CodeRabbit binary "${this.meta.binaryName}" not on PATH. Run \`codeam link coderabbit\` to install it first.`
13477
13651
  );
13478
13652
  }
13479
- const args2 = this.getDefaultArgs();
13480
- if (input.prRef) args2.push("--pr", input.prRef);
13481
- if (input.files && input.files.length > 0) {
13482
- args2.push(...input.files);
13483
- }
13484
- if (input.prompt) {
13485
- args2.push("--message", input.prompt);
13486
- }
13653
+ const args2 = input.structured === false ? ["review", "--plain"] : this.getDefaultArgs();
13654
+ if (input.changeSet) args2.push("--type", input.changeSet);
13655
+ if (input.base) args2.push("--base", input.base);
13656
+ if (input.baseCommit) args2.push("--base-commit", input.baseCommit);
13657
+ if (input.dir) args2.push("--dir", input.dir);
13658
+ if (input.apiKey) args2.push("--api-key", input.apiKey);
13487
13659
  if (input.extraArgs && input.extraArgs.length > 0) {
13488
13660
  args2.push(...input.extraArgs);
13489
13661
  }
@@ -13701,10 +13873,10 @@ function cursorCredentialLocator() {
13701
13873
  validate: validateNonEmptyCredential
13702
13874
  };
13703
13875
  }
13704
- function cursorLoginLauncher(os49) {
13876
+ function cursorLoginLauncher(os50) {
13705
13877
  return {
13706
13878
  async ensureInstalled() {
13707
- if (os49.findInPath("cursor-agent")) return true;
13879
+ if (os50.findInPath("cursor-agent")) return true;
13708
13880
  console.error(
13709
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"
13710
13882
  );
@@ -13768,15 +13940,14 @@ var CursorRuntimeStrategy = class {
13768
13940
  meta = getAgent("cursor");
13769
13941
  mode = "interactive";
13770
13942
  os;
13771
- constructor(os49) {
13772
- this.os = os49;
13943
+ constructor(os50) {
13944
+ this.os = os50;
13773
13945
  }
13774
13946
  async prepareLaunch() {
13775
13947
  const binary = this.os.findInPath("cursor-agent");
13776
13948
  if (!binary) {
13777
- throw new Error(
13778
- '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.'
13779
- );
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);
13780
13951
  }
13781
13952
  const sessionId = this.mintChatId(binary);
13782
13953
  if (sessionId) {
@@ -13791,10 +13962,20 @@ var CursorRuntimeStrategy = class {
13791
13962
  * failure. `cursor-agent create-chat` prints a bare UUID and exits 0 (verified
13792
13963
  * on cursor-agent 2026.06.24). Synchronous + bounded so prepareLaunch stays a
13793
13964
  * single deterministic step; a timeout/parse failure just disables pre-mint.
13965
+ *
13966
+ * ⚠️ Windows: `findInPath` resolves `cursor-agent.cmd` (or `.ps1`) via PATHEXT,
13967
+ * and Windows CANNOT spawn a `.cmd`/`.bat`/`.ps1` directly — it needs
13968
+ * `cmd.exe /c` / `powershell -File`. Spawning `binary` raw (as this used to)
13969
+ * failed with EINVAL on Windows → null id → no pre-mint → the baton threw
13970
+ * "agent did not expose a session id after spawn" (Windows-only). Route the
13971
+ * spawn through `os.buildLaunch`, exactly like the TUI launch above, so the
13972
+ * command is wrapped correctly per-platform. On macOS/Linux buildLaunch returns
13973
+ * the bare `{cmd: binary, args: ['create-chat']}` → behaviour unchanged.
13794
13974
  */
13795
13975
  mintChatId(binary) {
13796
13976
  try {
13797
- const r = (0, import_node_child_process10.spawnSync)(binary, ["create-chat"], {
13977
+ const launch = this.os.buildLaunch(binary, ["create-chat"]);
13978
+ const r = (0, import_node_child_process10.spawnSync)(launch.cmd, launch.args, {
13798
13979
  encoding: "utf8",
13799
13980
  timeout: 2e4,
13800
13981
  stdio: ["ignore", "pipe", "pipe"]
@@ -13976,10 +14157,10 @@ function aiderCredentialLocator() {
13976
14157
  validate: validateNonEmptyCredential
13977
14158
  };
13978
14159
  }
13979
- function aiderLoginLauncher(os49) {
14160
+ function aiderLoginLauncher(os50) {
13980
14161
  return {
13981
14162
  async ensureInstalled() {
13982
- if (os49.findInPath("aider")) return true;
14163
+ if (os50.findInPath("aider")) return true;
13983
14164
  console.error(
13984
14165
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
13985
14166
  );
@@ -13989,7 +14170,7 @@ function aiderLoginLauncher(os49) {
13989
14170
  console.error(
13990
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"
13991
14172
  );
13992
- 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"], {
13993
14174
  stdio: "ignore"
13994
14175
  });
13995
14176
  }
@@ -14061,8 +14242,8 @@ var AiderRuntimeStrategy = class {
14061
14242
  meta = getAgent("aider");
14062
14243
  mode = "interactive";
14063
14244
  os;
14064
- constructor(os49) {
14065
- this.os = os49;
14245
+ constructor(os50) {
14246
+ this.os = os50;
14066
14247
  }
14067
14248
  async prepareLaunch() {
14068
14249
  const binary = this.os.findInPath("aider");
@@ -14194,8 +14375,8 @@ function geminiCredentialLocator() {
14194
14375
  function geminiLoginLauncher() {
14195
14376
  return {
14196
14377
  async ensureInstalled() {
14197
- const os49 = createOsStrategy();
14198
- return os49.findInPath("gemini") !== null;
14378
+ const os50 = createOsStrategy();
14379
+ return os50.findInPath("gemini") !== null;
14199
14380
  },
14200
14381
  launch() {
14201
14382
  return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -14385,8 +14566,8 @@ var GeminiRuntimeStrategy = class {
14385
14566
  meta = getAgent("gemini");
14386
14567
  mode = "interactive";
14387
14568
  os;
14388
- constructor(os49) {
14389
- this.os = os49;
14569
+ constructor(os50) {
14570
+ this.os = os50;
14390
14571
  }
14391
14572
  async prepareLaunch() {
14392
14573
  const binary = this.os.findInPath("gemini");
@@ -14677,15 +14858,14 @@ var KimiRuntimeStrategy = class {
14677
14858
  meta = getAgent("kimi");
14678
14859
  mode = "interactive";
14679
14860
  os;
14680
- constructor(os49) {
14681
- this.os = os49;
14861
+ constructor(os50) {
14862
+ this.os = os50;
14682
14863
  }
14683
14864
  async prepareLaunch() {
14684
14865
  const binary = this.os.findInPath("kimi");
14685
14866
  if (!binary) {
14686
- throw new Error(
14687
- "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."
14688
- );
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);
14689
14869
  }
14690
14870
  const launch = this.os.buildLaunch(binary, []);
14691
14871
  return { cmd: launch.cmd, args: launch.args };
@@ -14792,19 +14972,19 @@ var KimiRuntimeStrategy = class {
14792
14972
 
14793
14973
  // src/agents/registry.ts
14794
14974
  var runtimeBuilders = {
14795
- claude: (os49) => new ClaudeRuntimeStrategy(os49),
14796
- codex: (os49) => new CodexRuntimeStrategy(os49),
14797
- coderabbit: (os49) => new CoderabbitRuntimeStrategy(os49),
14798
- cursor: (os49) => new CursorRuntimeStrategy(os49),
14799
- aider: (os49) => new AiderRuntimeStrategy(os49),
14800
- gemini: (os49) => new GeminiRuntimeStrategy(os49),
14801
- 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)
14802
14982
  };
14803
14983
  var deployBuilders = {
14804
14984
  claude: () => new ClaudeDeployStrategy(),
14805
14985
  codex: () => new CodexDeployStrategy()
14806
14986
  };
14807
- function createAgentStrategy(agent, os49 = createOsStrategy()) {
14987
+ function createAgentStrategy(agent, os50 = createOsStrategy()) {
14808
14988
  if (!AGENT_REGISTRY[agent]?.enabled) {
14809
14989
  throw new Error(
14810
14990
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -14814,10 +14994,10 @@ function createAgentStrategy(agent, os49 = createOsStrategy()) {
14814
14994
  if (!build) {
14815
14995
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
14816
14996
  }
14817
- return build(os49);
14997
+ return build(os50);
14818
14998
  }
14819
- function createInteractiveAgentStrategy(agent, os49 = createOsStrategy()) {
14820
- const s = createAgentStrategy(agent, os49);
14999
+ function createInteractiveAgentStrategy(agent, os50 = createOsStrategy()) {
15000
+ const s = createAgentStrategy(agent, os50);
14821
15001
  if (s.mode !== "interactive") {
14822
15002
  throw new Error(
14823
15003
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -15216,21 +15396,261 @@ async function linkDryRunPreflight(ctx) {
15216
15396
  process.exit(1);
15217
15397
  }
15218
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
+
15219
15639
  // src/commands/host-agent.ts
15220
- var import_node_child_process21 = require("child_process");
15221
- var os34 = __toESM(require("os"));
15222
- var fs40 = __toESM(require("fs"));
15223
- 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"));
15224
15644
 
15225
15645
  // src/commands/host/host-client.ts
15226
- var fs32 = __toESM(require("fs"));
15227
- var os28 = __toESM(require("os"));
15228
- var path35 = __toESM(require("path"));
15646
+ var fs33 = __toESM(require("fs"));
15647
+ var os29 = __toESM(require("os"));
15648
+ var path36 = __toESM(require("path"));
15229
15649
 
15230
15650
  // src/lib/restrict-to-owner.ts
15231
15651
  var import_node_fs5 = __toESM(require("fs"));
15232
15652
  var import_node_os4 = __toESM(require("os"));
15233
- var import_node_child_process14 = require("child_process");
15653
+ var import_node_child_process15 = require("child_process");
15234
15654
  var BROAD_WINDOWS_SIDS = [
15235
15655
  "*S-1-1-0",
15236
15656
  "*S-1-5-11",
@@ -15242,7 +15662,7 @@ function restrictToOwner(filePath) {
15242
15662
  try {
15243
15663
  if (process.platform === "win32") {
15244
15664
  const username = import_node_os4.default.userInfo().username;
15245
- (0, import_node_child_process14.execFileSync)(
15665
+ (0, import_node_child_process15.execFileSync)(
15246
15666
  "icacls",
15247
15667
  [
15248
15668
  filePath,
@@ -15264,7 +15684,7 @@ function restrictToOwner(filePath) {
15264
15684
  function sampleCpuTimes() {
15265
15685
  let idle = 0;
15266
15686
  let total = 0;
15267
- for (const cpu of os28.cpus()) {
15687
+ for (const cpu of os29.cpus()) {
15268
15688
  const t2 = cpu.times;
15269
15689
  idle += t2.idle;
15270
15690
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -15283,8 +15703,8 @@ var MetricsCollector = class {
15283
15703
  const prev = this.prevCpu;
15284
15704
  this.prevCpu = current;
15285
15705
  if (!prev) {
15286
- const cores = os28.cpus().length || 1;
15287
- const proxy = os28.loadavg()[0] / cores * 100;
15706
+ const cores = os29.cpus().length || 1;
15707
+ const proxy = os29.loadavg()[0] / cores * 100;
15288
15708
  return Math.min(100, Math.max(0, Math.round(proxy)));
15289
15709
  }
15290
15710
  const idleDelta = current.idle - prev.idle;
@@ -15297,8 +15717,8 @@ var MetricsCollector = class {
15297
15717
  collect() {
15298
15718
  return {
15299
15719
  cpuPct: this.cpuPct(),
15300
- ramUsedMb: Math.round((os28.totalmem() - os28.freemem()) / 1048576),
15301
- ramTotalMb: Math.round(os28.totalmem() / 1048576),
15720
+ ramUsedMb: Math.round((os29.totalmem() - os29.freemem()) / 1048576),
15721
+ ramTotalMb: Math.round(os29.totalmem() / 1048576),
15302
15722
  latencyMs: this.lastLatencyMs
15303
15723
  };
15304
15724
  }
@@ -15307,19 +15727,19 @@ function apiBase() {
15307
15727
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
15308
15728
  }
15309
15729
  function hostIdentityPath() {
15310
- return path35.join(os28.homedir(), ".codeam", "host-agent.json");
15730
+ return path36.join(os29.homedir(), ".codeam", "host-agent.json");
15311
15731
  }
15312
15732
  function collectOsInfo() {
15313
15733
  return {
15314
- distro: os28.platform(),
15315
- arch: os28.arch(),
15316
- kernel: os28.release(),
15734
+ distro: os29.platform(),
15735
+ arch: os29.arch(),
15736
+ kernel: os29.release(),
15317
15737
  nodeVersion: process.versions.node
15318
15738
  };
15319
15739
  }
15320
15740
  function loadHostIdentity() {
15321
15741
  try {
15322
- const raw = fs32.readFileSync(hostIdentityPath(), "utf8");
15742
+ const raw = fs33.readFileSync(hostIdentityPath(), "utf8");
15323
15743
  const parsed = JSON.parse(raw);
15324
15744
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
15325
15745
  const p2 = parsed;
@@ -15332,8 +15752,8 @@ function loadHostIdentity() {
15332
15752
  }
15333
15753
  function saveHostIdentity(identity) {
15334
15754
  const file = hostIdentityPath();
15335
- fs32.mkdirSync(path35.dirname(file), { recursive: true, mode: 448 });
15336
- 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), {
15337
15757
  encoding: "utf8",
15338
15758
  mode: 384
15339
15759
  });
@@ -15378,7 +15798,7 @@ function isTerminalEnrollError(err) {
15378
15798
  }
15379
15799
  function deleteHostIdentity() {
15380
15800
  try {
15381
- fs32.rmSync(hostIdentityPath(), { force: true });
15801
+ fs33.rmSync(hostIdentityPath(), { force: true });
15382
15802
  } catch {
15383
15803
  }
15384
15804
  }
@@ -15501,17 +15921,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
15501
15921
  }
15502
15922
 
15503
15923
  // src/commands/host/workspace.ts
15504
- var fs33 = __toESM(require("fs"));
15505
- var os29 = __toESM(require("os"));
15506
- var path36 = __toESM(require("path"));
15507
- 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");
15508
15928
  var import_node_util4 = require("util");
15509
- 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);
15510
15930
  function isAbsolutePathTarget(target) {
15511
- return path36.isAbsolute(target);
15931
+ return path37.isAbsolute(target);
15512
15932
  }
15513
15933
  function selfHostedWorkspaceRoot() {
15514
- return path36.join(os29.homedir(), ".codeam", "self-hosted");
15934
+ return path37.join(os30.homedir(), ".codeam", "self-hosted");
15515
15935
  }
15516
15936
  function nonInteractiveGitEnv() {
15517
15937
  return {
@@ -15564,13 +15984,13 @@ async function fetchGithubIdentity(token) {
15564
15984
  async function configureGitCredentials(dest, repoRef, cloneToken) {
15565
15985
  const gh = githubOwnerRepo(repoRef.trim());
15566
15986
  if (!gh || !cloneToken) return;
15567
- const credFile = path36.join(dest, ".git", "codeam-credentials");
15568
- 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
15569
15989
  `, { mode: 384 });
15570
15990
  restrictToOwner(credFile);
15571
15991
  const env = nonInteractiveGitEnv();
15572
15992
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
15573
- const credFilePosix = credFile.split(path36.sep).join("/");
15993
+ const credFilePosix = credFile.split(path37.sep).join("/");
15574
15994
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
15575
15995
  });
15576
15996
  await git2([
@@ -15606,17 +16026,17 @@ function maskToken(text, cloneToken) {
15606
16026
  }
15607
16027
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
15608
16028
  if (isAbsolutePathTarget(repoOrPath)) {
15609
- if (!fs33.existsSync(repoOrPath)) {
16029
+ if (!fs34.existsSync(repoOrPath)) {
15610
16030
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
15611
16031
  }
15612
16032
  return repoOrPath;
15613
16033
  }
15614
- const dest = path36.join(selfHostedWorkspaceRoot(), deployId);
15615
- if (fs33.existsSync(path36.join(dest, ".git"))) {
16034
+ const dest = path37.join(selfHostedWorkspaceRoot(), deployId);
16035
+ if (fs34.existsSync(path37.join(dest, ".git"))) {
15616
16036
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
15617
16037
  return dest;
15618
16038
  }
15619
- fs33.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
16039
+ fs34.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
15620
16040
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
15621
16041
  try {
15622
16042
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -15633,9 +16053,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
15633
16053
  }
15634
16054
 
15635
16055
  // src/commands/host/agent-provisioning.ts
15636
- var fs34 = __toESM(require("fs"));
15637
- var os30 = __toESM(require("os"));
15638
- var path37 = __toESM(require("path"));
16056
+ var fs35 = __toESM(require("fs"));
16057
+ var os31 = __toESM(require("os"));
16058
+ var path38 = __toESM(require("path"));
15639
16059
  var PUBLIC_TO_INTERNAL_AGENT = {
15640
16060
  claude_code: "claude",
15641
16061
  claude: "claude",
@@ -15651,22 +16071,22 @@ function toInternalAgentId(publicAgentId) {
15651
16071
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
15652
16072
  }
15653
16073
  function ensureDir(dir) {
15654
- fs34.mkdirSync(dir, { recursive: true, mode: 448 });
16074
+ fs35.mkdirSync(dir, { recursive: true, mode: 448 });
15655
16075
  }
15656
16076
  function writeFile0600(filePath, contents) {
15657
- ensureDir(path37.dirname(filePath));
15658
- fs34.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
16077
+ ensureDir(path38.dirname(filePath));
16078
+ fs35.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
15659
16079
  restrictToOwner(filePath);
15660
16080
  }
15661
16081
  function rmIfExists(filePath) {
15662
16082
  try {
15663
- fs34.rmSync(filePath, { force: true });
16083
+ fs35.rmSync(filePath, { force: true });
15664
16084
  } catch {
15665
16085
  }
15666
16086
  }
15667
16087
  var claudeProvisioner = {
15668
16088
  write(auth, home) {
15669
- const credentialsJson = path37.join(home, ".claude", ".credentials.json");
16089
+ const credentialsJson = path38.join(home, ".claude", ".credentials.json");
15670
16090
  if (auth.kind === "api_key") {
15671
16091
  rmIfExists(credentialsJson);
15672
16092
  return { ANTHROPIC_API_KEY: auth.value };
@@ -15678,8 +16098,8 @@ var claudeProvisioner = {
15678
16098
  } else {
15679
16099
  rmIfExists(credentialsJson);
15680
16100
  }
15681
- const claudeJson = path37.join(home, ".claude.json");
15682
- if (!fs34.existsSync(claudeJson)) {
16101
+ const claudeJson = path38.join(home, ".claude.json");
16102
+ if (!fs35.existsSync(claudeJson)) {
15683
16103
  writeFile0600(
15684
16104
  claudeJson,
15685
16105
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -15690,7 +16110,7 @@ var claudeProvisioner = {
15690
16110
  };
15691
16111
  var codexProvisioner = {
15692
16112
  write(auth, home) {
15693
- const authJson = path37.join(home, ".codex", "auth.json");
16113
+ const authJson = path38.join(home, ".codex", "auth.json");
15694
16114
  if (auth.kind === "api_key") {
15695
16115
  rmIfExists(authJson);
15696
16116
  return { OPENAI_API_KEY: auth.value };
@@ -15701,8 +16121,8 @@ var codexProvisioner = {
15701
16121
  };
15702
16122
  var geminiProvisioner = {
15703
16123
  write(auth, home) {
15704
- const settingsJson = path37.join(home, ".gemini", "settings.json");
15705
- 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");
15706
16126
  if (auth.kind === "api_key") {
15707
16127
  rmIfExists(oauthCreds);
15708
16128
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -15715,7 +16135,7 @@ var geminiProvisioner = {
15715
16135
  };
15716
16136
  var cursorProvisioner = {
15717
16137
  write(auth, home) {
15718
- const authJson = path37.join(home, ".config", "cursor", "auth.json");
16138
+ const authJson = path38.join(home, ".config", "cursor", "auth.json");
15719
16139
  if (auth.kind === "api_key") {
15720
16140
  rmIfExists(authJson);
15721
16141
  return { CURSOR_API_KEY: auth.value };
@@ -15741,8 +16161,8 @@ var cursorProvisioner = {
15741
16161
  var kimiProvisioner = {
15742
16162
  write(auth, home) {
15743
16163
  const credentialsFiles = [
15744
- path37.join(home, ".kimi", "credentials", "kimi-code.json"),
15745
- 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")
15746
16166
  ];
15747
16167
  if (auth.kind === "api_key") {
15748
16168
  credentialsFiles.forEach(rmIfExists);
@@ -15752,12 +16172,38 @@ var kimiProvisioner = {
15752
16172
  return {};
15753
16173
  }
15754
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
+ };
15755
16200
  var PROVISIONERS = {
15756
16201
  claude: claudeProvisioner,
15757
16202
  kimi: kimiProvisioner,
15758
16203
  codex: codexProvisioner,
15759
16204
  gemini: geminiProvisioner,
15760
- cursor: cursorProvisioner
16205
+ cursor: cursorProvisioner,
16206
+ coderabbit: coderabbitProvisioner
15761
16207
  };
15762
16208
  var UnsupportedAgentError = class extends Error {
15763
16209
  agentId;
@@ -15767,7 +16213,7 @@ var UnsupportedAgentError = class extends Error {
15767
16213
  this.agentId = agentId;
15768
16214
  }
15769
16215
  };
15770
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir()) {
16216
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os31.homedir()) {
15771
16217
  const internal = toInternalAgentId(publicAgentId);
15772
16218
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
15773
16219
  const provisioner = PROVISIONERS[internal];
@@ -15776,12 +16222,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os30.homedir(
15776
16222
  }
15777
16223
 
15778
16224
  // src/commands/host/git-tooling.ts
15779
- var import_node_child_process16 = require("child_process");
15780
- var fs35 = __toESM(require("fs"));
15781
- var os31 = __toESM(require("os"));
15782
- 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"));
15783
16229
  function codeamBinDir() {
15784
- 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");
15785
16231
  }
15786
16232
  var FALLBACK_GH_VERSION = "2.62.0";
15787
16233
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -15813,7 +16259,7 @@ async function download(url, dest) {
15813
16259
  const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
15814
16260
  if (!res.ok || !res.body) return false;
15815
16261
  const buf = Buffer.from(await res.arrayBuffer());
15816
- fs35.writeFileSync(dest, buf);
16262
+ fs36.writeFileSync(dest, buf);
15817
16263
  return true;
15818
16264
  } catch {
15819
16265
  return false;
@@ -15836,8 +16282,8 @@ async function ensureGhCli(runner, token, deps = {}) {
15836
16282
  const version3 = await resolveVersionFn(token);
15837
16283
  const asset = `gh_${version3}_${osToken}_${arch2}`;
15838
16284
  const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
15839
- const tmpRoot = fs35.mkdtempSync(path38.join(os31.tmpdir(), "codeam-gh-"));
15840
- 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}`);
15841
16287
  if (!await downloadFn(url, archive)) {
15842
16288
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
15843
16289
  return null;
@@ -15847,16 +16293,16 @@ async function ensureGhCli(runner, token, deps = {}) {
15847
16293
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
15848
16294
  return null;
15849
16295
  }
15850
- const extractedBin = path38.join(tmpRoot, asset, "bin", binaryName);
15851
- if (!fs35.existsSync(extractedBin)) {
16296
+ const extractedBin = path39.join(tmpRoot, asset, "bin", binaryName);
16297
+ if (!fs36.existsSync(extractedBin)) {
15852
16298
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
15853
16299
  return null;
15854
16300
  }
15855
16301
  const binDir = codeamBinDir();
15856
- fs35.mkdirSync(binDir, { recursive: true });
15857
- const target = path38.join(binDir, binaryName);
15858
- fs35.copyFileSync(extractedBin, target);
15859
- 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);
15860
16306
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
15861
16307
  return target;
15862
16308
  } catch (e) {
@@ -15890,7 +16336,7 @@ var defaultGitToolingRunner = {
15890
16336
  which(cmd) {
15891
16337
  try {
15892
16338
  const probe = process.platform === "win32" ? "where" : "which";
15893
- (0, import_node_child_process16.execFileSync)(probe, [cmd], { stdio: "ignore" });
16339
+ (0, import_node_child_process17.execFileSync)(probe, [cmd], { stdio: "ignore" });
15894
16340
  return true;
15895
16341
  } catch {
15896
16342
  return false;
@@ -15898,7 +16344,7 @@ var defaultGitToolingRunner = {
15898
16344
  },
15899
16345
  run(cmd, args2, opts = {}) {
15900
16346
  return new Promise((resolve7) => {
15901
- const child = (0, import_node_child_process16.spawn)(cmd, args2, {
16347
+ const child = (0, import_node_child_process17.spawn)(cmd, args2, {
15902
16348
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
15903
16349
  });
15904
16350
  let stderr = "";
@@ -16052,12 +16498,12 @@ var HeadroomStatsReporter = class {
16052
16498
  };
16053
16499
 
16054
16500
  // src/commands/host/os-packages.ts
16055
- var import_node_child_process17 = require("child_process");
16501
+ var import_node_child_process18 = require("child_process");
16056
16502
  var PM_INSTALL_TIMEOUT_MS = 18e4;
16057
16503
  var defaultHeadroomRunner = {
16058
16504
  which(cmd) {
16059
16505
  try {
16060
- (0, import_node_child_process17.execFileSync)("which", [cmd], { stdio: "ignore" });
16506
+ (0, import_node_child_process18.execFileSync)("which", [cmd], { stdio: "ignore" });
16061
16507
  return true;
16062
16508
  } catch {
16063
16509
  return false;
@@ -16066,7 +16512,7 @@ var defaultHeadroomRunner = {
16066
16512
  run(cmd, args2, opts = {}) {
16067
16513
  return new Promise((resolve7) => {
16068
16514
  const spawnEnv = opts.env ?? process.env;
16069
- 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 });
16070
16516
  let stderrBuf = "";
16071
16517
  let stdoutBuf = "";
16072
16518
  let settled = false;
@@ -16343,23 +16789,23 @@ async function ensureModernPython(runner) {
16343
16789
  }
16344
16790
 
16345
16791
  // src/commands/host/headroom-bootstrap.ts
16346
- var fs37 = __toESM(require("fs"));
16347
- var path40 = __toESM(require("path"));
16792
+ var fs38 = __toESM(require("fs"));
16793
+ var path41 = __toESM(require("path"));
16348
16794
 
16349
16795
  // src/commands/host/headroom-config.ts
16350
- var fs36 = __toESM(require("fs"));
16351
- var os32 = __toESM(require("os"));
16352
- var path39 = __toESM(require("path"));
16796
+ var fs37 = __toESM(require("fs"));
16797
+ var os33 = __toESM(require("os"));
16798
+ var path40 = __toESM(require("path"));
16353
16799
  function headroomConfigPath() {
16354
- return path39.join(os32.homedir(), ".codeam", "headroom-config.json");
16800
+ return path40.join(os33.homedir(), ".codeam", "headroom-config.json");
16355
16801
  }
16356
16802
  function persistHeadroomConfig(config) {
16357
16803
  try {
16358
16804
  const file = headroomConfigPath();
16359
- fs36.mkdirSync(path39.dirname(file), { recursive: true, mode: 448 });
16805
+ fs37.mkdirSync(path40.dirname(file), { recursive: true, mode: 448 });
16360
16806
  const tmp = `${file}.tmp-${process.pid}`;
16361
- fs36.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
16362
- fs36.renameSync(tmp, file);
16807
+ fs37.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
16808
+ fs37.renameSync(tmp, file);
16363
16809
  restrictToOwner(file);
16364
16810
  } catch (err) {
16365
16811
  log.warn(
@@ -16369,21 +16815,21 @@ function persistHeadroomConfig(config) {
16369
16815
  }
16370
16816
  }
16371
16817
  function agentSettingsPath(kind) {
16372
- const home = os32.homedir();
16373
- if (kind === "claude") return path39.join(home, ".claude", "settings.json");
16374
- if (kind === "codex") return path39.join(home, ".codex", "auth.json");
16375
- 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");
16376
16822
  return null;
16377
16823
  }
16378
16824
  function backupAgentHeadroomConfig(kind) {
16379
16825
  const src = agentSettingsPath(kind);
16380
16826
  if (!src) return;
16381
16827
  try {
16382
- if (!fs36.existsSync(src)) return;
16383
- const dest = path39.join(os32.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16384
- fs36.mkdirSync(path39.dirname(dest), { recursive: true, mode: 448 });
16385
- fs36.copyFileSync(src, dest);
16386
- 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);
16387
16833
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
16388
16834
  } catch (err) {
16389
16835
  log.warn(
@@ -16395,12 +16841,12 @@ function backupAgentHeadroomConfig(kind) {
16395
16841
  function restoreAgentHeadroomConfig(kind) {
16396
16842
  const dest = agentSettingsPath(kind);
16397
16843
  if (!dest) return false;
16398
- const src = path39.join(os32.homedir(), ".codeam", `headroom-backup-${kind}.json`);
16399
- 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;
16400
16846
  try {
16401
- fs36.mkdirSync(path39.dirname(dest), { recursive: true, mode: 448 });
16402
- fs36.copyFileSync(src, dest);
16403
- fs36.chmodSync(dest, 384);
16847
+ fs37.mkdirSync(path40.dirname(dest), { recursive: true, mode: 448 });
16848
+ fs37.copyFileSync(src, dest);
16849
+ fs37.chmodSync(dest, 384);
16404
16850
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
16405
16851
  return true;
16406
16852
  } catch (err) {
@@ -16413,7 +16859,7 @@ function restoreAgentHeadroomConfig(kind) {
16413
16859
  }
16414
16860
  function readHeadroomChildEnv() {
16415
16861
  try {
16416
- const raw = fs36.readFileSync(headroomConfigPath(), "utf8");
16862
+ const raw = fs37.readFileSync(headroomConfigPath(), "utf8");
16417
16863
  const parsed = JSON.parse(raw);
16418
16864
  if (typeof parsed !== "object" || parsed === null) return {};
16419
16865
  const o = parsed;
@@ -16449,37 +16895,37 @@ function bundledClaudeBinDir() {
16449
16895
  const roots = /* @__PURE__ */ new Set();
16450
16896
  let dir = __dirname;
16451
16897
  for (let i = 0; i < 6; i++) {
16452
- roots.add(path40.join(dir, "node_modules"));
16453
- const parent = path40.dirname(dir);
16898
+ roots.add(path41.join(dir, "node_modules"));
16899
+ const parent = path41.dirname(dir);
16454
16900
  if (parent === dir) break;
16455
16901
  dir = parent;
16456
16902
  }
16457
16903
  try {
16458
16904
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
16459
- const marker = `${path40.sep}@anthropic-ai${path40.sep}`;
16905
+ const marker = `${path41.sep}@anthropic-ai${path41.sep}`;
16460
16906
  const idx = main2.lastIndexOf(marker);
16461
16907
  if (idx !== -1) roots.add(main2.slice(0, idx));
16462
16908
  } catch {
16463
16909
  }
16464
16910
  for (const nm of roots) {
16465
- const atAnthropic = path40.join(nm, "@anthropic-ai");
16911
+ const atAnthropic = path41.join(nm, "@anthropic-ai");
16466
16912
  let entries;
16467
16913
  try {
16468
- entries = fs37.readdirSync(atAnthropic);
16914
+ entries = fs38.readdirSync(atAnthropic);
16469
16915
  } catch {
16470
16916
  continue;
16471
16917
  }
16472
16918
  for (const entry of entries) {
16473
16919
  if (!entry.startsWith("claude-agent-sdk-")) continue;
16474
- const bin = path40.join(atAnthropic, entry, "claude");
16475
- 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);
16476
16922
  }
16477
16923
  }
16478
16924
  return null;
16479
16925
  }
16480
16926
  async function getFreeDiskBytes(dir) {
16481
16927
  try {
16482
- const s = await fs37.promises.statfs(dir);
16928
+ const s = await fs38.promises.statfs(dir);
16483
16929
  return s.bsize * s.bavail;
16484
16930
  } catch {
16485
16931
  return null;
@@ -16541,7 +16987,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
16541
16987
  if (initKind === "claude") {
16542
16988
  const claudeDir = bundledClaudeBinDir();
16543
16989
  if (claudeDir) {
16544
- initEnv.PATH = `${claudeDir}${path40.delimiter}${process.env["PATH"] ?? ""}`;
16990
+ initEnv.PATH = `${claudeDir}${path41.delimiter}${process.env["PATH"] ?? ""}`;
16545
16991
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
16546
16992
  } else {
16547
16993
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -16573,26 +17019,26 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
16573
17019
  }
16574
17020
 
16575
17021
  // src/commands/host/self-update.ts
16576
- var import_node_child_process19 = require("child_process");
17022
+ var import_node_child_process20 = require("child_process");
16577
17023
 
16578
17024
  // src/lib/updateNotifier.ts
16579
- var fs38 = __toESM(require("fs"));
16580
- var os33 = __toESM(require("os"));
16581
- var path41 = __toESM(require("path"));
17025
+ var fs39 = __toESM(require("fs"));
17026
+ var os34 = __toESM(require("os"));
17027
+ var path42 = __toESM(require("path"));
16582
17028
  var https6 = __toESM(require("https"));
16583
- var import_node_child_process18 = require("child_process");
17029
+ var import_node_child_process19 = require("child_process");
16584
17030
  var import_picocolors3 = __toESM(require("picocolors"));
16585
17031
  var PKG_NAME = "codeam-cli";
16586
17032
  var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
16587
17033
  var TTL_MS = 24 * 60 * 60 * 1e3;
16588
17034
  var REQUEST_TIMEOUT_MS = 1500;
16589
17035
  function cachePath() {
16590
- const dir = path41.join(os33.homedir(), ".codeam");
16591
- return path41.join(dir, "update-check.json");
17036
+ const dir = path42.join(os34.homedir(), ".codeam");
17037
+ return path42.join(dir, "update-check.json");
16592
17038
  }
16593
17039
  function readCache() {
16594
17040
  try {
16595
- const raw = fs38.readFileSync(cachePath(), "utf8");
17041
+ const raw = fs39.readFileSync(cachePath(), "utf8");
16596
17042
  const parsed = JSON.parse(raw);
16597
17043
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
16598
17044
  return parsed;
@@ -16603,10 +17049,10 @@ function readCache() {
16603
17049
  function writeCache(cache) {
16604
17050
  try {
16605
17051
  const file = cachePath();
16606
- fs38.mkdirSync(path41.dirname(file), { recursive: true });
17052
+ fs39.mkdirSync(path42.dirname(file), { recursive: true });
16607
17053
  const tmp = `${file}.${process.pid}.tmp`;
16608
- fs38.writeFileSync(tmp, JSON.stringify(cache));
16609
- fs38.renameSync(tmp, file);
17054
+ fs39.writeFileSync(tmp, JSON.stringify(cache));
17055
+ fs39.renameSync(tmp, file);
16610
17056
  } catch {
16611
17057
  }
16612
17058
  }
@@ -16674,14 +17120,14 @@ function notifyIfStale(currentVersion, latest) {
16674
17120
  }
16675
17121
  function isLinkedInstall() {
16676
17122
  try {
16677
- const root = (0, import_node_child_process18.execSync)("npm root -g", {
17123
+ const root = (0, import_node_child_process19.execSync)("npm root -g", {
16678
17124
  encoding: "utf8",
16679
17125
  stdio: ["ignore", "pipe", "ignore"],
16680
17126
  timeout: 2e3
16681
17127
  }).trim();
16682
17128
  if (!root) return false;
16683
- const pkgPath = path41.join(root, PKG_NAME);
16684
- return fs38.lstatSync(pkgPath).isSymbolicLink();
17129
+ const pkgPath = path42.join(root, PKG_NAME);
17130
+ return fs39.lstatSync(pkgPath).isSymbolicLink();
16685
17131
  } catch {
16686
17132
  return false;
16687
17133
  }
@@ -16702,7 +17148,7 @@ function maybeAutoUpdate(currentVersion, latest) {
16702
17148
 
16703
17149
  `
16704
17150
  );
16705
- 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`], {
16706
17152
  stdio: "inherit",
16707
17153
  env: process.env
16708
17154
  });
@@ -16717,13 +17163,13 @@ function maybeAutoUpdate(currentVersion, latest) {
16717
17163
  return;
16718
17164
  }
16719
17165
  try {
16720
- fs38.unlinkSync(cachePath());
17166
+ fs39.unlinkSync(cachePath());
16721
17167
  } catch {
16722
17168
  }
16723
17169
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
16724
17170
 
16725
17171
  `);
16726
- 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), {
16727
17173
  stdio: "inherit",
16728
17174
  env: process.env
16729
17175
  });
@@ -16733,7 +17179,7 @@ async function autoUpgradeBeforeCriticalCommand() {
16733
17179
  if (process.env.NODE_ENV === "test") return;
16734
17180
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16735
17181
  if (process.env.CI) return;
16736
- const current = true ? "2.60.22" : null;
17182
+ const current = true ? "2.60.24" : null;
16737
17183
  if (!current) return;
16738
17184
  const cache = readCache();
16739
17185
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16750,7 +17196,7 @@ function checkForUpdates() {
16750
17196
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16751
17197
  if (process.env.CI) return;
16752
17198
  if (!process.stdout.isTTY) return;
16753
- const current = true ? "2.60.22" : null;
17199
+ const current = true ? "2.60.24" : null;
16754
17200
  if (!current) return;
16755
17201
  const cache = readCache();
16756
17202
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16770,11 +17216,11 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
16770
17216
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
16771
17217
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
16772
17218
  function currentCliVersion() {
16773
- return true ? "2.60.22" : null;
17219
+ return true ? "2.60.24" : null;
16774
17220
  }
16775
17221
  function runCmd(cmd, args2, timeoutMs) {
16776
17222
  return new Promise((resolve7) => {
16777
- (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) => {
16778
17224
  const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
16779
17225
  resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
16780
17226
  });
@@ -16836,19 +17282,19 @@ async function runSelfUpdate() {
16836
17282
  }
16837
17283
 
16838
17284
  // src/commands/host/teardown.ts
16839
- var import_node_child_process20 = require("child_process");
16840
- var fs39 = __toESM(require("fs"));
17285
+ var import_node_child_process21 = require("child_process");
17286
+ var fs40 = __toESM(require("fs"));
16841
17287
  var defaultDisableService = () => {
16842
17288
  try {
16843
- (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" });
16844
17290
  } catch {
16845
17291
  }
16846
17292
  };
16847
17293
  var defaultTeardownHeadroom = () => {
16848
17294
  try {
16849
- const kind = JSON.parse(fs39.readFileSync(headroomConfigPath(), "utf8")).agent;
17295
+ const kind = JSON.parse(fs40.readFileSync(headroomConfigPath(), "utf8")).agent;
16850
17296
  if (kind) {
16851
- (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 });
16852
17298
  }
16853
17299
  } catch {
16854
17300
  }
@@ -16914,8 +17360,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
16914
17360
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
16915
17361
  try {
16916
17362
  const file = headroomConfigPath();
16917
- if (!fs40.existsSync(file)) return null;
16918
- const cfg = JSON.parse(fs40.readFileSync(file, "utf8"));
17363
+ if (!fs41.existsSync(file)) return null;
17364
+ const cfg = JSON.parse(fs41.readFileSync(file, "utf8"));
16919
17365
  if (!cfg?.enabled) return null;
16920
17366
  const agent = cfg.agent ?? "claude";
16921
17367
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -17006,7 +17452,7 @@ var CONTROL_AGENT_META = {
17006
17452
  headroomWrappable: false,
17007
17453
  acp: false
17008
17454
  };
17009
- 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], {
17010
17456
  cwd,
17011
17457
  env: { ...process.env, ...env },
17012
17458
  stdio: ["ignore", "pipe", "pipe"],
@@ -17320,9 +17766,9 @@ var HostAgentSupervisor = class {
17320
17766
  API_TIMEOUT_MS: "3000000",
17321
17767
  CODEAM_AUTO_TOKEN: payload.autoPairToken
17322
17768
  };
17323
- const houseConfigDir = path42.join(os34.homedir(), ".codeam", "house-claude");
17769
+ const houseConfigDir = path43.join(os35.homedir(), ".codeam", "house-claude");
17324
17770
  try {
17325
- fs40.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
17771
+ fs41.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
17326
17772
  } catch {
17327
17773
  }
17328
17774
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -17340,14 +17786,14 @@ var HostAgentSupervisor = class {
17340
17786
  report("installing", "installing agent CLI");
17341
17787
  await this.runAgentInstall(payload.agentInstallScript);
17342
17788
  }
17343
- const home = process.env.HOME || os34.homedir();
17789
+ const home = process.env.HOME || os35.homedir();
17344
17790
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
17345
17791
  if (payload.cloneToken) {
17346
17792
  try {
17347
17793
  report("preparing", "configuring git tooling");
17348
17794
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
17349
17795
  if (ghCmd) {
17350
- childEnv.PATH = `${codeamBinDir()}${path42.delimiter}${childEnv.PATH}`;
17796
+ childEnv.PATH = `${codeamBinDir()}${path43.delimiter}${childEnv.PATH}`;
17351
17797
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
17352
17798
  }
17353
17799
  } catch (e) {
@@ -17363,7 +17809,7 @@ var HostAgentSupervisor = class {
17363
17809
  }
17364
17810
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
17365
17811
  report("headroom", "setting up Headroom proxy");
17366
- const freeBytes = await this.getFreeDisk(os34.homedir());
17812
+ const freeBytes = await this.getFreeDisk(os35.homedir());
17367
17813
  const alreadyInstalled = this.isHeadroomInstalled();
17368
17814
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
17369
17815
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -17485,8 +17931,8 @@ var HostAgentSupervisor = class {
17485
17931
  */
17486
17932
  runAgentInstall(script) {
17487
17933
  return new Promise((resolve7) => {
17488
- const home = process.env.HOME || os34.homedir();
17489
- 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], {
17490
17936
  env: { ...process.env, HOME: home },
17491
17937
  stdio: ["ignore", "pipe", "pipe"]
17492
17938
  });
@@ -17669,9 +18115,9 @@ async function configureHeadroom(action, ctx, deps) {
17669
18115
  }
17670
18116
 
17671
18117
  // src/services/headroom/budget-relaunch.ts
17672
- var fs41 = __toESM(require("fs"));
17673
- var os35 = __toESM(require("os"));
17674
- var path43 = __toESM(require("path"));
18118
+ var fs42 = __toESM(require("fs"));
18119
+ var os36 = __toESM(require("os"));
18120
+ var path44 = __toESM(require("path"));
17675
18121
  var import_child_process13 = require("child_process");
17676
18122
  function amendDeploymentManifestBudget(manifest, budget) {
17677
18123
  const rawArgs = manifest.proxy_args ?? [];
@@ -17705,7 +18151,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
17705
18151
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
17706
18152
  }
17707
18153
  function findHeadroomDeployments(homeDir2, deps) {
17708
- const deployDir = path43.join(homeDir2, ".headroom", "deploy");
18154
+ const deployDir = path44.join(homeDir2, ".headroom", "deploy");
17709
18155
  let profiles;
17710
18156
  try {
17711
18157
  profiles = deps.readDir(deployDir);
@@ -17714,7 +18160,7 @@ function findHeadroomDeployments(homeDir2, deps) {
17714
18160
  }
17715
18161
  const results = [];
17716
18162
  for (const profile of profiles) {
17717
- const manifestPath = path43.join(deployDir, profile, "manifest.json");
18163
+ const manifestPath = path44.join(deployDir, profile, "manifest.json");
17718
18164
  let raw;
17719
18165
  try {
17720
18166
  raw = deps.readJson(manifestPath);
@@ -17746,8 +18192,8 @@ async function applyBudgetToHeadroom(budget, deps) {
17746
18192
  }
17747
18193
  function writeManifestReal(manifestPath, manifest) {
17748
18194
  const tmp = manifestPath + ".codeam.tmp";
17749
- fs41.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
17750
- fs41.renameSync(tmp, manifestPath);
18195
+ fs42.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
18196
+ fs42.renameSync(tmp, manifestPath);
17751
18197
  }
17752
18198
  function restartDeploymentReal(profile) {
17753
18199
  try {
@@ -17777,11 +18223,11 @@ function spawnProxyReal2(_budget) {
17777
18223
  });
17778
18224
  }
17779
18225
  function makeRealApplyBudgetDeps() {
17780
- const homeDir2 = os35.homedir();
18226
+ const homeDir2 = os36.homedir();
17781
18227
  return {
17782
18228
  findDeployments: () => findHeadroomDeployments(homeDir2, {
17783
- readDir: (dir) => fs41.readdirSync(dir),
17784
- readJson: (filePath) => JSON.parse(fs41.readFileSync(filePath, "utf8"))
18229
+ readDir: (dir) => fs42.readdirSync(dir),
18230
+ readJson: (filePath) => JSON.parse(fs42.readFileSync(filePath, "utf8"))
17785
18231
  }),
17786
18232
  writeManifest: writeManifestReal,
17787
18233
  restartDeployment: restartDeploymentReal,
@@ -17794,11 +18240,11 @@ function makeRealApplyBudgetDeps() {
17794
18240
  var import_child_process14 = require("child_process");
17795
18241
  var import_fs = require("fs");
17796
18242
  var import_promises = __toESM(require("fs/promises"));
17797
- var import_os7 = __toESM(require("os"));
18243
+ var import_os8 = __toESM(require("os"));
17798
18244
  var import_path4 = __toESM(require("path"));
17799
18245
  var import_promises2 = require("stream/promises");
17800
18246
  var import_which = __toESM(require("which"));
17801
- 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");
17802
18248
  async function resolveCloudflared(opts = {}) {
17803
18249
  try {
17804
18250
  return await (0, import_which.default)("cloudflared");
@@ -17898,7 +18344,7 @@ function decodeTunnelToken(token) {
17898
18344
  }
17899
18345
  async function spawnNamedTunnel(bin, token, port) {
17900
18346
  const creds = decodeTunnelToken(token);
17901
- const credDir = import_path4.default.join(import_os7.default.homedir(), ".codeam");
18347
+ const credDir = import_path4.default.join(import_os8.default.homedir(), ".codeam");
17902
18348
  await import_promises.default.mkdir(credDir, { recursive: true });
17903
18349
  const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
17904
18350
  await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
@@ -18461,8 +18907,8 @@ function activePreviewSessionIds() {
18461
18907
 
18462
18908
  // src/services/preview/start-orchestrator.ts
18463
18909
  var import_child_process17 = require("child_process");
18464
- var fs46 = __toESM(require("fs"));
18465
- var path48 = __toESM(require("path"));
18910
+ var fs47 = __toESM(require("fs"));
18911
+ var path49 = __toESM(require("path"));
18466
18912
  var import_which2 = __toESM(require("which"));
18467
18913
  var INSTALL_TIMEOUT_MS = 5 * 6e4;
18468
18914
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -18529,8 +18975,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
18529
18975
  if (args2.length === 0) return detection;
18530
18976
  const binName = args2[0];
18531
18977
  if (binName.startsWith("-")) return detection;
18532
- const binPath = path48.join(cwd, "node_modules", ".bin", binName);
18533
- if (!fs46.existsSync(binPath)) return detection;
18978
+ const binPath = path49.join(cwd, "node_modules", ".bin", binName);
18979
+ if (!fs47.existsSync(binPath)) return detection;
18534
18980
  return {
18535
18981
  ...detection,
18536
18982
  command: binPath,
@@ -18880,9 +19326,9 @@ async function establishTunnel(ctx, dev) {
18880
19326
 
18881
19327
  // src/beads/bd-adapter.ts
18882
19328
  var import_child_process18 = require("child_process");
18883
- var fs47 = __toESM(require("fs"));
18884
- var os37 = __toESM(require("os"));
18885
- var path49 = __toESM(require("path"));
19329
+ var fs48 = __toESM(require("fs"));
19330
+ var os38 = __toESM(require("os"));
19331
+ var path50 = __toESM(require("path"));
18886
19332
  var BD_PACKAGE = "@beads/bd";
18887
19333
  function resolveBundledBdBinary() {
18888
19334
  return _resolveSeam.resolveBundled();
@@ -18894,11 +19340,11 @@ function _defaultResolveBundled() {
18894
19340
  } catch {
18895
19341
  return null;
18896
19342
  }
18897
- const binDir = path49.join(path49.dirname(pkgJsonPath), "bin");
19343
+ const binDir = path50.join(path50.dirname(pkgJsonPath), "bin");
18898
19344
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
18899
- const binaryPath = path49.join(binDir, binaryName);
19345
+ const binaryPath = path50.join(binDir, binaryName);
18900
19346
  try {
18901
- fs47.accessSync(binaryPath, fs47.constants.F_OK);
19347
+ fs48.accessSync(binaryPath, fs48.constants.F_OK);
18902
19348
  return binaryPath;
18903
19349
  } catch {
18904
19350
  return null;
@@ -18908,13 +19354,13 @@ function resolveBdOnPath() {
18908
19354
  return _resolveSeam.resolveOnPath();
18909
19355
  }
18910
19356
  function _defaultResolveOnPath() {
18911
- const dirs = (process.env.PATH ?? "").split(path49.delimiter).filter(Boolean);
19357
+ const dirs = (process.env.PATH ?? "").split(path50.delimiter).filter(Boolean);
18912
19358
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
18913
19359
  for (const dir of dirs) {
18914
19360
  for (const candidate of candidates) {
18915
- const full = path49.join(dir, candidate);
19361
+ const full = path50.join(dir, candidate);
18916
19362
  try {
18917
- fs47.accessSync(full, fs47.constants.F_OK);
19363
+ fs48.accessSync(full, fs48.constants.F_OK);
18918
19364
  return full;
18919
19365
  } catch {
18920
19366
  }
@@ -18999,7 +19445,7 @@ var BdAdapter = class {
18999
19445
  const env = { ...process.env };
19000
19446
  if (!env.HOME) {
19001
19447
  try {
19002
- const home = os37.homedir();
19448
+ const home = os38.homedir();
19003
19449
  if (home) env.HOME = home;
19004
19450
  } catch {
19005
19451
  }
@@ -19091,9 +19537,9 @@ function coerceIssue(row, projectKey) {
19091
19537
 
19092
19538
  // src/beads/provisioner.ts
19093
19539
  var import_child_process22 = require("child_process");
19094
- var fs50 = __toESM(require("fs"));
19095
- var os39 = __toESM(require("os"));
19096
- var path52 = __toESM(require("path"));
19540
+ var fs51 = __toESM(require("fs"));
19541
+ var os40 = __toESM(require("os"));
19542
+ var path53 = __toESM(require("path"));
19097
19543
 
19098
19544
  // src/beads/install-bd.ts
19099
19545
  var import_child_process19 = require("child_process");
@@ -19158,9 +19604,9 @@ async function installBd(platform3 = process.platform) {
19158
19604
 
19159
19605
  // src/beads/install-dolt.ts
19160
19606
  var import_child_process20 = require("child_process");
19161
- var fs48 = __toESM(require("fs"));
19162
- var os38 = __toESM(require("os"));
19163
- var path50 = __toESM(require("path"));
19607
+ var fs49 = __toESM(require("fs"));
19608
+ var os39 = __toESM(require("os"));
19609
+ var path51 = __toESM(require("path"));
19164
19610
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
19165
19611
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
19166
19612
  function resolveDoltInstallStrategy(platform3) {
@@ -19200,11 +19646,11 @@ function resolveDoltInstallStrategy(platform3) {
19200
19646
  }
19201
19647
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
19202
19648
  function doltPlatformTuple(platform3, arch2) {
19203
- const os49 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
19649
+ const os50 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
19204
19650
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
19205
19651
  if (!a) return null;
19206
- if (os49 === "windows" && a !== "amd64") return null;
19207
- return `${os49}-${a}`;
19652
+ if (os50 === "windows" && a !== "amd64") return null;
19653
+ return `${os50}-${a}`;
19208
19654
  }
19209
19655
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
19210
19656
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -19249,14 +19695,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
19249
19695
  return result;
19250
19696
  }
19251
19697
  var _doltPathSeam = {
19252
- homedir: () => os38.homedir(),
19698
+ homedir: () => os39.homedir(),
19253
19699
  getPath: () => process.env.PATH ?? "",
19254
19700
  setPath: (p2) => {
19255
19701
  process.env.PATH = p2;
19256
19702
  },
19257
19703
  exists: (p2) => {
19258
19704
  try {
19259
- fs48.accessSync(p2, fs48.constants.F_OK);
19705
+ fs49.accessSync(p2, fs49.constants.F_OK);
19260
19706
  return true;
19261
19707
  } catch {
19262
19708
  return false;
@@ -19267,7 +19713,7 @@ function doltBinaryNames(platform3) {
19267
19713
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
19268
19714
  }
19269
19715
  function knownDoltDirs(platform3) {
19270
- const P3 = platform3 === "win32" ? path50.win32 : path50.posix;
19716
+ const P3 = platform3 === "win32" ? path51.win32 : path51.posix;
19271
19717
  const home = _doltPathSeam.homedir();
19272
19718
  if (platform3 === "win32") {
19273
19719
  return [
@@ -19283,7 +19729,7 @@ function knownDoltDirs(platform3) {
19283
19729
  ].filter(Boolean);
19284
19730
  }
19285
19731
  function ensureDoltResolvable(platform3 = process.platform) {
19286
- const P3 = platform3 === "win32" ? path50.win32 : path50.posix;
19732
+ const P3 = platform3 === "win32" ? path51.win32 : path51.posix;
19287
19733
  const delim = platform3 === "win32" ? ";" : ":";
19288
19734
  const names = doltBinaryNames(platform3);
19289
19735
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -19419,8 +19865,8 @@ async function ensureSharedServer(adapter, options = {}) {
19419
19865
  // src/beads/project-key.ts
19420
19866
  var import_child_process21 = require("child_process");
19421
19867
  var crypto2 = __toESM(require("crypto"));
19422
- var fs49 = __toESM(require("fs"));
19423
- var path51 = __toESM(require("path"));
19868
+ var fs50 = __toESM(require("fs"));
19869
+ var path52 = __toESM(require("path"));
19424
19870
  function normalizeOrigin(raw) {
19425
19871
  const trimmed = raw.trim();
19426
19872
  if (!trimmed) return null;
@@ -19446,17 +19892,17 @@ function normalizeOrigin(raw) {
19446
19892
  return `${host2}/${pathPart}`;
19447
19893
  }
19448
19894
  function findRepoRoot(cwd) {
19449
- let dir = path51.resolve(cwd);
19895
+ let dir = path52.resolve(cwd);
19450
19896
  const seen = /* @__PURE__ */ new Set();
19451
19897
  for (let i = 0; i < 256; i++) {
19452
19898
  if (seen.has(dir)) return null;
19453
19899
  seen.add(dir);
19454
19900
  try {
19455
- const stat3 = fs49.statSync(path51.join(dir, ".git"), { throwIfNoEntry: false });
19901
+ const stat3 = fs50.statSync(path52.join(dir, ".git"), { throwIfNoEntry: false });
19456
19902
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
19457
19903
  } catch {
19458
19904
  }
19459
- const parent = path51.dirname(dir);
19905
+ const parent = path52.dirname(dir);
19460
19906
  if (parent === dir) return null;
19461
19907
  dir = parent;
19462
19908
  }
@@ -19467,7 +19913,7 @@ var _execSeam2 = {
19467
19913
  const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
19468
19914
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
19469
19915
  },
19470
- realpath: (p2) => fs49.realpathSync(p2)
19916
+ realpath: (p2) => fs50.realpathSync(p2)
19471
19917
  };
19472
19918
  function readOrigin(cwd) {
19473
19919
  try {
@@ -19496,7 +19942,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
19496
19942
  } catch {
19497
19943
  }
19498
19944
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
19499
- return { projectKey: `path:${hash}`, projectLabel: path51.basename(real) || "project" };
19945
+ return { projectKey: `path:${hash}`, projectLabel: path52.basename(real) || "project" };
19500
19946
  }
19501
19947
 
19502
19948
  // src/beads/project-prefix.ts
@@ -19541,17 +19987,17 @@ var _provisionSeam = {
19541
19987
  };
19542
19988
  var _linkSeam = {
19543
19989
  platform: () => process.platform,
19544
- homedir: () => os39.homedir(),
19990
+ homedir: () => os40.homedir(),
19545
19991
  isWritableDir: (dir) => {
19546
19992
  try {
19547
- fs50.accessSync(dir, fs50.constants.W_OK);
19993
+ fs51.accessSync(dir, fs51.constants.W_OK);
19548
19994
  return true;
19549
19995
  } catch {
19550
19996
  return false;
19551
19997
  }
19552
19998
  },
19553
19999
  ensureDir: (dir) => {
19554
- fs50.mkdirSync(dir, { recursive: true });
20000
+ fs51.mkdirSync(dir, { recursive: true });
19555
20001
  },
19556
20002
  /**
19557
20003
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -19572,9 +20018,9 @@ var _linkSeam = {
19572
20018
  * which `linkBdOntoPath` creates if missing.
19573
20019
  */
19574
20020
  cliBinDir: () => {
19575
- const pathDirs = (process.env.PATH ?? "").split(path52.delimiter).filter(Boolean);
20021
+ const pathDirs = (process.env.PATH ?? "").split(path53.delimiter).filter(Boolean);
19576
20022
  const home = _linkSeam.homedir();
19577
- const localBin = home ? path52.join(home, ".local", "bin") : null;
20023
+ const localBin = home ? path53.join(home, ".local", "bin") : null;
19578
20024
  if (localBin) {
19579
20025
  try {
19580
20026
  _linkSeam.ensureDir(localBin);
@@ -19584,16 +20030,16 @@ var _linkSeam = {
19584
20030
  const candidates = [];
19585
20031
  if (localBin) candidates.push(localBin);
19586
20032
  try {
19587
- candidates.push(path52.dirname(process.execPath));
20033
+ candidates.push(path53.dirname(process.execPath));
19588
20034
  } catch {
19589
20035
  }
19590
20036
  candidates.push("/usr/local/bin");
19591
20037
  const entry = process.argv[1];
19592
20038
  if (entry) {
19593
20039
  try {
19594
- candidates.push(path52.dirname(fs50.realpathSync(entry)));
20040
+ candidates.push(path53.dirname(fs51.realpathSync(entry)));
19595
20041
  } catch {
19596
- candidates.push(path52.dirname(entry));
20042
+ candidates.push(path53.dirname(entry));
19597
20043
  }
19598
20044
  }
19599
20045
  const onPathWritable = candidates.find(
@@ -19605,20 +20051,20 @@ var _linkSeam = {
19605
20051
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
19606
20052
  readlink: (linkPath) => {
19607
20053
  try {
19608
- return fs50.readlinkSync(linkPath);
20054
+ return fs51.readlinkSync(linkPath);
19609
20055
  } catch {
19610
20056
  return null;
19611
20057
  }
19612
20058
  },
19613
- unlink: (linkPath) => fs50.unlinkSync(linkPath),
19614
- symlink: (target, linkPath) => fs50.symlinkSync(target, linkPath)
20059
+ unlink: (linkPath) => fs51.unlinkSync(linkPath),
20060
+ symlink: (target, linkPath) => fs51.symlinkSync(target, linkPath)
19615
20061
  };
19616
20062
  function linkBdOntoPath(binaryPath) {
19617
20063
  if (_linkSeam.platform() === "win32") return;
19618
20064
  const binDir = _linkSeam.cliBinDir();
19619
20065
  if (!binDir) return;
19620
20066
  _linkSeam.ensureDir(binDir);
19621
- const linkPath = path52.join(binDir, "bd");
20067
+ const linkPath = path53.join(binDir, "bd");
19622
20068
  if (linkPath === binaryPath) return;
19623
20069
  const current = _linkSeam.readlink(linkPath);
19624
20070
  if (current === binaryPath) return;
@@ -19813,7 +20259,7 @@ function dedupeRecipes(agents) {
19813
20259
 
19814
20260
  // src/beads/watcher.ts
19815
20261
  var crypto4 = __toESM(require("crypto"));
19816
- var path53 = __toESM(require("path"));
20262
+ var path54 = __toESM(require("path"));
19817
20263
  var API_BASE6 = resolveApiBaseUrl();
19818
20264
  var DEBOUNCE_MS2 = 400;
19819
20265
  var ZERO_SUMMARY = {
@@ -19837,7 +20283,7 @@ var BeadsWatcher = class {
19837
20283
  constructor(opts) {
19838
20284
  this.opts = opts;
19839
20285
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
19840
- 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");
19841
20287
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
19842
20288
  }
19843
20289
  opts;
@@ -20254,8 +20700,8 @@ function cleanupAttachmentTempFiles() {
20254
20700
  function saveFilesTemp(files) {
20255
20701
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
20256
20702
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
20257
- const tmpPath = path55.join(os41.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
20258
- 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"));
20259
20705
  pendingAttachmentFiles.add(tmpPath);
20260
20706
  return tmpPath;
20261
20707
  });
@@ -20467,9 +20913,9 @@ var listFiles = async (ctx, cmd, parsed) => {
20467
20913
  await ctx.relay.sendResult(cmd.id, "completed", result);
20468
20914
  };
20469
20915
  var envReadH = async (ctx, cmd) => {
20470
- const envPath = path55.join(process.cwd(), ".env");
20916
+ const envPath = path56.join(process.cwd(), ".env");
20471
20917
  try {
20472
- const raw = await fs52.promises.readFile(envPath, "utf8");
20918
+ const raw = await fs53.promises.readFile(envPath, "utf8");
20473
20919
  await ctx.relay.sendResult(cmd.id, "completed", {
20474
20920
  exists: true,
20475
20921
  vars: parseDotenv(raw)
@@ -20500,14 +20946,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
20500
20946
  }
20501
20947
  seen.add(v.key);
20502
20948
  }
20503
- const envPath = path55.join(process.cwd(), ".env");
20504
- 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");
20505
20951
  try {
20506
- await fs52.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
20507
- await fs52.promises.rename(tmpPath, envPath);
20952
+ await fs53.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
20953
+ await fs53.promises.rename(tmpPath, envPath);
20508
20954
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
20509
20955
  } catch (err) {
20510
- await fs52.promises.rm(tmpPath, { force: true }).catch(() => void 0);
20956
+ await fs53.promises.rm(tmpPath, { force: true }).catch(() => void 0);
20511
20957
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
20512
20958
  }
20513
20959
  };
@@ -20551,7 +20997,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20551
20997
  let configuredAgent = rawAgentId;
20552
20998
  if (!configuredAgent) {
20553
20999
  try {
20554
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21000
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20555
21001
  configuredAgent = raw.agent ?? "";
20556
21002
  } catch {
20557
21003
  }
@@ -20585,7 +21031,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20585
21031
  persist: persistHeadroomConfig,
20586
21032
  readEnabled: () => {
20587
21033
  try {
20588
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21034
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20589
21035
  return raw.enabled === true;
20590
21036
  } catch {
20591
21037
  return false;
@@ -20658,6 +21104,63 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
20658
21104
  });
20659
21105
  await ctx.relay.sendResult(cmd.id, "completed", result);
20660
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
+ };
20661
21164
  var headroomBudgetH = async (ctx, cmd) => {
20662
21165
  const payload = cmd.payload;
20663
21166
  let rawAgentId = ctx.agentId || (typeof payload.agentId === "string" ? payload.agentId : "");
@@ -20674,7 +21177,7 @@ var headroomBudgetH = async (ctx, cmd) => {
20674
21177
  }
20675
21178
  let headroomActive = false;
20676
21179
  try {
20677
- const raw = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21180
+ const raw = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20678
21181
  headroomActive = raw.enabled === true;
20679
21182
  } catch {
20680
21183
  }
@@ -20684,7 +21187,7 @@ var headroomBudgetH = async (ctx, cmd) => {
20684
21187
  }
20685
21188
  let existingConfig = { enabled: true };
20686
21189
  try {
20687
- existingConfig = JSON.parse(fs52.readFileSync(headroomConfigPath(), "utf8"));
21190
+ existingConfig = JSON.parse(fs53.readFileSync(headroomConfigPath(), "utf8"));
20688
21191
  } catch {
20689
21192
  }
20690
21193
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -20797,13 +21300,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
20797
21300
  function buildNpmInstallInvocation(opts) {
20798
21301
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
20799
21302
  const execPath = opts?.execPath ?? process.execPath;
20800
- const exists2 = opts?.existsSync ?? fs52.existsSync;
20801
- const normalized = entryScript.split(path55.sep).join("/");
21303
+ const exists2 = opts?.existsSync ?? fs53.existsSync;
21304
+ const normalized = entryScript.split(path56.sep).join("/");
20802
21305
  const marker = "/lib/node_modules/codeam-cli/";
20803
21306
  const markerIdx = normalized.indexOf(marker);
20804
21307
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
20805
- const siblingNpm = path55.join(
20806
- path55.dirname(execPath),
21308
+ const siblingNpm = path56.join(
21309
+ path56.dirname(execPath),
20807
21310
  process.platform === "win32" ? "npm.cmd" : "npm"
20808
21311
  );
20809
21312
  const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
@@ -21375,6 +21878,7 @@ var handlers = {
21375
21878
  take_control: takeControlH,
21376
21879
  handback: handbackH,
21377
21880
  headroom_configure: headroomConfigureH,
21881
+ coderabbit_configure: coderabbitConfigureH,
21378
21882
  headroom_budget: headroomBudgetH,
21379
21883
  beads_configure: beadsConfigureH,
21380
21884
  cli_self_update: cliSelfUpdateH()
@@ -21645,11 +22149,11 @@ function resolveTokenValue(args2) {
21645
22149
  }
21646
22150
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
21647
22151
  if (fileFlag) {
21648
- const path70 = fileFlag.slice("--token-file=".length);
22152
+ const path71 = fileFlag.slice("--token-file=".length);
21649
22153
  try {
21650
- const content = fs53.readFileSync(path70, "utf8").trim();
21651
- if (content.length === 0) fail(`--token-file ${path70} is empty`);
21652
- rmIfExistsQuiet(path70);
22154
+ const content = fs54.readFileSync(path71, "utf8").trim();
22155
+ if (content.length === 0) fail(`--token-file ${path71} is empty`);
22156
+ rmIfExistsQuiet(path71);
21653
22157
  return content;
21654
22158
  } catch (err) {
21655
22159
  fail(`Could not read --token-file: ${err.message}`);
@@ -21678,7 +22182,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
21678
22182
  pluginId,
21679
22183
  ideName: "codeam-cli (codespace)",
21680
22184
  ideVersion: process.env.npm_package_version ?? "unknown",
21681
- hostname: os42.hostname(),
22185
+ hostname: os43.hostname(),
21682
22186
  codespaceName: process.env.CODESPACE_NAME ?? "",
21683
22187
  // Current git branch of the codespace's working directory, so the
21684
22188
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -21739,7 +22243,7 @@ async function claim(token, pluginId, pluginSecretHash) {
21739
22243
  }
21740
22244
  }
21741
22245
  function pairAutoLockPath() {
21742
- return path56.join(os42.homedir(), ".codeam", "pair-auto.lock");
22246
+ return path57.join(os43.homedir(), ".codeam", "pair-auto.lock");
21743
22247
  }
21744
22248
  function isLivePairAuto(pid) {
21745
22249
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -21749,7 +22253,7 @@ function isLivePairAuto(pid) {
21749
22253
  if (e.code !== "EPERM") return false;
21750
22254
  }
21751
22255
  try {
21752
- return fs53.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
22256
+ return fs54.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
21753
22257
  } catch {
21754
22258
  return true;
21755
22259
  }
@@ -21759,24 +22263,24 @@ function isLiveCodeam(pid) {
21759
22263
  }
21760
22264
  function daemonLockPath(sessionId) {
21761
22265
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
21762
- return path56.join(os42.homedir(), ".codeam", `daemon-${safe}.lock`);
22266
+ return path57.join(os43.homedir(), ".codeam", `daemon-${safe}.lock`);
21763
22267
  }
21764
22268
  function acquireDaemonLock(sessionId) {
21765
22269
  const lockPath = daemonLockPath(sessionId);
21766
22270
  try {
21767
- fs53.mkdirSync(path56.dirname(lockPath), { recursive: true });
22271
+ fs54.mkdirSync(path57.dirname(lockPath), { recursive: true });
21768
22272
  try {
21769
- fs53.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
22273
+ fs54.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21770
22274
  } catch (e) {
21771
22275
  if (e.code !== "EEXIST") throw e;
21772
- const holder = Number(fs53.readFileSync(lockPath, "utf8").trim());
22276
+ const holder = Number(fs54.readFileSync(lockPath, "utf8").trim());
21773
22277
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
21774
- fs53.writeFileSync(lockPath, String(process.pid));
22278
+ fs54.writeFileSync(lockPath, String(process.pid));
21775
22279
  }
21776
22280
  const release3 = () => {
21777
22281
  try {
21778
- if (fs53.existsSync(lockPath) && Number(fs53.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21779
- fs53.unlinkSync(lockPath);
22282
+ if (fs54.existsSync(lockPath) && Number(fs54.readFileSync(lockPath, "utf8").trim()) === process.pid) {
22283
+ fs54.unlinkSync(lockPath);
21780
22284
  }
21781
22285
  } catch {
21782
22286
  }
@@ -21798,19 +22302,19 @@ function acquireDaemonLock(sessionId) {
21798
22302
  function acquireSingletonLock() {
21799
22303
  const lockPath = pairAutoLockPath();
21800
22304
  try {
21801
- fs53.mkdirSync(path56.dirname(lockPath), { recursive: true });
22305
+ fs54.mkdirSync(path57.dirname(lockPath), { recursive: true });
21802
22306
  try {
21803
- fs53.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
22307
+ fs54.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21804
22308
  } catch (e) {
21805
22309
  if (e.code !== "EEXIST") throw e;
21806
- const holder = Number(fs53.readFileSync(lockPath, "utf8").trim());
22310
+ const holder = Number(fs54.readFileSync(lockPath, "utf8").trim());
21807
22311
  if (isLivePairAuto(holder)) return false;
21808
- fs53.writeFileSync(lockPath, String(process.pid));
22312
+ fs54.writeFileSync(lockPath, String(process.pid));
21809
22313
  }
21810
22314
  process.once("exit", () => {
21811
22315
  try {
21812
- if (fs53.existsSync(lockPath) && Number(fs53.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21813
- fs53.unlinkSync(lockPath);
22316
+ if (fs54.existsSync(lockPath) && Number(fs54.readFileSync(lockPath, "utf8").trim()) === process.pid) {
22317
+ fs54.unlinkSync(lockPath);
21814
22318
  }
21815
22319
  } catch {
21816
22320
  }
@@ -21892,7 +22396,7 @@ async function pairAuto(args2) {
21892
22396
  }
21893
22397
 
21894
22398
  // src/services/headroom/wrap-launch.ts
21895
- var import_node_child_process22 = require("child_process");
22399
+ var import_node_child_process23 = require("child_process");
21896
22400
  function wrapWithHeadroom(launch, opts) {
21897
22401
  if (!opts.enabled || !opts.headroomPresent) return launch;
21898
22402
  return {
@@ -21905,7 +22409,7 @@ var _present;
21905
22409
  function headroomPresent() {
21906
22410
  if (_present !== void 0) return Promise.resolve(_present);
21907
22411
  return new Promise((resolve7) => {
21908
- (0, import_node_child_process22.execFile)("headroom", ["--version"], (err) => {
22412
+ (0, import_node_child_process23.execFile)("headroom", ["--version"], (err) => {
21909
22413
  _present = !err;
21910
22414
  resolve7(_present);
21911
22415
  });
@@ -22255,11 +22759,11 @@ var AgentService = class _AgentService {
22255
22759
  };
22256
22760
 
22257
22761
  // src/agents/acp/adapters.ts
22258
- var path58 = __toESM(require("path"));
22762
+ var path59 = __toESM(require("path"));
22259
22763
 
22260
22764
  // src/agents/acp/agent-binary.ts
22261
22765
  var import_fs4 = __toESM(require("fs"));
22262
- var import_os8 = __toESM(require("os"));
22766
+ var import_os10 = __toESM(require("os"));
22263
22767
  var import_path8 = __toESM(require("path"));
22264
22768
  var import_child_process25 = require("child_process");
22265
22769
  function currentPlatformKey() {
@@ -22355,7 +22859,7 @@ function resolveCursorAgentBinary(deps = {}) {
22355
22859
  const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
22356
22860
  return existsSync26(exe) ? exe : null;
22357
22861
  }
22358
- const home = deps.homedir ?? import_os8.default.homedir();
22862
+ const home = deps.homedir ?? import_os10.default.homedir();
22359
22863
  const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
22360
22864
  return existsSync26(unix) ? unix : null;
22361
22865
  }
@@ -22429,7 +22933,7 @@ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
22429
22933
  }
22430
22934
 
22431
22935
  // src/agents/kimi/installer.ts
22432
- var import_node_child_process23 = require("child_process");
22936
+ var import_node_child_process24 = require("child_process");
22433
22937
  var import_node_os6 = require("os");
22434
22938
  var import_node_path6 = require("path");
22435
22939
  var INSTALL_URL2 = "https://code.kimi.com/kimi-code/install.sh";
@@ -22437,7 +22941,7 @@ function kimiBinDir() {
22437
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");
22438
22942
  }
22439
22943
  function kimiRuns() {
22440
- 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 });
22441
22945
  return !r.error && r.status === 0;
22442
22946
  }
22443
22947
  function augmentPath2() {
@@ -22447,7 +22951,7 @@ function augmentPath2() {
22447
22951
  }
22448
22952
  async function runInstaller2() {
22449
22953
  return new Promise((resolve7) => {
22450
- 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" });
22451
22955
  proc.on("close", (code) => resolve7(code === 0));
22452
22956
  proc.on("error", () => resolve7(false));
22453
22957
  });
@@ -22497,13 +23001,13 @@ function resolveBin(pkgName, binName) {
22497
23001
  try {
22498
23002
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
22499
23003
  const manifest = require_(`${pkgName}/package.json`);
22500
- const pkgDir = path58.dirname(manifestPath);
23004
+ const pkgDir = path59.dirname(manifestPath);
22501
23005
  const bin = manifest.bin;
22502
23006
  if (!bin) return null;
22503
- if (typeof bin === "string") return path58.resolve(pkgDir, bin);
23007
+ if (typeof bin === "string") return path59.resolve(pkgDir, bin);
22504
23008
  const target = binName ?? Object.keys(bin)[0];
22505
23009
  if (!target || !bin[target]) return null;
22506
- return path58.resolve(pkgDir, bin[target]);
23010
+ return path59.resolve(pkgDir, bin[target]);
22507
23011
  } catch {
22508
23012
  return null;
22509
23013
  }
@@ -22607,9 +23111,9 @@ function requiresAcp(agent) {
22607
23111
  var import_node_crypto10 = require("crypto");
22608
23112
 
22609
23113
  // src/services/history.service.ts
22610
- var fs55 = __toESM(require("fs"));
22611
- var path59 = __toESM(require("path"));
22612
- var os44 = __toESM(require("os"));
23114
+ var fs56 = __toESM(require("fs"));
23115
+ var path60 = __toESM(require("path"));
23116
+ var os45 = __toESM(require("os"));
22613
23117
  var https7 = __toESM(require("https"));
22614
23118
  var http6 = __toESM(require("http"));
22615
23119
  var import_zod2 = require("zod");
@@ -22636,7 +23140,7 @@ function parseJsonl(filePath) {
22636
23140
  const messages = [];
22637
23141
  let raw;
22638
23142
  try {
22639
- raw = fs55.readFileSync(filePath, "utf8");
23143
+ raw = fs56.readFileSync(filePath, "utf8");
22640
23144
  } catch (err) {
22641
23145
  if (err.code !== "ENOENT") {
22642
23146
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -22777,7 +23281,7 @@ var HistoryService = class _HistoryService {
22777
23281
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
22778
23282
  }
22779
23283
  get projectDir() {
22780
- 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));
22781
23285
  }
22782
23286
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
22783
23287
  setCurrentConversationId(id) {
@@ -22789,7 +23293,7 @@ var HistoryService = class _HistoryService {
22789
23293
  /** Return the current message count in the active conversation. */
22790
23294
  getCurrentMessageCount() {
22791
23295
  if (!this.currentConversationId) return 0;
22792
- const filePath = path59.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23296
+ const filePath = path60.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22793
23297
  return parseJsonl(filePath).length;
22794
23298
  }
22795
23299
  /**
@@ -22800,7 +23304,7 @@ var HistoryService = class _HistoryService {
22800
23304
  const deadline = Date.now() + timeoutMs;
22801
23305
  while (Date.now() < deadline) {
22802
23306
  if (!this.currentConversationId) return null;
22803
- const filePath = path59.join(this.projectDir, `${this.currentConversationId}.jsonl`);
23307
+ const filePath = path60.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22804
23308
  const messages = parseJsonl(filePath);
22805
23309
  if (messages.length > previousCount) {
22806
23310
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -22826,16 +23330,16 @@ var HistoryService = class _HistoryService {
22826
23330
  const dir = this.projectDir;
22827
23331
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22828
23332
  try {
22829
- 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) => {
22830
23334
  try {
22831
- const stat3 = fs55.statSync(path59.join(dir, e.name));
23335
+ const stat3 = fs56.statSync(path60.join(dir, e.name));
22832
23336
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22833
23337
  } catch {
22834
23338
  return { name: e.name, mtime: 0, birthtime: 0 };
22835
23339
  }
22836
23340
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
22837
23341
  if (files.length > 0) {
22838
- this.currentConversationId = path59.basename(files[0].name, ".jsonl");
23342
+ this.currentConversationId = path60.basename(files[0].name, ".jsonl");
22839
23343
  }
22840
23344
  } catch {
22841
23345
  }
@@ -22869,13 +23373,13 @@ var HistoryService = class _HistoryService {
22869
23373
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22870
23374
  let entries;
22871
23375
  try {
22872
- entries = fs55.readdirSync(dir, { withFileTypes: true });
23376
+ entries = fs56.readdirSync(dir, { withFileTypes: true });
22873
23377
  } catch {
22874
23378
  return null;
22875
23379
  }
22876
23380
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22877
23381
  try {
22878
- const stat3 = fs55.statSync(path59.join(dir, e.name));
23382
+ const stat3 = fs56.statSync(path60.join(dir, e.name));
22879
23383
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22880
23384
  } catch {
22881
23385
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -22884,12 +23388,12 @@ var HistoryService = class _HistoryService {
22884
23388
  if (files.length === 0) return null;
22885
23389
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
22886
23390
  if (!files.some((f) => f.name === targetFile)) return null;
22887
- return this.extractUsageFromFile(path59.join(dir, targetFile));
23391
+ return this.extractUsageFromFile(path60.join(dir, targetFile));
22888
23392
  }
22889
23393
  extractUsageFromFile(filePath) {
22890
23394
  let raw;
22891
23395
  try {
22892
- raw = fs55.readFileSync(filePath, "utf8");
23396
+ raw = fs56.readFileSync(filePath, "utf8");
22893
23397
  } catch {
22894
23398
  return null;
22895
23399
  }
@@ -22934,9 +23438,9 @@ var HistoryService = class _HistoryService {
22934
23438
  let totalCost = 0;
22935
23439
  let files;
22936
23440
  try {
22937
- files = fs55.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
23441
+ files = fs56.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22938
23442
  try {
22939
- return fs55.statSync(path59.join(projectDir, f)).mtimeMs >= monthStartMs;
23443
+ return fs56.statSync(path60.join(projectDir, f)).mtimeMs >= monthStartMs;
22940
23444
  } catch {
22941
23445
  return false;
22942
23446
  }
@@ -22947,7 +23451,7 @@ var HistoryService = class _HistoryService {
22947
23451
  for (const file of files) {
22948
23452
  let raw;
22949
23453
  try {
22950
- raw = fs55.readFileSync(path59.join(projectDir, file), "utf8");
23454
+ raw = fs56.readFileSync(path60.join(projectDir, file), "utf8");
22951
23455
  } catch {
22952
23456
  continue;
22953
23457
  }
@@ -23026,7 +23530,7 @@ var HistoryService = class _HistoryService {
23026
23530
  if (this.runtime.resolveHistoryFile) {
23027
23531
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
23028
23532
  }
23029
- return path59.join(this.projectDir, `${sessionId}.jsonl`);
23533
+ return path60.join(this.projectDir, `${sessionId}.jsonl`);
23030
23534
  }
23031
23535
  /**
23032
23536
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -23060,7 +23564,7 @@ var HistoryService = class _HistoryService {
23060
23564
  };
23061
23565
  });
23062
23566
  }
23063
- return parseJsonl(path59.join(this.projectDir, `${sessionId}.jsonl`));
23567
+ return parseJsonl(path60.join(this.projectDir, `${sessionId}.jsonl`));
23064
23568
  }
23065
23569
  async loadConversation(sessionId) {
23066
23570
  const messages = this.readConversation(sessionId);
@@ -23116,7 +23620,7 @@ var HistoryService = class _HistoryService {
23116
23620
  if (!filePath) return false;
23117
23621
  let mtimeMs;
23118
23622
  try {
23119
- mtimeMs = fs55.statSync(filePath).mtimeMs;
23623
+ mtimeMs = fs56.statSync(filePath).mtimeMs;
23120
23624
  } catch {
23121
23625
  return false;
23122
23626
  }
@@ -23184,11 +23688,11 @@ var HistoryService = class _HistoryService {
23184
23688
  };
23185
23689
 
23186
23690
  // src/agents/acp/client.ts
23187
- var import_node_child_process24 = require("child_process");
23188
- var fs56 = __toESM(require("fs/promises"));
23691
+ var import_node_child_process25 = require("child_process");
23692
+ var fs57 = __toESM(require("fs/promises"));
23189
23693
  var fsSync = __toESM(require("fs"));
23190
- var os45 = __toESM(require("os"));
23191
- var path60 = __toESM(require("path"));
23694
+ var os46 = __toESM(require("os"));
23695
+ var path61 = __toESM(require("path"));
23192
23696
  var import_node_stream = require("stream");
23193
23697
 
23194
23698
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -25788,7 +26292,7 @@ var AcpClient = class {
25788
26292
  "acpClient",
25789
26293
  `spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
25790
26294
  );
25791
- 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, {
25792
26296
  cwd,
25793
26297
  // extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
25794
26298
  // re-spawn) layers over process.env; PATH stays last so the augmented
@@ -26102,7 +26606,7 @@ var AcpClient = class {
26102
26606
  },
26103
26607
  readTextFile: async (params) => {
26104
26608
  try {
26105
- const content = await fs56.readFile(params.path, "utf8");
26609
+ const content = await fs57.readFile(params.path, "utf8");
26106
26610
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
26107
26611
  } catch (err) {
26108
26612
  const code = err.code;
@@ -26122,7 +26626,7 @@ var AcpClient = class {
26122
26626
  },
26123
26627
  writeTextFile: async (params) => {
26124
26628
  try {
26125
- await fs56.writeFile(params.path, params.content, "utf8");
26629
+ await fs57.writeFile(params.path, params.content, "utf8");
26126
26630
  return {};
26127
26631
  } catch (err) {
26128
26632
  const code = err.code;
@@ -26171,29 +26675,29 @@ function applyLineRange(content, line, limit) {
26171
26675
  return { content: lines.slice(start2, end).join("\n") };
26172
26676
  }
26173
26677
  function knownAgentBinaryDirs() {
26174
- const home = os45.homedir();
26678
+ const home = os46.homedir();
26175
26679
  const out2 = [];
26176
26680
  out2.push("/tmp/codeam-node20/bin");
26177
26681
  for (const root of [
26178
26682
  "/usr/local/share/nvm/versions/node",
26179
- path60.join(home, ".nvm/versions/node")
26683
+ path61.join(home, ".nvm/versions/node")
26180
26684
  ]) {
26181
26685
  try {
26182
26686
  for (const child of fsSync.readdirSync(root)) {
26183
- out2.push(path60.join(root, child, "bin"));
26687
+ out2.push(path61.join(root, child, "bin"));
26184
26688
  }
26185
26689
  } catch {
26186
26690
  }
26187
26691
  }
26188
- out2.push(path60.join(home, ".volta/bin"));
26692
+ out2.push(path61.join(home, ".volta/bin"));
26189
26693
  out2.push("/usr/local/bin");
26190
26694
  out2.push("/usr/bin");
26191
- out2.push(path60.join(home, ".local/bin"));
26192
- out2.push(path60.join(home, "bin"));
26695
+ out2.push(path61.join(home, ".local/bin"));
26696
+ out2.push(path61.join(home, "bin"));
26193
26697
  if (process.platform === "win32") {
26194
26698
  const { LOCALAPPDATA, APPDATA } = process.env;
26195
- if (LOCALAPPDATA) out2.push(path60.join(LOCALAPPDATA, "cursor-agent"));
26196
- 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"));
26197
26701
  }
26198
26702
  return out2.filter((p2) => {
26199
26703
  try {
@@ -26205,7 +26709,7 @@ function knownAgentBinaryDirs() {
26205
26709
  }
26206
26710
  function expandPathForAgentBinaries(existingPath) {
26207
26711
  const existing = new Set(
26208
- existingPath.split(path60.delimiter).filter((p2) => p2.length > 0)
26712
+ existingPath.split(path61.delimiter).filter((p2) => p2.length > 0)
26209
26713
  );
26210
26714
  const additions = [];
26211
26715
  for (const dir of knownAgentBinaryDirs()) {
@@ -26215,7 +26719,7 @@ function expandPathForAgentBinaries(existingPath) {
26215
26719
  }
26216
26720
  }
26217
26721
  if (additions.length === 0) return existingPath;
26218
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path60.delimiter);
26722
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path61.delimiter);
26219
26723
  }
26220
26724
 
26221
26725
  // src/agents/acp/headroom-budget-proxy.ts
@@ -26226,12 +26730,12 @@ function buildRelaunchProxyEnv(baseEnv) {
26226
26730
  return env;
26227
26731
  }
26228
26732
  var relaunchProxyWithoutBudget = async () => {
26229
- const { spawn: spawn40 } = await import("child_process");
26733
+ const { spawn: spawn41 } = await import("child_process");
26230
26734
  killHeadroomProxy();
26231
26735
  await new Promise((r) => setTimeout(r, 500));
26232
26736
  const proxyEnv = buildRelaunchProxyEnv(process.env);
26233
26737
  try {
26234
- const proxy = spawn40(
26738
+ const proxy = spawn41(
26235
26739
  "headroom",
26236
26740
  ["proxy", "--port", "8787"],
26237
26741
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -26697,15 +27201,15 @@ function commonPrefixLength(a, b) {
26697
27201
 
26698
27202
  // src/agents/acp/onboarding.ts
26699
27203
  var import_child_process26 = require("child_process");
26700
- var fs57 = __toESM(require("fs"));
26701
- var os46 = __toESM(require("os"));
26702
- var path61 = __toESM(require("path"));
27204
+ var fs58 = __toESM(require("fs"));
27205
+ var os47 = __toESM(require("os"));
27206
+ var path62 = __toESM(require("path"));
26703
27207
  var _onboardingSeam = {
26704
- markerPath: (sessionId) => path61.join(os46.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
26705
- exists: (p2) => fs57.existsSync(p2),
27208
+ markerPath: (sessionId) => path62.join(os47.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
27209
+ exists: (p2) => fs58.existsSync(p2),
26706
27210
  write: (p2) => {
26707
- fs57.mkdirSync(path61.dirname(p2), { recursive: true });
26708
- fs57.writeFileSync(p2, "");
27211
+ fs58.mkdirSync(path62.dirname(p2), { recursive: true });
27212
+ fs58.writeFileSync(p2, "");
26709
27213
  },
26710
27214
  disabled: () => {
26711
27215
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -26742,7 +27246,7 @@ function resolveRepoName(cwd) {
26742
27246
  if (name) return name;
26743
27247
  }
26744
27248
  }
26745
- const base = path61.basename(cwd || "");
27249
+ const base = path62.basename(cwd || "");
26746
27250
  if (base && !isUuid(base)) return base;
26747
27251
  return "this project";
26748
27252
  }
@@ -26994,8 +27498,8 @@ var import_crypto5 = require("crypto");
26994
27498
 
26995
27499
  // src/services/turn-files/git-changeset.ts
26996
27500
  var import_child_process27 = require("child_process");
26997
- var fs58 = __toESM(require("fs/promises"));
26998
- var path62 = __toESM(require("path"));
27501
+ var fs59 = __toESM(require("fs/promises"));
27502
+ var path63 = __toESM(require("path"));
26999
27503
  async function collectRepoChangeset(opts) {
27000
27504
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
27001
27505
  if (status2 === null) return null;
@@ -27013,7 +27517,7 @@ async function collectRepoChangeset(opts) {
27013
27517
  let stats;
27014
27518
  if (row.fileStatus === "added" && numstatEntry === void 0) {
27015
27519
  const lineCount = await readUntrackedLineCount(
27016
- path62.join(opts.repoRoot, row.filePath)
27520
+ path63.join(opts.repoRoot, row.filePath)
27017
27521
  );
27018
27522
  stats = { added: lineCount, removed: 0 };
27019
27523
  } else {
@@ -27044,7 +27548,7 @@ function readUntrackedLineCount(absPath) {
27044
27548
  }
27045
27549
  async function defaultReadUntrackedLineCount(absPath) {
27046
27550
  try {
27047
- const content = await fs58.readFile(absPath, "utf8");
27551
+ const content = await fs59.readFile(absPath, "utf8");
27048
27552
  let count = 0;
27049
27553
  let pos = -1;
27050
27554
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -27136,7 +27640,7 @@ function defaultRunGit(cwd, args2) {
27136
27640
  });
27137
27641
  }
27138
27642
  async function discoverRepos(workingDir, maxDepth = 4) {
27139
- const fs63 = await import("fs/promises");
27643
+ const fs64 = await import("fs/promises");
27140
27644
  const out2 = [];
27141
27645
  await walk(workingDir, 0);
27142
27646
  return out2;
@@ -27144,7 +27648,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27144
27648
  if (depth > maxDepth) return;
27145
27649
  let entries = [];
27146
27650
  try {
27147
- const dirents = await fs63.readdir(dir, { withFileTypes: true });
27651
+ const dirents = await fs64.readdir(dir, { withFileTypes: true });
27148
27652
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
27149
27653
  } catch {
27150
27654
  return;
@@ -27155,8 +27659,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27155
27659
  if (hasGit) {
27156
27660
  out2.push({
27157
27661
  repoRoot: dir,
27158
- repoPath: path62.relative(workingDir, dir),
27159
- repoName: path62.basename(dir)
27662
+ repoPath: path63.relative(workingDir, dir),
27663
+ repoName: path63.basename(dir)
27160
27664
  });
27161
27665
  return;
27162
27666
  }
@@ -27164,15 +27668,15 @@ async function discoverRepos(workingDir, maxDepth = 4) {
27164
27668
  if (!entry.isDirectory) continue;
27165
27669
  if (entry.name === "node_modules") continue;
27166
27670
  if (entry.name === "dist" || entry.name === "build") continue;
27167
- await walk(path62.join(dir, entry.name), depth + 1);
27671
+ await walk(path63.join(dir, entry.name), depth + 1);
27168
27672
  }
27169
27673
  }
27170
27674
  }
27171
27675
 
27172
27676
  // src/services/turn-files/files-outbox.ts
27173
- var fs59 = __toESM(require("fs/promises"));
27174
- var path63 = __toESM(require("path"));
27175
- var import_os9 = require("os");
27677
+ var fs60 = __toESM(require("fs/promises"));
27678
+ var path64 = __toESM(require("path"));
27679
+ var import_os11 = require("os");
27176
27680
  var HOME_OUTBOX_DIR = ".codeam/outbox";
27177
27681
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
27178
27682
  var BACKOFF_STEPS_MS = [
@@ -27204,16 +27708,16 @@ var FilesOutbox = class {
27204
27708
  backoffIndex = 0;
27205
27709
  stopped = false;
27206
27710
  constructor(opts) {
27207
- const base = opts.baseDir ?? path63.join(homeDir(), HOME_OUTBOX_DIR);
27208
- 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`);
27209
27713
  this.post = opts.post;
27210
27714
  this.autoSchedule = opts.autoSchedule !== false;
27211
27715
  }
27212
27716
  /** Persist the entry to disk and trigger a flush. Returns once the
27213
27717
  * line is durable on disk (not once the POST succeeds). */
27214
27718
  async enqueue(entry) {
27215
- await fs59.mkdir(path63.dirname(this.filePath), { recursive: true });
27216
- 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");
27217
27721
  this.backoffIndex = 0;
27218
27722
  if (this.autoSchedule) this.scheduleFlush(0);
27219
27723
  }
@@ -27302,7 +27806,7 @@ var FilesOutbox = class {
27302
27806
  async readAll() {
27303
27807
  let raw = "";
27304
27808
  try {
27305
- raw = await fs59.readFile(this.filePath, "utf8");
27809
+ raw = await fs60.readFile(this.filePath, "utf8");
27306
27810
  } catch {
27307
27811
  return [];
27308
27812
  }
@@ -27326,12 +27830,12 @@ var FilesOutbox = class {
27326
27830
  async rewrite(entries) {
27327
27831
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
27328
27832
  if (entries.length === 0) {
27329
- await fs59.unlink(this.filePath).catch(() => void 0);
27833
+ await fs60.unlink(this.filePath).catch(() => void 0);
27330
27834
  return;
27331
27835
  }
27332
27836
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
27333
- await fs59.writeFile(tmpPath, payload, "utf8");
27334
- await fs59.rename(tmpPath, this.filePath);
27837
+ await fs60.writeFile(tmpPath, payload, "utf8");
27838
+ await fs60.rename(tmpPath, this.filePath);
27335
27839
  }
27336
27840
  };
27337
27841
  function applyJitter(ms) {
@@ -27339,7 +27843,7 @@ function applyJitter(ms) {
27339
27843
  return Math.round(ms * factor);
27340
27844
  }
27341
27845
  function homeDir() {
27342
- return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os9.tmpdir)();
27846
+ return process.env.HOME ?? process.env.USERPROFILE ?? (0, import_os11.tmpdir)();
27343
27847
  }
27344
27848
 
27345
27849
  // src/services/turn-files/turn-file-aggregator.ts
@@ -30436,7 +30940,7 @@ var AcpDriver = class {
30436
30940
  };
30437
30941
 
30438
30942
  // src/baton/transcript-mirror.ts
30439
- var fs60 = __toESM(require("fs"));
30943
+ var fs61 = __toESM(require("fs"));
30440
30944
  var TranscriptMirror = class {
30441
30945
  constructor(deps) {
30442
30946
  this.deps = deps;
@@ -30503,7 +31007,7 @@ var TranscriptMirror = class {
30503
31007
  }
30504
31008
  };
30505
31009
  function defaultWatch(file, onChange) {
30506
- const w3 = fs60.watch(file, { persistent: false }, () => onChange());
31010
+ const w3 = fs61.watch(file, { persistent: false }, () => onChange());
30507
31011
  return () => w3.close();
30508
31012
  }
30509
31013
 
@@ -30755,15 +31259,15 @@ function toEpochMs(ts) {
30755
31259
  }
30756
31260
 
30757
31261
  // src/agents/claude/onboarding.ts
30758
- var fs61 = __toESM(require("fs"));
30759
- var os47 = __toESM(require("os"));
30760
- var path64 = __toESM(require("path"));
31262
+ var fs62 = __toESM(require("fs"));
31263
+ var os48 = __toESM(require("os"));
31264
+ var path65 = __toESM(require("path"));
30761
31265
  function ensureClaudeOnboarded() {
30762
31266
  try {
30763
- const file = path64.join(os47.homedir(), ".claude.json");
31267
+ const file = path65.join(os48.homedir(), ".claude.json");
30764
31268
  let config = {};
30765
31269
  try {
30766
- config = JSON.parse(fs61.readFileSync(file, "utf8"));
31270
+ config = JSON.parse(fs62.readFileSync(file, "utf8"));
30767
31271
  } catch {
30768
31272
  }
30769
31273
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -30774,8 +31278,8 @@ function ensureClaudeOnboarded() {
30774
31278
  if (typeof config.lastOnboardingVersion !== "string") {
30775
31279
  config.lastOnboardingVersion = "2.1.177";
30776
31280
  }
30777
- fs61.mkdirSync(path64.dirname(file), { recursive: true });
30778
- 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));
30779
31283
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
30780
31284
  } catch (err) {
30781
31285
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -31449,7 +31953,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
31449
31953
  var import_child_process28 = require("child_process");
31450
31954
  var import_util4 = require("util");
31451
31955
  var import_picocolors9 = __toESM(require("picocolors"));
31452
- var path65 = __toESM(require("path"));
31956
+ var path66 = __toESM(require("path"));
31453
31957
  var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
31454
31958
  var MAX_BUFFER = 8 * 1024 * 1024;
31455
31959
  function resetStdinForChild() {
@@ -31938,7 +32442,7 @@ var GitHubCodespacesProvider = class {
31938
32442
  });
31939
32443
  }
31940
32444
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
31941
- const remoteDir = path65.posix.dirname(remotePath);
32445
+ const remoteDir = path66.posix.dirname(remotePath);
31942
32446
  const parts = [
31943
32447
  `mkdir -p ${shellQuote(remoteDir)}`,
31944
32448
  `cat > ${shellQuote(remotePath)}`
@@ -32008,7 +32512,7 @@ function shellQuote(s) {
32008
32512
  // src/services/providers/gitpod.ts
32009
32513
  var import_child_process29 = require("child_process");
32010
32514
  var import_util5 = require("util");
32011
- var path66 = __toESM(require("path"));
32515
+ var path67 = __toESM(require("path"));
32012
32516
  var import_picocolors10 = __toESM(require("picocolors"));
32013
32517
  var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
32014
32518
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -32248,7 +32752,7 @@ var GitpodProvider = class {
32248
32752
  });
32249
32753
  }
32250
32754
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32251
- const remoteDir = path66.posix.dirname(remotePath);
32755
+ const remoteDir = path67.posix.dirname(remotePath);
32252
32756
  const parts = [
32253
32757
  `mkdir -p ${shellQuote2(remoteDir)}`,
32254
32758
  `cat > ${shellQuote2(remotePath)}`
@@ -32284,7 +32788,7 @@ function shellQuote2(s) {
32284
32788
  // src/services/providers/gitlab-workspaces.ts
32285
32789
  var import_child_process30 = require("child_process");
32286
32790
  var import_util6 = require("util");
32287
- var path67 = __toESM(require("path"));
32791
+ var path68 = __toESM(require("path"));
32288
32792
  var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
32289
32793
  var MAX_BUFFER3 = 8 * 1024 * 1024;
32290
32794
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -32544,7 +33048,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
32544
33048
  }
32545
33049
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
32546
33050
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
32547
- const remoteDir = path67.posix.dirname(remotePath);
33051
+ const remoteDir = path68.posix.dirname(remotePath);
32548
33052
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
32549
33053
  if (options.mode != null) {
32550
33054
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -32612,7 +33116,7 @@ function shellQuote3(s) {
32612
33116
  // src/services/providers/railway.ts
32613
33117
  var import_child_process31 = require("child_process");
32614
33118
  var import_util7 = require("util");
32615
- var path68 = __toESM(require("path"));
33119
+ var path69 = __toESM(require("path"));
32616
33120
  var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
32617
33121
  var MAX_BUFFER4 = 8 * 1024 * 1024;
32618
33122
  function resetStdinForChild4() {
@@ -32848,7 +33352,7 @@ var RailwayProvider = class {
32848
33352
  if (!projectId || !serviceId) {
32849
33353
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
32850
33354
  }
32851
- const remoteDir = path68.posix.dirname(remotePath);
33355
+ const remoteDir = path69.posix.dirname(remotePath);
32852
33356
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
32853
33357
  if (options.mode != null) {
32854
33358
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -33494,8 +33998,8 @@ async function invite() {
33494
33998
  var import_node_dns = require("dns");
33495
33999
  var import_node_util5 = require("util");
33496
34000
  var import_node_crypto12 = require("crypto");
33497
- var fs62 = __toESM(require("fs"));
33498
- var path69 = __toESM(require("path"));
34001
+ var fs63 = __toESM(require("fs"));
34002
+ var path70 = __toESM(require("path"));
33499
34003
  var import_picocolors14 = __toESM(require("picocolors"));
33500
34004
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
33501
34005
  async function checkDns(apiBase2) {
@@ -33551,13 +34055,13 @@ async function checkHealth(apiBase2) {
33551
34055
  }
33552
34056
  }
33553
34057
  function checkConfigDir() {
33554
- const dir = path69.join(require("os").homedir(), ".codeam");
34058
+ const dir = path70.join(require("os").homedir(), ".codeam");
33555
34059
  try {
33556
- fs62.mkdirSync(dir, { recursive: true, mode: 448 });
33557
- const probe = path69.join(dir, ".doctor-probe");
33558
- fs62.writeFileSync(probe, "ok", { mode: 384 });
33559
- const read2 = fs62.readFileSync(probe, "utf8");
33560
- 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);
33561
34065
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
33562
34066
  return {
33563
34067
  id: "config-dir",
@@ -33597,9 +34101,9 @@ function checkSessions() {
33597
34101
  }
33598
34102
  }
33599
34103
  function checkAgentBinaries() {
33600
- const os49 = createOsStrategy();
34104
+ const os50 = createOsStrategy();
33601
34105
  return getEnabledAgents().map((meta) => {
33602
- const found = os49.findInPath(meta.binaryName);
34106
+ const found = os50.findInPath(meta.binaryName);
33603
34107
  return {
33604
34108
  id: `agent-${meta.id}`,
33605
34109
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -33621,7 +34125,7 @@ function checkNodePty() {
33621
34125
  detail: "not required on this platform"
33622
34126
  };
33623
34127
  }
33624
- const vendoredPath = path69.join(__dirname, "vendor", "node-pty");
34128
+ const vendoredPath = path70.join(__dirname, "vendor", "node-pty");
33625
34129
  for (const target of [vendoredPath, "node-pty"]) {
33626
34130
  try {
33627
34131
  require(target);
@@ -33663,7 +34167,7 @@ function checkChokidar() {
33663
34167
  }
33664
34168
  async function doctor(args2 = []) {
33665
34169
  const json = args2.includes("--json");
33666
- const cliVersion = true ? "2.60.22" : "0.0.0-dev";
34170
+ const cliVersion = true ? "2.60.24" : "0.0.0-dev";
33667
34171
  const apiBase2 = resolveApiBaseUrl();
33668
34172
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
33669
34173
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -33862,7 +34366,7 @@ async function completion(args2) {
33862
34366
  // src/commands/version.ts
33863
34367
  var import_picocolors15 = __toESM(require("picocolors"));
33864
34368
  function version2() {
33865
- const v = true ? "2.60.22" : "unknown";
34369
+ const v = true ? "2.60.24" : "unknown";
33866
34370
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
33867
34371
  }
33868
34372
 
@@ -34011,10 +34515,10 @@ var EXIT_CODE_NAMES = {
34011
34515
  };
34012
34516
 
34013
34517
  // src/index.ts
34014
- var os48 = __toESM(require("os"));
34518
+ var os49 = __toESM(require("os"));
34015
34519
  if (!process.env.HOME) {
34016
34520
  try {
34017
- const home = os48.homedir();
34521
+ const home = os49.homedir();
34018
34522
  if (home) process.env.HOME = home;
34019
34523
  } catch {
34020
34524
  }