codeam-cli 2.60.8 → 2.60.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/index.js +552 -417
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -751,11 +751,11 @@ function quiet(fn) {
751
751
  log.debug(TAG, "ignored sync error", err);
752
752
  }
753
753
  }
754
- function rmIfExistsQuiet(path68) {
754
+ function rmIfExistsQuiet(path69) {
755
755
  try {
756
- fs2.rmSync(path68, { force: true });
756
+ fs2.rmSync(path69, { force: true });
757
757
  } catch (err) {
758
- log.debug(TAG, `rmIfExists failed for ${path68}`, err);
758
+ log.debug(TAG, `rmIfExists failed for ${path69}`, err);
759
759
  }
760
760
  }
761
761
  function killQuiet(target, signal = "SIGTERM") {
@@ -901,9 +901,9 @@ var _default = makeConfig();
901
901
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
902
902
 
903
903
  // src/commands/pair-auto.ts
904
- var fs51 = __toESM(require("fs"));
905
- var os40 = __toESM(require("os"));
906
- var path54 = __toESM(require("path"));
904
+ var fs52 = __toESM(require("fs"));
905
+ var os41 = __toESM(require("os"));
906
+ var path55 = __toESM(require("path"));
907
907
  var import_crypto4 = require("crypto");
908
908
 
909
909
  // src/services/telemetry.service.ts
@@ -939,8 +939,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
939
939
  return decodedFile;
940
940
  };
941
941
  }
