codeam-cli 2.60.7 → 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 +12 -0
  2. package/dist/index.js +576 -422
  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.7" : "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.7",
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.7" ? { ideVersion: "2.60.7" } : {}
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
@@ -12703,6 +12703,26 @@ function mapRole(codexRole) {
12703
12703
  if (codexRole === "assistant") return "agent";
12704
12704
  return "system";
12705
12705
  }
12706
+ function messageFromPayload(payload) {
12707
+ if (!payload || typeof payload !== "object") return null;
12708
+ const p2 = payload;
12709
+ if (p2.type === "message" && Array.isArray(p2.content)) {
12710
+ return {
12711
+ role: typeof p2.role === "string" ? p2.role : void 0,
12712
+ content: p2.content
12713
+ };
12714
+ }
12715
+ if (p2.Message && typeof p2.Message === "object") return p2.Message;
12716
+ return null;
12717
+ }
12718
+ function isSyntheticCodexTurn(role, text) {
12719
+ if (role === "developer" || role === "system") return true;
12720
+ const trimmed = text.trim();
12721
+ if (trimmed.startsWith("<environment_context>")) return true;
12722
+ if (trimmed.startsWith("<turn_aborted>")) return true;
12723
+ if (/^(<<ccr:[^>]*>>\s*)+$/.test(trimmed)) return true;
12724
+ return false;
12725
+ }
12706
12726
  function parseHistoryFile2(filePath) {
12707
12727
  const raw = import_node_fs3.default.readFileSync(filePath, "utf8");
12708
12728
  const lines = raw.split("\n").filter(Boolean);
@@ -12734,11 +12754,11 @@ function parseHistoryFile2(filePath) {
12734
12754
  const rec = parseLine(line);
12735
12755
  if (!rec) continue;
12736
12756
  if (rec.type !== "response_item") continue;
12737
- const payload = rec.payload;
12738
- const msg = payload?.Message;
12757
+ const msg = messageFromPayload(rec.payload);
12739
12758
  if (!msg) continue;
12740
12759
  const text = extractMessageText(msg.content);
12741
12760
  if (!text) continue;
12761
+ if (isSyntheticCodexTurn(msg.role, text)) continue;
12742
12762
  out2.push({
12743
12763
  id: `rollout:${idx}`,
12744
12764
  role: mapRole(msg.role),
@@ -12801,11 +12821,10 @@ function listResumableSessions2(cwd, homeOverride) {
12801
12821
  continue;
12802
12822
  }
12803
12823
  if (!summary && rec.type === "response_item") {
12804
- const payload = rec.payload;
12805
- const msg = payload?.Message;
12824
+ const msg = messageFromPayload(rec.payload);
12806
12825
  if (msg && msg.role === "user") {
12807
12826
  const text = extractMessageText(msg.content).trim();
12808
- if (text) summary = text.slice(0, 120);
12827
+ if (text && !isSyntheticCodexTurn(msg.role, text)) summary = text.slice(0, 120);
12809
12828
  }
12810
12829
  }
12811
12830
  if (metaCwd !== void 0 && summary) break;
@@ -12985,8 +13004,8 @@ function codexCredentialLocator() {
12985
13004
  function codexLoginLauncher() {
12986
13005
  return {
12987
13006
  async ensureInstalled() {
12988
- const os47 = createOsStrategy();
12989
- return os47.findInPath("codex") !== null;
13007
+ const os48 = createOsStrategy();
13008
+ return os48.findInPath("codex") !== null;
12990
13009
  },
12991
13010
  launch() {
12992
13011
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -13009,8 +13028,8 @@ var CodexRuntimeStrategy = class {
13009
13028
  meta = getAgent("codex");
13010
13029
  mode = "interactive";
13011
13030
  os;
13012
- constructor(os47) {
13013
- this.os = os47;
13031
+ constructor(os48) {
13032
+ this.os = os48;
13014
13033
  }
13015
13034
  async prepareLaunch() {
13016
13035
  let binary = this.os.findInPath("codex");
@@ -13109,12 +13128,12 @@ var CodexRuntimeStrategy = class {
13109
13128
  });
13110
13129
  }
13111
13130
  };
13112
- function resolveNpm(os47) {
13113
- return os47.id === "win32" ? "npm.cmd" : "npm";
13131
+ function resolveNpm(os48) {
13132
+ return os48.id === "win32" ? "npm.cmd" : "npm";
13114
13133
  }
13115
- async function installCodexViaNpm(os47) {
13134
+ async function installCodexViaNpm(os48) {
13116
13135
  return new Promise((resolve7, reject) => {
13117
- 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"], {
13118
13137
  stdio: "inherit"
13119
13138
  });
13120
13139
  proc.on("close", (code) => {
@@ -13131,16 +13150,16 @@ async function installCodexViaNpm(os47) {
13131
13150
  });
13132
13151
  });
13133
13152
  }
13134
- function augmentNpmGlobalBin(os47) {
13153
+ function augmentNpmGlobalBin(os48) {
13135
13154
  try {
13136
- 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"], {
13137
13156
  stdio: ["ignore", "pipe", "ignore"]
13138
13157
  });
13139
13158
  if (result.status !== 0) return;
13140
13159
  const prefix = result.stdout.toString().trim();
13141
13160
  if (!prefix) return;
13142
- const binDir = os47.id === "win32" ? prefix : path24.join(prefix, "bin");
13143
- os47.augmentPath([binDir]);
13161
+ const binDir = os48.id === "win32" ? prefix : path24.join(prefix, "bin");
13162
+ os48.augmentPath([binDir]);
13144
13163
  } catch {
13145
13164
  }
13146
13165
  }
@@ -13224,9 +13243,9 @@ var import_node_child_process8 = require("child_process");
13224
13243
  // src/agents/coderabbit/installer.ts
13225
13244
  var import_node_child_process6 = require("child_process");
13226
13245
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
13227
- async function ensureCoderabbitInstalled(os47) {
13228
- if (os47.findInPath("coderabbit")) return true;
13229
- if (os47.id === "win32") {
13246
+ async function ensureCoderabbitInstalled(os48) {
13247
+ if (os48.findInPath("coderabbit")) return true;
13248
+ if (os48.id === "win32") {
13230
13249
  console.error(
13231
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"
13232
13251
  );
@@ -13241,8 +13260,8 @@ async function ensureCoderabbitInstalled(os47) {
13241
13260
  proc.on("error", () => resolve7(false));
13242
13261
  });
13243
13262
  if (!ok) return false;
13244
- os47.augmentPath([`${os47.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13245
- return os47.findInPath("coderabbit") !== null;
13263
+ os48.augmentPath([`${os48.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
13264
+ return os48.findInPath("coderabbit") !== null;
13246
13265
  }
13247
13266
 
13248
13267
  // src/agents/coderabbit/link.ts
@@ -13277,10 +13296,10 @@ function coderabbitCredentialLocator() {
13277
13296
  validate: validateNonEmptyCredential
13278
13297
  };
13279
13298
  }
13280
- function coderabbitLoginLauncher(os47) {
13299
+ function coderabbitLoginLauncher(os48) {
13281
13300
  return {
13282
13301
  async ensureInstalled() {
13283
- return ensureCoderabbitInstalled(os47);
13302
+ return ensureCoderabbitInstalled(os48);
13284
13303
  },
13285
13304
  launch() {
13286
13305
  return (0, import_node_child_process7.spawn)("coderabbit", ["login"], { stdio: "inherit" });
@@ -13303,11 +13322,11 @@ function parseReview(stdout) {
13303
13322
  for (const line of lines) {
13304
13323
  const m = line.match(HUNK_LINE_RE);
13305
13324
  if (!m) continue;
13306
- const [, path68, lineNo, sevToken, message] = m;
13307
- if (!path68 || !lineNo || !message) continue;
13325
+ const [, path69, lineNo, sevToken, message] = m;
13326
+ if (!path69 || !lineNo || !message) continue;
13308
13327
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
13309
13328
  hunks.push({
13310
- path: path68.trim(),
13329
+ path: path69.trim(),
13311
13330
  line: Number(lineNo),
13312
13331
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
13313
13332
  message: cleanedMessage
@@ -13326,8 +13345,8 @@ var CoderabbitRuntimeStrategy = class {
13326
13345
  meta = getAgent("coderabbit");
13327
13346
  mode = "batch";
13328
13347
  os;
13329
- constructor(os47) {
13330
- this.os = os47;
13348
+ constructor(os48) {
13349
+ this.os = os48;
13331
13350
  }
13332
13351
  getDefaultArgs() {
13333
13352
  return ["review"];
@@ -13501,10 +13520,10 @@ function cursorCredentialLocator() {
13501
13520
  validate: validateNonEmptyCredential
13502
13521
  };
13503
13522
  }
13504
- function cursorLoginLauncher(os47) {
13523
+ function cursorLoginLauncher(os48) {
13505
13524
  return {
13506
13525
  async ensureInstalled() {
13507
- if (os47.findInPath("cursor-agent")) return true;
13526
+ if (os48.findInPath("cursor-agent")) return true;
13508
13527
  console.error(
13509
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"
13510
13529
  );
@@ -13566,8 +13585,8 @@ var CursorRuntimeStrategy = class {
13566
13585
  meta = getAgent("cursor");
13567
13586
  mode = "interactive";
13568
13587
  os;
13569
- constructor(os47) {
13570
- this.os = os47;
13588
+ constructor(os48) {
13589
+ this.os = os48;
13571
13590
  }
13572
13591
  async prepareLaunch() {
13573
13592
  const binary = this.os.findInPath("cursor-agent");
@@ -13713,10 +13732,10 @@ function aiderCredentialLocator() {
13713
13732
  validate: validateNonEmptyCredential
13714
13733
  };
13715
13734
  }
13716
- function aiderLoginLauncher(os47) {
13735
+ function aiderLoginLauncher(os48) {
13717
13736
  return {
13718
13737
  async ensureInstalled() {
13719
- if (os47.findInPath("aider")) return true;
13738
+ if (os48.findInPath("aider")) return true;
13720
13739
  console.error(
13721
13740
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
13722
13741
  );
@@ -13726,7 +13745,7 @@ function aiderLoginLauncher(os47) {
13726
13745
  console.error(
13727
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"
13728
13747
  );
13729
- 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"], {
13730
13749
  stdio: "ignore"
13731
13750
  });
13732
13751
  }
@@ -13798,8 +13817,8 @@ var AiderRuntimeStrategy = class {
13798
13817
  meta = getAgent("aider");
13799
13818
  mode = "interactive";
13800
13819
  os;
13801
- constructor(os47) {
13802
- this.os = os47;
13820
+ constructor(os48) {
13821
+ this.os = os48;
13803
13822
  }
13804
13823
  async prepareLaunch() {
13805
13824
  const binary = this.os.findInPath("aider");
@@ -13866,6 +13885,9 @@ var AiderRuntimeStrategy = class {
13866
13885
  }
13867
13886
  };
13868
13887
 
13888
+ // src/agents/gemini/runtime.ts
13889
+ var import_node_crypto5 = require("crypto");
13890
+
13869
13891
  // src/agents/gemini/link.ts
13870
13892
  var import_node_child_process11 = require("child_process");
13871
13893
 
@@ -13928,8 +13950,8 @@ function geminiCredentialLocator() {
13928
13950
  function geminiLoginLauncher() {
13929
13951
  return {
13930
13952
  async ensureInstalled() {
13931
- const os47 = createOsStrategy();
13932
- return os47.findInPath("gemini") !== null;
13953
+ const os48 = createOsStrategy();
13954
+ return os48.findInPath("gemini") !== null;
13933
13955
  },
13934
13956
  launch() {
13935
13957
  return (0, import_node_child_process11.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -13937,6 +13959,132 @@ function geminiLoginLauncher() {
13937
13959
  };
13938
13960
  }
13939
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
+
13940
14088
  // src/agents/gemini/runtime.ts
13941
14089
  var GEMINI_PRO_CONTEXT_WINDOW = 1e6;
13942
14090
  var GEMINI_FLASH_CONTEXT_WINDOW = 1e6;
@@ -13962,8 +14110,8 @@ var GeminiRuntimeStrategy = class {
13962
14110
  meta = getAgent("gemini");
13963
14111
  mode = "interactive";
13964
14112
  os;
13965
- constructor(os47) {
13966
- this.os = os47;
14113
+ constructor(os48) {
14114
+ this.os = os48;
13967
14115
  }
13968
14116
  async prepareLaunch() {
13969
14117
  const binary = this.os.findInPath("gemini");
@@ -13972,19 +14120,25 @@ var GeminiRuntimeStrategy = class {
13972
14120
  "Gemini CLI is not on PATH. Install it with:\n npm install -g @google/gemini-cli\n Then run `codeam pair` again."
13973
14121
  );
13974
14122
  }
13975
- 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 };
13976
14126
  }
13977
- // Gemini's REPL has no documented "resume previous session" flag,
13978
- // so a relaunch starts fresh. Returning an empty array is the
13979
- // documented "no-op resume" path (Cursor / Aider do the same).
13980
- resumeLaunchArgs(_sessionId, _opts) {
13981
- 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];
13982
14131
  }
13983
- resolveHistoryDir(_cwd) {
13984
- return null;
14132
+ resolveHistoryDir(cwd) {
14133
+ return resolveHistoryDir5(cwd);
13985
14134
  }
13986
- parseHistoryFile(_filePath) {
13987
- 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);
13988
14142
  }
13989
14143
  getCurrentUsage(_historyDir) {
13990
14144
  return null;
@@ -14062,18 +14216,18 @@ var GeminiRuntimeStrategy = class {
14062
14216
 
14063
14217
  // src/agents/registry.ts
14064
14218
  var runtimeBuilders = {
14065
- claude: (os47) => new ClaudeRuntimeStrategy(os47),
14066
- codex: (os47) => new CodexRuntimeStrategy(os47),
14067
- coderabbit: (os47) => new CoderabbitRuntimeStrategy(os47),
14068
- cursor: (os47) => new CursorRuntimeStrategy(os47),
14069
- aider: (os47) => new AiderRuntimeStrategy(os47),
14070
- 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)
14071
14225
  };
14072
14226
  var deployBuilders = {
14073
14227
  claude: () => new ClaudeDeployStrategy(),
14074
14228
  codex: () => new CodexDeployStrategy()
14075
14229
  };
14076
- function createAgentStrategy(agent, os47 = createOsStrategy()) {
14230
+ function createAgentStrategy(agent, os48 = createOsStrategy()) {
14077
14231
  if (!AGENT_REGISTRY[agent]?.enabled) {
14078
14232
  throw new Error(
14079
14233
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -14083,10 +14237,10 @@ function createAgentStrategy(agent, os47 = createOsStrategy()) {
14083
14237
  if (!build) {
14084
14238
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
14085
14239
  }
14086
- return build(os47);
14240
+ return build(os48);
14087
14241
  }
14088
- function createInteractiveAgentStrategy(agent, os47 = createOsStrategy()) {
14089
- const s = createAgentStrategy(agent, os47);
14242
+ function createInteractiveAgentStrategy(agent, os48 = createOsStrategy()) {
14243
+ const s = createAgentStrategy(agent, os48);
14090
14244
  if (s.mode !== "interactive") {
14091
14245
  throw new Error(
14092
14246
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -14142,7 +14296,7 @@ function parseLinkArgs(args2) {
14142
14296
  if (apiKeyFileArg) {
14143
14297
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
14144
14298
  try {
14145
- apiKey = fs28.readFileSync(path32.resolve(filePath), "utf8").trim();
14299
+ apiKey = fs29.readFileSync(path33.resolve(filePath), "utf8").trim();
14146
14300
  } catch (err) {
14147
14301
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
14148
14302
  }
@@ -14169,9 +14323,9 @@ async function link(args2 = []) {
14169
14323
  await linkDryRunPreflight(ctx);
14170
14324
  return;
14171
14325
  }
14172
- const pluginId = (0, import_node_crypto5.randomUUID)();
14173
- const pollSecret = (0, import_node_crypto5.randomBytes)(32).toString("base64url");
14174
- 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");
14175
14329
  const spin = dist_exports.spinner();
14176
14330
  spin.start("Requesting pairing code...");
14177
14331
  const pairing = await requestCode(pluginId, pluginSecretHash);
@@ -14269,7 +14423,7 @@ async function link(args2 = []) {
14269
14423
  return;
14270
14424
  }
14271
14425
  if (parsed.tokenFile) {
14272
- const credential = fs28.readFileSync(path32.resolve(parsed.tokenFile), "utf8").trim();
14426
+ const credential = fs29.readFileSync(path33.resolve(parsed.tokenFile), "utf8").trim();
14273
14427
  if (!credential) {
14274
14428
  showError(`--token-file ${parsed.tokenFile} is empty.`);
14275
14429
  process.exit(1);
@@ -14487,14 +14641,14 @@ async function linkDryRunPreflight(ctx) {
14487
14641
 
14488
14642
  // src/commands/host-agent.ts
14489
14643
  var import_node_child_process19 = require("child_process");
14490
- var os32 = __toESM(require("os"));
14491
- var fs38 = __toESM(require("fs"));
14492
- var path40 = __toESM(require("path"));
14644
+ var os33 = __toESM(require("os"));
14645
+ var fs39 = __toESM(require("fs"));
14646
+ var path41 = __toESM(require("path"));
14493
14647
 
14494
14648
  // src/commands/host/host-client.ts
14495
- var fs30 = __toESM(require("fs"));
14496
- var os26 = __toESM(require("os"));
14497
- var path33 = __toESM(require("path"));
14649
+ var fs31 = __toESM(require("fs"));
14650
+ var os27 = __toESM(require("os"));
14651
+ var path34 = __toESM(require("path"));
14498
14652
 
14499
14653
  // src/lib/restrict-to-owner.ts
14500
14654
  var import_node_fs5 = __toESM(require("fs"));
@@ -14533,7 +14687,7 @@ function restrictToOwner(filePath) {
14533
14687
  function sampleCpuTimes() {
14534
14688
  let idle = 0;
14535
14689
  let total = 0;
14536
- for (const cpu of os26.cpus()) {
14690
+ for (const cpu of os27.cpus()) {
14537
14691
  const t2 = cpu.times;
14538
14692
  idle += t2.idle;
14539
14693
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -14552,8 +14706,8 @@ var MetricsCollector = class {
14552
14706
  const prev = this.prevCpu;
14553
14707
  this.prevCpu = current;
14554
14708
  if (!prev) {
14555
- const cores = os26.cpus().length || 1;
14556
- const proxy = os26.loadavg()[0] / cores * 100;
14709
+ const cores = os27.cpus().length || 1;
14710
+ const proxy = os27.loadavg()[0] / cores * 100;
14557
14711
  return Math.min(100, Math.max(0, Math.round(proxy)));
14558
14712
  }
14559
14713
  const idleDelta = current.idle - prev.idle;
@@ -14566,8 +14720,8 @@ var MetricsCollector = class {
14566
14720
  collect() {
14567
14721
  return {
14568
14722
  cpuPct: this.cpuPct(),
14569
- ramUsedMb: Math.round((os26.totalmem() - os26.freemem()) / 1048576),
14570
- ramTotalMb: Math.round(os26.totalmem() / 1048576),
14723
+ ramUsedMb: Math.round((os27.totalmem() - os27.freemem()) / 1048576),
14724
+ ramTotalMb: Math.round(os27.totalmem() / 1048576),
14571
14725
  latencyMs: this.lastLatencyMs
14572
14726
  };
14573
14727
  }
@@ -14576,19 +14730,19 @@ function apiBase() {
14576
14730
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
14577
14731
  }
14578
14732
  function hostIdentityPath() {
14579
- return path33.join(os26.homedir(), ".codeam", "host-agent.json");
14733
+ return path34.join(os27.homedir(), ".codeam", "host-agent.json");
14580
14734
  }
14581
14735
  function collectOsInfo() {
14582
14736
  return {
14583
- distro: os26.platform(),
14584
- arch: os26.arch(),
14585
- kernel: os26.release(),
14737
+ distro: os27.platform(),
14738
+ arch: os27.arch(),
14739
+ kernel: os27.release(),
14586
14740
  nodeVersion: process.versions.node
14587
14741
  };
14588
14742
  }
14589
14743
  function loadHostIdentity() {
14590
14744
  try {
14591
- const raw = fs30.readFileSync(hostIdentityPath(), "utf8");
14745
+ const raw = fs31.readFileSync(hostIdentityPath(), "utf8");
14592
14746
  const parsed = JSON.parse(raw);
14593
14747
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
14594
14748
  const p2 = parsed;
@@ -14601,8 +14755,8 @@ function loadHostIdentity() {
14601
14755
  }
14602
14756
  function saveHostIdentity(identity) {
14603
14757
  const file = hostIdentityPath();
14604
- fs30.mkdirSync(path33.dirname(file), { recursive: true, mode: 448 });
14605
- 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), {
14606
14760
  encoding: "utf8",
14607
14761
  mode: 384
14608
14762
  });
@@ -14647,7 +14801,7 @@ function isTerminalEnrollError(err) {
14647
14801
  }
14648
14802
  function deleteHostIdentity() {
14649
14803
  try {
14650
- fs30.rmSync(hostIdentityPath(), { force: true });
14804
+ fs31.rmSync(hostIdentityPath(), { force: true });
14651
14805
  } catch {
14652
14806
  }
14653
14807
  }
@@ -14770,17 +14924,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
14770
14924
  }
14771
14925
 
14772
14926
  // src/commands/host/workspace.ts
14773
- var fs31 = __toESM(require("fs"));
14774
- var os27 = __toESM(require("os"));
14775
- var path34 = __toESM(require("path"));
14927
+ var fs32 = __toESM(require("fs"));
14928
+ var os28 = __toESM(require("os"));
14929
+ var path35 = __toESM(require("path"));
14776
14930
  var import_node_child_process13 = require("child_process");
14777
14931
  var import_node_util4 = require("util");
14778
14932
  var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process13.execFile);
14779
14933
  function isAbsolutePathTarget(target) {
14780
- return path34.isAbsolute(target);
14934
+ return path35.isAbsolute(target);
14781
14935
  }
14782
14936
  function selfHostedWorkspaceRoot() {
14783
- return path34.join(os27.homedir(), ".codeam", "self-hosted");
14937
+ return path35.join(os28.homedir(), ".codeam", "self-hosted");
14784
14938
  }
14785
14939
  function nonInteractiveGitEnv() {
14786
14940
  return {
@@ -14833,13 +14987,13 @@ async function fetchGithubIdentity(token) {
14833
14987
  async function configureGitCredentials(dest, repoRef, cloneToken) {
14834
14988
  const gh = githubOwnerRepo(repoRef.trim());
14835
14989
  if (!gh || !cloneToken) return;
14836
- const credFile = path34.join(dest, ".git", "codeam-credentials");
14837
- 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
14838
14992
  `, { mode: 384 });
14839
14993
  restrictToOwner(credFile);
14840
14994
  const env = nonInteractiveGitEnv();
14841
14995
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
14842
- const credFilePosix = credFile.split(path34.sep).join("/");
14996
+ const credFilePosix = credFile.split(path35.sep).join("/");
14843
14997
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
14844
14998
  });
14845
14999
  await git2([
@@ -14875,17 +15029,17 @@ function maskToken(text, cloneToken) {
14875
15029
  }
14876
15030
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14877
15031
  if (isAbsolutePathTarget(repoOrPath)) {
14878
- if (!fs31.existsSync(repoOrPath)) {
15032
+ if (!fs32.existsSync(repoOrPath)) {
14879
15033
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
14880
15034
  }
14881
15035
  return repoOrPath;
14882
15036
  }
14883
- const dest = path34.join(selfHostedWorkspaceRoot(), deployId);
14884
- if (fs31.existsSync(path34.join(dest, ".git"))) {
15037
+ const dest = path35.join(selfHostedWorkspaceRoot(), deployId);
15038
+ if (fs32.existsSync(path35.join(dest, ".git"))) {
14885
15039
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
14886
15040
  return dest;
14887
15041
  }
14888
- fs31.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
15042
+ fs32.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
14889
15043
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
14890
15044
  try {
14891
15045
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -14902,9 +15056,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14902
15056
  }
14903
15057
 
14904
15058
  // src/commands/host/agent-provisioning.ts
14905
- var fs32 = __toESM(require("fs"));
14906
- var os28 = __toESM(require("os"));
14907
- var path35 = __toESM(require("path"));
15059
+ var fs33 = __toESM(require("fs"));
15060
+ var os29 = __toESM(require("os"));
15061
+ var path36 = __toESM(require("path"));
14908
15062
  var PUBLIC_TO_INTERNAL_AGENT = {
14909
15063
  claude_code: "claude",
14910
15064
  claude: "claude",
@@ -14919,22 +15073,22 @@ function toInternalAgentId(publicAgentId) {
14919
15073
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
14920
15074
  }
14921
15075
  function ensureDir(dir) {
14922
- fs32.mkdirSync(dir, { recursive: true, mode: 448 });
15076
+ fs33.mkdirSync(dir, { recursive: true, mode: 448 });
14923
15077
  }
14924
15078
  function writeFile0600(filePath, contents) {
14925
- ensureDir(path35.dirname(filePath));
14926
- fs32.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
15079
+ ensureDir(path36.dirname(filePath));
15080
+ fs33.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
14927
15081
  restrictToOwner(filePath);
14928
15082
  }
14929
15083
  function rmIfExists(filePath) {
14930
15084
  try {
14931
- fs32.rmSync(filePath, { force: true });
15085
+ fs33.rmSync(filePath, { force: true });
14932
15086
  } catch {
14933
15087
  }
14934
15088
  }
14935
15089
  var claudeProvisioner = {
14936
15090
  write(auth, home) {
14937
- const credentialsJson = path35.join(home, ".claude", ".credentials.json");
15091
+ const credentialsJson = path36.join(home, ".claude", ".credentials.json");
14938
15092
  if (auth.kind === "api_key") {
14939
15093
  rmIfExists(credentialsJson);
14940
15094
  return { ANTHROPIC_API_KEY: auth.value };
@@ -14946,8 +15100,8 @@ var claudeProvisioner = {
14946
15100
  } else {
14947
15101
  rmIfExists(credentialsJson);
14948
15102
  }
14949
- const claudeJson = path35.join(home, ".claude.json");
14950
- if (!fs32.existsSync(claudeJson)) {
15103
+ const claudeJson = path36.join(home, ".claude.json");
15104
+ if (!fs33.existsSync(claudeJson)) {
14951
15105
  writeFile0600(
14952
15106
  claudeJson,
14953
15107
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -14958,7 +15112,7 @@ var claudeProvisioner = {
14958
15112
  };
14959
15113
  var codexProvisioner = {
14960
15114
  write(auth, home) {
14961
- const authJson = path35.join(home, ".codex", "auth.json");
15115
+ const authJson = path36.join(home, ".codex", "auth.json");
14962
15116
  if (auth.kind === "api_key") {
14963
15117
  rmIfExists(authJson);
14964
15118
  return { OPENAI_API_KEY: auth.value };
@@ -14969,8 +15123,8 @@ var codexProvisioner = {
14969
15123
  };
14970
15124
  var geminiProvisioner = {
14971
15125
  write(auth, home) {
14972
- const settingsJson = path35.join(home, ".gemini", "settings.json");
14973
- 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");
14974
15128
  if (auth.kind === "api_key") {
14975
15129
  rmIfExists(oauthCreds);
14976
15130
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -14983,7 +15137,7 @@ var geminiProvisioner = {
14983
15137
  };
14984
15138
  var cursorProvisioner = {
14985
15139
  write(auth, home) {
14986
- const authJson = path35.join(home, ".config", "cursor", "auth.json");
15140
+ const authJson = path36.join(home, ".config", "cursor", "auth.json");
14987
15141
  if (auth.kind === "api_key") {
14988
15142
  rmIfExists(authJson);
14989
15143
  return { CURSOR_API_KEY: auth.value };
@@ -15020,7 +15174,7 @@ var UnsupportedAgentError = class extends Error {
15020
15174
  this.agentId = agentId;
15021
15175
  }
15022
15176
  };
15023
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os28.homedir()) {
15177
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os29.homedir()) {
15024
15178
  const internal = toInternalAgentId(publicAgentId);
15025
15179
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
15026
15180
  const provisioner = PROVISIONERS[internal];
@@ -15030,11 +15184,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os28.homedir(
15030
15184
 
15031
15185
  // src/commands/host/git-tooling.ts
15032
15186
  var import_node_child_process14 = require("child_process");
15033
- var fs33 = __toESM(require("fs"));
15034
- var os29 = __toESM(require("os"));
15035
- var path36 = __toESM(require("path"));
15187
+ var fs34 = __toESM(require("fs"));
15188
+ var os30 = __toESM(require("os"));
15189
+ var path37 = __toESM(require("path"));
15036
15190
  function codeamBinDir() {
15037
- 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");
15038
15192
  }
15039
15193
  var FALLBACK_GH_VERSION = "2.62.0";
15040
15194
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -15066,7 +15220,7 @@ async function download(url, dest) {
15066
15220
  const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
15067
15221
  if (!res.ok || !res.body) return false;
15068
15222
  const buf = Buffer.from(await res.arrayBuffer());
15069
- fs33.writeFileSync(dest, buf);
15223
+ fs34.writeFileSync(dest, buf);
15070
15224
  return true;
15071
15225
  } catch {
15072
15226
  return false;
@@ -15089,8 +15243,8 @@ async function ensureGhCli(runner, token, deps = {}) {
15089
15243
  const version3 = await resolveVersionFn(token);
15090
15244
  const asset = `gh_${version3}_${osToken}_${arch2}`;
15091
15245
  const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
15092
- const tmpRoot = fs33.mkdtempSync(path36.join(os29.tmpdir(), "codeam-gh-"));
15093
- 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}`);
15094
15248
  if (!await downloadFn(url, archive)) {
15095
15249
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
15096
15250
  return null;
@@ -15100,16 +15254,16 @@ async function ensureGhCli(runner, token, deps = {}) {
15100
15254
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
15101
15255
  return null;
15102
15256
  }
15103
- const extractedBin = path36.join(tmpRoot, asset, "bin", binaryName);
15104
- if (!fs33.existsSync(extractedBin)) {
15257
+ const extractedBin = path37.join(tmpRoot, asset, "bin", binaryName);
15258
+ if (!fs34.existsSync(extractedBin)) {
15105
15259
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
15106
15260
  return null;
15107
15261
  }
15108
15262
  const binDir = codeamBinDir();
15109
- fs33.mkdirSync(binDir, { recursive: true });
15110
- const target = path36.join(binDir, binaryName);
15111
- fs33.copyFileSync(extractedBin, target);
15112
- 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);
15113
15267
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
15114
15268
  return target;
15115
15269
  } catch (e) {
@@ -15596,23 +15750,23 @@ async function ensureModernPython(runner) {
15596
15750
  }
15597
15751
 
15598
15752
  // src/commands/host/headroom-bootstrap.ts
15599
- var fs35 = __toESM(require("fs"));
15600
- var path38 = __toESM(require("path"));
15753
+ var fs36 = __toESM(require("fs"));
15754
+ var path39 = __toESM(require("path"));
15601
15755
 
15602
15756
  // src/commands/host/headroom-config.ts
15603
- var fs34 = __toESM(require("fs"));
15604
- var os30 = __toESM(require("os"));
15605
- var path37 = __toESM(require("path"));
15757
+ var fs35 = __toESM(require("fs"));
15758
+ var os31 = __toESM(require("os"));
15759
+ var path38 = __toESM(require("path"));
15606
15760
  function headroomConfigPath() {
15607
- return path37.join(os30.homedir(), ".codeam", "headroom-config.json");
15761
+ return path38.join(os31.homedir(), ".codeam", "headroom-config.json");
15608
15762
  }
15609
15763
  function persistHeadroomConfig(config) {
15610
15764
  try {
15611
15765
  const file = headroomConfigPath();
15612
- fs34.mkdirSync(path37.dirname(file), { recursive: true, mode: 448 });
15766
+ fs35.mkdirSync(path38.dirname(file), { recursive: true, mode: 448 });
15613
15767
  const tmp = `${file}.tmp-${process.pid}`;
15614
- fs34.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15615
- fs34.renameSync(tmp, file);
15768
+ fs35.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15769
+ fs35.renameSync(tmp, file);
15616
15770
  restrictToOwner(file);
15617
15771
  } catch (err) {
15618
15772
  log.warn(
@@ -15622,21 +15776,21 @@ function persistHeadroomConfig(config) {
15622
15776
  }
15623
15777
  }
15624
15778
  function agentSettingsPath(kind) {
15625
- const home = os30.homedir();
15626
- if (kind === "claude") return path37.join(home, ".claude", "settings.json");
15627
- if (kind === "codex") return path37.join(home, ".codex", "auth.json");
15628
- 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");
15629
15783
  return null;
15630
15784
  }
15631
15785
  function backupAgentHeadroomConfig(kind) {
15632
15786
  const src = agentSettingsPath(kind);
15633
15787
  if (!src) return;
15634
15788
  try {
15635
- if (!fs34.existsSync(src)) return;
15636
- const dest = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15637
- fs34.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
15638
- fs34.copyFileSync(src, dest);
15639
- 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);
15640
15794
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
15641
15795
  } catch (err) {
15642
15796
  log.warn(
@@ -15648,12 +15802,12 @@ function backupAgentHeadroomConfig(kind) {
15648
15802
  function restoreAgentHeadroomConfig(kind) {
15649
15803
  const dest = agentSettingsPath(kind);
15650
15804
  if (!dest) return false;
15651
- const src = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15652
- 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;
15653
15807
  try {
15654
- fs34.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
15655
- fs34.copyFileSync(src, dest);
15656
- fs34.chmodSync(dest, 384);
15808
+ fs35.mkdirSync(path38.dirname(dest), { recursive: true, mode: 448 });
15809
+ fs35.copyFileSync(src, dest);
15810
+ fs35.chmodSync(dest, 384);
15657
15811
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
15658
15812
  return true;
15659
15813
  } catch (err) {
@@ -15666,7 +15820,7 @@ function restoreAgentHeadroomConfig(kind) {
15666
15820
  }
15667
15821
  function readHeadroomChildEnv() {
15668
15822
  try {
15669
- const raw = fs34.readFileSync(headroomConfigPath(), "utf8");
15823
+ const raw = fs35.readFileSync(headroomConfigPath(), "utf8");
15670
15824
  const parsed = JSON.parse(raw);
15671
15825
  if (typeof parsed !== "object" || parsed === null) return {};
15672
15826
  const o = parsed;
@@ -15702,37 +15856,37 @@ function bundledClaudeBinDir() {
15702
15856
  const roots = /* @__PURE__ */ new Set();
15703
15857
  let dir = __dirname;
15704
15858
  for (let i = 0; i < 6; i++) {
15705
- roots.add(path38.join(dir, "node_modules"));
15706
- const parent = path38.dirname(dir);
15859
+ roots.add(path39.join(dir, "node_modules"));
15860
+ const parent = path39.dirname(dir);
15707
15861
  if (parent === dir) break;
15708
15862
  dir = parent;
15709
15863
  }
15710
15864
  try {
15711
15865
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
15712
- const marker = `${path38.sep}@anthropic-ai${path38.sep}`;
15866
+ const marker = `${path39.sep}@anthropic-ai${path39.sep}`;
15713
15867
  const idx = main2.lastIndexOf(marker);
15714
15868
  if (idx !== -1) roots.add(main2.slice(0, idx));
15715
15869
  } catch {
15716
15870
  }
15717
15871
  for (const nm of roots) {
15718
- const atAnthropic = path38.join(nm, "@anthropic-ai");
15872
+ const atAnthropic = path39.join(nm, "@anthropic-ai");
15719
15873
  let entries;
15720
15874
  try {
15721
- entries = fs35.readdirSync(atAnthropic);
15875
+ entries = fs36.readdirSync(atAnthropic);
15722
15876
  } catch {
15723
15877
  continue;
15724
15878
  }
15725
15879
  for (const entry of entries) {
15726
15880
  if (!entry.startsWith("claude-agent-sdk-")) continue;
15727
- const bin = path38.join(atAnthropic, entry, "claude");
15728
- 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);
15729
15883
  }
15730
15884
  }
15731
15885
  return null;
15732
15886
  }
15733
15887
  async function getFreeDiskBytes(dir) {
15734
15888
  try {
15735
- const s = await fs35.promises.statfs(dir);
15889
+ const s = await fs36.promises.statfs(dir);
15736
15890
  return s.bsize * s.bavail;
15737
15891
  } catch {
15738
15892
  return null;
@@ -15794,7 +15948,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15794
15948
  if (initKind === "claude") {
15795
15949
  const claudeDir = bundledClaudeBinDir();
15796
15950
  if (claudeDir) {
15797
- initEnv.PATH = `${claudeDir}${path38.delimiter}${process.env["PATH"] ?? ""}`;
15951
+ initEnv.PATH = `${claudeDir}${path39.delimiter}${process.env["PATH"] ?? ""}`;
15798
15952
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
15799
15953
  } else {
15800
15954
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -15829,9 +15983,9 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15829
15983
  var import_node_child_process17 = require("child_process");
15830
15984
 
15831
15985
  // src/lib/updateNotifier.ts
15832
- var fs36 = __toESM(require("fs"));
15833
- var os31 = __toESM(require("os"));
15834
- var path39 = __toESM(require("path"));
15986
+ var fs37 = __toESM(require("fs"));
15987
+ var os32 = __toESM(require("os"));
15988
+ var path40 = __toESM(require("path"));
15835
15989
  var https6 = __toESM(require("https"));
15836
15990
  var import_node_child_process16 = require("child_process");
15837
15991
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -15840,12 +15994,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
15840
15994
  var TTL_MS = 24 * 60 * 60 * 1e3;
15841
15995
  var REQUEST_TIMEOUT_MS = 1500;
15842
15996
  function cachePath() {
15843
- const dir = path39.join(os31.homedir(), ".codeam");
15844
- return path39.join(dir, "update-check.json");
15997
+ const dir = path40.join(os32.homedir(), ".codeam");
15998
+ return path40.join(dir, "update-check.json");
15845
15999
  }
15846
16000
  function readCache() {
15847
16001
  try {
15848
- const raw = fs36.readFileSync(cachePath(), "utf8");
16002
+ const raw = fs37.readFileSync(cachePath(), "utf8");
15849
16003
  const parsed = JSON.parse(raw);
15850
16004
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
15851
16005
  return parsed;
@@ -15856,10 +16010,10 @@ function readCache() {
15856
16010
  function writeCache(cache) {
15857
16011
  try {
15858
16012
  const file = cachePath();
15859
- fs36.mkdirSync(path39.dirname(file), { recursive: true });
16013
+ fs37.mkdirSync(path40.dirname(file), { recursive: true });
15860
16014
  const tmp = `${file}.${process.pid}.tmp`;
15861
- fs36.writeFileSync(tmp, JSON.stringify(cache));
15862
- fs36.renameSync(tmp, file);
16015
+ fs37.writeFileSync(tmp, JSON.stringify(cache));
16016
+ fs37.renameSync(tmp, file);
15863
16017
  } catch {
15864
16018
  }
15865
16019
  }
@@ -15933,8 +16087,8 @@ function isLinkedInstall() {
15933
16087
  timeout: 2e3
15934
16088
  }).trim();
15935
16089
  if (!root) return false;
15936
- const pkgPath = path39.join(root, PKG_NAME);
15937
- return fs36.lstatSync(pkgPath).isSymbolicLink();
16090
+ const pkgPath = path40.join(root, PKG_NAME);
16091
+ return fs37.lstatSync(pkgPath).isSymbolicLink();
15938
16092
  } catch {
15939
16093
  return false;
15940
16094
  }
@@ -15970,7 +16124,7 @@ function maybeAutoUpdate(currentVersion, latest) {
15970
16124
  return;
15971
16125
  }
15972
16126
  try {
15973
- fs36.unlinkSync(cachePath());
16127
+ fs37.unlinkSync(cachePath());
15974
16128
  } catch {
15975
16129
  }
15976
16130
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
@@ -15986,7 +16140,7 @@ async function autoUpgradeBeforeCriticalCommand() {
15986
16140
  if (process.env.NODE_ENV === "test") return;
15987
16141
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
15988
16142
  if (process.env.CI) return;
15989
- const current = true ? "2.60.7" : null;
16143
+ const current = true ? "2.60.9" : null;
15990
16144
  if (!current) return;
15991
16145
  const cache = readCache();
15992
16146
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16003,7 +16157,7 @@ function checkForUpdates() {
16003
16157
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
16004
16158
  if (process.env.CI) return;
16005
16159
  if (!process.stdout.isTTY) return;
16006
- const current = true ? "2.60.7" : null;
16160
+ const current = true ? "2.60.9" : null;
16007
16161
  if (!current) return;
16008
16162
  const cache = readCache();
16009
16163
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -16023,7 +16177,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
16023
16177
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
16024
16178
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
16025
16179
  function currentCliVersion() {
16026
- return true ? "2.60.7" : null;
16180
+ return true ? "2.60.9" : null;
16027
16181
  }
16028
16182
  function runCmd(cmd, args2, timeoutMs) {
16029
16183
  return new Promise((resolve7) => {
@@ -16090,7 +16244,7 @@ async function runSelfUpdate() {
16090
16244
 
16091
16245
  // src/commands/host/teardown.ts
16092
16246
  var import_node_child_process18 = require("child_process");
16093
- var fs37 = __toESM(require("fs"));
16247
+ var fs38 = __toESM(require("fs"));
16094
16248
  var defaultDisableService = () => {
16095
16249
  try {
16096
16250
  (0, import_node_child_process18.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
@@ -16099,7 +16253,7 @@ var defaultDisableService = () => {
16099
16253
  };
16100
16254
  var defaultTeardownHeadroom = () => {
16101
16255
  try {
16102
- const kind = JSON.parse(fs37.readFileSync(headroomConfigPath(), "utf8")).agent;
16256
+ const kind = JSON.parse(fs38.readFileSync(headroomConfigPath(), "utf8")).agent;
16103
16257
  if (kind) {
16104
16258
  (0, import_node_child_process18.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
16105
16259
  }
@@ -16167,8 +16321,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
16167
16321
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
16168
16322
  try {
16169
16323
  const file = headroomConfigPath();
16170
- if (!fs38.existsSync(file)) return null;
16171
- const cfg = JSON.parse(fs38.readFileSync(file, "utf8"));
16324
+ if (!fs39.existsSync(file)) return null;
16325
+ const cfg = JSON.parse(fs39.readFileSync(file, "utf8"));
16172
16326
  if (!cfg?.enabled) return null;
16173
16327
  const agent = cfg.agent ?? "claude";
16174
16328
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -16573,9 +16727,9 @@ var HostAgentSupervisor = class {
16573
16727
  API_TIMEOUT_MS: "3000000",
16574
16728
  CODEAM_AUTO_TOKEN: payload.autoPairToken
16575
16729
  };
16576
- const houseConfigDir = path40.join(os32.homedir(), ".codeam", "house-claude");
16730
+ const houseConfigDir = path41.join(os33.homedir(), ".codeam", "house-claude");
16577
16731
  try {
16578
- fs38.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
16732
+ fs39.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
16579
16733
  } catch {
16580
16734
  }
16581
16735
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -16593,14 +16747,14 @@ var HostAgentSupervisor = class {
16593
16747
  report("installing", "installing agent CLI");
16594
16748
  await this.runAgentInstall(payload.agentInstallScript);
16595
16749
  }
16596
- const home = process.env.HOME || os32.homedir();
16750
+ const home = process.env.HOME || os33.homedir();
16597
16751
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
16598
16752
  if (payload.cloneToken) {
16599
16753
  try {
16600
16754
  report("preparing", "configuring git tooling");
16601
16755
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
16602
16756
  if (ghCmd) {
16603
- childEnv.PATH = `${codeamBinDir()}${path40.delimiter}${childEnv.PATH}`;
16757
+ childEnv.PATH = `${codeamBinDir()}${path41.delimiter}${childEnv.PATH}`;
16604
16758
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
16605
16759
  }
16606
16760
  } catch (e) {
@@ -16616,7 +16770,7 @@ var HostAgentSupervisor = class {
16616
16770
  }
16617
16771
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
16618
16772
  report("headroom", "setting up Headroom proxy");
16619
- const freeBytes = await this.getFreeDisk(os32.homedir());
16773
+ const freeBytes = await this.getFreeDisk(os33.homedir());
16620
16774
  const alreadyInstalled = this.isHeadroomInstalled();
16621
16775
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
16622
16776
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -16738,7 +16892,7 @@ var HostAgentSupervisor = class {
16738
16892
  */
16739
16893
  runAgentInstall(script) {
16740
16894
  return new Promise((resolve7) => {
16741
- const home = process.env.HOME || os32.homedir();
16895
+ const home = process.env.HOME || os33.homedir();
16742
16896
  const child = (0, import_node_child_process19.spawn)("sh", ["-c", script], {
16743
16897
  env: { ...process.env, HOME: home },
16744
16898
  stdio: ["ignore", "pipe", "pipe"]
@@ -16922,9 +17076,9 @@ async function configureHeadroom(action, ctx, deps) {
16922
17076
  }
16923
17077
 
16924
17078
  // src/services/headroom/budget-relaunch.ts
16925
- var fs39 = __toESM(require("fs"));
16926
- var os33 = __toESM(require("os"));
16927
- var path41 = __toESM(require("path"));
17079
+ var fs40 = __toESM(require("fs"));
17080
+ var os34 = __toESM(require("os"));
17081
+ var path42 = __toESM(require("path"));
16928
17082
  var import_child_process13 = require("child_process");
16929
17083
  function amendDeploymentManifestBudget(manifest, budget) {
16930
17084
  const rawArgs = manifest.proxy_args ?? [];
@@ -16958,7 +17112,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
16958
17112
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
16959
17113
  }
16960
17114
  function findHeadroomDeployments(homeDir2, deps) {
16961
- const deployDir = path41.join(homeDir2, ".headroom", "deploy");
17115
+ const deployDir = path42.join(homeDir2, ".headroom", "deploy");
16962
17116
  let profiles;
16963
17117
  try {
16964
17118
  profiles = deps.readDir(deployDir);
@@ -16967,7 +17121,7 @@ function findHeadroomDeployments(homeDir2, deps) {
16967
17121
  }
16968
17122
  const results = [];
16969
17123
  for (const profile of profiles) {
16970
- const manifestPath = path41.join(deployDir, profile, "manifest.json");
17124
+ const manifestPath = path42.join(deployDir, profile, "manifest.json");
16971
17125
  let raw;
16972
17126
  try {
16973
17127
  raw = deps.readJson(manifestPath);
@@ -16999,8 +17153,8 @@ async function applyBudgetToHeadroom(budget, deps) {
16999
17153
  }
17000
17154
  function writeManifestReal(manifestPath, manifest) {
17001
17155
  const tmp = manifestPath + ".codeam.tmp";
17002
- fs39.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
17003
- fs39.renameSync(tmp, manifestPath);
17156
+ fs40.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
17157
+ fs40.renameSync(tmp, manifestPath);
17004
17158
  }
17005
17159
  function restartDeploymentReal(profile) {
17006
17160
  try {
@@ -17030,11 +17184,11 @@ function spawnProxyReal2(_budget) {
17030
17184
  });
17031
17185
  }
17032
17186
  function makeRealApplyBudgetDeps() {
17033
- const homeDir2 = os33.homedir();
17187
+ const homeDir2 = os34.homedir();
17034
17188
  return {
17035
17189
  findDeployments: () => findHeadroomDeployments(homeDir2, {
17036
- readDir: (dir) => fs39.readdirSync(dir),
17037
- readJson: (filePath) => JSON.parse(fs39.readFileSync(filePath, "utf8"))
17190
+ readDir: (dir) => fs40.readdirSync(dir),
17191
+ readJson: (filePath) => JSON.parse(fs40.readFileSync(filePath, "utf8"))
17038
17192
  }),
17039
17193
  writeManifest: writeManifestReal,
17040
17194
  restartDeployment: restartDeploymentReal,
@@ -17714,8 +17868,8 @@ function activePreviewSessionIds() {
17714
17868
 
17715
17869
  // src/services/preview/start-orchestrator.ts
17716
17870
  var import_child_process17 = require("child_process");
17717
- var fs44 = __toESM(require("fs"));
17718
- var path46 = __toESM(require("path"));
17871
+ var fs45 = __toESM(require("fs"));
17872
+ var path47 = __toESM(require("path"));
17719
17873
  var import_which2 = __toESM(require("which"));
17720
17874
  var INSTALL_TIMEOUT_MS = 5 * 6e4;
17721
17875
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -17782,8 +17936,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
17782
17936
  if (args2.length === 0) return detection;
17783
17937
  const binName = args2[0];
17784
17938
  if (binName.startsWith("-")) return detection;
17785
- const binPath = path46.join(cwd, "node_modules", ".bin", binName);
17786
- if (!fs44.existsSync(binPath)) return detection;
17939
+ const binPath = path47.join(cwd, "node_modules", ".bin", binName);
17940
+ if (!fs45.existsSync(binPath)) return detection;
17787
17941
  return {
17788
17942
  ...detection,
17789
17943
  command: binPath,
@@ -18133,9 +18287,9 @@ async function establishTunnel(ctx, dev) {
18133
18287
 
18134
18288
  // src/beads/bd-adapter.ts
18135
18289
  var import_child_process18 = require("child_process");
18136
- var fs45 = __toESM(require("fs"));
18137
- var os35 = __toESM(require("os"));
18138
- var path47 = __toESM(require("path"));
18290
+ var fs46 = __toESM(require("fs"));
18291
+ var os36 = __toESM(require("os"));
18292
+ var path48 = __toESM(require("path"));
18139
18293
  var BD_PACKAGE = "@beads/bd";
18140
18294
  function resolveBundledBdBinary() {
18141
18295
  return _resolveSeam.resolveBundled();
@@ -18147,11 +18301,11 @@ function _defaultResolveBundled() {
18147
18301
  } catch {
18148
18302
  return null;
18149
18303
  }
18150
- const binDir = path47.join(path47.dirname(pkgJsonPath), "bin");
18304
+ const binDir = path48.join(path48.dirname(pkgJsonPath), "bin");
18151
18305
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
18152
- const binaryPath = path47.join(binDir, binaryName);
18306
+ const binaryPath = path48.join(binDir, binaryName);
18153
18307
  try {
18154
- fs45.accessSync(binaryPath, fs45.constants.F_OK);
18308
+ fs46.accessSync(binaryPath, fs46.constants.F_OK);
18155
18309
  return binaryPath;
18156
18310
  } catch {
18157
18311
  return null;
@@ -18161,13 +18315,13 @@ function resolveBdOnPath() {
18161
18315
  return _resolveSeam.resolveOnPath();
18162
18316
  }
18163
18317
  function _defaultResolveOnPath() {
18164
- const dirs = (process.env.PATH ?? "").split(path47.delimiter).filter(Boolean);
18318
+ const dirs = (process.env.PATH ?? "").split(path48.delimiter).filter(Boolean);
18165
18319
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
18166
18320
  for (const dir of dirs) {
18167
18321
  for (const candidate of candidates) {
18168
- const full = path47.join(dir, candidate);
18322
+ const full = path48.join(dir, candidate);
18169
18323
  try {
18170
- fs45.accessSync(full, fs45.constants.F_OK);
18324
+ fs46.accessSync(full, fs46.constants.F_OK);
18171
18325
  return full;
18172
18326
  } catch {
18173
18327
  }
@@ -18252,7 +18406,7 @@ var BdAdapter = class {
18252
18406
  const env = { ...process.env };
18253
18407
  if (!env.HOME) {
18254
18408
  try {
18255
- const home = os35.homedir();
18409
+ const home = os36.homedir();
18256
18410
  if (home) env.HOME = home;
18257
18411
  } catch {
18258
18412
  }
@@ -18344,9 +18498,9 @@ function coerceIssue(row, projectKey) {
18344
18498
 
18345
18499
  // src/beads/provisioner.ts
18346
18500
  var import_child_process22 = require("child_process");
18347
- var fs48 = __toESM(require("fs"));
18348
- var os37 = __toESM(require("os"));
18349
- var path50 = __toESM(require("path"));
18501
+ var fs49 = __toESM(require("fs"));
18502
+ var os38 = __toESM(require("os"));
18503
+ var path51 = __toESM(require("path"));
18350
18504
 
18351
18505
  // src/beads/install-bd.ts
18352
18506
  var import_child_process19 = require("child_process");
@@ -18411,9 +18565,9 @@ async function installBd(platform3 = process.platform) {
18411
18565
 
18412
18566
  // src/beads/install-dolt.ts
18413
18567
  var import_child_process20 = require("child_process");
18414
- var fs46 = __toESM(require("fs"));
18415
- var os36 = __toESM(require("os"));
18416
- var path48 = __toESM(require("path"));
18568
+ var fs47 = __toESM(require("fs"));
18569
+ var os37 = __toESM(require("os"));
18570
+ var path49 = __toESM(require("path"));
18417
18571
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
18418
18572
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
18419
18573
  function resolveDoltInstallStrategy(platform3) {
@@ -18453,11 +18607,11 @@ function resolveDoltInstallStrategy(platform3) {
18453
18607
  }
18454
18608
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
18455
18609
  function doltPlatformTuple(platform3, arch2) {
18456
- const os47 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
18610
+ const os48 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
18457
18611
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
18458
18612
  if (!a) return null;
18459
- if (os47 === "windows" && a !== "amd64") return null;
18460
- return `${os47}-${a}`;
18613
+ if (os48 === "windows" && a !== "amd64") return null;
18614
+ return `${os48}-${a}`;
18461
18615
  }
18462
18616
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
18463
18617
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -18502,14 +18656,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
18502
18656
  return result;
18503
18657
  }
18504
18658
  var _doltPathSeam = {
18505
- homedir: () => os36.homedir(),
18659
+ homedir: () => os37.homedir(),
18506
18660
  getPath: () => process.env.PATH ?? "",
18507
18661
  setPath: (p2) => {
18508
18662
  process.env.PATH = p2;
18509
18663
  },
18510
18664
  exists: (p2) => {
18511
18665
  try {
18512
- fs46.accessSync(p2, fs46.constants.F_OK);
18666
+ fs47.accessSync(p2, fs47.constants.F_OK);
18513
18667
  return true;
18514
18668
  } catch {
18515
18669
  return false;
@@ -18520,7 +18674,7 @@ function doltBinaryNames(platform3) {
18520
18674
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
18521
18675
  }
18522
18676
  function knownDoltDirs(platform3) {
18523
- const P3 = platform3 === "win32" ? path48.win32 : path48.posix;
18677
+ const P3 = platform3 === "win32" ? path49.win32 : path49.posix;
18524
18678
  const home = _doltPathSeam.homedir();
18525
18679
  if (platform3 === "win32") {
18526
18680
  return [
@@ -18536,7 +18690,7 @@ function knownDoltDirs(platform3) {
18536
18690
  ].filter(Boolean);
18537
18691
  }
18538
18692
  function ensureDoltResolvable(platform3 = process.platform) {
18539
- const P3 = platform3 === "win32" ? path48.win32 : path48.posix;
18693
+ const P3 = platform3 === "win32" ? path49.win32 : path49.posix;
18540
18694
  const delim = platform3 === "win32" ? ";" : ":";
18541
18695
  const names = doltBinaryNames(platform3);
18542
18696
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -18672,8 +18826,8 @@ async function ensureSharedServer(adapter, options = {}) {
18672
18826
  // src/beads/project-key.ts
18673
18827
  var import_child_process21 = require("child_process");
18674
18828
  var crypto2 = __toESM(require("crypto"));
18675
- var fs47 = __toESM(require("fs"));
18676
- var path49 = __toESM(require("path"));
18829
+ var fs48 = __toESM(require("fs"));
18830
+ var path50 = __toESM(require("path"));
18677
18831
  function normalizeOrigin(raw) {
18678
18832
  const trimmed = raw.trim();
18679
18833
  if (!trimmed) return null;
@@ -18699,17 +18853,17 @@ function normalizeOrigin(raw) {
18699
18853
  return `${host2}/${pathPart}`;
18700
18854
  }
18701
18855
  function findRepoRoot(cwd) {
18702
- let dir = path49.resolve(cwd);
18856
+ let dir = path50.resolve(cwd);
18703
18857
  const seen = /* @__PURE__ */ new Set();
18704
18858
  for (let i = 0; i < 256; i++) {
18705
18859
  if (seen.has(dir)) return null;
18706
18860
  seen.add(dir);
18707
18861
  try {
18708
- const stat3 = fs47.statSync(path49.join(dir, ".git"), { throwIfNoEntry: false });
18862
+ const stat3 = fs48.statSync(path50.join(dir, ".git"), { throwIfNoEntry: false });
18709
18863
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
18710
18864
  } catch {
18711
18865
  }
18712
- const parent = path49.dirname(dir);
18866
+ const parent = path50.dirname(dir);
18713
18867
  if (parent === dir) return null;
18714
18868
  dir = parent;
18715
18869
  }
@@ -18720,7 +18874,7 @@ var _execSeam2 = {
18720
18874
  const out2 = (0, import_child_process21.execFileSync)(file, args2, opts);
18721
18875
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
18722
18876
  },
18723
- realpath: (p2) => fs47.realpathSync(p2)
18877
+ realpath: (p2) => fs48.realpathSync(p2)
18724
18878
  };
18725
18879
  function readOrigin(cwd) {
18726
18880
  try {
@@ -18749,7 +18903,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
18749
18903
  } catch {
18750
18904
  }
18751
18905
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
18752
- return { projectKey: `path:${hash}`, projectLabel: path49.basename(real) || "project" };
18906
+ return { projectKey: `path:${hash}`, projectLabel: path50.basename(real) || "project" };
18753
18907
  }
18754
18908
 
18755
18909
  // src/beads/project-prefix.ts
@@ -18791,17 +18945,17 @@ var _provisionSeam = {
18791
18945
  };
18792
18946
  var _linkSeam = {
18793
18947
  platform: () => process.platform,
18794
- homedir: () => os37.homedir(),
18948
+ homedir: () => os38.homedir(),
18795
18949
  isWritableDir: (dir) => {
18796
18950
  try {
18797
- fs48.accessSync(dir, fs48.constants.W_OK);
18951
+ fs49.accessSync(dir, fs49.constants.W_OK);
18798
18952
  return true;
18799
18953
  } catch {
18800
18954
  return false;
18801
18955
  }
18802
18956
  },
18803
18957
  ensureDir: (dir) => {
18804
- fs48.mkdirSync(dir, { recursive: true });
18958
+ fs49.mkdirSync(dir, { recursive: true });
18805
18959
  },
18806
18960
  /**
18807
18961
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -18822,9 +18976,9 @@ var _linkSeam = {
18822
18976
  * which `linkBdOntoPath` creates if missing.
18823
18977
  */
18824
18978
  cliBinDir: () => {
18825
- const pathDirs = (process.env.PATH ?? "").split(path50.delimiter).filter(Boolean);
18979
+ const pathDirs = (process.env.PATH ?? "").split(path51.delimiter).filter(Boolean);
18826
18980
  const home = _linkSeam.homedir();
18827
- const localBin = home ? path50.join(home, ".local", "bin") : null;
18981
+ const localBin = home ? path51.join(home, ".local", "bin") : null;
18828
18982
  if (localBin) {
18829
18983
  try {
18830
18984
  _linkSeam.ensureDir(localBin);
@@ -18834,16 +18988,16 @@ var _linkSeam = {
18834
18988
  const candidates = [];
18835
18989
  if (localBin) candidates.push(localBin);
18836
18990
  try {
18837
- candidates.push(path50.dirname(process.execPath));
18991
+ candidates.push(path51.dirname(process.execPath));
18838
18992
  } catch {
18839
18993
  }
18840
18994
  candidates.push("/usr/local/bin");
18841
18995
  const entry = process.argv[1];
18842
18996
  if (entry) {
18843
18997
  try {
18844
- candidates.push(path50.dirname(fs48.realpathSync(entry)));
18998
+ candidates.push(path51.dirname(fs49.realpathSync(entry)));
18845
18999
  } catch {
18846
- candidates.push(path50.dirname(entry));
19000
+ candidates.push(path51.dirname(entry));
18847
19001
  }
18848
19002
  }
18849
19003
  const onPathWritable = candidates.find(
@@ -18855,20 +19009,20 @@ var _linkSeam = {
18855
19009
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
18856
19010
  readlink: (linkPath) => {
18857
19011
  try {
18858
- return fs48.readlinkSync(linkPath);
19012
+ return fs49.readlinkSync(linkPath);
18859
19013
  } catch {
18860
19014
  return null;
18861
19015
  }
18862
19016
  },
18863
- unlink: (linkPath) => fs48.unlinkSync(linkPath),
18864
- symlink: (target, linkPath) => fs48.symlinkSync(target, linkPath)
19017
+ unlink: (linkPath) => fs49.unlinkSync(linkPath),
19018
+ symlink: (target, linkPath) => fs49.symlinkSync(target, linkPath)
18865
19019
  };
18866
19020
  function linkBdOntoPath(binaryPath) {
18867
19021
  if (_linkSeam.platform() === "win32") return;
18868
19022
  const binDir = _linkSeam.cliBinDir();
18869
19023
  if (!binDir) return;
18870
19024
  _linkSeam.ensureDir(binDir);
18871
- const linkPath = path50.join(binDir, "bd");
19025
+ const linkPath = path51.join(binDir, "bd");
18872
19026
  if (linkPath === binaryPath) return;
18873
19027
  const current = _linkSeam.readlink(linkPath);
18874
19028
  if (current === binaryPath) return;
@@ -19063,7 +19217,7 @@ function dedupeRecipes(agents) {
19063
19217
 
19064
19218
  // src/beads/watcher.ts
19065
19219
  var crypto4 = __toESM(require("crypto"));
19066
- var path51 = __toESM(require("path"));
19220
+ var path52 = __toESM(require("path"));
19067
19221
  var API_BASE6 = resolveApiBaseUrl();
19068
19222
  var DEBOUNCE_MS2 = 400;
19069
19223
  var ZERO_SUMMARY = {
@@ -19087,7 +19241,7 @@ var BeadsWatcher = class {
19087
19241
  constructor(opts) {
19088
19242
  this.opts = opts;
19089
19243
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
19090
- 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");
19091
19245
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
19092
19246
  }
19093
19247
  opts;
@@ -19504,8 +19658,8 @@ function cleanupAttachmentTempFiles() {
19504
19658
  function saveFilesTemp(files) {
19505
19659
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
19506
19660
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
19507
- const tmpPath = path53.join(os39.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
19508
- 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"));
19509
19663
  pendingAttachmentFiles.add(tmpPath);
19510
19664
  return tmpPath;
19511
19665
  });
@@ -19717,9 +19871,9 @@ var listFiles = async (ctx, cmd, parsed) => {
19717
19871
  await ctx.relay.sendResult(cmd.id, "completed", result);
19718
19872
  };
19719
19873
  var envReadH = async (ctx, cmd) => {
19720
- const envPath = path53.join(process.cwd(), ".env");
19874
+ const envPath = path54.join(process.cwd(), ".env");
19721
19875
  try {
19722
- const raw = await fs50.promises.readFile(envPath, "utf8");
19876
+ const raw = await fs51.promises.readFile(envPath, "utf8");
19723
19877
  await ctx.relay.sendResult(cmd.id, "completed", {
19724
19878
  exists: true,
19725
19879
  vars: parseDotenv(raw)
@@ -19750,14 +19904,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
19750
19904
  }
19751
19905
  seen.add(v.key);
19752
19906
  }
19753
- const envPath = path53.join(process.cwd(), ".env");
19754
- 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");
19755
19909
  try {
19756
- await fs50.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
19757
- await fs50.promises.rename(tmpPath, envPath);
19910
+ await fs51.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
19911
+ await fs51.promises.rename(tmpPath, envPath);
19758
19912
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
19759
19913
  } catch (err) {
19760
- await fs50.promises.rm(tmpPath, { force: true }).catch(() => void 0);
19914
+ await fs51.promises.rm(tmpPath, { force: true }).catch(() => void 0);
19761
19915
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
19762
19916
  }
19763
19917
  };
@@ -19801,7 +19955,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
19801
19955
  let configuredAgent = rawAgentId;
19802
19956
  if (!configuredAgent) {
19803
19957
  try {
19804
- const raw = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
19958
+ const raw = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19805
19959
  configuredAgent = raw.agent ?? "";
19806
19960
  } catch {
19807
19961
  }
@@ -19835,7 +19989,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
19835
19989
  persist: persistHeadroomConfig,
19836
19990
  readEnabled: () => {
19837
19991
  try {
19838
- const raw = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
19992
+ const raw = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19839
19993
  return raw.enabled === true;
19840
19994
  } catch {
19841
19995
  return false;
@@ -19924,7 +20078,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19924
20078
  }
19925
20079
  let headroomActive = false;
19926
20080
  try {
19927
- const raw = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
20081
+ const raw = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19928
20082
  headroomActive = raw.enabled === true;
19929
20083
  } catch {
19930
20084
  }
@@ -19934,7 +20088,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19934
20088
  }
19935
20089
  let existingConfig = { enabled: true };
19936
20090
  try {
19937
- existingConfig = JSON.parse(fs50.readFileSync(headroomConfigPath(), "utf8"));
20091
+ existingConfig = JSON.parse(fs51.readFileSync(headroomConfigPath(), "utf8"));
19938
20092
  } catch {
19939
20093
  }
19940
20094
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -20052,13 +20206,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
20052
20206
  function buildNpmInstallInvocation(opts) {
20053
20207
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
20054
20208
  const execPath = opts?.execPath ?? process.execPath;
20055
- const exists2 = opts?.existsSync ?? fs50.existsSync;
20056
- const normalized = entryScript.split(path53.sep).join("/");
20209
+ const exists2 = opts?.existsSync ?? fs51.existsSync;
20210
+ const normalized = entryScript.split(path54.sep).join("/");
20057
20211
  const marker = "/lib/node_modules/codeam-cli/";
20058
20212
  const markerIdx = normalized.indexOf(marker);
20059
20213
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
20060
- const siblingNpm = path53.join(
20061
- path53.dirname(execPath),
20214
+ const siblingNpm = path54.join(
20215
+ path54.dirname(execPath),
20062
20216
  process.platform === "win32" ? "npm.cmd" : "npm"
20063
20217
  );
20064
20218
  const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
@@ -20900,11 +21054,11 @@ function readTokenFromArgs(args2) {
20900
21054
  }
20901
21055
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
20902
21056
  if (fileFlag) {
20903
- const path68 = fileFlag.slice("--token-file=".length);
21057
+ const path69 = fileFlag.slice("--token-file=".length);
20904
21058
  try {
20905
- const content = fs51.readFileSync(path68, "utf8").trim();
20906
- if (content.length === 0) fail(`--token-file ${path68} is empty`);
20907
- rmIfExistsQuiet(path68);
21059
+ const content = fs52.readFileSync(path69, "utf8").trim();
21060
+ if (content.length === 0) fail(`--token-file ${path69} is empty`);
21061
+ rmIfExistsQuiet(path69);
20908
21062
  return content;
20909
21063
  } catch (err) {
20910
21064
  fail(`Could not read --token-file: ${err.message}`);
@@ -20928,7 +21082,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
20928
21082
  pluginId,
20929
21083
  ideName: "codeam-cli (codespace)",
20930
21084
  ideVersion: process.env.npm_package_version ?? "unknown",
20931
- hostname: os40.hostname(),
21085
+ hostname: os41.hostname(),
20932
21086
  codespaceName: process.env.CODESPACE_NAME ?? "",
20933
21087
  // Current git branch of the codespace's working directory, so the
20934
21088
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -20989,7 +21143,7 @@ async function claim(token, pluginId, pluginSecretHash) {
20989
21143
  }
20990
21144
  }
20991
21145
  function pairAutoLockPath() {
20992
- return path54.join(os40.homedir(), ".codeam", "pair-auto.lock");
21146
+ return path55.join(os41.homedir(), ".codeam", "pair-auto.lock");
20993
21147
  }
20994
21148
  function isLivePairAuto(pid) {
20995
21149
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -20999,7 +21153,7 @@ function isLivePairAuto(pid) {
20999
21153
  if (e.code !== "EPERM") return false;
21000
21154
  }
21001
21155
  try {
21002
- return fs51.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
21156
+ return fs52.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
21003
21157
  } catch {
21004
21158
  return true;
21005
21159
  }
@@ -21009,24 +21163,24 @@ function isLiveCodeam(pid) {
21009
21163
  }
21010
21164
  function daemonLockPath(sessionId) {
21011
21165
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
21012
- return path54.join(os40.homedir(), ".codeam", `daemon-${safe}.lock`);
21166
+ return path55.join(os41.homedir(), ".codeam", `daemon-${safe}.lock`);
21013
21167
  }
21014
21168
  function acquireDaemonLock(sessionId) {
21015
21169
  const lockPath = daemonLockPath(sessionId);
21016
21170
  try {
21017
- fs51.mkdirSync(path54.dirname(lockPath), { recursive: true });
21171
+ fs52.mkdirSync(path55.dirname(lockPath), { recursive: true });
21018
21172
  try {
21019
- fs51.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21173
+ fs52.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21020
21174
  } catch (e) {
21021
21175
  if (e.code !== "EEXIST") throw e;
21022
- const holder = Number(fs51.readFileSync(lockPath, "utf8").trim());
21176
+ const holder = Number(fs52.readFileSync(lockPath, "utf8").trim());
21023
21177
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
21024
- fs51.writeFileSync(lockPath, String(process.pid));
21178
+ fs52.writeFileSync(lockPath, String(process.pid));
21025
21179
  }
21026
21180
  const release3 = () => {
21027
21181
  try {
21028
- if (fs51.existsSync(lockPath) && Number(fs51.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21029
- fs51.unlinkSync(lockPath);
21182
+ if (fs52.existsSync(lockPath) && Number(fs52.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21183
+ fs52.unlinkSync(lockPath);
21030
21184
  }
21031
21185
  } catch {
21032
21186
  }
@@ -21048,19 +21202,19 @@ function acquireDaemonLock(sessionId) {
21048
21202
  function acquireSingletonLock() {
21049
21203
  const lockPath = pairAutoLockPath();
21050
21204
  try {
21051
- fs51.mkdirSync(path54.dirname(lockPath), { recursive: true });
21205
+ fs52.mkdirSync(path55.dirname(lockPath), { recursive: true });
21052
21206
  try {
21053
- fs51.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21207
+ fs52.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
21054
21208
  } catch (e) {
21055
21209
  if (e.code !== "EEXIST") throw e;
21056
- const holder = Number(fs51.readFileSync(lockPath, "utf8").trim());
21210
+ const holder = Number(fs52.readFileSync(lockPath, "utf8").trim());
21057
21211
  if (isLivePairAuto(holder)) return false;
21058
- fs51.writeFileSync(lockPath, String(process.pid));
21212
+ fs52.writeFileSync(lockPath, String(process.pid));
21059
21213
  }
21060
21214
  process.once("exit", () => {
21061
21215
  try {
21062
- if (fs51.existsSync(lockPath) && Number(fs51.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21063
- fs51.unlinkSync(lockPath);
21216
+ if (fs52.existsSync(lockPath) && Number(fs52.readFileSync(lockPath, "utf8").trim()) === process.pid) {
21217
+ fs52.unlinkSync(lockPath);
21064
21218
  }
21065
21219
  } catch {
21066
21220
  }
@@ -21505,7 +21659,7 @@ var AgentService = class _AgentService {
21505
21659
  };
21506
21660
 
21507
21661
  // src/agents/acp/adapters.ts
21508
- var path56 = __toESM(require("path"));
21662
+ var path57 = __toESM(require("path"));
21509
21663
 
21510
21664
  // src/agents/acp/agent-binary.ts
21511
21665
  var import_fs4 = __toESM(require("fs"));
@@ -21538,14 +21692,14 @@ function defaultSdkDir() {
21538
21692
  return resolveSdkDirViaRequire();
21539
21693
  }
21540
21694
  function resolveClaudeNativeBinary(deps = {}) {
21541
- const existsSync24 = deps.existsSync ?? import_fs4.default.existsSync;
21695
+ const existsSync25 = deps.existsSync ?? import_fs4.default.existsSync;
21542
21696
  const platformKey = deps.platformKey ?? currentPlatformKey();
21543
21697
  const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
21544
21698
  if (!sdkDir) return null;
21545
21699
  const scopeDir = import_path8.default.dirname(sdkDir);
21546
21700
  const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
21547
21701
  const candidate = import_path8.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
21548
- return existsSync24(candidate) ? candidate : null;
21702
+ return existsSync25(candidate) ? candidate : null;
21549
21703
  }
21550
21704
  var realSleep = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
21551
21705
  async function waitForClaudeNativeBinary(opts = {}) {
@@ -21596,18 +21750,18 @@ async function waitForCommandOnPath(cmd, opts = {}) {
21596
21750
  return check();
21597
21751
  }
21598
21752
  function resolveCursorAgentBinary(deps = {}) {
21599
- const existsSync24 = deps.existsSync ?? import_fs4.default.existsSync;
21753
+ const existsSync25 = deps.existsSync ?? import_fs4.default.existsSync;
21600
21754
  const platform3 = deps.platform ?? process.platform;
21601
21755
  const env = deps.env ?? process.env;
21602
21756
  if (platform3 === "win32") {
21603
21757
  const localAppData = env.LOCALAPPDATA;
21604
21758
  if (!localAppData) return null;
21605
21759
  const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
21606
- return existsSync24(exe) ? exe : null;
21760
+ return existsSync25(exe) ? exe : null;
21607
21761
  }
21608
21762
  const home = deps.homedir ?? import_os7.default.homedir();
21609
21763
  const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
21610
- return existsSync24(unix) ? unix : null;
21764
+ return existsSync25(unix) ? unix : null;
21611
21765
  }
21612
21766
  async function waitForCursorAgent(opts = {}) {
21613
21767
  const timeoutMs = opts.timeoutMs ?? 18e4;
@@ -21687,13 +21841,13 @@ function resolveBin(pkgName, binName) {
21687
21841
  try {
21688
21842
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
21689
21843
  const manifest = require_(`${pkgName}/package.json`);
21690
- const pkgDir = path56.dirname(manifestPath);
21844
+ const pkgDir = path57.dirname(manifestPath);
21691
21845
  const bin = manifest.bin;
21692
21846
  if (!bin) return null;
21693
- if (typeof bin === "string") return path56.resolve(pkgDir, bin);
21847
+ if (typeof bin === "string") return path57.resolve(pkgDir, bin);
21694
21848
  const target = binName ?? Object.keys(bin)[0];
21695
21849
  if (!target || !bin[target]) return null;
21696
- return path56.resolve(pkgDir, bin[target]);
21850
+ return path57.resolve(pkgDir, bin[target]);
21697
21851
  } catch {
21698
21852
  return null;
21699
21853
  }
@@ -21773,12 +21927,12 @@ function requiresAcp(agent) {
21773
21927
  }
21774
21928
 
21775
21929
  // src/agents/acp/runner.ts
21776
- var import_node_crypto7 = require("crypto");
21930
+ var import_node_crypto8 = require("crypto");
21777
21931
 
21778
21932
  // src/services/history.service.ts
21779
- var fs53 = __toESM(require("fs"));
21780
- var path57 = __toESM(require("path"));
21781
- var os42 = __toESM(require("os"));
21933
+ var fs54 = __toESM(require("fs"));
21934
+ var path58 = __toESM(require("path"));
21935
+ var os43 = __toESM(require("os"));
21782
21936
  var https7 = __toESM(require("https"));
21783
21937
  var http6 = __toESM(require("http"));
21784
21938
  var import_zod2 = require("zod");
@@ -21805,7 +21959,7 @@ function parseJsonl(filePath) {
21805
21959
  const messages = [];
21806
21960
  let raw;
21807
21961
  try {
21808
- raw = fs53.readFileSync(filePath, "utf8");
21962
+ raw = fs54.readFileSync(filePath, "utf8");
21809
21963
  } catch (err) {
21810
21964
  if (err.code !== "ENOENT") {
21811
21965
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -21946,7 +22100,7 @@ var HistoryService = class _HistoryService {
21946
22100
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
21947
22101
  }
21948
22102
  get projectDir() {
21949
- 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));
21950
22104
  }
21951
22105
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
21952
22106
  setCurrentConversationId(id) {
@@ -21958,7 +22112,7 @@ var HistoryService = class _HistoryService {
21958
22112
  /** Return the current message count in the active conversation. */
21959
22113
  getCurrentMessageCount() {
21960
22114
  if (!this.currentConversationId) return 0;
21961
- const filePath = path57.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22115
+ const filePath = path58.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21962
22116
  return parseJsonl(filePath).length;
21963
22117
  }
21964
22118
  /**
@@ -21969,7 +22123,7 @@ var HistoryService = class _HistoryService {
21969
22123
  const deadline = Date.now() + timeoutMs;
21970
22124
  while (Date.now() < deadline) {
21971
22125
  if (!this.currentConversationId) return null;
21972
- const filePath = path57.join(this.projectDir, `${this.currentConversationId}.jsonl`);
22126
+ const filePath = path58.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21973
22127
  const messages = parseJsonl(filePath);
21974
22128
  if (messages.length > previousCount) {
21975
22129
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -21995,16 +22149,16 @@ var HistoryService = class _HistoryService {
21995
22149
  const dir = this.projectDir;
21996
22150
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21997
22151
  try {
21998
- 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) => {
21999
22153
  try {
22000
- const stat3 = fs53.statSync(path57.join(dir, e.name));
22154
+ const stat3 = fs54.statSync(path58.join(dir, e.name));
22001
22155
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22002
22156
  } catch {
22003
22157
  return { name: e.name, mtime: 0, birthtime: 0 };
22004
22158
  }
22005
22159
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
22006
22160
  if (files.length > 0) {
22007
- this.currentConversationId = path57.basename(files[0].name, ".jsonl");
22161
+ this.currentConversationId = path58.basename(files[0].name, ".jsonl");
22008
22162
  }
22009
22163
  } catch {
22010
22164
  }
@@ -22038,13 +22192,13 @@ var HistoryService = class _HistoryService {
22038
22192
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
22039
22193
  let entries;
22040
22194
  try {
22041
- entries = fs53.readdirSync(dir, { withFileTypes: true });
22195
+ entries = fs54.readdirSync(dir, { withFileTypes: true });
22042
22196
  } catch {
22043
22197
  return null;
22044
22198
  }
22045
22199
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
22046
22200
  try {
22047
- const stat3 = fs53.statSync(path57.join(dir, e.name));
22201
+ const stat3 = fs54.statSync(path58.join(dir, e.name));
22048
22202
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
22049
22203
  } catch {
22050
22204
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -22053,12 +22207,12 @@ var HistoryService = class _HistoryService {
22053
22207
  if (files.length === 0) return null;
22054
22208
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
22055
22209
  if (!files.some((f) => f.name === targetFile)) return null;
22056
- return this.extractUsageFromFile(path57.join(dir, targetFile));
22210
+ return this.extractUsageFromFile(path58.join(dir, targetFile));
22057
22211
  }
22058
22212
  extractUsageFromFile(filePath) {
22059
22213
  let raw;
22060
22214
  try {
22061
- raw = fs53.readFileSync(filePath, "utf8");
22215
+ raw = fs54.readFileSync(filePath, "utf8");
22062
22216
  } catch {
22063
22217
  return null;
22064
22218
  }
@@ -22103,9 +22257,9 @@ var HistoryService = class _HistoryService {
22103
22257
  let totalCost = 0;
22104
22258
  let files;
22105
22259
  try {
22106
- files = fs53.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22260
+ files = fs54.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
22107
22261
  try {
22108
- return fs53.statSync(path57.join(projectDir, f)).mtimeMs >= monthStartMs;
22262
+ return fs54.statSync(path58.join(projectDir, f)).mtimeMs >= monthStartMs;
22109
22263
  } catch {
22110
22264
  return false;
22111
22265
  }
@@ -22116,7 +22270,7 @@ var HistoryService = class _HistoryService {
22116
22270
  for (const file of files) {
22117
22271
  let raw;
22118
22272
  try {
22119
- raw = fs53.readFileSync(path57.join(projectDir, file), "utf8");
22273
+ raw = fs54.readFileSync(path58.join(projectDir, file), "utf8");
22120
22274
  } catch {
22121
22275
  continue;
22122
22276
  }
@@ -22195,7 +22349,7 @@ var HistoryService = class _HistoryService {
22195
22349
  if (this.runtime.resolveHistoryFile) {
22196
22350
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
22197
22351
  }
22198
- return path57.join(this.projectDir, `${sessionId}.jsonl`);
22352
+ return path58.join(this.projectDir, `${sessionId}.jsonl`);
22199
22353
  }
22200
22354
  /**
22201
22355
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -22229,7 +22383,7 @@ var HistoryService = class _HistoryService {
22229
22383
  };
22230
22384
  });
22231
22385
  }
22232
- return parseJsonl(path57.join(this.projectDir, `${sessionId}.jsonl`));
22386
+ return parseJsonl(path58.join(this.projectDir, `${sessionId}.jsonl`));
22233
22387
  }
22234
22388
  async loadConversation(sessionId) {
22235
22389
  const messages = this.readConversation(sessionId);
@@ -22285,7 +22439,7 @@ var HistoryService = class _HistoryService {
22285
22439
  if (!filePath) return false;
22286
22440
  let mtimeMs;
22287
22441
  try {
22288
- mtimeMs = fs53.statSync(filePath).mtimeMs;
22442
+ mtimeMs = fs54.statSync(filePath).mtimeMs;
22289
22443
  } catch {
22290
22444
  return false;
22291
22445
  }
@@ -22354,10 +22508,10 @@ var HistoryService = class _HistoryService {
22354
22508
 
22355
22509
  // src/agents/acp/client.ts
22356
22510
  var import_node_child_process21 = require("child_process");
22357
- var fs54 = __toESM(require("fs/promises"));
22511
+ var fs55 = __toESM(require("fs/promises"));
22358
22512
  var fsSync = __toESM(require("fs"));
22359
- var os43 = __toESM(require("os"));
22360
- var path58 = __toESM(require("path"));
22513
+ var os44 = __toESM(require("os"));
22514
+ var path59 = __toESM(require("path"));
22361
22515
  var import_node_stream = require("stream");
22362
22516
 
22363
22517
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -25271,7 +25425,7 @@ var AcpClient = class {
25271
25425
  },
25272
25426
  readTextFile: async (params) => {
25273
25427
  try {
25274
- const content = await fs54.readFile(params.path, "utf8");
25428
+ const content = await fs55.readFile(params.path, "utf8");
25275
25429
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
25276
25430
  } catch (err) {
25277
25431
  const code = err.code;
@@ -25291,7 +25445,7 @@ var AcpClient = class {
25291
25445
  },
25292
25446
  writeTextFile: async (params) => {
25293
25447
  try {
25294
- await fs54.writeFile(params.path, params.content, "utf8");
25448
+ await fs55.writeFile(params.path, params.content, "utf8");
25295
25449
  return {};
25296
25450
  } catch (err) {
25297
25451
  const code = err.code;
@@ -25340,29 +25494,29 @@ function applyLineRange(content, line, limit) {
25340
25494
  return { content: lines.slice(start2, end).join("\n") };
25341
25495
  }
25342
25496
  function knownAgentBinaryDirs() {
25343
- const home = os43.homedir();
25497
+ const home = os44.homedir();
25344
25498
  const out2 = [];
25345
25499
  out2.push("/tmp/codeam-node20/bin");
25346
25500
  for (const root of [
25347
25501
  "/usr/local/share/nvm/versions/node",
25348
- path58.join(home, ".nvm/versions/node")
25502
+ path59.join(home, ".nvm/versions/node")
25349
25503
  ]) {
25350
25504
  try {
25351
25505
  for (const child of fsSync.readdirSync(root)) {
25352
- out2.push(path58.join(root, child, "bin"));
25506
+ out2.push(path59.join(root, child, "bin"));
25353
25507
  }
25354
25508
  } catch {
25355
25509
  }
25356
25510
  }
25357
- out2.push(path58.join(home, ".volta/bin"));
25511
+ out2.push(path59.join(home, ".volta/bin"));
25358
25512
  out2.push("/usr/local/bin");
25359
25513
  out2.push("/usr/bin");
25360
- out2.push(path58.join(home, ".local/bin"));
25361
- out2.push(path58.join(home, "bin"));
25514
+ out2.push(path59.join(home, ".local/bin"));
25515
+ out2.push(path59.join(home, "bin"));
25362
25516
  if (process.platform === "win32") {
25363
25517
  const { LOCALAPPDATA, APPDATA } = process.env;
25364
- if (LOCALAPPDATA) out2.push(path58.join(LOCALAPPDATA, "cursor-agent"));
25365
- 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"));
25366
25520
  }
25367
25521
  return out2.filter((p2) => {
25368
25522
  try {
@@ -25374,7 +25528,7 @@ function knownAgentBinaryDirs() {
25374
25528
  }
25375
25529
  function expandPathForAgentBinaries(existingPath) {
25376
25530
  const existing = new Set(
25377
- existingPath.split(path58.delimiter).filter((p2) => p2.length > 0)
25531
+ existingPath.split(path59.delimiter).filter((p2) => p2.length > 0)
25378
25532
  );
25379
25533
  const additions = [];
25380
25534
  for (const dir of knownAgentBinaryDirs()) {
@@ -25384,7 +25538,7 @@ function expandPathForAgentBinaries(existingPath) {
25384
25538
  }
25385
25539
  }
25386
25540
  if (additions.length === 0) return existingPath;
25387
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path58.delimiter);
25541
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path59.delimiter);
25388
25542
  }
25389
25543
 
25390
25544
  // src/agents/acp/headroom-budget-proxy.ts
@@ -25866,15 +26020,15 @@ function commonPrefixLength(a, b) {
25866
26020
 
25867
26021
  // src/agents/acp/onboarding.ts
25868
26022
  var import_child_process26 = require("child_process");
25869
- var fs55 = __toESM(require("fs"));
25870
- var os44 = __toESM(require("os"));
25871
- var path59 = __toESM(require("path"));
26023
+ var fs56 = __toESM(require("fs"));
26024
+ var os45 = __toESM(require("os"));
26025
+ var path60 = __toESM(require("path"));
25872
26026
  var _onboardingSeam = {
25873
- markerPath: (sessionId) => path59.join(os44.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25874
- exists: (p2) => fs55.existsSync(p2),
26027
+ markerPath: (sessionId) => path60.join(os45.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
26028
+ exists: (p2) => fs56.existsSync(p2),
25875
26029
  write: (p2) => {
25876
- fs55.mkdirSync(path59.dirname(p2), { recursive: true });
25877
- fs55.writeFileSync(p2, "");
26030
+ fs56.mkdirSync(path60.dirname(p2), { recursive: true });
26031
+ fs56.writeFileSync(p2, "");
25878
26032
  },
25879
26033
  disabled: () => {
25880
26034
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -25911,7 +26065,7 @@ function resolveRepoName(cwd) {
25911
26065
  if (name) return name;
25912
26066
  }
25913
26067
  }
25914
- const base = path59.basename(cwd || "");
26068
+ const base = path60.basename(cwd || "");
25915
26069
  if (base && !isUuid(base)) return base;
25916
26070
  return "this project";
25917
26071
  }
@@ -25974,7 +26128,7 @@ async function runOnboardingTurn(opts) {
25974
26128
  }
25975
26129
 
25976
26130
  // src/agents/acp/mappers.ts
25977
- var import_node_crypto6 = require("crypto");
26131
+ var import_node_crypto7 = require("crypto");
25978
26132
  function mapSessionUpdate(notification) {
25979
26133
  const update = notification.update;
25980
26134
  switch (update.sessionUpdate) {
@@ -26037,7 +26191,7 @@ function mapPermissionRequest(request) {
26037
26191
  }
26038
26192
  return {
26039
26193
  event: {
26040
- questionId: (0, import_node_crypto6.randomUUID)(),
26194
+ questionId: (0, import_node_crypto7.randomUUID)(),
26041
26195
  prompt,
26042
26196
  options: labels.length > 0 ? labels : void 0
26043
26197
  },
@@ -26047,7 +26201,7 @@ function mapPermissionRequest(request) {
26047
26201
  }
26048
26202
  function messageChunkId(messageId) {
26049
26203
  if (typeof messageId === "string" && messageId.length > 0) return messageId;
26050
- return (0, import_node_crypto6.randomUUID)();
26204
+ return (0, import_node_crypto7.randomUUID)();
26051
26205
  }
26052
26206
  function extractText4(content) {
26053
26207
  if (!content || typeof content !== "object") return null;
@@ -26163,8 +26317,8 @@ var import_crypto5 = require("crypto");
26163
26317
 
26164
26318
  // src/services/turn-files/git-changeset.ts
26165
26319
  var import_child_process27 = require("child_process");
26166
- var fs56 = __toESM(require("fs/promises"));
26167
- var path60 = __toESM(require("path"));
26320
+ var fs57 = __toESM(require("fs/promises"));
26321
+ var path61 = __toESM(require("path"));
26168
26322
  async function collectRepoChangeset(opts) {
26169
26323
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
26170
26324
  if (status2 === null) return null;
@@ -26182,7 +26336,7 @@ async function collectRepoChangeset(opts) {
26182
26336
  let stats;
26183
26337
  if (row.fileStatus === "added" && numstatEntry === void 0) {
26184
26338
  const lineCount = await readUntrackedLineCount(
26185
- path60.join(opts.repoRoot, row.filePath)
26339
+ path61.join(opts.repoRoot, row.filePath)
26186
26340
  );
26187
26341
  stats = { added: lineCount, removed: 0 };
26188
26342
  } else {
@@ -26213,7 +26367,7 @@ function readUntrackedLineCount(absPath) {
26213
26367
  }
26214
26368
  async function defaultReadUntrackedLineCount(absPath) {
26215
26369
  try {
26216
- const content = await fs56.readFile(absPath, "utf8");
26370
+ const content = await fs57.readFile(absPath, "utf8");
26217
26371
  let count = 0;
26218
26372
  let pos = -1;
26219
26373
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -26305,7 +26459,7 @@ function defaultRunGit(cwd, args2) {
26305
26459
  });
26306
26460
  }
26307
26461
  async function discoverRepos(workingDir, maxDepth = 4) {
26308
- const fs61 = await import("fs/promises");
26462
+ const fs62 = await import("fs/promises");
26309
26463
  const out2 = [];
26310
26464
  await walk(workingDir, 0);
26311
26465
  return out2;
@@ -26313,7 +26467,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
26313
26467
  if (depth > maxDepth) return;
26314
26468
  let entries = [];
26315
26469
  try {
26316
- const dirents = await fs61.readdir(dir, { withFileTypes: true });
26470
+ const dirents = await fs62.readdir(dir, { withFileTypes: true });
26317
26471
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
26318
26472
  } catch {
26319
26473
  return;
@@ -26324,8 +26478,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
26324
26478
  if (hasGit) {
26325
26479
  out2.push({
26326
26480
  repoRoot: dir,
26327
- repoPath: path60.relative(workingDir, dir),
26328
- repoName: path60.basename(dir)
26481
+ repoPath: path61.relative(workingDir, dir),
26482
+ repoName: path61.basename(dir)
26329
26483
  });
26330
26484
  return;
26331
26485
  }
@@ -26333,14 +26487,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
26333
26487
  if (!entry.isDirectory) continue;
26334
26488
  if (entry.name === "node_modules") continue;
26335
26489
  if (entry.name === "dist" || entry.name === "build") continue;
26336
- await walk(path60.join(dir, entry.name), depth + 1);
26490
+ await walk(path61.join(dir, entry.name), depth + 1);
26337
26491
  }
26338
26492
  }
26339
26493
  }
26340
26494
 
26341
26495
  // src/services/turn-files/files-outbox.ts
26342
- var fs57 = __toESM(require("fs/promises"));
26343
- var path61 = __toESM(require("path"));
26496
+ var fs58 = __toESM(require("fs/promises"));
26497
+ var path62 = __toESM(require("path"));
26344
26498
  var import_os8 = require("os");
26345
26499
  var HOME_OUTBOX_DIR = ".codeam/outbox";
26346
26500
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -26373,16 +26527,16 @@ var FilesOutbox = class {
26373
26527
  backoffIndex = 0;
26374
26528
  stopped = false;
26375
26529
  constructor(opts) {
26376
- const base = opts.baseDir ?? path61.join(homeDir(), HOME_OUTBOX_DIR);
26377
- 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`);
26378
26532
  this.post = opts.post;
26379
26533
  this.autoSchedule = opts.autoSchedule !== false;
26380
26534
  }
26381
26535
  /** Persist the entry to disk and trigger a flush. Returns once the
26382
26536
  * line is durable on disk (not once the POST succeeds). */
26383
26537
  async enqueue(entry) {
26384
- await fs57.mkdir(path61.dirname(this.filePath), { recursive: true });
26385
- 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");
26386
26540
  this.backoffIndex = 0;
26387
26541
  if (this.autoSchedule) this.scheduleFlush(0);
26388
26542
  }
@@ -26471,7 +26625,7 @@ var FilesOutbox = class {
26471
26625
  async readAll() {
26472
26626
  let raw = "";
26473
26627
  try {
26474
- raw = await fs57.readFile(this.filePath, "utf8");
26628
+ raw = await fs58.readFile(this.filePath, "utf8");
26475
26629
  } catch {
26476
26630
  return [];
26477
26631
  }
@@ -26495,12 +26649,12 @@ var FilesOutbox = class {
26495
26649
  async rewrite(entries) {
26496
26650
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
26497
26651
  if (entries.length === 0) {
26498
- await fs57.unlink(this.filePath).catch(() => void 0);
26652
+ await fs58.unlink(this.filePath).catch(() => void 0);
26499
26653
  return;
26500
26654
  }
26501
26655
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
26502
- await fs57.writeFile(tmpPath, payload, "utf8");
26503
- await fs57.rename(tmpPath, this.filePath);
26656
+ await fs58.writeFile(tmpPath, payload, "utf8");
26657
+ await fs58.rename(tmpPath, this.filePath);
26504
26658
  }
26505
26659
  };
26506
26660
  function applyJitter(ms) {
@@ -27860,7 +28014,7 @@ var AcpHistory = class {
27860
28014
  this.summary = trimmed.length > 120 ? trimmed.slice(0, 117) + "\u2026" : trimmed;
27861
28015
  }
27862
28016
  this.messages.push({
27863
- id: (0, import_node_crypto7.randomUUID)(),
28017
+ id: (0, import_node_crypto8.randomUUID)(),
27864
28018
  role: "user",
27865
28019
  text,
27866
28020
  timestamp: Date.now()
@@ -27869,7 +28023,7 @@ var AcpHistory = class {
27869
28023
  appendAgentReply(text) {
27870
28024
  if (text.length === 0) return;
27871
28025
  this.messages.push({
27872
- id: (0, import_node_crypto7.randomUUID)(),
28026
+ id: (0, import_node_crypto8.randomUUID)(),
27873
28027
  role: "agent",
27874
28028
  text,
27875
28029
  timestamp: Date.now()
@@ -28075,7 +28229,7 @@ async function runAcpSession(opts) {
28075
28229
  currentIndex: 0,
28076
28230
  done: true
28077
28231
  }),
28078
- 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 }),
28079
28233
  publishRawChunk: (chunk) => publisher.publishOutput(chunk),
28080
28234
  sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
28081
28235
  appendAgentReply: (text) => history.appendAgentReply(text),
@@ -29444,7 +29598,7 @@ var NativeTuiDriver = class {
29444
29598
  };
29445
29599
 
29446
29600
  // src/baton/acp-driver.ts
29447
- var import_node_crypto8 = require("crypto");
29601
+ var import_node_crypto9 = require("crypto");
29448
29602
  var AcpDriver = class {
29449
29603
  constructor(deps) {
29450
29604
  this.deps = deps;
@@ -29537,7 +29691,7 @@ var AcpDriver = class {
29537
29691
  currentIndex: 0,
29538
29692
  done: true
29539
29693
  }),
29540
- 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 }),
29541
29695
  publishRawChunk: (chunk) => publisher.publishOutput(chunk),
29542
29696
  sendResult: (commandId, status2, result) => relay.sendResult(commandId, status2, result),
29543
29697
  appendAgentReply: (text) => history.appendAgentReply(text),
@@ -29580,7 +29734,7 @@ var AcpDriver = class {
29580
29734
  };
29581
29735
 
29582
29736
  // src/baton/transcript-mirror.ts
29583
- var fs58 = __toESM(require("fs"));
29737
+ var fs59 = __toESM(require("fs"));
29584
29738
  var TranscriptMirror = class {
29585
29739
  constructor(deps) {
29586
29740
  this.deps = deps;
@@ -29647,7 +29801,7 @@ var TranscriptMirror = class {
29647
29801
  }
29648
29802
  };
29649
29803
  function defaultWatch(file, onChange) {
29650
- const w3 = fs58.watch(file, { persistent: false }, () => onChange());
29804
+ const w3 = fs59.watch(file, { persistent: false }, () => onChange());
29651
29805
  return () => w3.close();
29652
29806
  }
29653
29807
 
@@ -29894,15 +30048,15 @@ function toEpochMs(ts) {
29894
30048
  }
29895
30049
 
29896
30050
  // src/agents/claude/onboarding.ts
29897
- var fs59 = __toESM(require("fs"));
29898
- var os45 = __toESM(require("os"));
29899
- var path62 = __toESM(require("path"));
30051
+ var fs60 = __toESM(require("fs"));
30052
+ var os46 = __toESM(require("os"));
30053
+ var path63 = __toESM(require("path"));
29900
30054
  function ensureClaudeOnboarded() {
29901
30055
  try {
29902
- const file = path62.join(os45.homedir(), ".claude.json");
30056
+ const file = path63.join(os46.homedir(), ".claude.json");
29903
30057
  let config = {};
29904
30058
  try {
29905
- config = JSON.parse(fs59.readFileSync(file, "utf8"));
30059
+ config = JSON.parse(fs60.readFileSync(file, "utf8"));
29906
30060
  } catch {
29907
30061
  }
29908
30062
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -29913,8 +30067,8 @@ function ensureClaudeOnboarded() {
29913
30067
  if (typeof config.lastOnboardingVersion !== "string") {
29914
30068
  config.lastOnboardingVersion = "2.1.177";
29915
30069
  }
29916
- fs59.mkdirSync(path62.dirname(file), { recursive: true });
29917
- 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));
29918
30072
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
29919
30073
  } catch (err) {
29920
30074
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -30588,7 +30742,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
30588
30742
  var import_child_process28 = require("child_process");
30589
30743
  var import_util4 = require("util");
30590
30744
  var import_picocolors9 = __toESM(require("picocolors"));
30591
- var path63 = __toESM(require("path"));
30745
+ var path64 = __toESM(require("path"));
30592
30746
  var execFileP6 = (0, import_util4.promisify)(import_child_process28.execFile);
30593
30747
  var MAX_BUFFER = 8 * 1024 * 1024;
30594
30748
  function resetStdinForChild() {
@@ -31077,7 +31231,7 @@ var GitHubCodespacesProvider = class {
31077
31231
  });
31078
31232
  }
31079
31233
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
31080
- const remoteDir = path63.posix.dirname(remotePath);
31234
+ const remoteDir = path64.posix.dirname(remotePath);
31081
31235
  const parts = [
31082
31236
  `mkdir -p ${shellQuote(remoteDir)}`,
31083
31237
  `cat > ${shellQuote(remotePath)}`
@@ -31147,7 +31301,7 @@ function shellQuote(s) {
31147
31301
  // src/services/providers/gitpod.ts
31148
31302
  var import_child_process29 = require("child_process");
31149
31303
  var import_util5 = require("util");
31150
- var path64 = __toESM(require("path"));
31304
+ var path65 = __toESM(require("path"));
31151
31305
  var import_picocolors10 = __toESM(require("picocolors"));
31152
31306
  var execFileP7 = (0, import_util5.promisify)(import_child_process29.execFile);
31153
31307
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -31387,7 +31541,7 @@ var GitpodProvider = class {
31387
31541
  });
31388
31542
  }
31389
31543
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
31390
- const remoteDir = path64.posix.dirname(remotePath);
31544
+ const remoteDir = path65.posix.dirname(remotePath);
31391
31545
  const parts = [
31392
31546
  `mkdir -p ${shellQuote2(remoteDir)}`,
31393
31547
  `cat > ${shellQuote2(remotePath)}`
@@ -31423,7 +31577,7 @@ function shellQuote2(s) {
31423
31577
  // src/services/providers/gitlab-workspaces.ts
31424
31578
  var import_child_process30 = require("child_process");
31425
31579
  var import_util6 = require("util");
31426
- var path65 = __toESM(require("path"));
31580
+ var path66 = __toESM(require("path"));
31427
31581
  var execFileP8 = (0, import_util6.promisify)(import_child_process30.execFile);
31428
31582
  var MAX_BUFFER3 = 8 * 1024 * 1024;
31429
31583
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -31683,7 +31837,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
31683
31837
  }
31684
31838
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
31685
31839
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
31686
- const remoteDir = path65.posix.dirname(remotePath);
31840
+ const remoteDir = path66.posix.dirname(remotePath);
31687
31841
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
31688
31842
  if (options.mode != null) {
31689
31843
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -31751,7 +31905,7 @@ function shellQuote3(s) {
31751
31905
  // src/services/providers/railway.ts
31752
31906
  var import_child_process31 = require("child_process");
31753
31907
  var import_util7 = require("util");
31754
- var path66 = __toESM(require("path"));
31908
+ var path67 = __toESM(require("path"));
31755
31909
  var execFileP9 = (0, import_util7.promisify)(import_child_process31.execFile);
31756
31910
  var MAX_BUFFER4 = 8 * 1024 * 1024;
31757
31911
  function resetStdinForChild4() {
@@ -31987,7 +32141,7 @@ var RailwayProvider = class {
31987
32141
  if (!projectId || !serviceId) {
31988
32142
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
31989
32143
  }
31990
- const remoteDir = path66.posix.dirname(remotePath);
32144
+ const remoteDir = path67.posix.dirname(remotePath);
31991
32145
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
31992
32146
  if (options.mode != null) {
31993
32147
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -32632,9 +32786,9 @@ async function invite() {
32632
32786
  // src/commands/doctor.ts
32633
32787
  var import_node_dns = require("dns");
32634
32788
  var import_node_util5 = require("util");
32635
- var import_node_crypto9 = require("crypto");
32636
- var fs60 = __toESM(require("fs"));
32637
- var path67 = __toESM(require("path"));
32789
+ var import_node_crypto10 = require("crypto");
32790
+ var fs61 = __toESM(require("fs"));
32791
+ var path68 = __toESM(require("path"));
32638
32792
  var import_picocolors14 = __toESM(require("picocolors"));
32639
32793
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
32640
32794
  async function checkDns(apiBase2) {
@@ -32690,13 +32844,13 @@ async function checkHealth(apiBase2) {
32690
32844
  }
32691
32845
  }
32692
32846
  function checkConfigDir() {
32693
- const dir = path67.join(require("os").homedir(), ".codeam");
32847
+ const dir = path68.join(require("os").homedir(), ".codeam");
32694
32848
  try {
32695
- fs60.mkdirSync(dir, { recursive: true, mode: 448 });
32696
- const probe = path67.join(dir, ".doctor-probe");
32697
- fs60.writeFileSync(probe, "ok", { mode: 384 });
32698
- const read2 = fs60.readFileSync(probe, "utf8");
32699
- 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);
32700
32854
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
32701
32855
  return {
32702
32856
  id: "config-dir",
@@ -32736,9 +32890,9 @@ function checkSessions() {
32736
32890
  }
32737
32891
  }
32738
32892
  function checkAgentBinaries() {
32739
- const os47 = createOsStrategy();
32893
+ const os48 = createOsStrategy();
32740
32894
  return getEnabledAgents().map((meta) => {
32741
- const found = os47.findInPath(meta.binaryName);
32895
+ const found = os48.findInPath(meta.binaryName);
32742
32896
  return {
32743
32897
  id: `agent-${meta.id}`,
32744
32898
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -32760,7 +32914,7 @@ function checkNodePty() {
32760
32914
  detail: "not required on this platform"
32761
32915
  };
32762
32916
  }
32763
- const vendoredPath = path67.join(__dirname, "vendor", "node-pty");
32917
+ const vendoredPath = path68.join(__dirname, "vendor", "node-pty");
32764
32918
  for (const target of [vendoredPath, "node-pty"]) {
32765
32919
  try {
32766
32920
  require(target);
@@ -32802,9 +32956,9 @@ function checkChokidar() {
32802
32956
  }
32803
32957
  async function doctor(args2 = []) {
32804
32958
  const json = args2.includes("--json");
32805
- const cliVersion = true ? "2.60.7" : "0.0.0-dev";
32959
+ const cliVersion = true ? "2.60.9" : "0.0.0-dev";
32806
32960
  const apiBase2 = resolveApiBaseUrl();
32807
- const diagnosticId = (0, import_node_crypto9.randomUUID)();
32961
+ const diagnosticId = (0, import_node_crypto10.randomUUID)();
32808
32962
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
32809
32963
  const [dns, health] = await Promise.all([
32810
32964
  checkDns(apiBase2),
@@ -33001,7 +33155,7 @@ async function completion(args2) {
33001
33155
  // src/commands/version.ts
33002
33156
  var import_picocolors15 = __toESM(require("picocolors"));
33003
33157
  function version2() {
33004
- const v = true ? "2.60.7" : "unknown";
33158
+ const v = true ? "2.60.9" : "unknown";
33005
33159
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
33006
33160
  }
33007
33161
 
@@ -33150,10 +33304,10 @@ var EXIT_CODE_NAMES = {
33150
33304
  };
33151
33305
 
33152
33306
  // src/index.ts
33153
- var os46 = __toESM(require("os"));
33307
+ var os47 = __toESM(require("os"));
33154
33308
  if (!process.env.HOME) {
33155
33309
  try {
33156
- const home = os46.homedir();
33310
+ const home = os47.homedir();
33157
33311
  if (home) process.env.HOME = home;
33158
33312
  } catch {
33159
33313
  }