942
- function normalizeWindowsPath(path68) {
943
- return path68.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
942
+ function normalizeWindowsPath(path69) {
943
+ return path69.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
944
944
  }
945
945
 
946
946
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3420,9 +3420,9 @@ async function addSourceContext(frames) {
3420
3420
  LRU_FILE_CONTENTS_CACHE.reduce();
3421
3421
  return frames;
3422
3422
  }
3423
- function getContextLinesFromFile(path68, ranges, output) {
3423
+ function getContextLinesFromFile(path69, ranges, output) {
3424
3424
  return new Promise((resolve7) => {
3425
- const stream = (0, import_node_fs.createReadStream)(path68);
3425
+ const stream = (0, import_node_fs.createReadStream)(path69);
3426
3426
  const lineReaded = (0, import_node_readline.createInterface)({
3427
3427
  input: stream
3428
3428
  });
@@ -3437,7 +3437,7 @@ function getContextLinesFromFile(path68, ranges, output) {
3437
3437
  let rangeStart = range[0];
3438
3438
  let rangeEnd = range[1];
3439
3439
  function onStreamError() {
3440
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path68, 1);
3440
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path69, 1);
3441
3441
  lineReaded.close();
3442
3442
  lineReaded.removeAllListeners();
3443
3443
  destroyStreamAndResolve();
@@ -3498,8 +3498,8 @@ function clearLineContext(frame) {
3498
3498
  delete frame.context_line;
3499
3499
  delete frame.post_context;
3500
3500
  }
3501
- function shouldSkipContextLinesForFile(path68) {
3502
- return path68.startsWith("node:") || path68.endsWith(".min.js") || path68.endsWith(".min.cjs") || path68.endsWith(".min.mjs") || path68.startsWith("data:");
3501
+ function shouldSkipContextLinesForFile(path69) {
3502
+ return path69.startsWith("node:") || path69.endsWith(".min.js") || path69.endsWith(".min.cjs") || path69.endsWith(".min.mjs") || path69.startsWith("data:");
3503
3503
  }
3504
3504
  function shouldSkipContextLinesForFrame(frame) {
3505
3505
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5653,7 +5653,7 @@ function readAnonId() {
5653
5653
  }
5654
5654
  function superProperties() {
5655
5655
  return {
5656
- cliVersion: true ? "2.60.8" : "0.0.0-dev",
5656
+ cliVersion: true ? "2.60.9" : "0.0.0-dev",
5657
5657
  nodeVersion: process.version,
5658
5658
  platform: process.platform,
5659
5659
  arch: process.arch,
@@ -5834,7 +5834,7 @@ var os4 = __toESM(require("os"));
5834
5834
  // package.json
5835
5835
  var package_default = {
5836
5836
  name: "codeam-cli",
5837
- version: "2.60.8",
5837
+ version: "2.60.9",
5838
5838
  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.",
5839
5839
  type: "commonjs",
5840
5840
  main: "dist/index.js",
@@ -6905,7 +6905,7 @@ var CommandRelayService = class {
6905
6905
  // fresh + clear the "CLI update available" banner after a self-update
6906
6906
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
6907
6907
  // pair/reconnect). Older backends ignore the extra field.
6908
- ..."2.60.8" ? { ideVersion: "2.60.8" } : {}
6908
+ ..."2.60.9" ? { ideVersion: "2.60.9" } : {}
6909
6909
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
6910
6910
  }
6911
6911
  /**
@@ -7132,10 +7132,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
7132
7132
  /[\\/]Start Menu([\\/]|$)/i,
7133
7133
  /[\\/]Templates([\\/]|$)/i
7134
7134
  ];
7135
- function isUnsafeWindowsWatchRoot(dir, homedir37) {
7135
+ function isUnsafeWindowsWatchRoot(dir, homedir38) {
7136
7136
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
7137
7137
  const cwd = norm(dir);
7138
- const home = norm(homedir37);
7138
+ const home = norm(homedir38);
7139
7139
  if (cwd === home) return true;
7140
7140
  if (/^[a-z]:$/.test(cwd)) return true;
7141
7141
  const sysRoots = [
@@ -8279,9 +8279,9 @@ function closeAllTerminals() {
8279
8279
  }
8280
8280
 
8281
8281
  // src/commands/start/handlers.ts
8282
- var fs50 = __toESM(require("fs"));
8283
- var os39 = __toESM(require("os"));
8284
- var path53 = __toESM(require("path"));
8282
+ var fs51 = __toESM(require("fs"));
8283
+ var os40 = __toESM(require("os"));
8284
+ var path54 = __toESM(require("path"));
8285
8285
  var import_crypto3 = require("crypto");
8286
8286
  var import_child_process23 = require("child_process");
8287
8287
 
@@ -9062,9 +9062,9 @@ function findGitRoot2(startDir) {
9062
9062
  }
9063
9063
 
9064
9064
  // src/commands/link.ts
9065
- var import_node_crypto5 = require("crypto");
9066
- var fs28 = __toESM(require("fs"));
9067
- var path32 = __toESM(require("path"));
9065
+ var import_node_crypto6 = require("crypto");
9066
+ var fs29 = __toESM(require("fs"));
9067
+ var path33 = __toESM(require("path"));
9068
9068
  var import_chokidar = __toESM(require("chokidar"));
9069
9069
  var import_picocolors2 = __toESM(require("picocolors"));
9070
9070
 
@@ -11711,10 +11711,10 @@ function buildForPlatform(platform3) {
11711
11711
  var import_node_crypto4 = require("crypto");
11712
11712
 
11713
11713
  // src/agents/claude/resolver.ts
11714
- function buildClaudeLaunch(extraArgs = [], os47 = createOsStrategy()) {
11715
- const found = os47.findInPath("claude") ?? os47.findInPath("claude-code");
11714
+ function buildClaudeLaunch(extraArgs = [], os48 = createOsStrategy()) {
11715
+ const found = os48.findInPath("claude") ?? os48.findInPath("claude-code");
11716
11716
  if (!found) return null;
11717
- return os47.buildLaunch(found, extraArgs);
11717
+ return os48.buildLaunch(found, extraArgs);
11718
11718
  }
11719
11719
 
11720
11720
  // src/agents/claude/installer.ts
@@ -12304,8 +12304,8 @@ var ClaudeRuntimeStrategy = class {
12304
12304
  meta = getAgent("claude");
12305
12305
  mode = "interactive";
12306
12306
  os;
12307
- constructor(os47) {
12308
- this.os = os47;
12307
+ constructor(os48) {
12308
+ this.os = os48;
12309
12309
  }
12310
12310
  /**
12311
12311
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -13004,8 +13004,8 @@ function codexCredentialLocator() {
13004
13004
  function codexLoginLauncher() {
13005
13005
  return {
13006
13006
  async ensureInstalled() {
13007
- const os47 = createOsStrategy();
13008
- return os47.findInPath("codex") !== null;
13007
+ const os48 = createOsStrategy();
13008
+ return os48.findInPath("codex") !== null;
13009
13009
  },
13010
13010
  launch() {
13011
13011
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -13028,8 +13028,8 @@ var CodexRuntimeStrategy = class {
13028
13028
  meta = getAgent("codex");
13029
13029
  mode = "interactive";
13030
13030
  os;
13031
- constructor(os47) {
13032
- this.os = os47;
13031
+ constructor(os48) {
13032
+ this.os = os48;
13033
13033
  }
13034
13034
  async prepareLaunch() {
13035
13035
  let binary = this.os.findInPath("codex");
@@ -13128,12 +13128,12 @@ var CodexRuntimeStrategy = class {
13128
13128
  });
13129
13129
  }
13130
13130
  };
13131
- function resolveNpm(os47) {
13132
- return os47.id === "win32" ? "npm.cmd" : "npm";
13131
+ function resolveNpm(os48) {
13132
+ return os48.id === "win32" ? "npm.cmd" : "npm";
13133
13133
  }
13134
- async function installCodexViaNpm(os47) {
13134
+ async function installCodexViaNpm(os48) {
13135
13135
  return new Promise((resolve7, reject) => {
13136
- const proc = (0, import_node_child_process5.spawn)(resolveNpm(os47), ["install", "-g", "@openai/codex"], {
13136
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os48), ["install", "-g", "@openai/codex"], {
13137
13137
  stdio: "inherit"
13138
13138
  });
13139
13139
  proc.on("close", (code) => {
@@ -13150,16 +13150,16 @@ async function installCodexViaNpm(os47) {
13150
13150
  });
13151
13151
  });
13152
13152
  }
13153
- function augmentNpmGlobalBin(os47) {
13153
+ function augmentNpmGlobalBin(os48) {
13154
13154
  try {
13155
- const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os47), ["prefix", "-g"], {
13155
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os48), ["prefix", "-g"], {
13156
13156
  stdio: ["ignore", "pipe", "ignore"]
13157
13157
  });
13158
13158
  if (result.status !== 0) return;
13159
13159
  const prefix = result.stdout.toString().trim();
13160
13160
  if (!prefix) return;
13161
- const binDir = os47.id === "win32" ? prefix : path24.join(prefix, "bin");
13162
- os47.augmentPath([binDir]);
13161
+ const binDir = os48.id === "win32" ? prefix : path24.join(prefix, "bin");
13162
+ os48.augmentPath([binDir]);
13163
13163
  } catch {
13164
13164
  }
13165
13165
  }
@@ -13243,9 +13243,9 @@ var import_node_child_process8 = require("child_process");
13243
13243
  // src/agents/coderabbit/installer.ts
13244
13244
  var import_node_child_process6 = require("child_process");
13245
13245
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
13246
- async function ensureCoderabbitInstalled(os47) {
13247
- if (os47.findInPath("coderabbit")) return true;
13248
- if (os47.id === "win32") {
13246
+ async function ensureCoderabbitInstalled(os48) {
13247
+ if (os48.findInPath("coderabbit")) return true;
13248
+ if (os48.id === "win32") {
13249
13249
  console.error(
13250
13250
  "\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"
13251
13251
  );
@@ -13260,8 +13260,8 @@ async function ensureCoderabbitInstalled(os47) {
13260
13260
  proc.on("error", () => resolve7(false));
13261
13261
  });
13262
13262
  if (!ok) return false;
13263
- os47.augmentPath([`${os47.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13264
- return os47.findInPath("coderabbit") !== null;
13263
+ os48.augmentPath([`${os48.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13264
+ return os48.findInPath("coderabbit") !== null;
13265
13265
  }
13266
13266
 
13267
13267
  // src/agents/coderabbit/link.ts
@@ -13296,10 +13296,10 @@ function coderabbitCredentialLocator() {
13296
13296
  validate: validateNonEmptyCredential
13297
13297
  };
13298
13298
  }
13299
- function coderabbitLoginLauncher(os47) {
13299
+ function coderabbitLoginLauncher(os48) {
13300
13300
  return {
13301
13301
  async ensureInstalled() {
13302
- return ensureCoderabbitInstalled(os47);
13302
+ return ensureCoderabbitInstalled(os48);
13303
13303
  },
13304
13304
  launch() {
13305
13305
  return (0, import_node_child_process7.spawn)("coderabbit", ["login"], { stdio: "inherit" });
@@ -13322,11 +13322,11 @@ function parseReview(stdout) {
13322
13322
  for (const line of lines) {
13323
13323
  const m = line.match(HUNK_LINE_RE);
13324
13324
  if (!m) continue;
13325
- const [, path68, lineNo, sevToken, message] = m;
13326
- if (!path68 || !lineNo || !message) continue;
13325
+ const [, path69, lineNo, sevToken, message] = m;
13326
+ if (!path69 || !lineNo || !message) continue;
13327
13327
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
13328
13328
  hunks.push({
13329
- path: path68.trim(),
13329
+ path: path69.trim(),
13330
13330
  line: Number(lineNo),
13331
13331
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
13332
13332
  message: cleanedMessage
@@ -13345,8 +13345,8 @@ var CoderabbitRuntimeStrategy = class {
13345
13345
  meta = getAgent("coderabbit");
13346
13346
  mode = "batch";
13347
13347
  os;
13348
- constructor(os47) {
13349
- this.os = os47;
13348
+ constructor(os48) {
13349
+ this.os = os48;
13350
13350
  }
13351
13351
  getDefaultArgs() {
13352
13352
  return ["review"];
@@ -13520,10 +13520,10 @@ function cursorCredentialLocator() {
13520
13520
  validate: validateNonEmptyCredential
13521
13521
  };
13522
13522
  }
13523
- function cursorLoginLauncher(os47) {
13523
+ function cursorLoginLauncher(os48) {
13524
13524
  return {
13525
13525
  async ensureInstalled() {
13526
- if (os47.findInPath("cursor-agent")) return true;
13526
+ if (os48.findInPath("cursor-agent")) return true;
13527
13527
  console.error(
13528
13528
  "\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"
13529
13529
  );
@@ -13585,8 +13585,8 @@ var CursorRuntimeStrategy = class {
13585
13585
  meta = getAgent("cursor");
13586
13586
  mode = "interactive";
13587
13587
  os;
13588
- constructor(os47) {
13589
- this.os = os47;
13588
+ constructor(os48) {
13589
+ this.os = os48;
13590
13590
  }
13591
13591
  async prepareLaunch() {
13592
13592
  const binary = this.os.findInPath("cursor-agent");
@@ -13732,10 +13732,10 @@ function aiderCredentialLocator() {
13732
13732
  validate: validateNonEmptyCredential
13733
13733
  };
13734
13734
  }
13735
- function aiderLoginLauncher(os47) {
13735
+ function aiderLoginLauncher(os48) {
13736
13736
  return {
13737
13737
  async ensureInstalled() {
13738
- if (os47.findInPath("aider")) return true;
13738
+ if (os48.findInPath("aider")) return true;
13739
13739
  console.error(
13740
13740
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
13741
13741
  );
@@ -13745,7 +13745,7 @@ function aiderLoginLauncher(os47) {
13745
13745
  console.error(
13746
13746
  "\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"
13747
13747
  );
13748
- return (0, import_node_child_process10.spawn)(os47.id === "win32" ? "cmd.exe" : "sh", os47.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13748
+ return (0, import_node_child_process10.spawn)(os48.id === "win32" ? "cmd.exe" : "sh", os48.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13749
13749
  stdio: "ignore"
13750
13750
  });
13751
13751
  }
@@ -13817,8 +13817,8 @@ var AiderRuntimeStrategy = class {
13817
13817
  meta = getAgent("aider");
13818
13818
  mode = "interactive";
13819
13819
  os;
13820
- constructor(os47) {
13821
- this.os = os47;
13820
+ constructor(os48) {
13821
+ this.os = os48;
13822
13822
  }
13823
13823
  async prepareLaunch() {
13824
13824
  const binary = this.os.findInPath("aider");
@@ -13885,6 +13885,9 @@ var AiderRuntimeStrategy = class {
13885
13885
  }
13886
13886
  };
13887
13887
 
13888
+ // src/agents/gemini/runtime.ts
13889
+ var import_node_crypto5 = require("crypto");
13890
+
13888
13891
  // src/agents/gemini/link.ts
13889
13892
  var import_node_child_process11 = require("child_process");
13890
13893
 
@@ -13947,8 +13950,8 @@ function geminiCredentialLocator() {
13947
13950
  function geminiLoginLauncher() {
13948
13951
  return {
13949
13952
  async ensureInstalled() {
13950
- const os47 = createOsStrategy();
13951
- return os47.findInPath("gemini") !== null;
13953
+ const os48 = createOsStrategy();
13954
+ return os48.findInPath("gemini") !== null;
13952
13955
  },
13953
13956
  launch() {
13954
13957
  return (0, import_node_child_process11.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -13956,6 +13959,132 @@ function geminiLoginLauncher() {
13956
13959
  };
13957
13960
  }
13958
13961
 
13962
+ // src/agents/gemini/history.ts
13963
+ var fs28 = __toESM(require("fs"));
13964
+ var os25 = __toESM(require("os"));
13965
+ var path32 = __toESM(require("path"));
13966
+ var GEMINI_ROOT = path32.join(os25.homedir(), ".gemini");
13967
+ function projectNameForCwd(cwd, root) {
13968
+ try {
13969
+ const parsed = JSON.parse(
13970
+ fs28.readFileSync(path32.join(root, "projects.json"), "utf8")
13971
+ );
13972
+ const map = parsed.projects;
13973
+ if (map && typeof map === "object") {
13974
+ if (typeof map[cwd] === "string") return map[cwd];
13975
+ try {
13976
+ const rp = fs28.realpathSync(cwd);
13977
+ if (typeof map[rp] === "string") return map[rp];
13978
+ } catch {
13979
+ }
13980
+ }
13981
+ } catch {
13982
+ }
13983
+ return path32.basename(cwd) || null;
13984
+ }
13985
+ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
13986
+ const name = projectNameForCwd(cwd, root);
13987
+ if (!name) return null;
13988
+ const dir = path32.join(root, "tmp", name, "chats");
13989
+ return fs28.existsSync(dir) ? dir : null;
13990
+ }
13991
+ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
13992
+ const dir = resolveHistoryDir5(cwd, root);
13993
+ if (!dir) return null;
13994
+ let files;
13995
+ try {
13996
+ files = fs28.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
13997
+ } catch {
13998
+ return null;
13999
+ }
14000
+ if (files.length === 0) return null;
14001
+ const id8 = sessionId.slice(0, 8);
14002
+ const byName = files.find((f) => id8.length > 0 && f.includes(id8));
14003
+ if (byName) return path32.join(dir, byName);
14004
+ for (const f of files) {
14005
+ const full = path32.join(dir, f);
14006
+ try {
14007
+ const firstLine = fs28.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
14008
+ const hdr = JSON.parse(firstLine);
14009
+ if (hdr.sessionId === sessionId) return full;
14010
+ } catch {
14011
+ }
14012
+ }
14013
+ let newest = null;
14014
+ for (const f of files) {
14015
+ try {
14016
+ const mtime = fs28.statSync(path32.join(dir, f)).mtimeMs;
14017
+ if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
14018
+ } catch {
14019
+ }
14020
+ }
14021
+ return newest ? path32.join(dir, newest.file) : null;
14022
+ }
14023
+ function extractGeminiText(content) {
14024
+ const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
14025
+ const part = p2;
14026
+ return typeof part?.text === "string" ? part.text : "";
14027
+ }).join("") : null;
14028
+ const parts = fromParts(content);
14029
+ if (parts !== null) return parts;
14030
+ if (typeof content === "string") {
14031
+ const trimmed = content.trim();
14032
+ if (trimmed.startsWith("[")) {
14033
+ try {
14034
+ const asParts = fromParts(JSON.parse(trimmed));
14035
+ if (asParts !== null) return asParts;
14036
+ } catch {
14037
+ }
14038
+ }
14039
+ return content;
14040
+ }
14041
+ return "";
14042
+ }
14043
+ function isSyntheticGeminiTurn(text) {
14044
+ return text.trim().startsWith("<session_context>");
14045
+ }
14046
+ function parseHistoryFile5(filePath) {
14047
+ let raw;
14048
+ try {
14049
+ raw = fs28.readFileSync(filePath, "utf8");
14050
+ } catch {
14051
+ return [];
14052
+ }
14053
+ const out2 = [];
14054
+ const seen = /* @__PURE__ */ new Set();
14055
+ let idx = 0;
14056
+ const consider = (m) => {
14057
+ if (m.type !== "user" && m.type !== "gemini") return;
14058
+ const id = typeof m.id === "string" ? m.id : `pos-${idx}`;
14059
+ if (seen.has(id)) return;
14060
+ const text = extractGeminiText(m.content);
14061
+ if (!text || isSyntheticGeminiTurn(text)) return;
14062
+ seen.add(id);
14063
+ out2.push({
14064
+ id: `gemini:${id}`,
14065
+ role: m.type === "user" ? "user" : "agent",
14066
+ text,
14067
+ timestamp: typeof m.timestamp === "string" ? m.timestamp : (/* @__PURE__ */ new Date(0)).toISOString()
14068
+ });
14069
+ idx += 1;
14070
+ };
14071
+ for (const line of raw.split("\n")) {
14072
+ if (!line.trim()) continue;
14073
+ let rec;
14074
+ try {
14075
+ rec = JSON.parse(line);
14076
+ } catch {
14077
+ continue;
14078
+ }
14079
+ if (rec.$set && Array.isArray(rec.$set.messages)) {
14080
+ for (const m of rec.$set.messages) consider(m);
14081
+ } else if (rec.type === "user" || rec.type === "gemini") {
14082
+ consider(rec);
14083
+ }
14084
+ }
14085
+ return out2;
14086
+ }
14087
+
13959
14088
  // src/agents/gemini/runtime.ts
13960
14089
  var GEMINI_PRO_CONTEXT_WINDOW = 1e6;
13961
14090
  var GEMINI_FLASH_CONTEXT_WINDOW = 1e6;
@@ -13981,8 +14110,8 @@ var GeminiRuntimeStrategy = class {
13981
14110
  meta = getAgent("gemini");
13982
14111
  mode = "interactive";
13983
14112
  os;
13984
- constructor(os47) {
13985
- this.os = os47;
14113
+ constructor(os48) {
14114
+ this.os = os48;
13986
14115
  }
13987
14116
  async prepareLaunch() {
13988
14117
  const binary = this.os.findInPath("gemini");
@@ -13991,19 +14120,25 @@ var GeminiRuntimeStrategy = class {
13991
14120
  "Gemini CLI is not on PATH. Install it with:\n npm install -g @google/gemini-cli\n Then run `codeam pair` again."
13992
14121
  );
13993
14122
  }
13994
- return this.os.buildLaunch(binary);
14123
+ const sessionId = (0, import_node_crypto5.randomUUID)();
14124
+ const launch = this.os.buildLaunch(binary, ["--session-id", sessionId]);
14125
+ return { cmd: launch.cmd, args: launch.args, sessionId };
13995
14126
  }
13996
- // Gemini's REPL has no documented "resume previous session" flag,
13997
- // so a relaunch starts fresh. Returning an empty array is the
13998
- // documented "no-op resume" path (Cursor / Aider do the same).
13999
- resumeLaunchArgs(_sessionId, _opts) {
14000
- return [];
14127
+ // Re-attach the same conversation on hand-back (baton) by passing the same
14128
+ // `--session-id`. Gemini resolves an existing id to the prior transcript.
14129
+ resumeLaunchArgs(sessionId, _opts) {
14130
+ return ["--session-id", sessionId];
14001
14131
  }
14002
- resolveHistoryDir(_cwd) {
14003
- return null;
14132
+ resolveHistoryDir(cwd) {
14133
+ return resolveHistoryDir5(cwd);
14004
14134
  }
14005
- parseHistoryFile(_filePath) {
14006
- return [];
14135
+ /** `~/.gemini/tmp/<project>/chats/session-<ts>-<id8>.jsonl`. Presence of this
14136
+ * method is what lets the baton engage for Gemini (`runtimeSupportsBaton`). */
14137
+ resolveHistoryFile(cwd, sessionId) {
14138
+ return resolveHistoryFile4(cwd, sessionId);
14139
+ }
14140
+ parseHistoryFile(filePath) {
14141
+ return parseHistoryFile5(filePath);
14007
14142
  }
14008
14143
  getCurrentUsage(_historyDir) {
14009
14144
  return null;
@@ -14081,18 +14216,18 @@ var GeminiRuntimeStrategy = class {
14081
14216
 
14082
14217
  // src/agents/registry.ts
14083
14218
  var runtimeBuilders = {
14084
- claude: (os47) => new ClaudeRuntimeStrategy(os47),
14085
- codex: (os47) => new CodexRuntimeStrategy(os47),
14086
- coderabbit: (os47) => new CoderabbitRuntimeStrategy(os47),
14087
- cursor: (os47) => new CursorRuntimeStrategy(os47),
14088
- aider: (os47) => new AiderRuntimeStrategy(os47),
14089
- gemini: (os47) => new GeminiRuntimeStrategy(os47)
14219
+ claude: (os48) => new ClaudeRuntimeStrategy(os48),
14220
+ codex: (os48) => new CodexRuntimeStrategy(os48),
14221
+ coderabbit: (os48) => new CoderabbitRuntimeStrategy(os48),
14222
+ cursor: (os48) => new CursorRuntimeStrategy(os48),
14223
+ aider: (os48) => new AiderRuntimeStrategy(os48),
14224
+ gemini: (os48) => new GeminiRuntimeStrategy(os48)
14090
14225
  };
14091
14226
  var deployBuilders = {
14092
14227
  claude: () => new ClaudeDeployStrategy(),
14093
14228
  codex: () => new CodexDeployStrategy()
14094
14229
  };
14095
- function createAgentStrategy(agent, os47 = createOsStrategy()) {
14230
+ function createAgentStrategy(agent, os48 = createOsStrategy()) {
14096
14231
  if (!AGENT_REGISTRY[agent]?.enabled) {
14097
14232
  throw new Error(
14098
14233
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -14102,10 +14237,10 @@ function createAgentStrategy(agent, os47 = createOsStrategy()) {
14102
14237
  if (!build) {
14103
14238
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
14104
14239
  }
14105
- return build(os47);
14240
+ return build(os48);
14106
14241
  }
14107
- function createInteractiveAgentStrategy(agent, os47 = createOsStrategy()) {
14108
- const s = createAgentStrategy(agent, os47);
14242
+ function createInteractiveAgentStrategy(agent, os48 = createOsStrategy()) {
14243
+ const s = createAgentStrategy(agent, os48);
14109
14244
  if (s.mode !== "interactive") {
14110
14245
  throw new Error(
14111
14246
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -14161,7 +14296,7 @@ function parseLinkArgs(args2) {
14161
14296
  if (apiKeyFileArg) {
14162
14297
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
14163
14298
  try {
14164
- apiKey = fs28.readFileSync(path32.resolve(filePath), "utf8").trim();
14299
+ apiKey = fs29.readFileSync(path33.resolve(filePath), "utf8").trim();
14165
14300
  } catch (err) {
14166
14301
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
14167
14302
  }
@@ -14188,9 +14323,9 @@ async function link(args2 = []) {
14188
14323
  await linkDryRunPreflight(ctx);
14189
14324
  return;
14190
14325
  }
14191
- const pluginId = (0, import_node_crypto5.randomUUID)();
14192
- const pollSecret = (0, import_node_crypto5.randomBytes)(32).toString("base64url");
14193
- const pluginSecretHash = (0, import_node_crypto5.createHash)("sha256").update(pollSecret).digest("hex");
14326
+ const pluginId = (0, import_node_crypto6.randomUUID)();
14327
+ const pollSecret = (0, import_node_crypto6.randomBytes)(32).toString("base64url");
14328
+ const pluginSecretHash = (0, import_node_crypto6.createHash)("sha256").update(pollSecret).digest("hex");
14194
14329
  const spin = dist_exports.spinner();
14195
14330
  spin.start("Requesting pairing code...");
14196
14331
  const pairing = await requestCode(pluginId, pluginSecretHash);
@@ -14288,7 +14423,7 @@ async function link(args2 = []) {
14288
14423
  return;
14289
14424
  }
14290
14425
  if (parsed.tokenFile) {
14291
- const credential = fs28.readFileSync(path32.resolve(parsed.tokenFile), "utf8").trim();
14426
+ const credential = fs29.readFileSync(path33.resolve(parsed.tokenFile), "utf8").trim();
14292
14427
  if (!credential) {
14293
14428
  showError(`--token-file ${parsed.tokenFile} is empty.`);
14294
14429
  process.exit(1);
@@ -14506,14 +14641,14 @@ async function linkDryRunPreflight(ctx) {
14506
14641
 
14507
14642
  // src/commands/host-agent.ts
14508
14643
  var import_node_child_process19 = require("child_process");
14509
- var os32 = __toESM(require("os"));
14510
- var fs38 = __toESM(require("fs"));
14511
- var path40 = __toESM(require("path"));
14644
+ var os33 = __toESM(require("os"));
14645
+ var fs39 = __toESM(require("fs"));
14646
+ var path41 = __toESM(require("path"));
14512
14647
 
14513
14648
  // src/commands/host/host-client.ts
14514
- var fs30 = __toESM(require("fs"));
14515
- var os26 = __toESM(require("os"));
14516
- var path33 = __toESM(require("path"));
14649
+ var fs31 = __toESM(require("fs"));
14650
+ var os27 = __toESM(require("os"));
14651
+ var path34 = __toESM(require("path"));
14517
14652
 
14518
14653
  // src/lib/restrict-to-owner.ts
14519
14654
  var import_node_fs5 = __toESM(require("fs"));
@@ -14552,7 +14687,7 @@ function restrictToOwner(filePath) {
14552
14687
  function sampleCpuTimes() {
14553
14688
  let idle = 0;
14554
14689
  let total = 0;
14555
- for (const cpu of os26.cpus()) {
14690
+ for (const cpu of os27.cpus()) {
14556
14691
  const t2 = cpu.times;
14557
14692
  idle += t2.idle;
14558
14693
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -14571,8 +14706,8 @@ var MetricsCollector = class {
14571
14706
  const prev = this.prevCpu;
14572
14707
  this.prevCpu = current;
14573
14708
  if (!prev) {
14574
- const cores = os26.cpus().length || 1;
14575
- const proxy = os26.loadavg()[0] / cores * 100;
14709
+ const cores = os27.cpus().length || 1;
14710
+ const proxy = os27.loadavg()[0] / cores * 100;
14576
14711
  return Math.min(100, Math.max(0, Math.round(proxy)));
14577
14712
  }
14578
14713
  const idleDelta = current.idle - prev.idle;
@@ -14585,8 +14720,8 @@ var MetricsCollector = class {
14585
14720
  collect() {
14586
14721
  return {
14587
14722
  cpuPct: this.cpuPct(),
14588
- ramUsedMb: Math.round((os26.totalmem() - os26.freemem()) / 1048576),
14589
- ramTotalMb: Math.round(os26.totalmem() / 1048576),
14723
+ ramUsedMb: Math.round((os27.totalmem() - os27.freemem()) / 1048576),
14724
+ ramTotalMb: Math.round(os27.totalmem() / 1048576),
14590
14725
  latencyMs: this.lastLatencyMs
14591
14726
  };
14592
14727
  }
@@ -14595,19 +14730,19 @@ function apiBase() {
14595
14730
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
14596
14731
  }
14597
14732
  function hostIdentityPath() {
14598
- return path33.join(os26.homedir(), ".codeam", "host-agent.json");
14733
+ return path34.join(os27.homedir(), ".codeam", "host-agent.json");
14599
14734
  }
14600
14735
  function collectOsInfo() {
14601
14736
  return {
14602
- distro: os26.platform(),
14603
- arch: os26.arch(),
14604
- kernel: os26.release(),
14737
+ distro: os27.platform(),
14738
+ arch: os27.arch(),
14739
+ kernel: os27.release(),
14605
14740
  nodeVersion: process.versions.node
14606
14741
  };
14607
14742
  }
14608
14743
  function loadHostIdentity() {
14609
14744
  try {
14610
- const raw = fs30.readFileSync(hostIdentityPath(), "utf8");
14745
+ const raw = fs31.readFileSync(hostIdentityPath(), "utf8");
14611
14746
  const parsed = JSON.parse(raw);
14612
14747
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
14613
14748
  const p2 = parsed;
@@ -14620,8 +14755,8 @@ function loadHostIdentity() {
14620
14755
  }
14621
14756
  function saveHostIdentity(identity) {
14622
14757
  const file = hostIdentityPath();
14623
- fs30.mkdirSync(path33.dirname(file), { recursive: true, mode: 448 });
14624
- fs30.writeFileSync(file, JSON.stringify(identity, null, 2), {
14758
+ fs31.mkdirSync(path34.dirname(file), { recursive: true, mode: 448 });
14759
+ fs31.writeFileSync(file, JSON.stringify(identity, null, 2), {
14625
14760
  encoding: "utf8",
14626
14761
  mode: 384
14627
14762
  });
@@ -14666,7 +14801,7 @@ function isTerminalEnrollError(err) {
14666
14801
  }
14667
14802
  function deleteHostIdentity() {
14668
14803
  try {
14669
- fs30.rmSync(hostIdentityPath(), { force: true });
14804
+ fs31.rmSync(hostIdentityPath(), { force: true });
14670
14805
  } catch {
14671
14806
  }
14672
14807
  }
@@ -14789,17 +14924,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
14789
14924
  }
14790
14925
 
14791
14926
  // src/commands/host/workspace.ts
14792
- var fs31 = __toESM(require("fs"));
14793
- var os27 = __toESM(require("os"));
14794
- var path34 = __toESM(require("path"));
14927
+ var fs32 = __toESM(require("fs"));
14928
+ var os28 = __toESM(require("os"));
14929
+ var path35 = __toESM(require("path"));
14795
14930
  var import_node_child_process13 = require("child_process");
14796
14931
  var import_node_util4 = require("util");
14797
14932
  var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process13.execFile);
14798
14933
  function isAbsolutePathTarget(target) {
14799
- return path34.isAbsolute(target);
14934
+ return path35.isAbsolute(target);
14800
14935
  }
14801
14936
  function selfHostedWorkspaceRoot() {
14802
- return path34.join(os27.homedir(), ".codeam", "self-hosted");
14937
+ return path35.join(os28.homedir(), ".codeam", "self-hosted");
14803
14938
  }
14804
14939
  function nonInteractiveGitEnv() {
14805
14940
  return {
@@ -14852,13 +14987,13 @@ async function fetchGithubIdentity(token) {
14852
14987
  async function configureGitCredentials(dest, repoRef, cloneToken) {
14853
14988
  const gh = githubOwnerRepo(repoRef.trim());
14854
14989
  if (!gh || !cloneToken) return;
14855
- const credFile = path34.join(dest, ".git", "codeam-credentials");
14856
- fs31.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
14990
+ const credFile = path35.join(dest, ".git", "codeam-credentials");
14991
+ fs32.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
14857
14992
  `, { mode: 384 });
14858
14993
  restrictToOwner(credFile);
14859
14994
  const env = nonInteractiveGitEnv();
14860
14995
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
14861
- const credFilePosix = credFile.split(path34.sep).join("/");
14996
+ const credFilePosix = credFile.split(path35.sep).join("/");
14862
14997
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
14863
14998
  });
14864
14999
  await git2([
@@ -14894,17 +15029,17 @@ function maskToken(text, cloneToken) {
14894
15029
  }
14895
15030
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14896
15031
  if (isAbsolutePathTarget(repoOrPath)) {
14897
- if (!fs31.existsSync(repoOrPath)) {
15032
+ if (!fs32.existsSync(repoOrPath)) {
14898
15033
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
14899
15034
  }
14900
15035
  return repoOrPath;
14901
15036
  }
14902
- const dest = path34.join(selfHostedWorkspaceRoot(), deployId);
14903
- if (fs31.existsSync(path34.join(dest, ".git"))) {
15037
+ const dest = path35.join(selfHostedWorkspaceRoot(), deployId);
15038
+ if (fs32.existsSync(path35.join(dest, ".git"))) {
14904
15039
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
14905
15040
  return dest;
14906
15041
  }
14907
- fs31.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
15042
+ fs32.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
14908
15043
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
14909
15044
  try {
14910
15045
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -14921,9 +15056,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14921
15056
  }
14922
15057
 
14923
15058
  // src/commands/host/agent-provisioning.ts
14924
- var fs32 = __toESM(require("fs"));
14925
- var os28 = __toESM(require("os"));
14926
- var path35 = __toESM(require("path"));
15059
+ var fs33 = __toESM(require("fs"));
15060
+ var os29 = __toESM(require("os"));
15061
+ var path36 = __toESM(require("path"));
14927
15062
  var PUBLIC_TO_INTERNAL_AGENT = {
14928
15063
  claude_code: "claude",
14929
15064
  claude: "claude",
@@ -14938,22 +15073,22 @@ function toInternalAgentId(publicAgentId) {
14938
15073
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
14939
15074
  }
14940
15075
  function ensureDir(dir) {
14941
- fs32.mkdirSync(dir, { recursive: true, mode: 448 });
15076
+ fs33.mkdirSync(dir, { recursive: true, mode: 448 });
14942
15077
  }
14943
15078
  function writeFile0600(filePath, contents) {
14944
- ensureDir(path35.dirname(filePath));
14945
- fs32.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
15079
+ ensureDir(path36.dirname(filePath));
15080
+ fs33.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
14946
15081
  restrictToOwner(filePath);
14947
15082
  }
14948
15083
  function rmIfExists(filePath) {
14949
15084
  try {
14950
- fs32.rmSync(filePath, { force: true });
15085
+ fs33.rmSync(filePath, { force: true });
14951
15086
  } catch {
14952
15087
  }
14953
15088
  }
14954
15089
  var claudeProvisioner = {
14955
15090
  write(auth, home) {
14956
- const credentialsJson = path35.join(home, ".claude", ".credentials.json");
15091
+ const credentialsJson = path36.join(home, ".claude", ".credentials.json");
14957
15092
  if (auth.kind === "api_key") {
14958
15093
  rmIfExists(credentialsJson);
14959
15094
  return { ANTHROPIC_API_KEY: auth.value };
@@ -14965,8 +15100,8 @@ var claudeProvisioner = {
14965
15100
  } else {
14966
15101
  rmIfExists(credentialsJson);
14967
15102
  }
14968
- const claudeJson = path35.join(home, ".claude.json");
14969
- if (!fs32.existsSync(claudeJson)) {
15103
+ const claudeJson = path36.join(home, ".claude.json");
15104
+ if (!fs33.existsSync(claudeJson)) {
14970
15105
  writeFile0600(
14971
15106
  claudeJson,
14972
15107
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -14977,7 +15112,7 @@ var claudeProvisioner = {
14977
15112
  };
14978
15113
  var codexProvisioner = {
14979
15114
  write(auth, home) {
14980
- const authJson = path35.join(home, ".codex", "auth.json");
15115
+ const authJson = path36.join(home, ".codex", "auth.json");
14981
15116
  if (auth.kind === "api_key") {
14982
15117
  rmIfExists(authJson);
14983
15118
  return { OPENAI_API_KEY: auth.value };
@@ -14988,8 +15123,8 @@ var codexProvisioner = {
14988
15123
  };
14989
15124
  var geminiProvisioner = {
14990
15125
  write(auth, home) {
14991
- const settingsJson = path35.join(home, ".gemini", "settings.json");
14992
- const oauthCreds = path35.join(home, ".gemini", "oauth_creds.json");
15126
+ const settingsJson = path36.join(home, ".gemini", "settings.json");
15127
+ const oauthCreds = path36.join(home, ".gemini", "oauth_creds.json");
14993
15128
  if (auth.kind === "api_key") {
14994
15129
  rmIfExists(oauthCreds);
14995
15130
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -15002,7 +15137,7 @@ var geminiProvisioner = {
15002
15137
  };
15003
15138
  var cursorProvisioner = {
15004
15139
  write(auth, home) {
15005
- const authJson = path35.join(home, ".config", "cursor", "auth.json");
15140
+ const authJson = path36.join(home, ".config", "cursor", "auth.json");
15006
15141
  if (auth.kind === "api_key") {
15007
15142
  rmIfExists(authJson);
15008
15143
  return { CURSOR_API_KEY: auth.value };
@@ -15039,7 +15174,7 @@ var UnsupportedAgentError = class extends Error {
15039
15174
  this.agentId = agentId;
15040
15175
  }
15041
15176
  };
15042
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os28.homedir()) {
15177
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os29.homedir()) {
15043
15178
  const internal = toInternalAgentId(publicAgentId);
15044
15179
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
15045
15180
  const provisioner = PROVISIONERS[internal];
@@ -15049,11 +15184,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os28.homedir(
15049
15184
 
15050
15185
  // src/commands/host/git-tooling.ts
15051
15186
  var import_node_child_process14 = require("child_process");
15052
- var fs33 = __toESM(require("fs"));
15053
- var os29 = __toESM(require("os"));
15054
- var path36 = __toESM(require("path"));
15187
+ var fs34 = __toESM(require("fs"));
15188
+ var os30 = __toESM(require("os"));
15189
+ var path37 = __toESM(require("path"));
15055
15190
  function codeamBinDir() {
15056
- return process.env.CODEAM_BIN_DIR ?? path36.join(os29.homedir(), ".codeam", "bin");
15191
+ return process.env.CODEAM_BIN_DIR ?? path37.join(os30.homedir(), ".codeam", "bin");
15057
15192
  }
15058
15193
  var FALLBACK_GH_VERSION = "2.62.0";
15059
15194
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -15085,7 +15220,7 @@ async function download(url, dest) {
15085
15220
  const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
15086
15221
  if (!res.ok || !res.body) return false;
15087
15222
  const buf = Buffer.from(await res.arrayBuffer());
15088
- fs33.writeFileSync(dest, buf);
15223
+ fs34.writeFileSync(dest, buf);
15089
15224
  return true;
15090
15225
  } catch {
15091
15226
  return false;
@@ -15108,8 +15243,8 @@ async function ensureGhCli(runner, token, deps = {}) {
15108
15243
  const version3 = await resolveVersionFn(token);
15109
15244
  const asset = `gh_${version3}_${osToken}_${arch2}`;
15110
15245
  const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
15111
- const tmpRoot = fs33.mkdtempSync(path36.join(os29.tmpdir(), "codeam-gh-"));
15112
- const archive = path36.join(tmpRoot, `${asset}.${ext}`);
15246
+ const tmpRoot = fs34.mkdtempSync(path37.join(os30.tmpdir(), "codeam-gh-"));
15247
+ const archive = path37.join(tmpRoot, `${asset}.${ext}`);
15113
15248
  if (!await downloadFn(url, archive)) {
15114
15249
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
15115
15250
  return null;
@@ -15119,16 +15254,16 @@ async function ensureGhCli(runner, token, deps = {}) {
15119
15254
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
15120
15255
  return null;
15121
15256
  }
15122
- const extractedBin = path36.join(tmpRoot, asset, "bin", binaryName);
15123
- if (!fs33.existsSync(extractedBin)) {
15257
+ const extractedBin = path37.join(tmpRoot, asset, "bin", binaryName);
15258
+ if (!fs34.existsSync(extractedBin)) {
15124
15259
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
15125
15260
  return null;
15126
15261
  }
15127
15262
  const binDir = codeamBinDir();
15128
- fs33.mkdirSync(binDir, { recursive: true });
15129
- const target = path36.join(binDir, binaryName);
15130
- fs33.copyFileSync(extractedBin, target);
15131
- fs33.chmodSync(target, 493);
15263
+ fs34.mkdirSync(binDir, { recursive: true });
15264
+ const target = path37.join(binDir, binaryName);
15265
+ fs34.copyFileSync(extractedBin, target);
15266
+ fs34.chmodSync(target, 493);
15132
15267
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
15133
15268
  return target;
15134
15269
  } catch (e) {
@@ -15615,23 +15750,23 @@ async function ensureModernPython(runner) {
15615
15750
  }
15616
15751
 
15617
15752
  // src/commands/host/headroom-bootstrap.ts
15618
- var fs35 = __toESM(require("fs"));
15619
- var path38 = __toESM(require("path"));
15753
+ var fs36 = __toESM(require("fs"));
15754
+ var path39 = __toESM(require("path"));
15620
15755
 
15621
15756
  // src/commands/host/headroom-config.ts
15622
- var fs34 = __toESM(require("fs"));
15623
- var os30 = __toESM(require("os"));
15624
- var path37 = __toESM(require("path"));
15757
+ var fs35 = __toESM(require("fs"));
15758
+ var os31 = __toESM(require("os"));
15759
+ var path38 = __toESM(require("path"));
15625
15760
  function headroomConfigPath() {
15626
- return path37.join(os30.homedir(), ".codeam", "headroom-config.json");
15761
+ return path38.join(os31.homedir(), ".codeam", "headroom-config.json");
15627
15762
  }
15628
15763
  function persistHeadroomConfig(config) {
15629
15764
  try {
15630
15765
  const file = headroomConfigPath();
15631
- fs34.mkdirSync(path37.dirname(file), { recursive: true, mode: 448 });
15766
+ fs35.mkdirSync(path38.dirname(file), { recursive: true, mode: 448 });
15632
15767
  const tmp = `${file}.tmp-${process.pid}`;
15633
- fs34.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15634
- fs34.renameSync(tmp, file);
15768
+ fs35.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15769
+ fs35.renameSync(tmp, file);
15635
15770
  restrictToOwner(file);
15636
15771
  } catch (err) {
15637
15772
  log.warn(
@@ -15641,21 +15776,21 @@ function persistHeadroomConfig(config) {
15641
15776
  }
15642
15777
  }
15643
15778
  function agentSettingsPath(kind) {
15644
- const home = os30.homedir();
15645
- if (kind === "claude") return path37.join(home, ".claude", "settings.json");
15646
- if (kind === "codex") return path37.join(home, ".codex", "auth.json");
15647
- if (kind === "copilot") return path37.join(home, ".config", "github-copilot", "hosts.json");
15779
+ const home = os31.homedir();
15780
+ if (kind === "claude") return path38.join(home, ".claude", "settings.json");
15781
+ if (kind === "codex") return path38.join(home, ".codex", "auth.json");
15782
+ if (kind === "copilot") return path38.join(home, ".config", "github-copilot", "hosts.json");
15648
15783
  return null;
15649
15784
  }
15650
15785
  function backupAgentHeadroomConfig(kind) {
15651
15786
  const src = agentSettingsPath(kind);
15652
15787
  if (!src) return;
15653
15788
  try {
15654
- if (!fs34.existsSync(src)) return;
15655
- const dest = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15656
- fs34.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
15657
- fs34.copyFileSync(src, dest);
15658
- fs34.chmodSync(dest, 384);
15789
+ if (!fs35.existsSync(src)) return;
15790
+ const dest = path38.join(os31.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15791
+ fs35.mkdirSync(path38.dirname(dest), { recursive: true, mode: 448 });
15792
+ fs35.copyFileSync(src, dest);
15793
+ fs35.chmodSync(dest, 384);
15659
15794
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
15660
15795
  } catch (err) {
15661
15796
  log.warn(
@@ -15667,12 +15802,12 @@ function backupAgentHeadroomConfig(kind) {
15667
15802
  function restoreAgentHeadroomConfig(kind) {
15668
15803
  const dest = agentSettingsPath(kind);
15669
15804
  if (!dest) return false;
15670
- const src = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15671
- if (!fs34.existsSync(src)) return false;
15805
+ const src = path38.join(os31.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15806
+ if (!fs35.existsSync(src)) return false;
15672
15807
  try {
15673
- fs34.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
15674
- fs34.copyFileSync(src, dest);
15675
- fs34.chmodSync(dest, 384);
15808
+ fs35.mkdirSync(path38.dirname(dest), { recursive: true, mode: 448 });
15809
+ fs35.copyFileSync(src, dest);
15810
+ fs35.chmodSync(dest, 384);
15676
15811
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
15677
15812
  return true;
15678
15813
  } catch (err) {
@@ -15685,7 +15820,7 @@ function restoreAgentHeadroomConfig(kind) {
15685
15820
  }
15686
15821
  function readHeadroomChildEnv() {
15687
15822
  try {
15688
- const raw = fs34.readFileSync(headroomConfigPath(), "utf8");
15823
+ const raw = fs35.readFileSync(headroomConfigPath(), "utf8");
15689
15824
  const parsed = JSON.parse(raw);
15690
15825
  if (typeof parsed !== "object" || parsed === null) return {};
15691
15826
  const o = parsed;
@@ -15721,37 +15856,37 @@ function bundledClaudeBinDir() {
15721
15856
  const roots = /* @__PURE__ */ new Set();
15722
15857
  let dir = __dirname;
15723
15858
  for (let i = 0; i < 6; i++) {
15724
- roots.add(path38.join(dir, "node_modules"));
15725
- const parent = path38.dirname(dir);
15859
+ roots.add(path39.join(dir, "node_modules"));
15860
+ const parent = path39.dirname(dir);
15726
15861
  if (parent === dir) break;
15727
15862
  dir = parent;
15728
15863
  }
15729
15864
  try {
15730
15865
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
15731
- const marker = `${path38.sep}@anthropic-ai${path38.sep}`;
15866
+ const marker = `${path39.sep}@anthropic-ai${path39.sep}`;
15732
15867
  const idx = main2.lastIndexOf(marker);
15733
15868
  if (idx !== -1) roots.add(main2.slice(0, idx));
15734
15869
  } catch {
15735
15870
  }
15736
15871
  for (const nm of roots) {
15737
- const atAnthropic = path38.join(nm, "@anthropic-ai");
15872
+ const atAnthropic = path39.join(nm, "@anthropic-ai");
15738
15873
  let entries;
15739
15874
  try {
15740
- entries = fs35.readdirSync(atAnthropic);
15875
+ entries = fs36.readdirSync(atAnthropic);
15741
15876
  } catch {
15742
15877
  continue;
15743
15878
  }
15744
15879
  for (const entry of entries) {
15745
15880
  if (!entry.startsWith("claude-agent-sdk-")) continue;
15746
- const bin = path38.join(atAnthropic, entry, "claude");
15747
- if (fs35.existsSync(bin)) return path38.dirname(bin);
15881
+ const bin = path39.join(atAnthropic, entry, "claude");
15882
+ if (fs36.existsSync(bin)) return path39.dirname(bin);
15748
15883
  }
15749
15884
  }
15750
15885
  return null;
15751
15886
  }
15752
15887
  async function getFreeDiskBytes(dir) {
15753
15888
  try {
15754
- const s = await fs35.promises.statfs(dir);
15889
+ const s = await fs36.promises.statfs(dir);
15755
15890
  return s.bsize * s.bavail;
15756
15891
  } catch {
15757
15892
  return null;
@@ -15813,7 +15948,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15813
15948
  if (initKind === "claude") {
15814
15949
  const claudeDir = bundledClaudeBinDir();
15815
15950
  if (claudeDir) {
15816
- initEnv.PATH = `${claudeDir}${path38.delimiter}${process.env["PATH"] ?? ""}`;
15951
+ initEnv.PATH = `${claudeDir}${path39.delimiter}${process.env["PATH"] ?? ""}`;
15817
15952
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
15818
15953
  } else {
15819
15954
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -15848,9 +15983,9 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15848
15983
  var import_node_child_process17 = require("child_process");
15849
15984
 
15850
15985
  // src/lib/updateNotifier.ts
15851
- var fs36 = __toESM(require("fs"));
15852
- var os31 = __toESM(require("os"));
15853
- var path39 = __toESM(require("path"));
15986
+ var fs37 = __toESM(require("fs"));
15987
+ var os32 = __toESM(require("os"));
15988
+ var path40 = __toESM(require("path"));
15854
15989
  var https6 = __toESM(require("https"));
15855
15990
  var import_node_child_process16 = require("child_process");
15856
15991
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -15859,12 +15994,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
15859
15994
  var TTL_MS = 24 * 60 * 60 * 1e3;
15860
15995
  var REQUEST_TIMEOUT_MS = 1500;
15861
15996
  function cachePath() {
15862
- const dir = path39.join(os31.homedir(), ".codeam");
15863
- return path39.join(dir, "update-check.json");
15997
+ const dir = path40.join(os32.homedir(), ".codeam");
15998
+ return path40.join(dir, "update-check.json");
15864
15999
  }
15865
16000
  function readCache() {
15866
16001
  try {
15867
- const raw = fs36.readFileSync(cachePath(), "utf8");
16002
+ const raw = fs37.readFileSync(cachePath(), "utf8");
15868
16003
  const parsed = JSON.parse(raw);
15869
16004
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
15870
16005
  return parsed;
@@ -15875,10 +16010,10 @@ function readCache() {
15875
16010
  function writeCache(cache) {
15876
16011
  try {
15877
16012
  const file = cachePath();
15878
- fs36.mkdirSync(path39.dirname(file), { recursive: true });
16013
+ fs37.mkdirSync(path40.dirname(file), { recursive: true });
15879
16014
  const tmp = `${file}.${process.pid}.tmp`;
15880
- fs36.writeFileSync(tmp, JSON.stringify(cache));
15881
- fs36.renameSync(tmp, file);
16015
+ fs37.writeFileSync(tmp, JSON.stringify(cache));
16016
+ fs37.renameSync(tmp, file);
15882
16017
  } catch {
15883
16018
  }
15884
16019
  }
@@ -15952,8 +16087,8 @@ function isLinkedInstall() {
15952
16087
  timeout: 2e3
15953
16088
  }).trim();
15954
16089
  if (!root) return false;
15955
- const pkgPath = path39.join(root, PKG_NAME);
15956
- return fs36.lstatSync(pkgPath).isSymbolicLink();
16090
+ const pkgPath = path40.join(root, PKG_NAME);
16091
+ return fs37.lstatSync(pkgPath).isSymbolicLink();
15957
16092
  } catch {
15958
16093
  return false;
15959
16094
  }
@@ -15989,7 +16124,7 @@ function maybeAutoUpdate(currentVersion, latest) {
15989
16124
  return;
15990
16125
  }
15991
16126
  try {
15992
- fs36.unlinkSync(cachePath());
16127
+ fs37.unlinkSync(cachePath());
15993
16128
  } catch {
15994
16129
  }
15995
16130
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
@@ -16005,7 +16140,7 @@ async function autoUpgradeBeforeCriticalCommand() {
16005
16140
  if (process.env.NODE_ENV === "test") return;
16006
16141
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16007
16142
  if (process.env.CI) return;
16008
- const current = true ? "2.60.8" : null;
16143
+ const current = true ? "2.60.9" : null;
16009
16144
  if (!current) return;
16010
16145
  const cache = readCache();
16011
16146
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16022,7 +16157,7 @@ function checkForUpdates() {
16022
16157
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16023
16158
  if (process.env.CI) return;
16024
16159
  if (!process.stdout.isTTY) return;
16025
- const current = true ? "2.60.8" : null;
16160
+ const current = true ? "2.60.9" : null;
16026
16161
  if (!current) return;
16027
16162
  const cache = readCache();
16028
16163
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16042,7 +16177,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
16042
16177
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
16043
16178
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
16044
16179
  function currentCliVersion() {
16045
- return true ? "2.60.8" : null;
16180
+ return true ? "2.60.9" : null;
16046
16181
  }
16047
16182
  function runCmd(cmd, args2, timeoutMs) {
16048
16183
  return new Promise((resolve7) => {
@@ -16109,7 +16244,7 @@ async function runSelfUpdate() {
16109
16244
 
16110
16245
  // src/commands/host/teardown.ts
16111
16246
  var import_node_child_process18 = require("child_process");
16112
- var fs37 = __toESM(require("fs"));
16247
+ var fs38 = __toESM(require("fs"));
16113
16248
  var defaultDisableService = () => {
16114
16249
  try {
16115
16250
  (0, import_node_child_process18.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
@@ -16118,7 +16253,7 @@ var defaultDisableService = () => {
16118
16253
  };
16119
16254
  var defaultTeardownHeadroom = () => {
16120
16255
  try {
16121
- const kind = JSON.parse(fs37.readFileSync(headroomConfigPath(), "utf8")).agent;
16256
+ const kind = JSON.parse(fs38.readFileSync(headroomConfigPath(), "utf8")).agent;
16122
16257
  if (kind) {
16123
16258
  (0, import_node_child_process18.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
16124
16259
  }
@@ -16186,8 +16321,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
16186
16321
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
16187
16322
  try {
16188
16323
  const file = headroomConfigPath();
16189
- if (!fs38.existsSync(file)) return null;
16190
- const cfg = JSON.parse(fs38.readFileSync(file, "utf8"));
16324
+ if (!fs39.existsSync(file)) return null;
16325
+ const cfg = JSON.parse(fs39.readFileSync(file, "utf8"));
16191
16326
  if (!cfg?.enabled) return null;
16192
16327
  const agent = cfg.agent ?? "claude";
16193
16328
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -16592,9 +16727,9 @@ var HostAgentSupervisor = class {
16592
16727
  API_TIMEOUT_MS: "3000000",
16593
16728
  CODEAM_AUTO_TOKEN: payload.autoPairToken
16594
16729
  };
16595
- const houseConfigDir = path40.join(os32.homedir(), ".codeam", "house-claude");
16730
+ const houseConfigDir = path41.join(os33.homedir(), ".codeam", "house-claude");
16596
16731
  try {
16597
- fs38.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
16732
+ fs39.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
16598
16733
  } catch {
16599
16734
  }
16600
16735
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -16612,14 +16747,14 @@ var HostAgentSupervisor = class {
16612
16747
  report("installing", "installing agent CLI");
16613
16748
  await this.runAgentInstall(payload.agentInstallScript);
16614
16749
  }
16615
- const home = process.env.HOME || os32.homedir();
16750
+ const home = process.env.HOME || os33.homedir();
16616
16751
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
16617
16752
  if (payload.cloneToken) {
16618
16753
  try {
16619
16754
  report("preparing", "configuring git tooling");
16620
16755
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
16621
16756
  if (ghCmd) {
16622
- childEnv.PATH = `${codeamBinDir()}${path40.delimiter}${childEnv.PATH}`;
16757
+ childEnv.PATH = `${codeamBinDir()}${path41.delimiter}${childEnv.PATH}`;
16623
16758
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
16624
16759
  }
16625
16760
  } catch (e) {
@@ -16635,7 +16770,7 @@ var HostAgentSupervisor = class {
16635
16770
  }
16636
16771
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
16637
16772
  report("headroom", "setting up Headroom proxy");
16638
- const freeBytes = await this.getFreeDisk(os32.homedir());
16773
+ const freeBytes = await this.getFreeDisk(os33.homedir());
16639
16774
  const alreadyInstalled = this.isHeadroomInstalled();
16640
16775
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
16641
16776
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -16757,7 +16892,7 @@ var HostAgentSupervisor = class {
16757
16892
  */
16758
16893
  runAgentInstall(script) {
16759
16894
  return new Promise((resolve7) => {
16760
- const home = process.env.HOME || os32.homedir();
16895
+ const home = process.env.HOME || os33.homedir();
16761
16896
  const child = (0, import_node_child_process19.spawn)("sh", ["-c", script], {
16762
16897
  env: { ...process.env, HOME: home },
16763
16898
  stdio: ["ignore", "pipe", "pipe"]
@@ -16941,9 +17076,9 @@ async function configureHeadroom(action, ctx, deps) {
16941
17076
  }
16942
17077
 
16943
17078
  // src/services/headroom/budget-relaunch.ts
16944
- var fs39 = __toESM(require("fs"));
16945
- var os33 = __toESM(require("os"));
16946
- var path41 = __toESM(require("path"));
17079
+ var fs40 = __toESM(require("fs"));
17080
+ var os34 = __toESM(require("os"));
17081
+ var path42 = __toESM(require("path"));
16947
17082
  var import_child_process13 = require("child_process");
16948
17083
  function amendDeploymentManifestBudget(manifest, budget) {
16949
17084
  const rawArgs = manifest.proxy_args ?? [];
@@ -16977,7 +17112,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
16977
17112
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
16978
17113
  }
16979
17114
  function findHeadroomDeployments(homeDir2, deps) {
16980
- const deployDir = path41.join(homeDir2, ".headroom", "deploy");
17115
+ const deployDir = path42.join(homeDir2, ".headroom", "deploy");
16981
17116
  let profiles;
16982
17117
  try {
16983
17118
  profiles = deps.readDir(deployDir);
@@ -16986,7 +17121,7 @@ function findHeadroomDeployments(homeDir2, deps) {
16986
17121
  }
16987
17122
  const results = [];
16988
17123
  for (const profile of profiles) {
16989
- const manifestPath = path41.join(deployDir, profile, "manifest.json");
17124
+ const manifestPath = path42.join(deployDir, profile, "manifest.json");
16990
17125
  let raw;
16991
17126
  try {
16992
17127
  raw = deps.readJson(manifestPath);
@@ -17018,8 +17153,8 @@ async function applyBudgetToHeadroom(budget, deps) {
17018
17153
  }
17019
17154
  function writeManifestReal(manifestPath, manifest) {
17020
17155
  const tmp = manifestPath + ".codeam.tmp";
17021
- fs39.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
17022
- fs39.renameSync(tmp, manifestPath);
17156
+ fs40.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
17157
+ fs40.renameSync(tmp, manifestPath);
17023
17158
  }
17024
17159
  function restartDeploymentReal(profile) {
17025
17160
  try {
@@ -17049,11 +17184,11 @@ function spawnProxyReal2(_budget) {
17049
17184
  });
17050
17185
  }
17051
17186
  function makeRealApplyBudgetDeps() {
17052
- const homeDir2 = os33.homedir();
17187
+ const homeDir2 = os34.homedir();
17053
17188
  return {
17054
17189
  findDeployments: () => findHeadroomDeployments(homeDir2, {
17055
- readDir: (dir) => fs39.readdirSync(dir),
17056
- readJson: (filePath) => JSON.parse(fs39.readFileSync(filePath, "utf8"))
17190
+ readDir: (dir) => fs40.readdirSync(dir),
17191
+ readJson: (filePath) => JSON.parse(fs40.readFileSync(filePath, "utf8"))
17057
17192
  }),
17058
17193
  writeManifest: writeManifestReal,
17059
17194
  restartDeployment: restartDeploymentReal,
@@ -17733,8 +17868,8 @@ function activePreviewSessionIds() {
17733
17868
 
17734
17869
  // src/services/preview/start-orchestrator.ts
17735
17870
  var import_child_process17 = require("child_process");
17736
- var fs44 = __toESM(require("fs"));
17737
- var path46 = __toESM(require("path"));
17871
+ var fs45 = __toESM(require("fs"));
17872
+ var path47 = __toESM(require("path"));
17738
17873
  var import_which2 = __toESM(require("which"));
17739
17874
  var INSTALL_TIMEOUT_MS = 5 * 6e4;
17740
17875
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -17801,8 +17936,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
17801
17936
  if (args2.length === 0) return detection;
17802
17937
  const binName = args2[0];
17803
17938
  if (binName.startsWith("-")) return detection;
17804
- const binPath = path46.join(cwd, "node_modules", ".bin", binName);
17805
- if (!fs44.existsSync(binPath)) return detection;
17939
+ const binPath = path47.join(cwd, "node_modules", ".bin", binName);
17940
+ if (!fs45.existsSync(binPath)) return detection;
17806
17941
  return {
17807
17942
  ...detection,
17808
17943
  command: binPath,
@@ -18152,9 +18287,9 @@ async function establishTunnel(ctx, dev) {
18152
18287
 
18153
18288
  // src/beads/bd-adapter.ts
18154
18289
  var import_child_process18 = require("child_process");
18155
- var fs45 = __toESM(require("fs"));
18156
- var os35 = __toESM(require("os"));
18157
- var path47 = __toESM(require("path"));
18290
+ var fs46 = __toESM(require("fs"));
18291
+ var os36 = __toESM(require("os"));
18292
+ var path48 = __toESM(require("path"));
18158
18293
  var BD_PACKAGE = "@beads/bd";
18159
18294
  function resolveBundledBdBinary() {
18160
18295
  return _resolveSeam.resolveBundled();
@@ -18166,11 +18301,11 @@ function _defaultResolveBundled() {
18166
18301
  } catch {
18167
18302
  return null;
18168
18303
  }
18169
- const binDir = path47.join(path47.dirname(pkgJsonPath), "bin");
18304
+ const binDir = path48.join(path48.dirname(pkgJsonPath), "bin");
18170
18305
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
18171
- const binaryPath = path47.join(binDir, binaryName);
18306
+ const binaryPath = path48.join(binDir, binaryName);
18172
18307
  try {
18173
- fs45.accessSync(binaryPath, fs45.constants.F_OK);
18308
+ fs46.accessSync(binaryPath, fs46.constants.F_OK);
18174
18309
  return binaryPath;
18175
18310
  } catch {
18176
18311
  return null;
@@ -18180,13 +18315,13 @@ function resolveBdOnPath() {
18180
18315
  return _resolveSeam.resolveOnPath();
18181
18316
  }
18182
18317
  function _defaultResolveOnPath() {
18183
- const dirs = (process.env.PATH ?? "").split(path47.delimiter).filter(Boolean);
18318
+ const dirs = (process.env.PATH ?? "").split(path48.delimiter).filter(Boolean);
18184
18319
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
18185
18320
  for (const dir of dirs) {
18186
18321
  for (const candidate of candidates) {
18187
- const full = path47.join(dir, candidate);
18322
+ const full = path48.join(dir, candidate);
18188
18323
  try {
18189
- fs45.accessSync(full, fs45.constants.F_OK);
18324
+ fs46.accessSync(full, fs46.constants.F_OK);
18190
18325
  return full;
18191
18326
  } catch {
18192
18327
  }
@@ -18271,7 +18406,7 @@ var BdAdapter = class {
18271
18406
  const env = { ...process.env };
18272
18407
  if (!env.HOME) {
18273
18408
  try {
18274
- const home = os35.homedir();
18409
+ const home = os36.homedir();
18275
18410
  if (home) env.HOME = home;
18276
18411
  } catch {
18277
18412
  }
@@ -18363,9 +18498,9 @@ function coerceIssue(row, projectKey) {
18363
18498
 
18364
18499
  // src/beads/provisioner.ts
18365
18500
  var import_child_process22 = require("child_process");
18366
- var fs48 = __toESM(require("fs"));
18367
- var os37 = __toESM(require("os"));
18368
- var path50 = __toESM(require("path"));
18501
+ var fs49 = __toESM(require("fs"));
18502
+ var os38 = __toESM(require("os"));
18503
+ var path51 = __toESM(require("path"));
18369
18504
 
18370
18505
  // src/beads/install-bd.ts
18371
18506
  var import_child_process19 = require("child_process");
@@ -18430,9 +18565,9 @@ async function installBd(platform3 = process.platform) {
18430
18565
 
18431
18566
  // src/beads/install-dolt.ts
18432
18567
  var import_child_process20 = require("child_process");
18433
- var fs46 = __toESM(require("fs"));
18434
- var os36 = __toESM(require("os"));
18435
- var path48 = __toESM(require("path"));
18568
+ var fs47 = __toESM(require("fs"));
18569
+ var os37 = __toESM(require("os"));
18570
+ var path49 = __toESM(require("path"));
18436
18571
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
18437
18572
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
18438
18573
  function resolveDoltInstallStrategy(platform3) {
@@ -18472,11 +18607,11 @@ function resolveDoltInstallStrategy(platform3) {
18472
18607
  }
18473
18608
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
18474
18609
  function doltPlatformTuple(platform3, arch2) {
18475
- const os47 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
18610
+ const os48 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
18476
18611
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
18477
18612
  if (!a) return null;
18478
- if (os47 === "windows" && a !== "amd64") return null;
18479
- return `${os47}-${a}`;
18613
+ if (os48 === "windows" && a !== "amd64") return null;
18614
+ return `${os48}-${a}`;
18480
18615
  }
18481
18616
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
18482
18617
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -18521,14 +18656,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
18521
18656
  return result;
18522
18657
  }
18523
18658
  var _doltPathSeam = {
18524
- homedir: () => os36.homedir(),
18659
+ homedir: () => os37.homedir(),
18525
18660
  getPath: () => process.env.PATH ?? "",
18526
18661
  setPath: (p2) => {
18527
18662
  process.env.PATH = p2;
18528
18663
  },
18529
18664
  exists: (p2) => {
18530
18665
  try {
18531
- fs46.accessSync(p2, fs46.constants.F_OK);
18666
+ fs47.accessSync(p2, fs47.constants.F_OK);
18532
18667
  return true;
18533
18668
  } catch {
18534
18669
  return false;
@@ -18539,7 +18674,7 @@ function doltBinaryNames(platform3) {
18539
18674
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
18540
18675
  }
18541
18676
  function knownDoltDirs(platform3) {
18542
- const P3 = platform3 === "win32" ? path48.win32 : path48.posix;
18677
+ const P3 = platform3 === "win32" ? path49.win32 : path49.posix;
18543
18678
  const home = _doltPathSeam.homedir();
18544
18679
  if (platform3 === "win32") {
18545
18680
  return [
@@ -18555,7 +18690,7 @@ function knownDoltDirs(platform3) {
18555
18690
  ].filter(Boolean);
18556
18691
  }
18557
18692
  function ensureDoltResolvable(platform3 = process.platform) {
18558
- const P3 = platform3 === "win32" ? path48.win32 : path48.posix;
18693
+ const P3 = platform3 === "win32" ? path49.win32 : path49.posix;
18559
18694
  const delim = platform3 === "win32" ? ";" : ":";
18560
18695
  const names = doltBinaryNames(platform3);
18561
18696
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -18691,8 +18826,8 @@ async function ensureSharedServer(adapter, options = {}) {
18691
18826
  // src/beads/project-key.ts
18692
18827
  var import_child_process21 = require("child_process");
18693
18828
  var crypto2 = __toESM(require("crypto"));
18694
- var fs47 = __toESM(require("fs"));
18695
- var path49 = __toESM(require("path"));
18829
+ var fs48 = __toESM(require("fs"));
18830
+ var path50 = __toESM(require("path"));
18696
18831
  function normalizeOrigin(raw) {
18697
18832
  const trimmed = raw.trim();
18698
18833
  if (!trimmed) return null;
@@ -18718,17 +18853,17 @@ function normalizeOrigin(raw) {
18718
18853
  return `${host2}/${pathPart}`;
18719
18854
  }
18720
18855
  function findRepoRoot(cwd) {
18721
- let dir = path49.resolve(cwd);
18856
+ let dir = path50.resolve(cwd);
18722
18857
  const seen = /* @__PURE__ */ new Set();
18723
18858
  for (let i = 0; i < 256; i++) {
18724
18859
  if (seen.has(dir)) return null;
18725
18860
  seen.add(dir);
18726
18861
  try {
18727
- const stat3 = fs47.statSync(path49.join(dir, ".git"), { throwIfNoEntry: false });
18862
+ const stat3 = fs48.statSync(path50.join(dir, ".git"), { throwIfNoEntry: false });
18728
18863
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
18729
18864
  } catch {
18730
18865
  }
18731
- const parent = path49.dirname(dir);
18866
+ const parent = path50.dirname(dir);
18732
18867
  if (parent === dir) return null;
18733
18868
  dir = parent;
18734
18869
  }
@@ -18739,7 +18874,7 @@ var _execSeam2 = {
18739
18874
  const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
18740
18875
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
18741
18876
  },
18742
- realpath: (p2) => fs47.realpathSync(p2)
18877
+ realpath: (p2) => fs48.realpathSync(p2)
18743
18878
  };
18744
18879
  function readOrigin(cwd) {
18745
18880
  try {
@@ -18768,7 +18903,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
18768
18903
  } catch {
18769
18904
  }
18770
18905
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
18771
- return { projectKey: `path:${hash}`, projectLabel: path49.basename(real) || "project" };
18906
+ return { projectKey: `path:${hash}`, projectLabel: path50.basename(real) || "project" };
18772
18907
  }
18773
18908
 
18774
18909
  // src/beads/project-prefix.ts
@@ -18810,17 +18945,17 @@ var _provisionSeam = {
18810
18945
  };
18811
18946
  var _linkSeam = {
18812
18947
  platform: () => process.platform,
18813
- homedir: () => os37.homedir(),
18948
+ homedir: () => os38.homedir(),
18814
18949
  isWritableDir: (dir) => {
18815
18950
  try {
18816
- fs48.accessSync(dir, fs48.constants.W_OK);
18951
+ fs49.accessSync(dir, fs49.constants.W_OK);
18817
18952
  return true;
18818
18953
  } catch {
18819
18954
  return false;
18820
18955
  }
18821
18956
  },
18822
18957
  ensureDir: (dir) => {
18823
- fs48.mkdirSync(dir, { recursive: true });
18958
+ fs49.mkdirSync(dir, { recursive: true });
18824
18959
  },
18825
18960
  /**
18826
18961
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -18841,9 +18976,9 @@ var _linkSeam = {
18841
18976
  * which `linkBdOntoPath` creates if missing.
18842
18977
  */
18843
18978
  cliBinDir: () => {
18844
- const pathDirs = (process.env.PATH ?? "").split(path50.delimiter).filter(Boolean);
18979
+ const pathDirs = (process.env.PATH ?? "").split(path51.delimiter).filter(Boolean);
18845
18980
  const home = _linkSeam.homedir();
18846
- const localBin = home ? path50.join(home, ".local", "bin") : null;
18981
+ const localBin = home ? path51.join(home, ".local", "bin") : null;
18847
18982
  if (localBin) {
18848
18983
  try {
18849
18984
  _linkSeam.ensureDir(localBin);
@@ -18853,16 +18988,16 @@ var _linkSeam = {
18853
18988
  const candidates = [];
18854
18989
  if (localBin) candidates.push(localBin);
18855
18990
  try {
18856
- candidates.push(path50.dirname(process.execPath));
18991
+ candidates.push(path51.dirname(process.execPath));
18857
18992
  } catch {
18858
18993
  }
18859
18994
  candidates.push("/usr/local/bin");
18860
18995
  const entry = process.argv[1];
18861
18996
  if (entry) {
18862
18997
  try {
18863
- candidates.push(path50.dirname(fs48.realpathSync(entry)));
18998
+ candidates.push(path51.dirname(fs49.realpathSync(entry)));
18864
18999
  } catch {
18865
- candidates.push(path50.dirname(entry));
19000
+ candidates.push(path51.dirname(entry));
18866
19001
  }
18867
19002
  }
18868
19003
  const onPathWritable = candidates.find(
@@ -18874,20 +19009,20 @@ var _linkSeam = {
18874
19009
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
18875
19010
  readlink: (linkPath) => {
18876
19011
  try {
18877
- return fs48.readlinkSync(linkPath);
19012
+ return fs49.readlinkSync(linkPath);
18878
19013
  } catch {
18879
19014
  return null;
18880
19015
  }
18881
19016
  },
18882
- unlink: (linkPath) => fs48.unlinkSync(linkPath),
18883
- symlink: (target, linkPath) => fs48.symlinkSync(target, linkPath)
19017
+ unlink: (linkPath) => fs49.unlinkSync(linkPath),
19018
+ symlink: (target, linkPath) => fs49.symlinkSync(target, linkPath)
18884
19019
  };
18885
19020
  function linkBdOntoPath(binaryPath) {
18886
19021
  if (_linkSeam.platform() === "win32") return;
18887
19022
  const binDir = _linkSeam.cliBinDir();
18888
19023
  if (!binDir) return;
18889
19024
  _linkSeam.ensureDir(binDir);
18890
- const linkPath = path50.join(binDir, "bd");
19025
+ const linkPath = path51.join(binDir, "bd");
18891
19026
  if (linkPath === binaryPath) return;
18892
19027
  const current = _linkSeam.readlink(linkPath);
18893
19028
  if (current === binaryPath) return;
@@ -19082,7 +19217,7 @@ function dedupeRecipes(agents) {
19082
19217
 
19083
19218
  // src/beads/watcher.ts
19084
19219
  var crypto4 = __toESM(require("crypto"));
19085
- var path51 = __toESM(require("path"));
19220
+ var path52 = __toESM(require("path"));
19086
19221
  var API_BASE6 = resolveApiBaseUrl();
19087
19222
  var DEBOUNCE_MS2 = 400;
19088
19223
  var ZERO_SUMMARY = {
@@ -19106,7 +19241,7 @@ var BeadsWatcher = class {
19106
19241
  constructor(opts) {
19107
19242
  this.opts = opts;
19108
19243
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
19109
- this.feedPath = opts.feedPath ?? path51.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
19244
+ this.feedPath = opts.feedPath ?? path52.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
19110
19245
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
19111
19246
  }
19112
19247
  opts;
@@ -19523,8 +19658,8 @@ function cleanupAttachmentTempFiles() {
19523
19658
  function saveFilesTemp(files) {
19524
19659
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
19525
19660
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
19526
- const tmpPath = path53.join(os39.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
19527
- fs50.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
19661
+ const tmpPath = path54.join(os40.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
19662
+ fs51.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
19528
19663
  pendingAttachmentFiles.add(tmpPath);
19529
19664
  return tmpPath;
19530
19665
  });
@@ -19736,9 +19871,9 @@ var listFiles = async (ctx, cmd, parsed) => {
19736
19871
  await ctx.relay.sendResult(cmd.id, "completed", result);
19737
19872
  };
19738
19873
  var envReadH = async (ctx, cmd) => {
19739
- const envPath = path53.join(process.cwd(), ".env");
19874
+ const envPath = path54.join(process.cwd(), ".env");
19740
19875
  try {
19741
- const raw = await fs50.promises.readFile(envPath, "utf8");
19876
+ const raw = await fs51.promises.readFile(envPath, "utf8");
19742
19877
  await ctx.relay.sendResult(cmd.id, "completed", {
19743
19878
  exists: true,
19744
19879
  vars: parseDotenv(raw)
@@ -19769,14 +19904,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
19769
19904
  }
19770
19905
  seen.add(v.key);
19771
19906
  }
19772
- const envPath = path53.join(process.cwd(), ".env");
19773
- const tmpPath = path53.join(process.cwd(), ".env.codeam.tmp");
19907
+ const envPath = path54.join(process.cwd(), ".env");
19908
+ const tmpPath = path54.join(process.cwd(), ".env.codeam.tmp");
19774
19909
  try {
19775
- await fs50.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
19776
- await fs50.promises.rename(tmpPath, envPath);
19910
+ await fs51.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
19911
+ await fs51.promises.rename(tmpPath, envPath);
19777
19912
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
19778
19913
  } catch (err) {
19779
- await fs50.promises.rm(tmpPath, { force: true }).catch(() => void 0);
19914
+ await fs51.promises.rm(tmpPath, { force: true }).catch(() => void 0);
19780
19915
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
19781
19916
  }
19782
19917
  };
@@ -19820,7 +19955,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
19820
19955
  let configuredAgent = rawAgentId;
19821
19956
  if (!configuredAgent) {
19822
19957
  try {
19823
- const raw = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
19958
+ const raw = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19824
19959
  configuredAgent = raw.agent ?? "";
19825
19960
  } catch {
19826
19961
  }
@@ -19854,7 +19989,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
19854
19989
  persist: persistHeadroomConfig,
19855
19990
  readEnabled: () => {
19856
19991
  try {
19857
- const raw = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
19992
+ const raw = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19858
19993
  return raw.enabled === true;
19859
19994
  } catch {
19860
19995
  return false;
@@ -19943,7 +20078,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19943
20078
  }
19944
20079
  let headroomActive = false;
19945
20080
  try {
19946
- const raw = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
20081
+ const raw = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19947
20082
  headroomActive = raw.enabled === true;
19948
20083
  } catch {
19949
20084
  }
@@ -19953,7 +20088,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19953
20088
  }
19954
20089
  let existingConfig = { enabled: true };
19955
20090
  try {
19956
- existingConfig = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
20091
+ existingConfig = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19957
20092
  } catch {
19958
20093
  }
19959
20094
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -20071,13 +20206,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
20071
20206
  function buildNpmInstallInvocation(opts) {
20072
20207
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
20073
20208
  const execPath = opts?.execPath ?? process.execPath;
20074
- const exists2 = opts?.existsSync ?? fs50.existsSync;
20075
- const normalized = entryScript.split(path53.sep).join("/");
20209
+ const exists2 = opts?.existsSync ?? fs51.existsSync;
20210
+ const normalized = entryScript.split(path54.sep).join("/");
20076
20211
  const marker = "/lib/node_modules/codeam-cli/";
20077
20212
  const markerIdx = normalized.indexOf(marker);
20078
20213
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
20079
- const siblingNpm = path53.join(
20080
- path53.dirname(execPath),
20214
+ const siblingNpm = path54.join(
20215
+ path54.dirname(execPath),
20081
20216
  process.platform === "win32" ? "npm.cmd" : "npm"
20082
20217
  );
20083
20218
  const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
@@ -20919,11 +21054,11 @@ function readTokenFromArgs(args2) {
20919
21054
  }
20920
21055
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
20921
21056
  if (fileFlag) {
20922
- const path68 = fileFlag.slice("--token-file=".length);
21057
+ const path69 = fileFlag.slice("--token-file=".length);
20923
21058
  try {
20924
- const content = fs51.readFileSync(path68, "utf8").trim();
20925
- if (content.length === 0) fail(`--token-file ${path68} is empty`);
20926
- rmIfExistsQuiet(path68);
21059
+ const content = fs52.readFileSync(path69, "utf8").trim();
21060
+ if (content.length === 0) fail(`--token-file ${path69} is empty`);
21061
+ rmIfExistsQuiet(path69);
20927
21062
  return content;
20928
21063
  } catch (err) {
20929
21064
  fail(`Could not read --token-file: ${err.message}`);
@@ -20947,7 +21082,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
20947
21082
  pluginId,
20948
21083
  ideName: "codeam-cli (codespace)",
20949
21084
  ideVersion: process.env.npm_package_version ?? "unknown",
20950
- hostname: os40.hostname(),
21085
+ hostname: os41.hostname(),
20951
21086
  codespaceName: process.env.CODESPACE_NAME ?? "",
20952
21087
  // Current git branch of the codespace's working directory, so the
20953
21088
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -21008,7 +21143,7 @@ async function claim(token, pluginId, pluginSecretHash) {
21008
21143
  }
21009
21144
  }
21010
21145
  function pairAutoLockPath() {
21011
- return path54.join(os40.homedir(), ".codeam", "pair-auto.lock");
21146
+ return path55.join(os41.homedir(), ".codeam", "pair-auto.lock");
21012
21147
  }
21013
21148
  function isLivePairAuto(pid) {
21014
21149
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -21018,7 +21153,7 @@ function isLivePairAuto(pid) {
21018
21153
  if (e.code !== "EPERM") return false;
21019
21154
  }
21020
21155
  try {
21021
- return fs51.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
21156
+ return fs52.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
21022
21157
  } catch {
21023
21158
  return true;
21024
21159
  }
@@ -21028,24 +21163,24 @@ function isLiveCodeam(pid) {
21028
21163
  }
21029
21164
  function daemonLockPath(sessionId) {
21030
21165
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
21031
- return path54.join(os40.homedir(), ".codeam", `daemon-${safe}.lock`);
21166
+ return path55.join(os41.homedir(), ".codeam", `daemon-${safe}.lock`);
21032
21167
  }
21033
21168
  function acquireDaemonLock(sessionId) {
21034
21169
  const lockPath = daemonLockPath(sessionId);
21035
21170
  try {
21036
- fs51.mkdirSync(path54.dirname(lockPath), { recursive: true });
21171
+ fs52.mkdirSync(path55.dirname(lockPath), { recursive: true });
21037
21172
  try {
21038
- fs51.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21173
+ fs52.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21039
21174
  } catch (e) {
21040
21175
  if (e.code !== "EEXIST") throw e;
21041
- const holder = Number(fs51.readFileSync(lockPath, "utf8").trim());
21176
+ const holder = Number(fs52.readFileSync(lockPath, "utf8").trim());
21042
21177
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
21043
- fs51.writeFileSync(lockPath, String(process.pid));
21178
+ fs52.writeFileSync(lockPath, String(process.pid));
21044
21179
  }
21045
21180
  const release3 = () => {
21046
21181
  try {
21047
- if (fs51.existsSync(lockPath) && Number(fs51.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21048
- fs51.unlinkSync(lockPath);
21182
+ if (fs52.existsSync(lockPath) && Number(fs52.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21183
+ fs52.unlinkSync(lockPath);
21049
21184
  }
21050
21185
  } catch {
21051
21186
  }
@@ -21067,19 +21202,19 @@ function acquireDaemonLock(sessionId) {
21067
21202
  function acquireSingletonLock() {
21068
21203
  const lockPath = pairAutoLockPath();
21069
21204
  try {
21070
- fs51.mkdirSync(path54.dirname(lockPath), { recursive: true });
21205
+ fs52.mkdirSync(path55.dirname(lockPath), { recursive: true });
21071
21206
  try {
21072
- fs51.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21207
+ fs52.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21073
21208
  } catch (e) {
21074
21209
  if (e.code !== "EEXIST") throw e;
21075
- const holder = Number(fs51.readFileSync(lockPath, "utf8").trim());
21210
+ const holder = Number(fs52.readFileSync(lockPath, "utf8").trim());
21076
21211
  if (isLivePairAuto(holder)) return false;
21077
- fs51.writeFileSync(lockPath, String(process.pid));
21212
+ fs52.writeFileSync(lockPath, String(process.pid));
21078
21213
  }
21079
21214
  process.once("exit", () => {
21080
21215
  try {
21081
- if (fs51.existsSync(lockPath) && Number(fs51.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21082
- fs51.unlinkSync(lockPath);
21216
+ if (fs52.existsSync(lockPath) && Number(fs52.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21217
+ fs52.unlinkSync(lockPath);
21083
21218
  }
21084
21219
  } catch {
21085
21220
  }
@@ -21524,7 +21659,7 @@ var AgentService = class _AgentService {
21524
21659
  };
21525
21660
 
21526
21661
  // src/agents/acp/adapters.ts
21527
- var path56 = __toESM(require("path"));
21662
+ var path57 = __toESM(require("path"));
21528
21663
 
21529
21664
  // src/agents/acp/agent-binary.ts
21530
21665
  var import_fs4 = __toESM(require("fs"));
@@ -21557,14 +21692,14 @@ function defaultSdkDir() {
21557
21692
  return resolveSdkDirViaRequire();
21558
21693
  }
21559
21694
  function resolveClaudeNativeBinary(deps = {}) {
21560
- const existsSync24 = deps.existsSync ?? import_fs4.default.existsSync;
21695
+ const existsSync25 = deps.existsSync ?? import_fs4.default.existsSync;
21561
21696
  const platformKey = deps.platformKey ?? currentPlatformKey();
21562
21697
  const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
21563
21698
  if (!sdkDir) return null;
21564
21699
  const scopeDir = import_path8.default.dirname(sdkDir);
21565
21700
  const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
21566
21701
  const candidate = import_path8.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
21567
- return existsSync24(candidate) ? candidate : null;
21702
+ return existsSync25(candidate) ? candidate : null;
21568
21703
  }
21569
21704
  var realSleep = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
21570
21705
  async function waitForClaudeNativeBinary(opts = {}) {
@@ -21615,18 +21750,18 @@ async function waitForCommandOnPath(cmd, opts = {}) {
21615
21750
  return check();
21616
21751
  }
21617
21752
  function resolveCursorAgentBinary(deps = {}) {
21618
- const existsSync24 = deps.existsSync ?? import_fs4.default.existsSync;
21753
+ const existsSync25 = deps.existsSync ?? import_fs4.default.existsSync;
21619
21754
  const platform3 = deps.platform ?? process.platform;
21620
21755
  const env = deps.env ?? process.env;
21621
21756
  if (platform3 === "win32") {
21622
21757
  const localAppData = env.LOCALAPPDATA;
21623
21758
  if (!localAppData) return null;
21624
21759
  const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
21625
- return existsSync24(exe) ? exe : null;
21760
+ return existsSync25(exe) ? exe : null;
21626
21761
  }
21627
21762
  const home = deps.homedir ?? import_os7.default.homedir();
21628
21763
  const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
21629
- return existsSync24(unix) ? unix : null;
21764
+ return existsSync25(unix) ? unix : null;
21630
21765
  }
21631
21766
  async function waitForCursorAgent(opts = {}) {
21632
21767
  const timeoutMs = opts.timeoutMs ?? 18e4;
@@ -21706,13 +21841,13 @@ function resolveBin(pkgName, binName) {
21706
21841
  try {
21707
21842
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
21708
21843
  const manifest = require_(`${pkgName}/package.json`);
21709
- const pkgDir = path56.dirname(manifestPath);
21844
+ const pkgDir = path57.dirname(manifestPath);
21710
21845
  const bin = manifest.bin;
21711
21846
  if (!bin) return null;
21712
- if (typeof bin === "string") return path56.resolve(pkgDir, bin);
21847
+ if (typeof bin === "string") return path57.resolve(pkgDir, bin);
21713
21848
  const target = binName ?? Object.keys(bin)[0];
21714
21849
  if (!target || !bin[target]) return null;
21715
- return path56.resolve(pkgDir, bin[target]);
21850
+ return path57.resolve(pkgDir, bin[target]);
21716
21851
  } catch {
21717
21852
  return null;
21718
21853
  }
@@ -21792,12 +21927,12 @@ function requiresAcp(agent) {
21792
21927
  }
21793
21928
 
21794
21929
  // src/agents/acp/runner.ts
21795
- var import_node_crypto7 = require("crypto");
21930
+ var import_node_crypto8 = require("crypto");
21796
21931
 
21797
21932
  // src/services/history.service.ts
21798
- var fs53 = __toESM(require("fs"));
21799
- var path57 = __toESM(require("path"));
21800
- var os42 = __toESM(require("os"));
21933
+ var fs54 = __toESM(require("fs"));
21934
+ var path58 = __toESM(require("path"));
21935
+ var os43 = __toESM(require("os"));
21801
21936
  var https7 = __toESM(require("https"));
21802
21937
  var http6 = __toESM(require("http"));
21803
21938
  var import_zod2 = require("zod");
@@ -21824,7 +21959,7 @@ function parseJsonl(filePath) {
21824
21959
  const messages = [];
21825
21960
  let raw;
21826
21961
  try {
21827
- raw = fs53.readFileSync(filePath, "utf8");
21962
+ raw = fs54.readFileSync(filePath, "utf8");
21828
21963
  } catch (err) {
21829
21964
  if (err.code !== "ENOENT") {
21830
21965
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -21965,7 +22100,7 @@ var HistoryService = class _HistoryService {
21965
22100
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
21966
22101
  }
21967
22102
  get projectDir() {
21968
- return this.runtime.resolveHistoryDir(this.cwd) ?? path57.join(os42.homedir(), ".claude", "projects", encodeCwd(this.cwd));
22103
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path58.join(os43.homedir(), ".claude", "projects", encodeCwd(this.cwd));
21969
22104
  }
21970
22105
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
21971
22106
  setCurrentConversationId(id) {
@@ -21977,7 +22112,7 @@ var HistoryService = class _HistoryService {
21977
22112
  /** Return the current message count in the active conversation. */
21978
22113
  getCurrentMessageCount() {
21979
22114
  if (!this.currentConversationId) return 0;
21980
- const filePath = path57.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22115
+ const filePath = path58.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21981
22116
  return parseJsonl(filePath).length;
21982
22117
  }
21983
22118
  /**
@@ -21988,7 +22123,7 @@ var HistoryService = class _HistoryService {
21988
22123
  const deadline = Date.now() + timeoutMs;
21989
22124
  while (Date.now() < deadline) {
21990
22125
  if (!this.currentConversationId) return null;
21991
- const filePath = path57.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22126
+ const filePath = path58.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21992
22127
  const messages = parseJsonl(filePath);
21993
22128
  if (messages.length > previousCount) {
21994
22129
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -22014,16 +22149,16 @@ var HistoryService = class _HistoryService {
22014
22149
  const dir = this.projectDir;
22015
22150
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22016
22151
  try {
22017
- const files = fs53.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22152
+ const files = fs54.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22018
22153
  try {
22019
- const stat3 = fs53.statSync(path57.join(dir, e.name));
22154
+ const stat3 = fs54.statSync(path58.join(dir, e.name));
22020
22155
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22021
22156
  } catch {
22022
22157
  return { name: e.name, mtime: 0, birthtime: 0 };
22023
22158
  }
22024
22159
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
22025
22160
  if (files.length > 0) {
22026
- this.currentConversationId = path57.basename(files[0].name, ".jsonl");
22161
+ this.currentConversationId = path58.basename(files[0].name, ".jsonl");
22027
22162
  }
22028
22163
  } catch {
22029
22164
  }
@@ -22057,13 +22192,13 @@ var HistoryService = class _HistoryService {
22057
22192
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22058
22193
  let entries;
22059
22194
  try {
22060
- entries = fs53.readdirSync(dir, { withFileTypes: true });
22195
+ entries = fs54.readdirSync(dir, { withFileTypes: true });
22061
22196
  } catch {
22062
22197
  return null;
22063
22198
  }
22064
22199
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22065
22200
  try {
22066
- const stat3 = fs53.statSync(path57.join(dir, e.name));
22201
+ const stat3 = fs54.statSync(path58.join(dir, e.name));
22067
22202
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22068
22203
  } catch {
22069
22204
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -22072,12 +22207,12 @@ var HistoryService = class _HistoryService {
22072
22207
  if (files.length === 0) return null;
22073
22208
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
22074
22209
  if (!files.some((f) => f.name === targetFile)) return null;
22075
- return this.extractUsageFromFile(path57.join(dir, targetFile));
22210
+ return this.extractUsageFromFile(path58.join(dir, targetFile));
22076
22211
  }
22077
22212
  extractUsageFromFile(filePath) {
22078
22213
  let raw;
22079
22214
  try {
22080
- raw = fs53.readFileSync(filePath, "utf8");
22215
+ raw = fs54.readFileSync(filePath, "utf8");
22081
22216
  } catch {
22082
22217
  return null;
22083
22218
  }
@@ -22122,9 +22257,9 @@ var HistoryService = class _HistoryService {
22122
22257
  let totalCost = 0;
22123
22258
  let files;
22124
22259
  try {
22125
- files = fs53.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22260
+ files = fs54.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22126
22261
  try {
22127
- return fs53.statSync(path57.join(projectDir, f)).mtimeMs >= monthStartMs;
22262
+ return fs54.statSync(path58.join(projectDir, f)).mtimeMs >= monthStartMs;
22128
22263
  } catch {
22129
22264
  return false;
22130
22265
  }
@@ -22135,7 +22270,7 @@ var HistoryService = class _HistoryService {
22135
22270
  for (const file of files) {
22136
22271
  let raw;
22137
22272
  try {
22138
- raw = fs53.readFileSync(path57.join(projectDir, file), "utf8");
22273
+ raw = fs54.readFileSync(path58.join(projectDir, file), "utf8");
22139
22274
  } catch {
22140
22275
  continue;
22141
22276
  }
@@ -22214,7 +22349,7 @@ var HistoryService = class _HistoryService {
22214
22349
  if (this.runtime.resolveHistoryFile) {
22215
22350
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
22216
22351
  }
22217
- return path57.join(this.projectDir, `${sessionId}.jsonl`);
22352
+ return path58.join(this.projectDir, `${sessionId}.jsonl`);
22218
22353
  }
22219
22354
  /**
22220
22355
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -22248,7 +22383,7 @@ var HistoryService = class _HistoryService {
22248
22383
  };
22249
22384
  });
22250
22385
  }
22251
- return parseJsonl(path57.join(this.projectDir, `${sessionId}.jsonl`));
22386
+ return parseJsonl(path58.join(this.projectDir, `${sessionId}.jsonl`));
22252
22387
  }
22253
22388
  async loadConversation(sessionId) {
22254
22389
  const messages = this.readConversation(sessionId);
@@ -22304,7 +22439,7 @@ var HistoryService = class _HistoryService {
22304
22439
  if (!filePath) return false;
22305
22440
  let mtimeMs;
22306
22441
  try {
22307
- mtimeMs = fs53.statSync(filePath).mtimeMs;
22442
+ mtimeMs = fs54.statSync(filePath).mtimeMs;
22308
22443
  } catch {
22309
22444
  return false;
22310
22445
  }
@@ -22373,10 +22508,10 @@ var HistoryService = class _HistoryService {
22373
22508
 
22374
22509
  // src/agents/acp/client.ts
22375
22510
  var import_node_child_process21 = require("child_process");
22376
- var fs54 = __toESM(require("fs/promises"));
22511
+ var fs55 = __toESM(require("fs/promises"));
22377
22512
  var fsSync = __toESM(require("fs"));
22378
- var os43 = __toESM(require("os"));
22379
- var path58 = __toESM(require("path"));
22513
+ var os44 = __toESM(require("os"));
22514
+ var path59 = __toESM(require("path"));
22380
22515
  var import_node_stream = require("stream");
22381
22516
 
22382
22517
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -25290,7 +25425,7 @@ var AcpClient = class {
25290
25425
  },
25291
25426
  readTextFile: async (params) => {
25292
25427
  try {
25293
- const content = await fs54.readFile(params.path, "utf8");
25428
+ const content = await fs55.readFile(params.path, "utf8");
25294
25429
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
25295
25430
  } catch (err) {
25296
25431
  const code = err.code;
@@ -25310,7 +25445,7 @@ var AcpClient = class {
25310
25445
  },
25311
25446
  writeTextFile: async (params) => {
25312
25447
  try {
25313
- await fs54.writeFile(params.path, params.content, "utf8");
25448
+ await fs55.writeFile(params.path, params.content, "utf8");
25314
25449
  return {};
25315
25450
  } catch (err) {
25316
25451
  const code = err.code;
@@ -25359,29 +25494,29 @@ function applyLineRange(content, line, limit) {
25359
25494
  return { content: lines.slice(start2, end).join("\n") };
25360
25495
  }
25361
25496
  function knownAgentBinaryDirs() {
25362
- const home = os43.homedir();
25497
+ const home = os44.homedir();
25363
25498
  const out2 = [];
25364
25499
  out2.push("/tmp/codeam-node20/bin");
25365
25500
  for (const root of [
25366
25501
  "/usr/local/share/nvm/versions/node",
25367
- path58.join(home, ".nvm/versions/node")
25502
+ path59.join(home, ".nvm/versions/node")
25368
25503
  ]) {
25369
25504
  try {
25370
25505
  for (const child of fsSync.readdirSync(root)) {
25371
- out2.push(path58.join(root, child, "bin"));
25506
+ out2.push(path59.join(root, child, "bin"));
25372
25507
  }
25373
25508
  } catch {
25374
25509
  }
25375
25510
  }
25376
- out2.push(path58.join(home, ".volta/bin"));
25511
+ out2.push(path59.join(home, ".volta/bin"));
25377
25512
  out2.push("/usr/local/bin");
25378
25513
  out2.push("/usr/bin");
25379
- out2.push(path58.join(home, ".local/bin"));
25380
- out2.push(path58.join(home, "bin"));
25514
+ out2.push(path59.join(home, ".local/bin"));
25515
+ out2.push(path59.join(home, "bin"));
25381
25516
  if (process.platform === "win32") {
25382
25517
  const { LOCALAPPDATA, APPDATA } = process.env;
25383
- if (LOCALAPPDATA) out2.push(path58.join(LOCALAPPDATA, "cursor-agent"));
25384
- if (APPDATA) out2.push(path58.join(APPDATA, "npm"));
25518
+ if (LOCALAPPDATA) out2.push(path59.join(LOCALAPPDATA, "cursor-agent"));
25519
+ if (APPDATA) out2.push(path59.join(APPDATA, "npm"));
25385
25520
  }
25386
25521
  return out2.filter((p2) => {
25387
25522
  try {
@@ -25393,7 +25528,7 @@ function knownAgentBinaryDirs() {
25393
25528
  }
25394
25529
  function expandPathForAgentBinaries(existingPath) {
25395
25530
  const existing = new Set(
25396
- existingPath.split(path58.delimiter).filter((p2) => p2.length > 0)
25531
+ existingPath.split(path59.delimiter).filter((p2) => p2.length > 0)
25397
25532
  );
25398
25533
  const additions = [];
25399
25534
  for (const dir of knownAgentBinaryDirs()) {
@@ -25403,7 +25538,7 @@ function expandPathForAgentBinaries(existingPath) {
25403
25538
  }
25404
25539
  }
25405
25540
  if (additions.length === 0) return existingPath;
25406
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path58.delimiter);
25541
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path59.delimiter);
25407
25542
  }
25408
25543
 
25409
25544
  // src/agents/acp/headroom-budget-proxy.ts
@@ -25885,15 +26020,15 @@ function commonPrefixLength(a, b) {
25885
26020
 
25886
26021
  // src/agents/acp/onboarding.ts
25887
26022
  var import_child_process26 = require("child_process");
25888
- var fs55 = __toESM(require("fs"));
25889
- var os44 = __toESM(require("os"));
25890
- var path59 = __toESM(require("path"));
26023
+ var fs56 = __toESM(require("fs"));
26024
+ var os45 = __toESM(require("os"));
26025
+ var path60 = __toESM(require("path"));
25891
26026
  var _onboardingSeam = {
25892
- markerPath: (sessionId) => path59.join(os44.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25893
- exists: (p2) => fs55.existsSync(p2),
26027
+ markerPath: (sessionId) => path60.join(os45.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
26028
+ exists: (p2) => fs56.existsSync(p2),
25894
26029
  write: (p2) => {
25895
- fs55.mkdirSync(path59.dirname(p2), { recursive: true });
25896
- fs55.writeFileSync(p2, "");
26030
+ fs56.mkdirSync(path60.dirname(p2), { recursive: true });
26031
+ fs56.writeFileSync(p2, "");
25897
26032
  },
25898
26033
  disabled: () => {
25899
26034
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -25930,7 +26065,7 @@ function resolveRepoName(cwd) {
25930
26065
  if (name) return name;
25931
26066
  }
25932
26067
  }
25933
- const base = path59.basename(cwd || "");
26068
+ const base = path60.basename(cwd || "");
25934
26069
  if (base && !isUuid(base)) return base;
25935
26070
  return "this project";
25936
26071
  }
@@ -25993,7 +26128,7 @@ async function runOnboardingTurn(opts) {
25993
26128
  }
25994
26129
 
25995
26130
  // src/agents/acp/mappers.ts
25996
- var import_node_crypto6 = require("crypto");
26131
+ var import_node_crypto7 = require("crypto");
25997
26132
  function mapSessionUpdate(notification) {
25998
26133
  const update = notification.update;
25999
26134
  switch (update.sessionUpdate) {
@@ -26056,7 +26191,7 @@ function mapPermissionRequest(request) {
26056
26191
  }
26057
26192
  return {
26058
26193
  event: {
26059
- questionId: (0, import_node_crypto6.randomUUID)(),
26194
+ questionId: (0, import_node_crypto7.randomUUID)(),
26060
26195
  prompt,
26061
26196
  options: labels.length > 0 ? labels : void 0
26062
26197
  },
@@ -26066,7 +26201,7 @@ function mapPermissionRequest(request) {
26066
26201
  }
26067
26202
  function messageChunkId(messageId) {
26068
26203
  if (typeof messageId === "string" && messageId.length > 0) return messageId;
26069
- return (0, import_node_crypto6.randomUUID)();
26204
+ return (0, import_node_crypto7.randomUUID)();
26070
26205
  }
26071
26206
  function extractText4(content) {
26072
26207
  if (!content || typeof content !== "object") return null;
@@ -26182,8 +26317,8 @@ var import_crypto5 = require("crypto");
26182
26317
 
26183
26318
  // src/services/turn-files/git-changeset.ts
26184
26319
  var import_child_process27 = require("child_process");
26185
- var fs56 = __toESM(require("fs/promises"));
26186
- var path60 = __toESM(require("path"));
26320
+ var fs57 = __toESM(require("fs/promises"));
26321
+ var path61 = __toESM(require("path"));
26187
26322
  async function collectRepoChangeset(opts) {
26188
26323
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
26189
26324
  if (status2 === null) return null;
@@ -26201,7 +26336,7 @@ async function collectRepoChangeset(opts) {
26201
26336
  let stats;
26202
26337
  if (row.fileStatus === "added" && numstatEntry === void 0) {
26203
26338
  const lineCount = await readUntrackedLineCount(
26204
- path60.join(opts.repoRoot, row.filePath)
26339
+ path61.join(opts.repoRoot, row.filePath)
26205
26340
  );
26206
26341
  stats = { added: lineCount, removed: 0 };
26207
26342
  } else {
@@ -26232,7 +26367,7 @@ function readUntrackedLineCount(absPath) {
26232
26367
  }
26233
26368
  async function defaultReadUntrackedLineCount(absPath) {
26234
26369
  try {
26235
- const content = await fs56.readFile(absPath, "utf8");
26370
+ const content = await fs57.readFile(absPath, "utf8");
26236
26371
  let count = 0;
26237
26372
  let pos = -1;
26238
26373
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -26324,7 +26459,7 @@ function defaultRunGit(cwd, args2) {
26324
26459
  });
26325
26460
  }
26326
26461
  async function discoverRepos(workingDir, maxDepth = 4) {
26327
- const fs61 = await import("fs/promises");
26462
+ const fs62 = await import("fs/promises");
26328
26463
  const out2 = [];
26329
26464
  await walk(workingDir, 0);
26330
26465
  return out2;
@@ -26332,7 +26467,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
26332
26467
  if (depth > maxDepth) return;
26333
26468
  let entries = [];
26334
26469
  try {
26335
- const dirents = await fs61.readdir(dir, { withFileTypes: true });
26470
+ const dirents = await fs62.readdir(dir, { withFileTypes: true });
26336
26471
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
26337
26472
  } catch {
26338
26473
  return;
@@ -26343,8 +26478,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
26343
26478
  if (hasGit) {
26344
26479
  out2.push({
26345
26480
  repoRoot: dir,
26346
- repoPath: path60.relative(workingDir, dir),
26347
- repoName: path60.basename(dir)
26481
+ repoPath: path61.relative(workingDir, dir),
26482
+ repoName: path61.basename(dir)
26348
26483
  });
26349
26484
  return;
26350
26485
  }
@@ -26352,14 +26487,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
26352
26487
  if (!entry.isDirectory) continue;
26353
26488
  if (entry.name === "node_modules") continue;
26354
26489
  if (entry.name === "dist" || entry.name === "build") continue;
26355
- await walk(path60.join(dir, entry.name), depth + 1);
26490
+ await walk(path61.join(dir, entry.name), depth + 1);
26356
26491
  }
26357
26492
  }
26358
26493
  }
26359
26494
 
26360
26495
  // src/services/turn-files/files-outbox.ts
26361
- var fs57 = __toESM(require("fs/promises"));
26362
- var path61 = __toESM(require("path"));
26496
+ var fs58 = __toESM(require("fs/promises"));
26497
+ var path62 = __toESM(require("path"));
26363
26498
  var import_os8 = require("os");
26364
26499
  var HOME_OUTBOX_DIR = ".codeam/outbox";
26365
26500
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -26392,16 +26527,16 @@ var FilesOutbox = class {
26392
26527
  backoffIndex = 0;
26393
26528
  stopped = false;
26394
26529
  constructor(opts) {
26395
- const base = opts.baseDir ?? path61.join(homeDir(), HOME_OUTBOX_DIR);
26396
- this.filePath = path61.join(base, `${opts.sessionId}.jsonl`);
26530
+ const base = opts.baseDir ?? path62.join(homeDir(), HOME_OUTBOX_DIR);
26531
+ this.filePath = path62.join(base, `${opts.sessionId}.jsonl`);
26397
26532
  this.post = opts.post;
26398
26533
  this.autoSchedule = opts.autoSchedule !== false;
26399
26534
  }
26400
26535
  /** Persist the entry to disk and trigger a flush. Returns once the
26401
26536
  * line is durable on disk (not once the POST succeeds). */
26402
26537
  async enqueue(entry) {
26403
- await fs57.mkdir(path61.dirname(this.filePath), { recursive: true });
26404
- await fs57.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
26538
+ await fs58.mkdir(path62.dirname(this.filePath), { recursive: true });
26539
+ await fs58.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
26405
26540
  this.backoffIndex = 0;
26406
26541
  if (this.autoSchedule) this.scheduleFlush(0);
26407
26542
  }
@@ -26490,7 +26625,7 @@ var FilesOutbox = class {
26490
26625
  async readAll() {
26491
26626
  let raw = "";
26492
26627
  try {
26493
- raw = await fs57.readFile(this.filePath, "utf8");
26628
+ raw = await fs58.readFile(this.filePath, "utf8");
26494
26629
  } catch {
26495
26630
  return [];
26496
26631
  }
@@ -26514,12 +26649,12 @@ var FilesOutbox = class {
26514
26649
  async rewrite(entries) {
26515
26650
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
26516
26651
  if (entries.length === 0) {
26517
- await fs57.unlink(this.filePath).catch(() => void 0);
26652
+ await fs58.unlink(this.filePath).catch(() => void 0);
26518
26653
  return;
26519
26654
  }
26520
26655
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
26521
- await fs57.writeFile(tmpPath, payload, "utf8");
26522
- await fs57.rename(tmpPath, this.filePath);
26656
+ await fs58.writeFile(tmpPath, payload, "utf8");
26657
+ await fs58.rename(tmpPath, this.filePath);
26523
26658
  }
26524
26659
  };
26525
26660
  function applyJitter(ms) {
@@ -27879,7 +28014,7 @@ var AcpHistory = class {
27879
28014
  this.summary = trimmed.length > 120 ? trimmed.slice(0, 117) + "\u2026" : trimmed;
27880
28015
  }
27881
28016
  this.messages.push({
27882
- id: (0, import_node_crypto7.randomUUID)(),
28017
+ id: (0, import_node_crypto8.randomUUID)(),
27883
28018
  role: "user",
27884
28019
  text,
27885
28020
  timestamp: Date.now()
@@ -27888,7 +28023,7 @@ var AcpHistory = class {
27888
28023
  appendAgentReply(text) {
27889
28024
  if (text.length === 0) return;
27890
28025
  this.messages.push({
27891
- id: (0, import_node_crypto7.randomUUID)(),
28026
+ id: (0, import_node_crypto8.randomUUID)(),
27892
28027
  role: "agent",
27893
28028
  text,
27894
28029
  timestamp: Date.now()
@@ -28094,7 +28229,7 @@ async function runAcpSession(opts) {
28094
28229
  currentIndex: 0,
28095
28230
  done: true
28096
28231
  }),
28097
- publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto7.randomUUID)(), prompt, options }),
28232
+ publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto8.randomUUID)(), prompt, options }),
28098
28233
  publishRawChunk: (chunk) => publisher.publishOutput(chunk),
28099
28234
  sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
28100
28235
  appendAgentReply: (text) => history.appendAgentReply(text),
@@ -29463,7 +29598,7 @@ var NativeTuiDriver = class {
29463
29598
  };
29464
29599
 
29465
29600
  // src/baton/acp-driver.ts
29466
- var import_node_crypto8 = require("crypto");
29601
+ var import_node_crypto9 = require("crypto");
29467
29602
  var AcpDriver = class {
29468
29603
  constructor(deps) {
29469
29604
  this.deps = deps;
@@ -29556,7 +29691,7 @@ var AcpDriver = class {
29556
29691
  currentIndex: 0,
29557
29692
  done: true
29558
29693
  }),
29559
- publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto8.randomUUID)(), prompt, options }),
29694
+ publishAwaitingAnswer: (prompt, options) => publisher.publishAwaitingAnswer({ questionId: (0, import_node_crypto9.randomUUID)(), prompt, options }),
29560
29695
  publishRawChunk: (chunk) => publisher.publishOutput(chunk),
29561
29696
  sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
29562
29697
  appendAgentReply: (text) => history.appendAgentReply(text),
@@ -29599,7 +29734,7 @@ var AcpDriver = class {
29599
29734
  };
29600
29735
 
29601
29736
  // src/baton/transcript-mirror.ts
29602
- var fs58 = __toESM(require("fs"));
29737
+ var fs59 = __toESM(require("fs"));
29603
29738
  var TranscriptMirror = class {
29604
29739
  constructor(deps) {
29605
29740
  this.deps = deps;
@@ -29666,7 +29801,7 @@ var TranscriptMirror = class {
29666
29801
  }
29667
29802
  };
29668
29803
  function defaultWatch(file, onChange) {
29669
- const w3 = fs58.watch(file, { persistent: false }, () => onChange());
29804
+ const w3 = fs59.watch(file, { persistent: false }, () => onChange());
29670
29805
  return () => w3.close();
29671
29806
  }
29672
29807
 
@@ -29913,15 +30048,15 @@ function toEpochMs(ts) {
29913
30048
  }
29914
30049
 
29915
30050
  // src/agents/claude/onboarding.ts
29916
- var fs59 = __toESM(require("fs"));
29917
- var os45 = __toESM(require("os"));
29918
- var path62 = __toESM(require("path"));
30051
+ var fs60 = __toESM(require("fs"));
30052
+ var os46 = __toESM(require("os"));
30053
+ var path63 = __toESM(require("path"));
29919
30054
  function ensureClaudeOnboarded() {
29920
30055
  try {
29921
- const file = path62.join(os45.homedir(), ".claude.json");
30056
+ const file = path63.join(os46.homedir(), ".claude.json");
29922
30057
  let config = {};
29923
30058
  try {
29924
- config = JSON.parse(fs59.readFileSync(file, "utf8"));
30059
+ config = JSON.parse(fs60.readFileSync(file, "utf8"));
29925
30060
  } catch {
29926
30061
  }
29927
30062
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -29932,8 +30067,8 @@ function ensureClaudeOnboarded() {
29932
30067
  if (typeof config.lastOnboardingVersion !== "string") {
29933
30068
  config.lastOnboardingVersion = "2.1.177";
29934
30069
  }
29935
- fs59.mkdirSync(path62.dirname(file), { recursive: true });
29936
- fs59.writeFileSync(file, JSON.stringify(config, null, 2));
30070
+ fs60.mkdirSync(path63.dirname(file), { recursive: true });
30071
+ fs60.writeFileSync(file, JSON.stringify(config, null, 2));
29937
30072
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
29938
30073
  } catch (err) {
29939
30074
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -30607,7 +30742,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
30607
30742
  var import_child_process28 = require("child_process");
30608
30743
  var import_util4 = require("util");
30609
30744
  var import_picocolors9 = __toESM(require("picocolors"));
30610
- var path63 = __toESM(require("path"));
30745
+ var path64 = __toESM(require("path"));
30611
30746
  var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
30612
30747
  var MAX_BUFFER = 8 * 1024 * 1024;
30613
30748
  function resetStdinForChild() {
@@ -31096,7 +31231,7 @@ var GitHubCodespacesProvider = class {
31096
31231
  });
31097
31232
  }
31098
31233
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
31099
- const remoteDir = path63.posix.dirname(remotePath);
31234
+ const remoteDir = path64.posix.dirname(remotePath);
31100
31235
  const parts = [
31101
31236
  `mkdir -p ${shellQuote(remoteDir)}`,
31102
31237
  `cat > ${shellQuote(remotePath)}`
@@ -31166,7 +31301,7 @@ function shellQuote(s) {
31166
31301
  // src/services/providers/gitpod.ts
31167
31302
  var import_child_process29 = require("child_process");
31168
31303
  var import_util5 = require("util");
31169
- var path64 = __toESM(require("path"));
31304
+ var path65 = __toESM(require("path"));
31170
31305
  var import_picocolors10 = __toESM(require("picocolors"));
31171
31306
  var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
31172
31307
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -31406,7 +31541,7 @@ var GitpodProvider = class {
31406
31541
  });
31407
31542
  }
31408
31543
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
31409
- const remoteDir = path64.posix.dirname(remotePath);
31544
+ const remoteDir = path65.posix.dirname(remotePath);
31410
31545
  const parts = [
31411
31546
  `mkdir -p ${shellQuote2(remoteDir)}`,
31412
31547
  `cat > ${shellQuote2(remotePath)}`
@@ -31442,7 +31577,7 @@ function shellQuote2(s) {
31442
31577
  // src/services/providers/gitlab-workspaces.ts
31443
31578
  var import_child_process30 = require("child_process");
31444
31579
  var import_util6 = require("util");
31445
- var path65 = __toESM(require("path"));
31580
+ var path66 = __toESM(require("path"));
31446
31581
  var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
31447
31582
  var MAX_BUFFER3 = 8 * 1024 * 1024;
31448
31583
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -31702,7 +31837,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
31702
31837
  }
31703
31838
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
31704
31839
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
31705
- const remoteDir = path65.posix.dirname(remotePath);
31840
+ const remoteDir = path66.posix.dirname(remotePath);
31706
31841
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
31707
31842
  if (options.mode != null) {
31708
31843
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -31770,7 +31905,7 @@ function shellQuote3(s) {
31770
31905
  // src/services/providers/railway.ts
31771
31906
  var import_child_process31 = require("child_process");
31772
31907
  var import_util7 = require("util");
31773
- var path66 = __toESM(require("path"));
31908
+ var path67 = __toESM(require("path"));
31774
31909
  var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
31775
31910
  var MAX_BUFFER4 = 8 * 1024 * 1024;
31776
31911
  function resetStdinForChild4() {
@@ -32006,7 +32141,7 @@ var RailwayProvider = class {
32006
32141
  if (!projectId || !serviceId) {
32007
32142
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
32008
32143
  }
32009
- const remoteDir = path66.posix.dirname(remotePath);
32144
+ const remoteDir = path67.posix.dirname(remotePath);
32010
32145
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
32011
32146
  if (options.mode != null) {
32012
32147
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -32651,9 +32786,9 @@ async function invite() {
32651
32786
  // src/commands/doctor.ts
32652
32787
  var import_node_dns = require("dns");
32653
32788
  var import_node_util5 = require("util");
32654
- var import_node_crypto9 = require("crypto");
32655
- var fs60 = __toESM(require("fs"));
32656
- var path67 = __toESM(require("path"));
32789
+ var import_node_crypto10 = require("crypto");
32790
+ var fs61 = __toESM(require("fs"));
32791
+ var path68 = __toESM(require("path"));
32657
32792
  var import_picocolors14 = __toESM(require("picocolors"));
32658
32793
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
32659
32794
  async function checkDns(apiBase2) {
@@ -32709,13 +32844,13 @@ async function checkHealth(apiBase2) {
32709
32844
  }
32710
32845
  }
32711
32846
  function checkConfigDir() {
32712
- const dir = path67.join(require("os").homedir(), ".codeam");
32847
+ const dir = path68.join(require("os").homedir(), ".codeam");
32713
32848
  try {
32714
- fs60.mkdirSync(dir, { recursive: true, mode: 448 });
32715
- const probe = path67.join(dir, ".doctor-probe");
32716
- fs60.writeFileSync(probe, "ok", { mode: 384 });
32717
- const read2 = fs60.readFileSync(probe, "utf8");
32718
- fs60.unlinkSync(probe);
32849
+ fs61.mkdirSync(dir, { recursive: true, mode: 448 });
32850
+ const probe = path68.join(dir, ".doctor-probe");
32851
+ fs61.writeFileSync(probe, "ok", { mode: 384 });
32852
+ const read2 = fs61.readFileSync(probe, "utf8");
32853
+ fs61.unlinkSync(probe);
32719
32854
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
32720
32855
  return {
32721
32856
  id: "config-dir",
@@ -32755,9 +32890,9 @@ function checkSessions() {
32755
32890
  }
32756
32891
  }
32757
32892
  function checkAgentBinaries() {
32758
- const os47 = createOsStrategy();
32893
+ const os48 = createOsStrategy();
32759
32894
  return getEnabledAgents().map((meta) => {
32760
- const found = os47.findInPath(meta.binaryName);
32895
+ const found = os48.findInPath(meta.binaryName);
32761
32896
  return {
32762
32897
  id: `agent-${meta.id}`,
32763
32898
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -32779,7 +32914,7 @@ function checkNodePty() {
32779
32914
  detail: "not required on this platform"
32780
32915
  };
32781
32916
  }
32782
- const vendoredPath = path67.join(__dirname, "vendor", "node-pty");
32917
+ const vendoredPath = path68.join(__dirname, "vendor", "node-pty");
32783
32918
  for (const target of [vendoredPath, "node-pty"]) {
32784
32919
  try {
32785
32920
  require(target);
@@ -32821,9 +32956,9 @@ function checkChokidar() {
32821
32956
  }
32822
32957
  async function doctor(args2 = []) {
32823
32958
  const json = args2.includes("--json");
32824
- const cliVersion = true ? "2.60.8" : "0.0.0-dev";
32959
+ const cliVersion = true ? "2.60.9" : "0.0.0-dev";
32825
32960
  const apiBase2 = resolveApiBaseUrl();
32826
- const diagnosticId = (0, import_node_crypto9.randomUUID)();
32961
+ const diagnosticId = (0, import_node_crypto10.randomUUID)();
32827
32962
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
32828
32963
  const [dns, health] = await Promise.all([
32829
32964
  checkDns(apiBase2),
@@ -33020,7 +33155,7 @@ async function completion(args2) {
33020
33155
  // src/commands/version.ts
33021
33156
  var import_picocolors15 = __toESM(require("picocolors"));
33022
33157
  function version2() {
33023
- const v = true ? "2.60.8" : "unknown";
33158
+ const v = true ? "2.60.9" : "unknown";
33024
33159
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
33025
33160
  }
33026
33161
 
@@ -33169,10 +33304,10 @@ var EXIT_CODE_NAMES = {
33169
33304
  };
33170
33305
 
33171
33306
  // src/index.ts
33172
- var os46 = __toESM(require("os"));
33307
+ var os47 = __toESM(require("os"));
33173
33308
  if (!process.env.HOME) {
33174
33309
  try {
33175
- const home = os46.homedir();
33310
+ const home = os47.homedir();
33176
33311
  if (home) process.env.HOME = home;
33177
33312
  } catch {
33178
33313
  }