codeam-cli 2.53.2 → 2.53.3

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 +7 -0
  2. package/dist/index.js +764 -669
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -202,6 +202,18 @@ function renderToLines(raw) {
202
202
  // ../../packages/shared/src/models/pricing.ts
203
203
  var MODEL_PRICING = {
204
204
  // ── Anthropic / Claude ────────────────────────────────────
205
+ // The 4.x rows below cover the model ids actually emitted by the CLI
206
+ // (apps/cli/src/agents/claude/runtime.ts listModels) and the JetBrains
207
+ // fallback catalog (RemoteCommandRouter.kt). Prices are copied from the
208
+ // same-family base rows (claude-opus-4 / claude-sonnet-4 /
209
+ // claude-3-5-haiku) until distinct published rates land.
210
+ "claude-opus-4-7": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
211
+ "claude-opus-4-6": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
212
+ "claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
213
+ // Haiku-tier prices copied from claude-3-5-haiku (closest same-tier
214
+ // sibling in this table) — previously this id matched NO row and was
215
+ // silently billed at sonnet rates via the unknown-model fallback.
216
+ "claude-haiku-4-5": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
205
217
  "claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
206
218
  "claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
207
219
  "claude-3-5-sonnet": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
@@ -220,6 +232,10 @@ var MODEL_PRICING = {
220
232
  };
221
233
  var MODEL_CONTEXT_WINDOW = {
222
234
  // ── Anthropic / Claude ────────────────────────────────────
235
+ "claude-opus-4-7": 1e6,
236
+ "claude-opus-4-6": 1e6,
237
+ "claude-sonnet-4-6": 1e6,
238
+ "claude-haiku-4-5": 2e5,
223
239
  "claude-opus-4": 1e6,
224
240
  "claude-sonnet-4": 1e6,
225
241
  "claude-3-5-sonnet": 2e5,
@@ -234,18 +250,23 @@ var MODEL_CONTEXT_WINDOW = {
234
250
  "codex-auto-review": 272e3
235
251
  };
236
252
  var DEFAULT_CONTEXT_WINDOW = 2e5;
237
- function getPricing(model) {
238
- for (const [prefix, pricing] of Object.entries(MODEL_PRICING)) {
239
- if (model.startsWith(prefix)) return pricing;
253
+ function longestPrefixMatch(table, model) {
254
+ let best;
255
+ let bestLen = -1;
256
+ for (const [prefix, value] of Object.entries(table)) {
257
+ if (prefix.length > bestLen && model.startsWith(prefix)) {
258
+ best = value;
259
+ bestLen = prefix.length;
260
+ }
240
261
  }
241
- return MODEL_PRICING["claude-sonnet-4"];
262
+ return best;
263
+ }
264
+ function getPricing(model) {
265
+ return longestPrefixMatch(MODEL_PRICING, model) ?? MODEL_PRICING["claude-sonnet-4"];
242
266
  }
243
267
  function getContextWindow(model) {
244
268
  if (!model) return DEFAULT_CONTEXT_WINDOW;
245
- for (const [prefix, size] of Object.entries(MODEL_CONTEXT_WINDOW)) {
246
- if (model.startsWith(prefix)) return size;
247
- }
248
- return DEFAULT_CONTEXT_WINDOW;
269
+ return longestPrefixMatch(MODEL_CONTEXT_WINDOW, model) ?? DEFAULT_CONTEXT_WINDOW;
249
270
  }
250
271
 
251
272
  // ../../packages/shared/src/agents/registry.ts
@@ -522,9 +543,9 @@ var _default = makeConfig();
522
543
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
523
544
 
524
545
  // src/commands/pair-auto.ts
525
- var fs45 = __toESM(require("fs"));
526
- var os38 = __toESM(require("os"));
527
- var path50 = __toESM(require("path"));
546
+ var fs46 = __toESM(require("fs"));
547
+ var os39 = __toESM(require("os"));
548
+ var path51 = __toESM(require("path"));
528
549
  var import_crypto4 = require("crypto");
529
550
 
530
551
  // src/services/telemetry.service.ts
@@ -560,8 +581,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
560
581
  return decodedFile;
561
582
  };
562
583
  }
563
- function normalizeWindowsPath(path64) {
564
- return path64.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
584
+ function normalizeWindowsPath(path65) {
585
+ return path65.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
565
586
  }
566
587
 
567
588
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3041,9 +3062,9 @@ async function addSourceContext(frames) {
3041
3062
  LRU_FILE_CONTENTS_CACHE.reduce();
3042
3063
  return frames;
3043
3064
  }
3044
- function getContextLinesFromFile(path64, ranges, output) {
3065
+ function getContextLinesFromFile(path65, ranges, output) {
3045
3066
  return new Promise((resolve7) => {
3046
- const stream = (0, import_node_fs.createReadStream)(path64);
3067
+ const stream = (0, import_node_fs.createReadStream)(path65);
3047
3068
  const lineReaded = (0, import_node_readline.createInterface)({
3048
3069
  input: stream
3049
3070
  });
@@ -3058,7 +3079,7 @@ function getContextLinesFromFile(path64, ranges, output) {
3058
3079
  let rangeStart = range[0];
3059
3080
  let rangeEnd = range[1];
3060
3081
  function onStreamError() {
3061
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path64, 1);
3082
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path65, 1);
3062
3083
  lineReaded.close();
3063
3084
  lineReaded.removeAllListeners();
3064
3085
  destroyStreamAndResolve();
@@ -3119,8 +3140,8 @@ function clearLineContext(frame) {
3119
3140
  delete frame.context_line;
3120
3141
  delete frame.post_context;
3121
3142
  }
3122
- function shouldSkipContextLinesForFile(path64) {
3123
- return path64.startsWith("node:") || path64.endsWith(".min.js") || path64.endsWith(".min.cjs") || path64.endsWith(".min.mjs") || path64.startsWith("data:");
3143
+ function shouldSkipContextLinesForFile(path65) {
3144
+ return path65.startsWith("node:") || path65.endsWith(".min.js") || path65.endsWith(".min.cjs") || path65.endsWith(".min.mjs") || path65.startsWith("data:");
3124
3145
  }
3125
3146
  function shouldSkipContextLinesForFrame(frame) {
3126
3147
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5397,7 +5418,7 @@ function readAnonId() {
5397
5418
  }
5398
5419
  function superProperties() {
5399
5420
  return {
5400
- cliVersion: true ? "2.53.2" : "0.0.0-dev",
5421
+ cliVersion: true ? "2.53.3" : "0.0.0-dev",
5401
5422
  nodeVersion: process.version,
5402
5423
  platform: process.platform,
5403
5424
  arch: process.arch,
@@ -5578,7 +5599,7 @@ var os4 = __toESM(require("os"));
5578
5599
  // package.json
5579
5600
  var package_default = {
5580
5601
  name: "codeam-cli",
5581
- version: "2.53.2",
5602
+ version: "2.53.3",
5582
5603
  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.",
5583
5604
  type: "commonjs",
5584
5605
  main: "dist/index.js",
@@ -6106,9 +6127,9 @@ function computePollDelay({ baseMs, failures }) {
6106
6127
 
6107
6128
  // src/services/headroom/proxy-supervisor.ts
6108
6129
  var import_child_process2 = require("child_process");
6109
- var fs4 = __toESM(require("fs"));
6110
- var os5 = __toESM(require("os"));
6111
- var path4 = __toESM(require("path"));
6130
+ var fs5 = __toESM(require("fs"));
6131
+ var os6 = __toESM(require("os"));
6132
+ var path5 = __toESM(require("path"));
6112
6133
 
6113
6134
  // src/services/headroom/budget-args.ts
6114
6135
  function buildBudgetProxyArgs(env) {
@@ -6118,6 +6139,74 @@ function buildBudgetProxyArgs(env) {
6118
6139
  return ["--budget", budget, "--budget-period", period];
6119
6140
  }
6120
6141
 
6142
+ // src/services/headroom/proxy-pid.ts
6143
+ var import_node_child_process = require("child_process");
6144
+ var fs4 = __toESM(require("fs"));
6145
+ var os5 = __toESM(require("os"));
6146
+ var path4 = __toESM(require("path"));
6147
+ function headroomProxyPidfilePath() {
6148
+ return path4.join(os5.homedir(), ".codeam", "headroom-proxy.pid");
6149
+ }
6150
+ function writeHeadroomProxyPidfile(pid) {
6151
+ if (!pid) return;
6152
+ try {
6153
+ const file = headroomProxyPidfilePath();
6154
+ fs4.mkdirSync(path4.dirname(file), { recursive: true, mode: 448 });
6155
+ fs4.writeFileSync(file, `${pid}
6156
+ `, { encoding: "utf8", mode: 384 });
6157
+ } catch {
6158
+ }
6159
+ }
6160
+ function readHeadroomProxyPidfile() {
6161
+ try {
6162
+ const pid = Number(fs4.readFileSync(headroomProxyPidfilePath(), "utf8").trim());
6163
+ return Number.isInteger(pid) && pid > 0 ? pid : null;
6164
+ } catch {
6165
+ return null;
6166
+ }
6167
+ }
6168
+ function isPidAlive(pid) {
6169
+ try {
6170
+ process.kill(pid, 0);
6171
+ return true;
6172
+ } catch {
6173
+ return false;
6174
+ }
6175
+ }
6176
+ function pkillFallback() {
6177
+ try {
6178
+ const killer = (0, import_node_child_process.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
6179
+ detached: true,
6180
+ stdio: "ignore"
6181
+ });
6182
+ killer.once("error", () => {
6183
+ });
6184
+ killer.unref();
6185
+ } catch {
6186
+ }
6187
+ }
6188
+ function killHeadroomProxy() {
6189
+ const pid = readHeadroomProxyPidfile();
6190
+ if (pid !== null && isPidAlive(pid)) {
6191
+ try {
6192
+ process.kill(pid, "SIGTERM");
6193
+ try {
6194
+ fs4.rmSync(headroomProxyPidfilePath(), { force: true });
6195
+ } catch {
6196
+ }
6197
+ return;
6198
+ } catch {
6199
+ }
6200
+ }
6201
+ if (pid !== null) {
6202
+ try {
6203
+ fs4.rmSync(headroomProxyPidfilePath(), { force: true });
6204
+ } catch {
6205
+ }
6206
+ }
6207
+ pkillFallback();
6208
+ }
6209
+
6121
6210
  // src/services/headroom/proxy-supervisor.ts
6122
6211
  async function ensureHeadroomProxy(deps) {
6123
6212
  if (!deps.isConfigured()) return "skip";
@@ -6132,17 +6221,17 @@ async function ensureHeadroomProxy(deps) {
6132
6221
  deps.spawnProxy();
6133
6222
  return "respawned";
6134
6223
  }
6135
- function isHeadroomConfiguredReal(homeDir2 = os5.homedir()) {
6224
+ function isHeadroomConfiguredReal(homeDir2 = os6.homedir()) {
6136
6225
  if (process.env.HEADROOM_ENABLED === "1") return true;
6137
- const csEnv = path4.join(homeDir2, ".codeam", "codespace-env.json");
6226
+ const csEnv = path5.join(homeDir2, ".codeam", "codespace-env.json");
6138
6227
  try {
6139
- const j2 = JSON.parse(fs4.readFileSync(csEnv, "utf8"));
6228
+ const j2 = JSON.parse(fs5.readFileSync(csEnv, "utf8"));
6140
6229
  if (j2.HEADROOM_ENABLED === "1" || j2.HEADROOM_ENABLED === 1) return true;
6141
6230
  } catch {
6142
6231
  }
6143
- const settings = path4.join(homeDir2, ".claude", "settings.json");
6232
+ const settings = path5.join(homeDir2, ".claude", "settings.json");
6144
6233
  try {
6145
- if (fs4.readFileSync(settings, "utf8").includes("127.0.0.1:8787")) return true;
6234
+ if (fs5.readFileSync(settings, "utf8").includes("127.0.0.1:8787")) return true;
6146
6235
  } catch {
6147
6236
  }
6148
6237
  return false;
@@ -6176,6 +6265,7 @@ function spawnProxyReal() {
6176
6265
  log.warn("headroom-supervisor", `respawn error (best-effort): ${e.message}`);
6177
6266
  });
6178
6267
  proxy.unref();
6268
+ writeHeadroomProxyPidfile(proxy.pid);
6179
6269
  } catch (e) {
6180
6270
  log.warn(
6181
6271
  "headroom-supervisor",
@@ -6543,7 +6633,7 @@ var CommandRelayService = class {
6543
6633
  // fresh + clear the "CLI update available" banner after a self-update
6544
6634
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
6545
6635
  // pair/reconnect). Older backends ignore the extra field.
6546
- ..."2.53.2" ? { ideVersion: "2.53.2" } : {}
6636
+ ..."2.53.3" ? { ideVersion: "2.53.3" } : {}
6547
6637
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
6548
6638
  }
6549
6639
  /**
@@ -6609,9 +6699,9 @@ var CommandRelayService = class {
6609
6699
 
6610
6700
  // src/services/file-watcher.service.ts
6611
6701
  var import_child_process3 = require("child_process");
6612
- var fs5 = __toESM(require("fs"));
6613
- var os6 = __toESM(require("os"));
6614
- var path5 = __toESM(require("path"));
6702
+ var fs6 = __toESM(require("fs"));
6703
+ var os7 = __toESM(require("os"));
6704
+ var path6 = __toESM(require("path"));
6615
6705
  var import_ignore = __toESM(require("ignore"));
6616
6706
 
6617
6707
  // src/services/file-watcher/diff-parser.ts
@@ -6770,10 +6860,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
6770
6860
  /[\\/]Start Menu([\\/]|$)/i,
6771
6861
  /[\\/]Templates([\\/]|$)/i
6772
6862
  ];
6773
- function isUnsafeWindowsWatchRoot(dir, homedir35) {
6863
+ function isUnsafeWindowsWatchRoot(dir, homedir36) {
6774
6864
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
6775
6865
  const cwd = norm(dir);
6776
- const home = norm(homedir35);
6866
+ const home = norm(homedir36);
6777
6867
  if (cwd === home) return true;
6778
6868
  if (/^[a-z]:$/.test(cwd)) return true;
6779
6869
  const sysRoots = [
@@ -6803,18 +6893,18 @@ var _findGitRootSeam = {
6803
6893
  resolve: _defaultFindGitRoot
6804
6894
  };
6805
6895
  function _defaultFindGitRoot(startDir) {
6806
- let dir = path5.resolve(startDir);
6896
+ let dir = path6.resolve(startDir);
6807
6897
  const seen = /* @__PURE__ */ new Set();
6808
6898
  for (let i = 0; i < 256; i++) {
6809
6899
  if (seen.has(dir)) return null;
6810
6900
  seen.add(dir);
6811
6901
  try {
6812
- const gitPath = path5.join(dir, ".git");
6813
- const stat3 = fs5.statSync(gitPath, { throwIfNoEntry: false });
6902
+ const gitPath = path6.join(dir, ".git");
6903
+ const stat3 = fs6.statSync(gitPath, { throwIfNoEntry: false });
6814
6904
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
6815
6905
  } catch {
6816
6906
  }
6817
- const parent = path5.dirname(dir);
6907
+ const parent = path6.dirname(dir);
6818
6908
  if (parent === dir) return null;
6819
6909
  dir = parent;
6820
6910
  }
@@ -6872,7 +6962,7 @@ var FileWatcherService = class {
6872
6962
  throw new Error("FileWatcherService has already been stopped \u2014 re-instantiate to restart.");
6873
6963
  }
6874
6964
  const isWin = process.platform === "win32";
6875
- if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os6.homedir())) {
6965
+ if (isWin && isUnsafeWindowsWatchRoot(this.opts.workingDir, os7.homedir())) {
6876
6966
  log.warn(
6877
6967
  "fileWatcher",
6878
6968
  `refusing to watch ${this.opts.workingDir} \u2014 looks like a Windows user-profile or system path. Run codeam from your project folder to enable file change emission.`
@@ -7059,7 +7149,7 @@ var FileWatcherService = class {
7059
7149
  }
7060
7150
  async emitForFile(absPath, changeType) {
7061
7151
  if (this.stopped) return;
7062
- const fileDir = path5.dirname(absPath);
7152
+ const fileDir = path6.dirname(absPath);
7063
7153
  let gitRoot = this.gitRootByDir.get(fileDir);
7064
7154
  if (gitRoot === void 0) {
7065
7155
  gitRoot = findGitRoot(fileDir);
@@ -7072,19 +7162,19 @@ var FileWatcherService = class {
7072
7162
  );
7073
7163
  return;
7074
7164
  }
7075
- const relPathInRepo = path5.relative(gitRoot, absPath);
7165
+ const relPathInRepo = path6.relative(gitRoot, absPath);
7076
7166
  if (!relPathInRepo || relPathInRepo.startsWith("..")) return;
7077
7167
  const matcher = this.getGitIgnoreMatcher(gitRoot);
7078
7168
  if (matcher && matcher.ignores(relPathInRepo)) {
7079
7169
  log.trace(
7080
7170
  "fileWatcher",
7081
- `${relPathInRepo} ignored by ${path5.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
7171
+ `${relPathInRepo} ignored by ${path6.basename(gitRoot)}/.gitignore \u2014 suppressing emit`
7082
7172
  );
7083
7173
  return;
7084
7174
  }
7085
7175
  this.opts.onRepoDirty?.(gitRoot);
7086
- const repoPath = path5.relative(this.opts.workingDir, gitRoot);
7087
- const repoName = path5.basename(gitRoot);
7176
+ const repoPath = path6.relative(this.opts.workingDir, gitRoot);
7177
+ const repoName = path6.basename(gitRoot);
7088
7178
  let diffText = "";
7089
7179
  let fileStatus = "modified";
7090
7180
  if (changeType === "unlink") {
@@ -7259,7 +7349,7 @@ var FileWatcherService = class {
7259
7349
  collectGitignoreFiles(repoRoot, dir, matcher) {
7260
7350
  let entries;
7261
7351
  try {
7262
- entries = fs5.readdirSync(dir, { withFileTypes: true });
7352
+ entries = fs6.readdirSync(dir, { withFileTypes: true });
7263
7353
  } catch {
7264
7354
  return;
7265
7355
  }
@@ -7268,16 +7358,16 @@ var FileWatcherService = class {
7268
7358
  );
7269
7359
  if (gitignoreEntry) {
7270
7360
  try {
7271
- const body = fs5.readFileSync(path5.join(dir, ".gitignore"), "utf8");
7272
- const rel = path5.relative(repoRoot, dir).replace(/\\/g, "/");
7361
+ const body = fs6.readFileSync(path6.join(dir, ".gitignore"), "utf8");
7362
+ const rel = path6.relative(repoRoot, dir).replace(/\\/g, "/");
7273
7363
  const prefixed = body.split(/\r?\n/).map((line) => {
7274
7364
  const trimmed = line.trim();
7275
7365
  if (!trimmed || trimmed.startsWith("#")) return line;
7276
7366
  if (!rel) return line;
7277
7367
  if (trimmed.startsWith("!")) {
7278
- return "!" + path5.posix.join(rel, trimmed.slice(1));
7368
+ return "!" + path6.posix.join(rel, trimmed.slice(1));
7279
7369
  }
7280
- return path5.posix.join(rel, trimmed);
7370
+ return path6.posix.join(rel, trimmed);
7281
7371
  }).join("\n");
7282
7372
  matcher.add(prefixed);
7283
7373
  } catch {
@@ -7286,7 +7376,7 @@ var FileWatcherService = class {
7286
7376
  for (const entry of entries) {
7287
7377
  if (!entry.isDirectory()) continue;
7288
7378
  if (entry.name === ".git") continue;
7289
- const childAbs = path5.join(dir, entry.name);
7379
+ const childAbs = path6.join(dir, entry.name);
7290
7380
  if (isIgnoredFilePath(childAbs)) continue;
7291
7381
  this.collectGitignoreFiles(repoRoot, childAbs, matcher);
7292
7382
  }
@@ -7917,9 +8007,9 @@ function closeAllTerminals() {
7917
8007
  }
7918
8008
 
7919
8009
  // src/commands/start/handlers.ts
7920
- var fs44 = __toESM(require("fs"));
7921
- var os37 = __toESM(require("os"));
7922
- var path49 = __toESM(require("path"));
8010
+ var fs45 = __toESM(require("fs"));
8011
+ var os38 = __toESM(require("os"));
8012
+ var path50 = __toESM(require("path"));
7923
8013
  var import_crypto3 = require("crypto");
7924
8014
  var import_child_process22 = require("child_process");
7925
8015
  var import_which2 = __toESM(require("which"));
@@ -8072,8 +8162,8 @@ function parsePayload2(schema, raw) {
8072
8162
  }
8073
8163
 
8074
8164
  // src/services/file-ops.service.ts
8075
- var fs6 = __toESM(require("fs/promises"));
8076
- var path7 = __toESM(require("path"));
8165
+ var fs7 = __toESM(require("fs/promises"));
8166
+ var path8 = __toESM(require("path"));
8077
8167
  var MAX_FILE_BYTES = 5 * 1024 * 1024;
8078
8168
  var MAX_WALK_DEPTH = 6;
8079
8169
  var MAX_VISITED_DIRS = 5e3;
@@ -8108,12 +8198,12 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
8108
8198
  "__pycache__"
8109
8199
  ]);
8110
8200
  function isUnder(parent, candidate) {
8111
- const rel = path7.relative(parent, candidate);
8112
- return rel === "" || !rel.startsWith("..") && !path7.isAbsolute(rel);
8201
+ const rel = path8.relative(parent, candidate);
8202
+ return rel === "" || !rel.startsWith("..") && !path8.isAbsolute(rel);
8113
8203
  }
8114
8204
  async function isExistingFile(absPath) {
8115
8205
  try {
8116
- const stat3 = await fs6.stat(absPath);
8206
+ const stat3 = await fs7.stat(absPath);
8117
8207
  return stat3.isFile();
8118
8208
  } catch {
8119
8209
  return false;
@@ -8126,13 +8216,13 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
8126
8216
  ctx.visited++;
8127
8217
  let entries = [];
8128
8218
  try {
8129
- entries = await fs6.readdir(dir, { withFileTypes: true });
8219
+ entries = await fs7.readdir(dir, { withFileTypes: true });
8130
8220
  } catch {
8131
8221
  return;
8132
8222
  }
8133
8223
  for (const e of entries) {
8134
8224
  if (!e.isFile()) continue;
8135
- const full = path7.join(dir, e.name);
8225
+ const full = path8.join(dir, e.name);
8136
8226
  if (needleVariants.some((needle) => full.endsWith(needle))) {
8137
8227
  ctx.matches.push(full);
8138
8228
  if (ctx.matches.length >= ctx.cap) return;
@@ -8142,21 +8232,21 @@ async function walkForSuffix(dir, needleVariants, depth, ctx) {
8142
8232
  if (!e.isDirectory()) continue;
8143
8233
  if (SUBDIR_IGNORE.has(e.name)) continue;
8144
8234
  if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
8145
- await walkForSuffix(path7.join(dir, e.name), needleVariants, depth + 1, ctx);
8235
+ await walkForSuffix(path8.join(dir, e.name), needleVariants, depth + 1, ctx);
8146
8236
  if (ctx.matches.length >= ctx.cap) return;
8147
8237
  }
8148
8238
  }
8149
8239
  async function findFile(rawPath) {
8150
8240
  const cwd = process.cwd();
8151
- if (path7.isAbsolute(rawPath)) {
8152
- const abs = path7.normalize(rawPath);
8241
+ if (path8.isAbsolute(rawPath)) {
8242
+ const abs = path8.normalize(rawPath);
8153
8243
  if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
8154
8244
  }
8155
- const direct = path7.resolve(cwd, rawPath);
8245
+ const direct = path8.resolve(cwd, rawPath);
8156
8246
  if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
8157
- const normalized = path7.normalize(rawPath).replace(/^[./\\]+/, "");
8247
+ const normalized = path8.normalize(rawPath).replace(/^[./\\]+/, "");
8158
8248
  const needles = [
8159
- `${path7.sep}${normalized}`,
8249
+ `${path8.sep}${normalized}`,
8160
8250
  `/${normalized}`
8161
8251
  ].filter((v, i, a) => a.indexOf(v) === i);
8162
8252
  const ctx = { visited: 0, matches: [], cap: 16 };
@@ -8170,7 +8260,7 @@ async function findWriteTarget(rawPath) {
8170
8260
  const found = await findFile(rawPath);
8171
8261
  if (found) return found;
8172
8262
  const cwd = process.cwd();
8173
- const fallback = path7.isAbsolute(rawPath) ? path7.normalize(rawPath) : path7.resolve(cwd, rawPath);
8263
+ const fallback = path8.isAbsolute(rawPath) ? path8.normalize(rawPath) : path8.resolve(cwd, rawPath);
8174
8264
  if (!isUnder(cwd, fallback)) return null;
8175
8265
  return fallback;
8176
8266
  }
@@ -8187,11 +8277,11 @@ async function readProjectFile(rawPath) {
8187
8277
  if (!abs) {
8188
8278
  return { error: `File not found in the project tree: ${rawPath}` };
8189
8279
  }
8190
- const stat3 = await fs6.stat(abs);
8280
+ const stat3 = await fs7.stat(abs);
8191
8281
  if (stat3.size > MAX_FILE_BYTES) {
8192
8282
  return { error: `File too large (${(stat3.size / 1024 / 1024).toFixed(1)} MB > ${MAX_FILE_BYTES / 1024 / 1024} MB).` };
8193
8283
  }
8194
- const buf = await fs6.readFile(abs);
8284
+ const buf = await fs7.readFile(abs);
8195
8285
  if (looksBinary(buf)) {
8196
8286
  return { error: "Binary file \u2014 refusing to open in a code editor." };
8197
8287
  }
@@ -8210,8 +8300,8 @@ async function writeProjectFile(rawPath, content) {
8210
8300
  if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
8211
8301
  return { error: "Content too large." };
8212
8302
  }
8213
- await fs6.mkdir(path7.dirname(abs), { recursive: true });
8214
- await fs6.writeFile(abs, content, "utf-8");
8303
+ await fs7.mkdir(path8.dirname(abs), { recursive: true });
8304
+ await fs7.writeFile(abs, content, "utf-8");
8215
8305
  return { ok: true };
8216
8306
  } catch (e) {
8217
8307
  const msg = e instanceof Error ? e.message : "Write failed";
@@ -8222,8 +8312,8 @@ async function writeProjectFile(rawPath, content) {
8222
8312
  // src/services/project-ops.service.ts
8223
8313
  var import_child_process5 = require("child_process");
8224
8314
  var import_util = require("util");
8225
- var fs7 = __toESM(require("fs/promises"));
8226
- var path8 = __toESM(require("path"));
8315
+ var fs8 = __toESM(require("fs/promises"));
8316
+ var path9 = __toESM(require("path"));
8227
8317
  var execFileP = (0, import_util.promisify)(import_child_process5.execFile);
8228
8318
  var PROJECT_IGNORE = /* @__PURE__ */ new Set([
8229
8319
  "node_modules",
@@ -8271,7 +8361,7 @@ async function listProjectFiles(opts = {}) {
8271
8361
  }
8272
8362
  let entries = [];
8273
8363
  try {
8274
- entries = await fs7.readdir(dir, { withFileTypes: true });
8364
+ entries = await fs8.readdir(dir, { withFileTypes: true });
8275
8365
  } catch {
8276
8366
  return;
8277
8367
  }
@@ -8281,18 +8371,18 @@ async function listProjectFiles(opts = {}) {
8281
8371
  return;
8282
8372
  }
8283
8373
  if (PROJECT_IGNORE.has(e.name)) continue;
8284
- const full = path8.join(dir, e.name);
8374
+ const full = path9.join(dir, e.name);
8285
8375
  if (e.isDirectory()) {
8286
8376
  if (depth >= 12) continue;
8287
8377
  await walk(full, depth + 1);
8288
8378
  } else if (e.isFile()) {
8289
- const rel = path8.relative(root, full);
8379
+ const rel = path9.relative(root, full);
8290
8380
  if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
8291
8381
  continue;
8292
8382
  }
8293
8383
  let size = 0;
8294
8384
  try {
8295
- const st3 = await fs7.stat(full);
8385
+ const st3 = await fs8.stat(full);
8296
8386
  size = st3.size;
8297
8387
  } catch {
8298
8388
  }
@@ -8394,8 +8484,8 @@ async function gitStatus(cwd) {
8394
8484
  let hasMergeInProgress = false;
8395
8485
  try {
8396
8486
  const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
8397
- const mergeHead = path8.isAbsolute(gitDir) ? path8.join(gitDir, "MERGE_HEAD") : path8.join(root, gitDir, "MERGE_HEAD");
8398
- await fs7.access(mergeHead);
8487
+ const mergeHead = path9.isAbsolute(gitDir) ? path9.join(gitDir, "MERGE_HEAD") : path9.join(root, gitDir, "MERGE_HEAD");
8488
+ await fs8.access(mergeHead);
8399
8489
  hasMergeInProgress = true;
8400
8490
  } catch {
8401
8491
  }
@@ -8541,7 +8631,7 @@ async function jsSearchFiles(opts, cwd, cap) {
8541
8631
  }
8542
8632
  let content = "";
8543
8633
  try {
8544
- content = await fs7.readFile(path8.join(cwd, f.path), "utf8");
8634
+ content = await fs8.readFile(path9.join(cwd, f.path), "utf8");
8545
8635
  } catch {
8546
8636
  continue;
8547
8637
  }
@@ -8618,14 +8708,14 @@ function formatRemaining(expiresAt) {
8618
8708
 
8619
8709
  // src/services/apply-file-review.service.ts
8620
8710
  var import_child_process6 = require("child_process");
8621
- var fs8 = __toESM(require("fs"));
8622
- var path9 = __toESM(require("path"));
8711
+ var fs9 = __toESM(require("fs"));
8712
+ var path10 = __toESM(require("path"));
8623
8713
  async function applyFileReview(workingDir, filePath, action) {
8624
- if (filePath.includes("..") || path9.isAbsolute(filePath)) {
8714
+ if (filePath.includes("..") || path10.isAbsolute(filePath)) {
8625
8715
  return { ok: false, action, filePath, error: "invalid file path" };
8626
8716
  }
8627
- const absFile = path9.resolve(workingDir, filePath);
8628
- const repoRoot = findGitRoot2(path9.dirname(absFile));
8717
+ const absFile = path10.resolve(workingDir, filePath);
8718
+ const repoRoot = findGitRoot2(path10.dirname(absFile));
8629
8719
  if (!repoRoot) {
8630
8720
  return {
8631
8721
  ok: false,
@@ -8634,7 +8724,7 @@ async function applyFileReview(workingDir, filePath, action) {
8634
8724
  error: `no enclosing git repo for ${filePath}`
8635
8725
  };
8636
8726
  }
8637
- const relInRepo = path9.relative(repoRoot, absFile);
8727
+ const relInRepo = path10.relative(repoRoot, absFile);
8638
8728
  if (!relInRepo || relInRepo.startsWith("..")) {
8639
8729
  return { ok: false, action, filePath, error: "path escapes repo root" };
8640
8730
  }
@@ -8683,17 +8773,17 @@ function runGit2(cwd, args2) {
8683
8773
  });
8684
8774
  }
8685
8775
  function findGitRoot2(startDir) {
8686
- let dir = path9.resolve(startDir);
8776
+ let dir = path10.resolve(startDir);
8687
8777
  const seen = /* @__PURE__ */ new Set();
8688
8778
  for (let i = 0; i < 256; i++) {
8689
8779
  if (seen.has(dir)) return null;
8690
8780
  seen.add(dir);
8691
8781
  try {
8692
- const stat3 = fs8.statSync(path9.join(dir, ".git"), { throwIfNoEntry: false });
8782
+ const stat3 = fs9.statSync(path10.join(dir, ".git"), { throwIfNoEntry: false });
8693
8783
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
8694
8784
  } catch {
8695
8785
  }
8696
- const parent = path9.dirname(dir);
8786
+ const parent = path10.dirname(dir);
8697
8787
  if (parent === dir) return null;
8698
8788
  dir = parent;
8699
8789
  }
@@ -8702,8 +8792,8 @@ function findGitRoot2(startDir) {
8702
8792
 
8703
8793
  // src/commands/link.ts
8704
8794
  var import_node_crypto5 = require("crypto");
8705
- var fs26 = __toESM(require("fs"));
8706
- var path31 = __toESM(require("path"));
8795
+ var fs27 = __toESM(require("fs"));
8796
+ var path32 = __toESM(require("path"));
8707
8797
  var import_chokidar = __toESM(require("chokidar"));
8708
8798
  var import_picocolors2 = __toESM(require("picocolors"));
8709
8799
 
@@ -10758,19 +10848,19 @@ function parseFrame(frame, dispatch) {
10758
10848
  }
10759
10849
 
10760
10850
  // src/os/posix.ts
10761
- var fs10 = __toESM(require("fs"));
10762
- var os8 = __toESM(require("os"));
10763
- var path12 = __toESM(require("path"));
10851
+ var fs11 = __toESM(require("fs"));
10852
+ var os9 = __toESM(require("os"));
10853
+ var path13 = __toESM(require("path"));
10764
10854
  var import_node_crypto2 = require("crypto");
10765
10855
 
10766
10856
  // src/os/strategy.ts
10767
- var path10 = __toESM(require("path"));
10857
+ var path11 = __toESM(require("path"));
10768
10858
  function findInPathFor(name, opts) {
10769
- const dirs = (process.env.PATH ?? "").split(path10.delimiter).filter(Boolean);
10859
+ const dirs = (process.env.PATH ?? "").split(path11.delimiter).filter(Boolean);
10770
10860
  const candidates = opts.candidates(name);
10771
10861
  for (const dir of dirs) {
10772
10862
  for (const candidate of candidates) {
10773
- const full = path10.join(dir, candidate);
10863
+ const full = path11.join(dir, candidate);
10774
10864
  try {
10775
10865
  opts.accessSync(full, opts.accessFlag);
10776
10866
  return full;
@@ -10783,9 +10873,9 @@ function findInPathFor(name, opts) {
10783
10873
 
10784
10874
  // src/services/pty/unix.strategy.ts
10785
10875
  var import_child_process7 = require("child_process");
10786
- var fs9 = __toESM(require("fs"));
10787
- var os7 = __toESM(require("os"));
10788
- var path11 = __toESM(require("path"));
10876
+ var fs10 = __toESM(require("fs"));
10877
+ var os8 = __toESM(require("os"));
10878
+ var path12 = __toESM(require("path"));
10789
10879
 
10790
10880
  // src/services/pty/types.ts
10791
10881
  function findInPath(name) {
@@ -10867,8 +10957,8 @@ var UnixPtyStrategy = class {
10867
10957
  }
10868
10958
  const cols = process.stdout.columns || 220;
10869
10959
  const rows = process.stdout.rows || 50;
10870
- this.helperPath = path11.join(os7.tmpdir(), "codeam-pty-helper.py");
10871
- fs9.writeFileSync(this.helperPath, PYTHON_PTY_HELPER, { mode: 420 });
10960
+ this.helperPath = path12.join(os8.tmpdir(), "codeam-pty-helper.py");
10961
+ fs10.writeFileSync(this.helperPath, PYTHON_PTY_HELPER, { mode: 420 });
10872
10962
  this.proc = (0, import_child_process7.spawn)(python, [this.helperPath, cmd, ...args2], {
10873
10963
  stdio: ["pipe", "pipe", "inherit"],
10874
10964
  cwd,
@@ -10997,7 +11087,7 @@ var UnixPtyStrategy = class {
10997
11087
  removeTempFile() {
10998
11088
  if (this.helperPath) {
10999
11089
  try {
11000
- fs9.unlinkSync(this.helperPath);
11090
+ fs10.unlinkSync(this.helperPath);
11001
11091
  } catch {
11002
11092
  }
11003
11093
  this.helperPath = null;
@@ -11008,11 +11098,11 @@ var UnixPtyStrategy = class {
11008
11098
  // src/os/posix.ts
11009
11099
  var PosixOsStrategy = class {
11010
11100
  homeDir() {
11011
- return os8.homedir();
11101
+ return os9.homedir();
11012
11102
  }
11013
11103
  scratchPath(prefix) {
11014
11104
  const tag = `${process.pid}-${(0, import_node_crypto2.randomBytes)(4).toString("hex")}`;
11015
- return path12.join(os8.tmpdir(), `${prefix}-${tag}`);
11105
+ return path13.join(os9.tmpdir(), `${prefix}-${tag}`);
11016
11106
  }
11017
11107
  devNull() {
11018
11108
  return "/dev/null";
@@ -11020,8 +11110,8 @@ var PosixOsStrategy = class {
11020
11110
  findInPath(name) {
11021
11111
  return findInPathFor(name, {
11022
11112
  candidates: () => [name],
11023
- accessFlag: fs10.constants.X_OK,
11024
- accessSync: fs10.accessSync
11113
+ accessFlag: fs11.constants.X_OK,
11114
+ accessSync: fs11.accessSync
11025
11115
  });
11026
11116
  }
11027
11117
  augmentPath(dirs) {
@@ -11049,15 +11139,15 @@ var LinuxOsStrategy = class extends PosixOsStrategy {
11049
11139
  };
11050
11140
 
11051
11141
  // src/os/win32.ts
11052
- var fs11 = __toESM(require("fs"));
11053
- var os9 = __toESM(require("os"));
11054
- var path14 = __toESM(require("path"));
11142
+ var fs12 = __toESM(require("fs"));
11143
+ var os10 = __toESM(require("os"));
11144
+ var path15 = __toESM(require("path"));
11055
11145
  var import_node_crypto3 = require("crypto");
11056
11146
 
11057
11147
  // src/services/pty/windows-conpty.strategy.ts
11058
- var path13 = __toESM(require("path"));
11148
+ var path14 = __toESM(require("path"));
11059
11149
  function loadNodePty2() {
11060
- const vendoredPath = path13.join(__dirname, "vendor", "node-pty");
11150
+ const vendoredPath = path14.join(__dirname, "vendor", "node-pty");
11061
11151
  try {
11062
11152
  return require(vendoredPath);
11063
11153
  } catch (vendorErr) {
@@ -11243,25 +11333,25 @@ var WINDOWS_EXEC_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
11243
11333
  var Win32OsStrategy = class {
11244
11334
  id = "win32";
11245
11335
  homeDir() {
11246
- return os9.homedir();
11336
+ return os10.homedir();
11247
11337
  }
11248
11338
  scratchPath(prefix) {
11249
11339
  const tag = `${process.pid}-${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`;
11250
- return path14.join(os9.tmpdir(), `${prefix}-${tag}`);
11340
+ return path15.join(os10.tmpdir(), `${prefix}-${tag}`);
11251
11341
  }
11252
11342
  devNull() {
11253
11343
  return "NUL";
11254
11344
  }
11255
11345
  findInPath(name) {
11256
- const hasExt = path14.extname(name).length > 0;
11346
+ const hasExt = path15.extname(name).length > 0;
11257
11347
  return findInPathFor(name, {
11258
11348
  candidates: (n) => hasExt ? [n] : [...WINDOWS_EXEC_EXTS.map((ext) => `${n}${ext}`), n],
11259
11349
  // Windows has no Unix execute bit; presence + matching extension
11260
11350
  // IS the executability check. X_OK on Windows is a no-op alias
11261
11351
  // for F_OK at the libuv layer anyway, but F_OK makes intent
11262
11352
  // explicit.
11263
- accessFlag: fs11.constants.F_OK,
11264
- accessSync: fs11.accessSync
11353
+ accessFlag: fs12.constants.F_OK,
11354
+ accessSync: fs12.accessSync
11265
11355
  });
11266
11356
  }
11267
11357
  augmentPath(dirs) {
@@ -11298,7 +11388,7 @@ var Win32OsStrategy = class {
11298
11388
  return `"${escaped.replace(/[&|^<>()%!]/g, "^$&")}"`;
11299
11389
  }
11300
11390
  buildLaunch(binaryPath, extraArgs = []) {
11301
- const ext = path14.extname(binaryPath).toLowerCase();
11391
+ const ext = path15.extname(binaryPath).toLowerCase();
11302
11392
  if (ext === ".cmd" || ext === ".bat") {
11303
11393
  return { cmd: "cmd.exe", args: ["/c", binaryPath, ...extraArgs] };
11304
11394
  }
@@ -11353,28 +11443,28 @@ function buildForPlatform(platform3) {
11353
11443
  var import_node_crypto4 = require("crypto");
11354
11444
 
11355
11445
  // src/agents/claude/resolver.ts
11356
- function buildClaudeLaunch(extraArgs = [], os44 = createOsStrategy()) {
11357
- const found = os44.findInPath("claude") ?? os44.findInPath("claude-code");
11446
+ function buildClaudeLaunch(extraArgs = [], os45 = createOsStrategy()) {
11447
+ const found = os45.findInPath("claude") ?? os45.findInPath("claude-code");
11358
11448
  if (!found) return null;
11359
- return os44.buildLaunch(found, extraArgs);
11449
+ return os45.buildLaunch(found, extraArgs);
11360
11450
  }
11361
11451
 
11362
11452
  // src/agents/claude/installer.ts
11363
11453
  var import_child_process9 = require("child_process");
11364
- var path15 = __toESM(require("path"));
11365
- var os10 = __toESM(require("os"));
11454
+ var path16 = __toESM(require("path"));
11455
+ var os11 = __toESM(require("os"));
11366
11456
  function probeInstallDirs() {
11367
- const home = os10.homedir();
11457
+ const home = os11.homedir();
11368
11458
  if (process.platform === "win32") {
11369
11459
  return [
11370
- path15.join(home, ".claude", "local"),
11371
- path15.join(home, "AppData", "Local", "AnthropicClaude"),
11372
- path15.join(home, "AppData", "Local", "Programs", "AnthropicClaude")
11460
+ path16.join(home, ".claude", "local"),
11461
+ path16.join(home, "AppData", "Local", "AnthropicClaude"),
11462
+ path16.join(home, "AppData", "Local", "Programs", "AnthropicClaude")
11373
11463
  ];
11374
11464
  }
11375
11465
  return [
11376
- path15.join(home, ".local", "bin"),
11377
- path15.join(home, ".claude", "local"),
11466
+ path16.join(home, ".local", "bin"),
11467
+ path16.join(home, ".claude", "local"),
11378
11468
  "/usr/local/bin"
11379
11469
  ];
11380
11470
  }
@@ -11383,7 +11473,7 @@ function isAvailable() {
11383
11473
  }
11384
11474
  function augmentPath() {
11385
11475
  const dirs = probeInstallDirs();
11386
- const sep7 = path15.delimiter;
11476
+ const sep7 = path16.delimiter;
11387
11477
  const current = process.env.PATH ?? "";
11388
11478
  const existing = new Set(current.split(sep7).filter(Boolean));
11389
11479
  const additions = dirs.filter((d3) => !existing.has(d3));
@@ -11441,15 +11531,15 @@ async function ensureClaudeInstalled() {
11441
11531
  }
11442
11532
 
11443
11533
  // src/agents/claude/link.ts
11444
- var import_node_child_process2 = require("child_process");
11534
+ var import_node_child_process3 = require("child_process");
11445
11535
 
11446
11536
  // src/agents/claude/local-token.ts
11447
- var import_node_child_process = require("child_process");
11448
- var fs12 = __toESM(require("fs"));
11449
- var os11 = __toESM(require("os"));
11450
- var path16 = __toESM(require("path"));
11537
+ var import_node_child_process2 = require("child_process");
11538
+ var fs13 = __toESM(require("fs"));
11539
+ var os12 = __toESM(require("os"));
11540
+ var path17 = __toESM(require("path"));
11451
11541
  var import_node_util3 = require("util");
11452
- var execFileP2 = (0, import_node_util3.promisify)(import_node_child_process.execFile);
11542
+ var execFileP2 = (0, import_node_util3.promisify)(import_node_child_process2.execFile);
11453
11543
  var KEYCHAIN_SERVICE_NAMES = [
11454
11544
  "Claude Code-credentials",
11455
11545
  "claude-code-credentials",
@@ -11457,17 +11547,17 @@ var KEYCHAIN_SERVICE_NAMES = [
11457
11547
  "Anthropic Claude"
11458
11548
  ];
11459
11549
  function claudeCredentialsPaths() {
11460
- const home = os11.homedir();
11550
+ const home = os12.homedir();
11461
11551
  return [
11462
- path16.join(home, ".claude", ".credentials.json"),
11463
- path16.join(home, ".config", "claude", ".credentials.json")
11552
+ path17.join(home, ".claude", ".credentials.json"),
11553
+ path17.join(home, ".config", "claude", ".credentials.json")
11464
11554
  ];
11465
11555
  }
11466
11556
  async function extractLocalClaudeToken() {
11467
11557
  const agentState = readClaudeAgentState();
11468
11558
  for (const flat of claudeCredentialsPaths()) {
11469
- if (!fs12.existsSync(flat)) continue;
11470
- const credential = fs12.readFileSync(flat, "utf8").trim();
11559
+ if (!fs13.existsSync(flat)) continue;
11560
+ const credential = fs13.readFileSync(flat, "utf8").trim();
11471
11561
  if (credential.length > 0) {
11472
11562
  return { method: "oauth", credential, source: "flat-file", agentState };
11473
11563
  }
@@ -11492,10 +11582,10 @@ async function extractLocalClaudeToken() {
11492
11582
  }
11493
11583
  function readClaudeAgentState() {
11494
11584
  const STATE_MAX_BYTES = 256 * 1024;
11495
- const candidate = path16.join(os11.homedir(), ".claude.json");
11585
+ const candidate = path17.join(os12.homedir(), ".claude.json");
11496
11586
  try {
11497
- if (!fs12.existsSync(candidate)) return void 0;
11498
- const buf = fs12.readFileSync(candidate);
11587
+ if (!fs13.existsSync(candidate)) return void 0;
11588
+ const buf = fs13.readFileSync(candidate);
11499
11589
  if (buf.length === 0 || buf.length > STATE_MAX_BYTES) return void 0;
11500
11590
  const text = buf.toString("utf8").trim();
11501
11591
  return text.length > 0 ? text : void 0;
@@ -11542,7 +11632,7 @@ function extractSetupTokenFromOutput(output) {
11542
11632
  }
11543
11633
  function captureClaudeSetupToken() {
11544
11634
  return new Promise((resolve7, reject) => {
11545
- const child = (0, import_node_child_process2.spawn)("claude", ["setup-token"], {
11635
+ const child = (0, import_node_child_process3.spawn)("claude", ["setup-token"], {
11546
11636
  stdio: ["inherit", "pipe", "inherit"]
11547
11637
  });
11548
11638
  let out2 = "";
@@ -11570,7 +11660,7 @@ function claudeLoginLauncher() {
11570
11660
  return {
11571
11661
  ensureInstalled: ensureClaudeInstalled,
11572
11662
  launch() {
11573
- const child = (0, import_node_child_process2.spawn)("claude", [], { stdio: ["pipe", "inherit", "inherit"] });
11663
+ const child = (0, import_node_child_process3.spawn)("claude", [], { stdio: ["pipe", "inherit", "inherit"] });
11574
11664
  child.stdin?.write("/login\n");
11575
11665
  return child;
11576
11666
  },
@@ -11582,9 +11672,9 @@ function claudeLoginLauncher() {
11582
11672
  }
11583
11673
 
11584
11674
  // src/agents/claude/quota.ts
11585
- var fs13 = __toESM(require("fs"));
11586
- var os12 = __toESM(require("os"));
11587
- var path17 = __toESM(require("path"));
11675
+ var fs14 = __toESM(require("fs"));
11676
+ var os13 = __toESM(require("os"));
11677
+ var path18 = __toESM(require("path"));
11588
11678
  var import_child_process10 = require("child_process");
11589
11679
  var HELPER_SCRIPT = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
11590
11680
  m,s=pty.openpty()
@@ -11647,8 +11737,8 @@ async function fetchClaudeQuota() {
11647
11737
  resolve7(null);
11648
11738
  return;
11649
11739
  }
11650
- const helperPath = path17.join(os12.tmpdir(), "codeam-quota-helper.py");
11651
- fs13.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
11740
+ const helperPath = path18.join(os13.tmpdir(), "codeam-quota-helper.py");
11741
+ fs14.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
11652
11742
  const python = findInPath("python3") ?? findInPath("python");
11653
11743
  if (!python) {
11654
11744
  resolve7(null);
@@ -11675,7 +11765,7 @@ async function fetchClaudeQuota() {
11675
11765
  } catch {
11676
11766
  }
11677
11767
  try {
11678
- fs13.unlinkSync(helperPath);
11768
+ fs14.unlinkSync(helperPath);
11679
11769
  } catch {
11680
11770
  }
11681
11771
  resolve7(result);
@@ -11768,24 +11858,24 @@ async function spawnAndCapture(cmd, args2, opts = {}) {
11768
11858
  }
11769
11859
 
11770
11860
  // src/agents/claude/history.ts
11771
- var fs14 = __toESM(require("fs"));
11772
- var path18 = __toESM(require("path"));
11773
- var os13 = __toESM(require("os"));
11861
+ var fs15 = __toESM(require("fs"));
11862
+ var path19 = __toESM(require("path"));
11863
+ var os14 = __toESM(require("os"));
11774
11864
  function encodeCwd(cwd) {
11775
11865
  return cwd.replace(/[\\/:]/g, "-");
11776
11866
  }
11777
11867
  function resolveHistoryDir(cwd, projectsRoot) {
11778
- const root = projectsRoot ?? path18.join(os13.homedir(), ".claude", "projects");
11779
- const primary = path18.join(root, encodeCwd(cwd));
11780
- if (fs14.existsSync(primary)) return primary;
11868
+ const root = projectsRoot ?? path19.join(os14.homedir(), ".claude", "projects");
11869
+ const primary = path19.join(root, encodeCwd(cwd));
11870
+ if (fs15.existsSync(primary)) return primary;
11781
11871
  try {
11782
- const entries = fs14.readdirSync(root, { withFileTypes: true });
11872
+ const entries = fs15.readdirSync(root, { withFileTypes: true });
11783
11873
  const wanted = encodeCwd(cwd);
11784
11874
  for (const e of entries) {
11785
11875
  if (!e.isDirectory()) continue;
11786
11876
  const candidate = e.name.replace(/-+/g, "-");
11787
11877
  if (candidate === wanted.replace(/-+/g, "-")) {
11788
- return path18.join(root, e.name);
11878
+ return path19.join(root, e.name);
11789
11879
  }
11790
11880
  }
11791
11881
  } catch {
@@ -11797,23 +11887,23 @@ function getCurrentUsage(historyDir, bootTimeMs = 0) {
11797
11887
  const cutoff = bootTimeMs > 0 ? bootTimeMs - GRACE_MS : 0;
11798
11888
  let entries;
11799
11889
  try {
11800
- entries = fs14.readdirSync(historyDir, { withFileTypes: true });
11890
+ entries = fs15.readdirSync(historyDir, { withFileTypes: true });
11801
11891
  } catch {
11802
11892
  return null;
11803
11893
  }
11804
11894
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
11805
11895
  try {
11806
- const stat3 = fs14.statSync(path18.join(historyDir, e.name));
11896
+ const stat3 = fs15.statSync(path19.join(historyDir, e.name));
11807
11897
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
11808
11898
  } catch {
11809
11899
  return { name: e.name, mtime: 0, birthtime: 0 };
11810
11900
  }
11811
11901
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
11812
11902
  if (files.length === 0) return null;
11813
- const filePath = path18.join(historyDir, files[0].name);
11903
+ const filePath = path19.join(historyDir, files[0].name);
11814
11904
  let raw;
11815
11905
  try {
11816
- raw = fs14.readFileSync(filePath, "utf8");
11906
+ raw = fs15.readFileSync(filePath, "utf8");
11817
11907
  } catch {
11818
11908
  return null;
11819
11909
  }
@@ -11858,7 +11948,7 @@ function parseHistoryFile(filePath) {
11858
11948
  const out2 = [];
11859
11949
  let raw;
11860
11950
  try {
11861
- raw = fs14.readFileSync(filePath, "utf8");
11951
+ raw = fs15.readFileSync(filePath, "utf8");
11862
11952
  } catch {
11863
11953
  return out2;
11864
11954
  }
@@ -11903,7 +11993,7 @@ function listResumableSessions(cwd) {
11903
11993
  if (!dir) return [];
11904
11994
  let entries;
11905
11995
  try {
11906
- entries = fs14.readdirSync(dir, { withFileTypes: true });
11996
+ entries = fs15.readdirSync(dir, { withFileTypes: true });
11907
11997
  } catch {
11908
11998
  return [];
11909
11999
  }
@@ -11911,15 +12001,15 @@ function listResumableSessions(cwd) {
11911
12001
  for (const entry of entries) {
11912
12002
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
11913
12003
  const id = entry.name.slice(0, -".jsonl".length);
11914
- const filePath = path18.join(dir, entry.name);
12004
+ const filePath = path19.join(dir, entry.name);
11915
12005
  let timestamp = Date.now();
11916
12006
  try {
11917
- timestamp = fs14.statSync(filePath).mtimeMs;
12007
+ timestamp = fs15.statSync(filePath).mtimeMs;
11918
12008
  } catch {
11919
12009
  }
11920
12010
  let summary = "";
11921
12011
  try {
11922
- const raw = fs14.readFileSync(filePath, "utf8");
12012
+ const raw = fs15.readFileSync(filePath, "utf8");
11923
12013
  for (const line of raw.split("\n")) {
11924
12014
  if (!line.trim()) continue;
11925
12015
  try {
@@ -11949,8 +12039,8 @@ var ClaudeRuntimeStrategy = class {
11949
12039
  meta = getAgent("claude");
11950
12040
  mode = "interactive";
11951
12041
  os;
11952
- constructor(os44) {
11953
- this.os = os44;
12042
+ constructor(os45) {
12043
+ this.os = os45;
11954
12044
  }
11955
12045
  /**
11956
12046
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -12082,24 +12172,24 @@ var ClaudeRuntimeStrategy = class {
12082
12172
  };
12083
12173
 
12084
12174
  // src/agents/claude/deploy.ts
12085
- var fs16 = __toESM(require("fs"));
12086
- var os15 = __toESM(require("os"));
12087
- var path20 = __toESM(require("path"));
12175
+ var fs17 = __toESM(require("fs"));
12176
+ var os16 = __toESM(require("os"));
12177
+ var path21 = __toESM(require("path"));
12088
12178
 
12089
12179
  // src/agents/claude/credentials.ts
12090
12180
  var import_child_process12 = require("child_process");
12091
- var fs15 = __toESM(require("fs"));
12092
- var os14 = __toESM(require("os"));
12093
- var path19 = __toESM(require("path"));
12181
+ var fs16 = __toESM(require("fs"));
12182
+ var os15 = __toESM(require("os"));
12183
+ var path20 = __toESM(require("path"));
12094
12184
  var import_util2 = require("util");
12095
12185
  var execFileP3 = (0, import_util2.promisify)(import_child_process12.execFile);
12096
12186
  async function detectLocalClaudeCredentials() {
12097
- const localClaudeDir = path19.join(os14.homedir(), ".claude");
12098
- const flat = path19.join(localClaudeDir, ".credentials.json");
12099
- if (fs15.existsSync(flat)) {
12187
+ const localClaudeDir = path20.join(os15.homedir(), ".claude");
12188
+ const flat = path20.join(localClaudeDir, ".credentials.json");
12189
+ if (fs16.existsSync(flat)) {
12100
12190
  return { source: "flat-file", description: "~/.claude/.credentials.json" };
12101
12191
  }
12102
- if (os14.platform() === "darwin") {
12192
+ if (os15.platform() === "darwin") {
12103
12193
  try {
12104
12194
  await execFileP3(
12105
12195
  "security",
@@ -12114,9 +12204,9 @@ async function detectLocalClaudeCredentials() {
12114
12204
  return { source: "none", description: "" };
12115
12205
  }
12116
12206
  async function bridgeClaudeCredentials(provider, workspaceId) {
12117
- const localClaudeDir = path19.join(os14.homedir(), ".claude");
12118
- const fileBased = path19.join(localClaudeDir, ".credentials.json");
12119
- if (fs15.existsSync(fileBased)) {
12207
+ const localClaudeDir = path20.join(os15.homedir(), ".claude");
12208
+ const fileBased = path20.join(localClaudeDir, ".credentials.json");
12209
+ if (fs16.existsSync(fileBased)) {
12120
12210
  return { source: "flat-file", description: "~/.claude/.credentials.json" };
12121
12211
  }
12122
12212
  if (process.platform === "darwin") {
@@ -12208,8 +12298,8 @@ var ClaudeDeployStrategy = class {
12208
12298
  process.exit(1);
12209
12299
  }
12210
12300
  claudeStep.stop("\u2713 Claude CLI installed");
12211
- const localClaudeDir = path20.join(os15.homedir(), ".claude");
12212
- const haveLocalClaude = fs16.existsSync(localClaudeDir) && fs16.statSync(localClaudeDir).isDirectory();
12301
+ const localClaudeDir = path21.join(os16.homedir(), ".claude");
12302
+ const haveLocalClaude = fs17.existsSync(localClaudeDir) && fs17.statSync(localClaudeDir).isDirectory();
12213
12303
  if (haveLocalClaude) {
12214
12304
  const copyStep = fe();
12215
12305
  copyStep.start("Copying local Claude config to workspace\u2026");
@@ -12263,10 +12353,10 @@ var ClaudeDeployStrategy = class {
12263
12353
  }
12264
12354
  }
12265
12355
  if (opts.bridged !== "none") {
12266
- const localClaudeJson = path20.join(os15.homedir(), ".claude.json");
12267
- if (fs16.existsSync(localClaudeJson)) {
12356
+ const localClaudeJson = path21.join(os16.homedir(), ".claude.json");
12357
+ if (fs17.existsSync(localClaudeJson)) {
12268
12358
  try {
12269
- const contents = fs16.readFileSync(localClaudeJson);
12359
+ const contents = fs17.readFileSync(localClaudeJson);
12270
12360
  await provider.uploadFile(
12271
12361
  workspaceId,
12272
12362
  "/home/codespace/.claude.json",
@@ -12298,8 +12388,8 @@ var ClaudeDeployStrategy = class {
12298
12388
  };
12299
12389
 
12300
12390
  // src/agents/codex/runtime.ts
12301
- var import_node_child_process4 = require("child_process");
12302
- var path23 = __toESM(require("path"));
12391
+ var import_node_child_process5 = require("child_process");
12392
+ var path24 = __toESM(require("path"));
12303
12393
 
12304
12394
  // src/agents/codex/history.ts
12305
12395
  var import_node_fs3 = __toESM(require("fs"));
@@ -12556,19 +12646,19 @@ function getCurrentUsage2(historyDir) {
12556
12646
  }
12557
12647
 
12558
12648
  // src/agents/codex/link.ts
12559
- var import_node_child_process3 = require("child_process");
12649
+ var import_node_child_process4 = require("child_process");
12560
12650
 
12561
12651
  // src/agents/codex/local-token.ts
12562
- var fs18 = __toESM(require("fs"));
12563
- var os17 = __toESM(require("os"));
12564
- var path22 = __toESM(require("path"));
12652
+ var fs19 = __toESM(require("fs"));
12653
+ var os18 = __toESM(require("os"));
12654
+ var path23 = __toESM(require("path"));
12565
12655
  function codexCredentialsPath() {
12566
- return path22.join(os17.homedir(), ".codex", "auth.json");
12656
+ return path23.join(os18.homedir(), ".codex", "auth.json");
12567
12657
  }
12568
12658
  async function extractLocalCodexToken() {
12569
12659
  const file = codexCredentialsPath();
12570
- if (!fs18.existsSync(file)) return null;
12571
- const credential = fs18.readFileSync(file, "utf8").trim();
12660
+ if (!fs19.existsSync(file)) return null;
12661
+ const credential = fs19.readFileSync(file, "utf8").trim();
12572
12662
  if (credential.length === 0) return null;
12573
12663
  return { method: "oauth", credential, source: "flat-file" };
12574
12664
  }
@@ -12627,11 +12717,11 @@ function codexCredentialLocator() {
12627
12717
  function codexLoginLauncher() {
12628
12718
  return {
12629
12719
  async ensureInstalled() {
12630
- const os44 = createOsStrategy();
12631
- return os44.findInPath("codex") !== null;
12720
+ const os45 = createOsStrategy();
12721
+ return os45.findInPath("codex") !== null;
12632
12722
  },
12633
12723
  launch() {
12634
- return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
12724
+ return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
12635
12725
  }
12636
12726
  };
12637
12727
  }
@@ -12651,8 +12741,8 @@ var CodexRuntimeStrategy = class {
12651
12741
  meta = getAgent("codex");
12652
12742
  mode = "interactive";
12653
12743
  os;
12654
- constructor(os44) {
12655
- this.os = os44;
12744
+ constructor(os45) {
12745
+ this.os = os45;
12656
12746
  }
12657
12747
  async prepareLaunch() {
12658
12748
  let binary = this.os.findInPath("codex");
@@ -12751,12 +12841,12 @@ var CodexRuntimeStrategy = class {
12751
12841
  });
12752
12842
  }
12753
12843
  };
12754
- function resolveNpm(os44) {
12755
- return os44.id === "win32" ? "npm.cmd" : "npm";
12844
+ function resolveNpm(os45) {
12845
+ return os45.id === "win32" ? "npm.cmd" : "npm";
12756
12846
  }
12757
- async function installCodexViaNpm(os44) {
12847
+ async function installCodexViaNpm(os45) {
12758
12848
  return new Promise((resolve7, reject) => {
12759
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os44), ["install", "-g", "@openai/codex"], {
12849
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os45), ["install", "-g", "@openai/codex"], {
12760
12850
  stdio: "inherit"
12761
12851
  });
12762
12852
  proc.on("close", (code) => {
@@ -12773,16 +12863,16 @@ async function installCodexViaNpm(os44) {
12773
12863
  });
12774
12864
  });
12775
12865
  }
12776
- function augmentNpmGlobalBin(os44) {
12866
+ function augmentNpmGlobalBin(os45) {
12777
12867
  try {
12778
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os44), ["prefix", "-g"], {
12868
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os45), ["prefix", "-g"], {
12779
12869
  stdio: ["ignore", "pipe", "ignore"]
12780
12870
  });
12781
12871
  if (result.status !== 0) return;
12782
12872
  const prefix = result.stdout.toString().trim();
12783
12873
  if (!prefix) return;
12784
- const binDir = os44.id === "win32" ? prefix : path23.join(prefix, "bin");
12785
- os44.augmentPath([binDir]);
12874
+ const binDir = os45.id === "win32" ? prefix : path24.join(prefix, "bin");
12875
+ os45.augmentPath([binDir]);
12786
12876
  } catch {
12787
12877
  }
12788
12878
  }
@@ -12861,14 +12951,14 @@ var CodexDeployStrategy = class {
12861
12951
  };
12862
12952
 
12863
12953
  // src/agents/coderabbit/runtime.ts
12864
- var import_node_child_process7 = require("child_process");
12954
+ var import_node_child_process8 = require("child_process");
12865
12955
 
12866
12956
  // src/agents/coderabbit/installer.ts
12867
- var import_node_child_process5 = require("child_process");
12957
+ var import_node_child_process6 = require("child_process");
12868
12958
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
12869
- async function ensureCoderabbitInstalled(os44) {
12870
- if (os44.findInPath("coderabbit")) return true;
12871
- if (os44.id === "win32") {
12959
+ async function ensureCoderabbitInstalled(os45) {
12960
+ if (os45.findInPath("coderabbit")) return true;
12961
+ if (os45.id === "win32") {
12872
12962
  console.error(
12873
12963
  "\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"
12874
12964
  );
@@ -12876,22 +12966,22 @@ async function ensureCoderabbitInstalled(os44) {
12876
12966
  }
12877
12967
  console.log("\n CodeRabbit CLI not found \u2014 installing via the official script\u2026\n");
12878
12968
  const ok = await new Promise((resolve7) => {
12879
- const proc = (0, import_node_child_process5.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL} | sh`], {
12969
+ const proc = (0, import_node_child_process6.spawn)("sh", ["-c", `curl -fsSL ${INSTALL_URL} | sh`], {
12880
12970
  stdio: "inherit"
12881
12971
  });
12882
12972
  proc.on("close", (code) => resolve7(code === 0));
12883
12973
  proc.on("error", () => resolve7(false));
12884
12974
  });
12885
12975
  if (!ok) return false;
12886
- os44.augmentPath([`${os44.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12887
- return os44.findInPath("coderabbit") !== null;
12976
+ os45.augmentPath([`${os45.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12977
+ return os45.findInPath("coderabbit") !== null;
12888
12978
  }
12889
12979
 
12890
12980
  // src/agents/coderabbit/link.ts
12891
- var import_node_child_process6 = require("child_process");
12892
- var fs20 = __toESM(require("fs"));
12893
- var os19 = __toESM(require("os"));
12894
- var path25 = __toESM(require("path"));
12981
+ var import_node_child_process7 = require("child_process");
12982
+ var fs21 = __toESM(require("fs"));
12983
+ var os20 = __toESM(require("os"));
12984
+ var path26 = __toESM(require("path"));
12895
12985
 
12896
12986
  // src/agents/strategy.ts
12897
12987
  function validateNonEmptyCredential(token) {
@@ -12900,12 +12990,12 @@ function validateNonEmptyCredential(token) {
12900
12990
 
12901
12991
  // src/agents/coderabbit/link.ts
12902
12992
  function authPath() {
12903
- return path25.join(os19.homedir(), ".coderabbit", "auth.json");
12993
+ return path26.join(os20.homedir(), ".coderabbit", "auth.json");
12904
12994
  }
12905
12995
  async function extractLocalCoderabbitToken() {
12906
12996
  const file = authPath();
12907
- if (!fs20.existsSync(file)) return null;
12908
- const credential = fs20.readFileSync(file, "utf8").trim();
12997
+ if (!fs21.existsSync(file)) return null;
12998
+ const credential = fs21.readFileSync(file, "utf8").trim();
12909
12999
  if (credential.length === 0) return null;
12910
13000
  return { method: "oauth", credential, source: "flat-file" };
12911
13001
  }
@@ -12919,13 +13009,13 @@ function coderabbitCredentialLocator() {
12919
13009
  validate: validateNonEmptyCredential
12920
13010
  };
12921
13011
  }
12922
- function coderabbitLoginLauncher(os44) {
13012
+ function coderabbitLoginLauncher(os45) {
12923
13013
  return {
12924
13014
  async ensureInstalled() {
12925
- return ensureCoderabbitInstalled(os44);
13015
+ return ensureCoderabbitInstalled(os45);
12926
13016
  },
12927
13017
  launch() {
12928
- return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
13018
+ return (0, import_node_child_process7.spawn)("coderabbit", ["login"], { stdio: "inherit" });
12929
13019
  }
12930
13020
  };
12931
13021
  }
@@ -12945,11 +13035,11 @@ function parseReview(stdout) {
12945
13035
  for (const line of lines) {
12946
13036
  const m = line.match(HUNK_LINE_RE);
12947
13037
  if (!m) continue;
12948
- const [, path64, lineNo, sevToken, message] = m;
12949
- if (!path64 || !lineNo || !message) continue;
13038
+ const [, path65, lineNo, sevToken, message] = m;
13039
+ if (!path65 || !lineNo || !message) continue;
12950
13040
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
12951
13041
  hunks.push({
12952
- path: path64.trim(),
13042
+ path: path65.trim(),
12953
13043
  line: Number(lineNo),
12954
13044
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
12955
13045
  message: cleanedMessage
@@ -12968,8 +13058,8 @@ var CoderabbitRuntimeStrategy = class {
12968
13058
  meta = getAgent("coderabbit");
12969
13059
  mode = "batch";
12970
13060
  os;
12971
- constructor(os44) {
12972
- this.os = os44;
13061
+ constructor(os45) {
13062
+ this.os = os45;
12973
13063
  }
12974
13064
  getDefaultArgs() {
12975
13065
  return ["review"];
@@ -13010,7 +13100,7 @@ var CoderabbitRuntimeStrategy = class {
13010
13100
  return new Promise((resolve7, reject) => {
13011
13101
  const stdoutBuf = [];
13012
13102
  const stderrBuf = [];
13013
- const proc = (0, import_node_child_process7.spawn)(launch.cmd, launch.args, {
13103
+ const proc = (0, import_node_child_process8.spawn)(launch.cmd, launch.args, {
13014
13104
  env: { ...process.env, ...launch.env ?? {} },
13015
13105
  stdio: ["ignore", "pipe", "pipe"]
13016
13106
  });
@@ -13037,12 +13127,12 @@ var CoderabbitRuntimeStrategy = class {
13037
13127
  };
13038
13128
 
13039
13129
  // src/agents/cursor/history.ts
13040
- var fs21 = __toESM(require("fs"));
13041
- var os20 = __toESM(require("os"));
13042
- var path26 = __toESM(require("path"));
13043
- var HISTORY_ROOT = path26.join(os20.homedir(), ".cursor", "projects");
13130
+ var fs22 = __toESM(require("fs"));
13131
+ var os21 = __toESM(require("os"));
13132
+ var path27 = __toESM(require("path"));
13133
+ var HISTORY_ROOT = path27.join(os21.homedir(), ".cursor", "projects");
13044
13134
  function resolveHistoryDir3(cwd) {
13045
- if (!fs21.existsSync(HISTORY_ROOT)) return null;
13135
+ if (!fs22.existsSync(HISTORY_ROOT)) return null;
13046
13136
  void cwd;
13047
13137
  return HISTORY_ROOT;
13048
13138
  }
@@ -13054,19 +13144,19 @@ function getCurrentUsage3(_historyDir) {
13054
13144
  }
13055
13145
 
13056
13146
  // src/agents/cursor/link.ts
13057
- var import_node_child_process8 = require("child_process");
13147
+ var import_node_child_process9 = require("child_process");
13058
13148
 
13059
13149
  // src/agents/cursor/local-token.ts
13060
- var fs22 = __toESM(require("fs"));
13061
- var os21 = __toESM(require("os"));
13062
- var path27 = __toESM(require("path"));
13150
+ var fs23 = __toESM(require("fs"));
13151
+ var os22 = __toESM(require("os"));
13152
+ var path28 = __toESM(require("path"));
13063
13153
  function cursorCredentialsPath() {
13064
- return path27.join(os21.homedir(), ".cursor", "auth.json");
13154
+ return path28.join(os22.homedir(), ".cursor", "auth.json");
13065
13155
  }
13066
13156
  async function extractLocalCursorToken() {
13067
13157
  const file = cursorCredentialsPath();
13068
- if (!fs22.existsSync(file)) return null;
13069
- const credential = fs22.readFileSync(file, "utf8").trim();
13158
+ if (!fs23.existsSync(file)) return null;
13159
+ const credential = fs23.readFileSync(file, "utf8").trim();
13070
13160
  if (credential.length === 0) return null;
13071
13161
  return { method: "oauth", credential, source: "flat-file" };
13072
13162
  }
@@ -13085,17 +13175,17 @@ function cursorCredentialLocator() {
13085
13175
  validate: validateNonEmptyCredential
13086
13176
  };
13087
13177
  }
13088
- function cursorLoginLauncher(os44) {
13178
+ function cursorLoginLauncher(os45) {
13089
13179
  return {
13090
13180
  async ensureInstalled() {
13091
- if (os44.findInPath("cursor-agent")) return true;
13181
+ if (os45.findInPath("cursor-agent")) return true;
13092
13182
  console.error(
13093
13183
  "\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"
13094
13184
  );
13095
13185
  return false;
13096
13186
  },
13097
13187
  launch() {
13098
- return (0, import_node_child_process8.spawn)("cursor-agent", ["login"], { stdio: "inherit" });
13188
+ return (0, import_node_child_process9.spawn)("cursor-agent", ["login"], { stdio: "inherit" });
13099
13189
  }
13100
13190
  };
13101
13191
  }
@@ -13150,8 +13240,8 @@ var CursorRuntimeStrategy = class {
13150
13240
  meta = getAgent("cursor");
13151
13241
  mode = "interactive";
13152
13242
  os;
13153
- constructor(os44) {
13154
- this.os = os44;
13243
+ constructor(os45) {
13244
+ this.os = os45;
13155
13245
  }
13156
13246
  async prepareLaunch() {
13157
13247
  const binary = this.os.findInPath("cursor-agent");
@@ -13230,12 +13320,12 @@ var CursorRuntimeStrategy = class {
13230
13320
  };
13231
13321
 
13232
13322
  // src/agents/aider/history.ts
13233
- var fs23 = __toESM(require("fs"));
13234
- var path28 = __toESM(require("path"));
13323
+ var fs24 = __toESM(require("fs"));
13324
+ var path29 = __toESM(require("path"));
13235
13325
  var AIDER_HISTORY_FILE = ".aider.chat.history.md";
13236
13326
  function resolveHistoryDir4(cwd) {
13237
- const candidate = path28.join(cwd, AIDER_HISTORY_FILE);
13238
- return fs23.existsSync(candidate) ? cwd : null;
13327
+ const candidate = path29.join(cwd, AIDER_HISTORY_FILE);
13328
+ return fs24.existsSync(candidate) ? cwd : null;
13239
13329
  }
13240
13330
  function parseHistoryFile4(_filePath) {
13241
13331
  return [];
@@ -13245,13 +13335,13 @@ function getCurrentUsage4(_historyDir) {
13245
13335
  }
13246
13336
 
13247
13337
  // src/agents/aider/link.ts
13248
- var import_node_child_process9 = require("child_process");
13338
+ var import_node_child_process10 = require("child_process");
13249
13339
 
13250
13340
  // src/agents/aider/local-token.ts
13251
- var fs24 = __toESM(require("fs"));
13252
- var os22 = __toESM(require("os"));
13253
- var path29 = __toESM(require("path"));
13254
- var AIDER_CONF_FILE = path29.join(os22.homedir(), ".aider.conf.yml");
13341
+ var fs25 = __toESM(require("fs"));
13342
+ var os23 = __toESM(require("os"));
13343
+ var path30 = __toESM(require("path"));
13344
+ var AIDER_CONF_FILE = path30.join(os23.homedir(), ".aider.conf.yml");
13255
13345
  var API_KEY_ENV_VARS = [
13256
13346
  "ANTHROPIC_API_KEY",
13257
13347
  "OPENAI_API_KEY",
@@ -13266,8 +13356,8 @@ async function extractLocalAiderToken() {
13266
13356
  return { method: "api_key", credential: value.trim(), source: "flat-file" };
13267
13357
  }
13268
13358
  }
13269
- if (fs24.existsSync(AIDER_CONF_FILE)) {
13270
- const conf = fs24.readFileSync(AIDER_CONF_FILE, "utf8");
13359
+ if (fs25.existsSync(AIDER_CONF_FILE)) {
13360
+ const conf = fs25.readFileSync(AIDER_CONF_FILE, "utf8");
13271
13361
  const match = conf.match(/^api-key:\s*['"]?([^'"\n]+)['"]?\s*$/m);
13272
13362
  if (match) {
13273
13363
  return { method: "api_key", credential: match[1].trim(), source: "flat-file" };
@@ -13290,10 +13380,10 @@ function aiderCredentialLocator() {
13290
13380
  validate: validateNonEmptyCredential
13291
13381
  };
13292
13382
  }
13293
- function aiderLoginLauncher(os44) {
13383
+ function aiderLoginLauncher(os45) {
13294
13384
  return {
13295
13385
  async ensureInstalled() {
13296
- if (os44.findInPath("aider")) return true;
13386
+ if (os45.findInPath("aider")) return true;
13297
13387
  console.error(
13298
13388
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
13299
13389
  );
@@ -13303,7 +13393,7 @@ function aiderLoginLauncher(os44) {
13303
13393
  console.error(
13304
13394
  "\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"
13305
13395
  );
13306
- return (0, import_node_child_process9.spawn)(os44.id === "win32" ? "cmd.exe" : "sh", os44.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13396
+ return (0, import_node_child_process10.spawn)(os45.id === "win32" ? "cmd.exe" : "sh", os45.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13307
13397
  stdio: "ignore"
13308
13398
  });
13309
13399
  }
@@ -13375,8 +13465,8 @@ var AiderRuntimeStrategy = class {
13375
13465
  meta = getAgent("aider");
13376
13466
  mode = "interactive";
13377
13467
  os;
13378
- constructor(os44) {
13379
- this.os = os44;
13468
+ constructor(os45) {
13469
+ this.os = os45;
13380
13470
  }
13381
13471
  async prepareLaunch() {
13382
13472
  const binary = this.os.findInPath("aider");
@@ -13444,22 +13534,22 @@ var AiderRuntimeStrategy = class {
13444
13534
  };
13445
13535
 
13446
13536
  // src/agents/gemini/link.ts
13447
- var import_node_child_process10 = require("child_process");
13537
+ var import_node_child_process11 = require("child_process");
13448
13538
 
13449
13539
  // src/agents/gemini/local-token.ts
13450
- var fs25 = __toESM(require("fs"));
13451
- var os23 = __toESM(require("os"));
13452
- var path30 = __toESM(require("path"));
13540
+ var fs26 = __toESM(require("fs"));
13541
+ var os24 = __toESM(require("os"));
13542
+ var path31 = __toESM(require("path"));
13453
13543
  function geminiCredentialsPath() {
13454
- return path30.join(os23.homedir(), ".gemini", "oauth_creds.json");
13544
+ return path31.join(os24.homedir(), ".gemini", "oauth_creds.json");
13455
13545
  }
13456
13546
  function geminiCredentialsPaths() {
13457
13547
  return [geminiCredentialsPath()];
13458
13548
  }
13459
13549
  async function extractLocalGeminiToken() {
13460
13550
  const file = geminiCredentialsPath();
13461
- if (!fs25.existsSync(file)) return null;
13462
- const credential = fs25.readFileSync(file, "utf8").trim();
13551
+ if (!fs26.existsSync(file)) return null;
13552
+ const credential = fs26.readFileSync(file, "utf8").trim();
13463
13553
  if (credential.length === 0) return null;
13464
13554
  return { method: "oauth", credential, source: "flat-file" };
13465
13555
  }
@@ -13505,11 +13595,11 @@ function geminiCredentialLocator() {
13505
13595
  function geminiLoginLauncher() {
13506
13596
  return {
13507
13597
  async ensureInstalled() {
13508
- const os44 = createOsStrategy();
13509
- return os44.findInPath("gemini") !== null;
13598
+ const os45 = createOsStrategy();
13599
+ return os45.findInPath("gemini") !== null;
13510
13600
  },
13511
13601
  launch() {
13512
- return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
13602
+ return (0, import_node_child_process11.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
13513
13603
  }
13514
13604
  };
13515
13605
  }
@@ -13539,8 +13629,8 @@ var GeminiRuntimeStrategy = class {
13539
13629
  meta = getAgent("gemini");
13540
13630
  mode = "interactive";
13541
13631
  os;
13542
- constructor(os44) {
13543
- this.os = os44;
13632
+ constructor(os45) {
13633
+ this.os = os45;
13544
13634
  }
13545
13635
  async prepareLaunch() {
13546
13636
  const binary = this.os.findInPath("gemini");
@@ -13639,18 +13729,18 @@ var GeminiRuntimeStrategy = class {
13639
13729
 
13640
13730
  // src/agents/registry.ts
13641
13731
  var runtimeBuilders = {
13642
- claude: (os44) => new ClaudeRuntimeStrategy(os44),
13643
- codex: (os44) => new CodexRuntimeStrategy(os44),
13644
- coderabbit: (os44) => new CoderabbitRuntimeStrategy(os44),
13645
- cursor: (os44) => new CursorRuntimeStrategy(os44),
13646
- aider: (os44) => new AiderRuntimeStrategy(os44),
13647
- gemini: (os44) => new GeminiRuntimeStrategy(os44)
13732
+ claude: (os45) => new ClaudeRuntimeStrategy(os45),
13733
+ codex: (os45) => new CodexRuntimeStrategy(os45),
13734
+ coderabbit: (os45) => new CoderabbitRuntimeStrategy(os45),
13735
+ cursor: (os45) => new CursorRuntimeStrategy(os45),
13736
+ aider: (os45) => new AiderRuntimeStrategy(os45),
13737
+ gemini: (os45) => new GeminiRuntimeStrategy(os45)
13648
13738
  };
13649
13739
  var deployBuilders = {
13650
13740
  claude: () => new ClaudeDeployStrategy(),
13651
13741
  codex: () => new CodexDeployStrategy()
13652
13742
  };
13653
- function createAgentStrategy(agent, os44 = createOsStrategy()) {
13743
+ function createAgentStrategy(agent, os45 = createOsStrategy()) {
13654
13744
  if (!AGENT_REGISTRY[agent]?.enabled) {
13655
13745
  throw new Error(
13656
13746
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -13660,10 +13750,10 @@ function createAgentStrategy(agent, os44 = createOsStrategy()) {
13660
13750
  if (!build) {
13661
13751
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
13662
13752
  }
13663
- return build(os44);
13753
+ return build(os45);
13664
13754
  }
13665
- function createInteractiveAgentStrategy(agent, os44 = createOsStrategy()) {
13666
- const s = createAgentStrategy(agent, os44);
13755
+ function createInteractiveAgentStrategy(agent, os45 = createOsStrategy()) {
13756
+ const s = createAgentStrategy(agent, os45);
13667
13757
  if (s.mode !== "interactive") {
13668
13758
  throw new Error(
13669
13759
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -13719,7 +13809,7 @@ function parseLinkArgs(args2) {
13719
13809
  if (apiKeyFileArg) {
13720
13810
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
13721
13811
  try {
13722
- apiKey = fs26.readFileSync(path31.resolve(filePath), "utf8").trim();
13812
+ apiKey = fs27.readFileSync(path32.resolve(filePath), "utf8").trim();
13723
13813
  } catch (err) {
13724
13814
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
13725
13815
  }
@@ -13846,7 +13936,7 @@ async function link(args2 = []) {
13846
13936
  return;
13847
13937
  }
13848
13938
  if (parsed.tokenFile) {
13849
- const credential = fs26.readFileSync(path31.resolve(parsed.tokenFile), "utf8").trim();
13939
+ const credential = fs27.readFileSync(path32.resolve(parsed.tokenFile), "utf8").trim();
13850
13940
  if (!credential) {
13851
13941
  showError(`--token-file ${parsed.tokenFile} is empty.`);
13852
13942
  process.exit(1);
@@ -14066,15 +14156,15 @@ async function linkDryRunPreflight(ctx) {
14066
14156
  }
14067
14157
 
14068
14158
  // src/commands/host-agent.ts
14069
- var import_node_child_process15 = require("child_process");
14070
- var os30 = __toESM(require("os"));
14071
- var fs33 = __toESM(require("fs"));
14072
- var path37 = __toESM(require("path"));
14159
+ var import_node_child_process16 = require("child_process");
14160
+ var os31 = __toESM(require("os"));
14161
+ var fs34 = __toESM(require("fs"));
14162
+ var path38 = __toESM(require("path"));
14073
14163
 
14074
14164
  // src/util/restrict-to-owner.ts
14075
14165
  var import_node_fs5 = __toESM(require("fs"));
14076
14166
  var import_node_os3 = __toESM(require("os"));
14077
- var import_node_child_process11 = require("child_process");
14167
+ var import_node_child_process12 = require("child_process");
14078
14168
  var BROAD_WINDOWS_SIDS = [
14079
14169
  "*S-1-1-0",
14080
14170
  "*S-1-5-11",
@@ -14086,7 +14176,7 @@ function restrictToOwner(filePath) {
14086
14176
  try {
14087
14177
  if (process.platform === "win32") {
14088
14178
  const username = import_node_os3.default.userInfo().username;
14089
- (0, import_node_child_process11.execFileSync)(
14179
+ (0, import_node_child_process12.execFileSync)(
14090
14180
  "icacls",
14091
14181
  [
14092
14182
  filePath,
@@ -14105,13 +14195,13 @@ function restrictToOwner(filePath) {
14105
14195
  }
14106
14196
 
14107
14197
  // src/commands/host/host-client.ts
14108
- var fs28 = __toESM(require("fs"));
14109
- var os25 = __toESM(require("os"));
14110
- var path32 = __toESM(require("path"));
14198
+ var fs29 = __toESM(require("fs"));
14199
+ var os26 = __toESM(require("os"));
14200
+ var path33 = __toESM(require("path"));
14111
14201
  function sampleCpuTimes() {
14112
14202
  let idle = 0;
14113
14203
  let total = 0;
14114
- for (const cpu of os25.cpus()) {
14204
+ for (const cpu of os26.cpus()) {
14115
14205
  const t2 = cpu.times;
14116
14206
  idle += t2.idle;
14117
14207
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -14130,8 +14220,8 @@ var MetricsCollector = class {
14130
14220
  const prev = this.prevCpu;
14131
14221
  this.prevCpu = current;
14132
14222
  if (!prev) {
14133
- const cores = os25.cpus().length || 1;
14134
- const proxy = os25.loadavg()[0] / cores * 100;
14223
+ const cores = os26.cpus().length || 1;
14224
+ const proxy = os26.loadavg()[0] / cores * 100;
14135
14225
  return Math.min(100, Math.max(0, Math.round(proxy)));
14136
14226
  }
14137
14227
  const idleDelta = current.idle - prev.idle;
@@ -14144,8 +14234,8 @@ var MetricsCollector = class {
14144
14234
  collect() {
14145
14235
  return {
14146
14236
  cpuPct: this.cpuPct(),
14147
- ramUsedMb: Math.round((os25.totalmem() - os25.freemem()) / 1048576),
14148
- ramTotalMb: Math.round(os25.totalmem() / 1048576),
14237
+ ramUsedMb: Math.round((os26.totalmem() - os26.freemem()) / 1048576),
14238
+ ramTotalMb: Math.round(os26.totalmem() / 1048576),
14149
14239
  latencyMs: this.lastLatencyMs
14150
14240
  };
14151
14241
  }
@@ -14154,19 +14244,19 @@ function apiBase() {
14154
14244
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
14155
14245
  }
14156
14246
  function hostIdentityPath() {
14157
- return path32.join(os25.homedir(), ".codeam", "host-agent.json");
14247
+ return path33.join(os26.homedir(), ".codeam", "host-agent.json");
14158
14248
  }
14159
14249
  function collectOsInfo() {
14160
14250
  return {
14161
- distro: os25.platform(),
14162
- arch: os25.arch(),
14163
- kernel: os25.release(),
14251
+ distro: os26.platform(),
14252
+ arch: os26.arch(),
14253
+ kernel: os26.release(),
14164
14254
  nodeVersion: process.versions.node
14165
14255
  };
14166
14256
  }
14167
14257
  function loadHostIdentity() {
14168
14258
  try {
14169
- const raw = fs28.readFileSync(hostIdentityPath(), "utf8");
14259
+ const raw = fs29.readFileSync(hostIdentityPath(), "utf8");
14170
14260
  const parsed = JSON.parse(raw);
14171
14261
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
14172
14262
  const p2 = parsed;
@@ -14179,8 +14269,8 @@ function loadHostIdentity() {
14179
14269
  }
14180
14270
  function saveHostIdentity(identity) {
14181
14271
  const file = hostIdentityPath();
14182
- fs28.mkdirSync(path32.dirname(file), { recursive: true, mode: 448 });
14183
- fs28.writeFileSync(file, JSON.stringify(identity, null, 2), {
14272
+ fs29.mkdirSync(path33.dirname(file), { recursive: true, mode: 448 });
14273
+ fs29.writeFileSync(file, JSON.stringify(identity, null, 2), {
14184
14274
  encoding: "utf8",
14185
14275
  mode: 384
14186
14276
  });
@@ -14225,7 +14315,7 @@ function isTerminalEnrollError(err) {
14225
14315
  }
14226
14316
  function deleteHostIdentity() {
14227
14317
  try {
14228
- fs28.rmSync(hostIdentityPath(), { force: true });
14318
+ fs29.rmSync(hostIdentityPath(), { force: true });
14229
14319
  } catch {
14230
14320
  }
14231
14321
  }
@@ -14348,17 +14438,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
14348
14438
  }
14349
14439
 
14350
14440
  // src/commands/host/workspace.ts
14351
- var fs29 = __toESM(require("fs"));
14352
- var os26 = __toESM(require("os"));
14353
- var path33 = __toESM(require("path"));
14354
- var import_node_child_process12 = require("child_process");
14441
+ var fs30 = __toESM(require("fs"));
14442
+ var os27 = __toESM(require("os"));
14443
+ var path34 = __toESM(require("path"));
14444
+ var import_node_child_process13 = require("child_process");
14355
14445
  var import_node_util4 = require("util");
14356
- var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process12.execFile);
14446
+ var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process13.execFile);
14357
14447
  function isAbsolutePathTarget(target) {
14358
- return path33.isAbsolute(target);
14448
+ return path34.isAbsolute(target);
14359
14449
  }
14360
14450
  function selfHostedWorkspaceRoot() {
14361
- return path33.join(os26.homedir(), ".codeam", "self-hosted");
14451
+ return path34.join(os27.homedir(), ".codeam", "self-hosted");
14362
14452
  }
14363
14453
  function nonInteractiveGitEnv() {
14364
14454
  return {
@@ -14411,13 +14501,13 @@ async function fetchGithubIdentity(token) {
14411
14501
  async function configureGitCredentials(dest, repoRef, cloneToken) {
14412
14502
  const gh = githubOwnerRepo(repoRef.trim());
14413
14503
  if (!gh || !cloneToken) return;
14414
- const credFile = path33.join(dest, ".git", "codeam-credentials");
14415
- fs29.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
14504
+ const credFile = path34.join(dest, ".git", "codeam-credentials");
14505
+ fs30.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
14416
14506
  `, { mode: 384 });
14417
14507
  restrictToOwner(credFile);
14418
14508
  const env = nonInteractiveGitEnv();
14419
14509
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
14420
- const credFilePosix = credFile.split(path33.sep).join("/");
14510
+ const credFilePosix = credFile.split(path34.sep).join("/");
14421
14511
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
14422
14512
  });
14423
14513
  await git2([
@@ -14453,17 +14543,17 @@ function maskToken(text, cloneToken) {
14453
14543
  }
14454
14544
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14455
14545
  if (isAbsolutePathTarget(repoOrPath)) {
14456
- if (!fs29.existsSync(repoOrPath)) {
14546
+ if (!fs30.existsSync(repoOrPath)) {
14457
14547
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
14458
14548
  }
14459
14549
  return repoOrPath;
14460
14550
  }
14461
- const dest = path33.join(selfHostedWorkspaceRoot(), deployId);
14462
- if (fs29.existsSync(path33.join(dest, ".git"))) {
14551
+ const dest = path34.join(selfHostedWorkspaceRoot(), deployId);
14552
+ if (fs30.existsSync(path34.join(dest, ".git"))) {
14463
14553
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
14464
14554
  return dest;
14465
14555
  }
14466
- fs29.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
14556
+ fs30.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
14467
14557
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
14468
14558
  try {
14469
14559
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -14480,9 +14570,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14480
14570
  }
14481
14571
 
14482
14572
  // src/commands/host/agent-provisioning.ts
14483
- var fs30 = __toESM(require("fs"));
14484
- var os27 = __toESM(require("os"));
14485
- var path34 = __toESM(require("path"));
14573
+ var fs31 = __toESM(require("fs"));
14574
+ var os28 = __toESM(require("os"));
14575
+ var path35 = __toESM(require("path"));
14486
14576
  var PUBLIC_TO_INTERNAL_AGENT = {
14487
14577
  claude_code: "claude",
14488
14578
  claude: "claude",
@@ -14497,22 +14587,22 @@ function toInternalAgentId(publicAgentId) {
14497
14587
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
14498
14588
  }
14499
14589
  function ensureDir(dir) {
14500
- fs30.mkdirSync(dir, { recursive: true, mode: 448 });
14590
+ fs31.mkdirSync(dir, { recursive: true, mode: 448 });
14501
14591
  }
14502
14592
  function writeFile0600(filePath, contents) {
14503
- ensureDir(path34.dirname(filePath));
14504
- fs30.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
14593
+ ensureDir(path35.dirname(filePath));
14594
+ fs31.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
14505
14595
  restrictToOwner(filePath);
14506
14596
  }
14507
14597
  function rmIfExists(filePath) {
14508
14598
  try {
14509
- fs30.rmSync(filePath, { force: true });
14599
+ fs31.rmSync(filePath, { force: true });
14510
14600
  } catch {
14511
14601
  }
14512
14602
  }
14513
14603
  var claudeProvisioner = {
14514
14604
  write(auth, home) {
14515
- const credentialsJson = path34.join(home, ".claude", ".credentials.json");
14605
+ const credentialsJson = path35.join(home, ".claude", ".credentials.json");
14516
14606
  if (auth.kind === "api_key") {
14517
14607
  rmIfExists(credentialsJson);
14518
14608
  return { ANTHROPIC_API_KEY: auth.value };
@@ -14524,8 +14614,8 @@ var claudeProvisioner = {
14524
14614
  } else {
14525
14615
  rmIfExists(credentialsJson);
14526
14616
  }
14527
- const claudeJson = path34.join(home, ".claude.json");
14528
- if (!fs30.existsSync(claudeJson)) {
14617
+ const claudeJson = path35.join(home, ".claude.json");
14618
+ if (!fs31.existsSync(claudeJson)) {
14529
14619
  writeFile0600(
14530
14620
  claudeJson,
14531
14621
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -14536,7 +14626,7 @@ var claudeProvisioner = {
14536
14626
  };
14537
14627
  var codexProvisioner = {
14538
14628
  write(auth, home) {
14539
- const authJson = path34.join(home, ".codex", "auth.json");
14629
+ const authJson = path35.join(home, ".codex", "auth.json");
14540
14630
  if (auth.kind === "api_key") {
14541
14631
  rmIfExists(authJson);
14542
14632
  return { OPENAI_API_KEY: auth.value };
@@ -14547,8 +14637,8 @@ var codexProvisioner = {
14547
14637
  };
14548
14638
  var geminiProvisioner = {
14549
14639
  write(auth, home) {
14550
- const settingsJson = path34.join(home, ".gemini", "settings.json");
14551
- const oauthCreds = path34.join(home, ".gemini", "oauth_creds.json");
14640
+ const settingsJson = path35.join(home, ".gemini", "settings.json");
14641
+ const oauthCreds = path35.join(home, ".gemini", "oauth_creds.json");
14552
14642
  if (auth.kind === "api_key") {
14553
14643
  rmIfExists(oauthCreds);
14554
14644
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -14561,7 +14651,7 @@ var geminiProvisioner = {
14561
14651
  };
14562
14652
  var cursorProvisioner = {
14563
14653
  write(auth, home) {
14564
- const authJson = path34.join(home, ".config", "cursor", "auth.json");
14654
+ const authJson = path35.join(home, ".config", "cursor", "auth.json");
14565
14655
  if (auth.kind === "api_key") {
14566
14656
  rmIfExists(authJson);
14567
14657
  return { CURSOR_API_KEY: auth.value };
@@ -14598,7 +14688,7 @@ var UnsupportedAgentError = class extends Error {
14598
14688
  this.agentId = agentId;
14599
14689
  }
14600
14690
  };
14601
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os27.homedir()) {
14691
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os28.homedir()) {
14602
14692
  const internal = toInternalAgentId(publicAgentId);
14603
14693
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
14604
14694
  const provisioner = PROVISIONERS[internal];
@@ -14607,12 +14697,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os27.homedir(
14607
14697
  }
14608
14698
 
14609
14699
  // src/commands/host/git-tooling.ts
14610
- var import_node_child_process13 = require("child_process");
14611
- var fs31 = __toESM(require("fs"));
14612
- var os28 = __toESM(require("os"));
14613
- var path35 = __toESM(require("path"));
14700
+ var import_node_child_process14 = require("child_process");
14701
+ var fs32 = __toESM(require("fs"));
14702
+ var os29 = __toESM(require("os"));
14703
+ var path36 = __toESM(require("path"));
14614
14704
  function codeamBinDir() {
14615
- return process.env.CODEAM_BIN_DIR ?? path35.join(os28.homedir(), ".codeam", "bin");
14705
+ return process.env.CODEAM_BIN_DIR ?? path36.join(os29.homedir(), ".codeam", "bin");
14616
14706
  }
14617
14707
  var FALLBACK_GH_VERSION = "2.62.0";
14618
14708
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -14644,7 +14734,7 @@ async function download(url, dest) {
14644
14734
  const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
14645
14735
  if (!res.ok || !res.body) return false;
14646
14736
  const buf = Buffer.from(await res.arrayBuffer());
14647
- fs31.writeFileSync(dest, buf);
14737
+ fs32.writeFileSync(dest, buf);
14648
14738
  return true;
14649
14739
  } catch {
14650
14740
  return false;
@@ -14667,8 +14757,8 @@ async function ensureGhCli(runner, token, deps = {}) {
14667
14757
  const version3 = await resolveVersionFn(token);
14668
14758
  const asset = `gh_${version3}_${osToken}_${arch2}`;
14669
14759
  const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
14670
- const tmpRoot = fs31.mkdtempSync(path35.join(os28.tmpdir(), "codeam-gh-"));
14671
- const archive = path35.join(tmpRoot, `${asset}.${ext}`);
14760
+ const tmpRoot = fs32.mkdtempSync(path36.join(os29.tmpdir(), "codeam-gh-"));
14761
+ const archive = path36.join(tmpRoot, `${asset}.${ext}`);
14672
14762
  if (!await downloadFn(url, archive)) {
14673
14763
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
14674
14764
  return null;
@@ -14678,16 +14768,16 @@ async function ensureGhCli(runner, token, deps = {}) {
14678
14768
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
14679
14769
  return null;
14680
14770
  }
14681
- const extractedBin = path35.join(tmpRoot, asset, "bin", binaryName);
14682
- if (!fs31.existsSync(extractedBin)) {
14771
+ const extractedBin = path36.join(tmpRoot, asset, "bin", binaryName);
14772
+ if (!fs32.existsSync(extractedBin)) {
14683
14773
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
14684
14774
  return null;
14685
14775
  }
14686
14776
  const binDir = codeamBinDir();
14687
- fs31.mkdirSync(binDir, { recursive: true });
14688
- const target = path35.join(binDir, binaryName);
14689
- fs31.copyFileSync(extractedBin, target);
14690
- fs31.chmodSync(target, 493);
14777
+ fs32.mkdirSync(binDir, { recursive: true });
14778
+ const target = path36.join(binDir, binaryName);
14779
+ fs32.copyFileSync(extractedBin, target);
14780
+ fs32.chmodSync(target, 493);
14691
14781
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
14692
14782
  return target;
14693
14783
  } catch (e) {
@@ -14721,7 +14811,7 @@ var defaultGitToolingRunner = {
14721
14811
  which(cmd) {
14722
14812
  try {
14723
14813
  const probe = process.platform === "win32" ? "where" : "which";
14724
- (0, import_node_child_process13.execFileSync)(probe, [cmd], { stdio: "ignore" });
14814
+ (0, import_node_child_process14.execFileSync)(probe, [cmd], { stdio: "ignore" });
14725
14815
  return true;
14726
14816
  } catch {
14727
14817
  return false;
@@ -14729,7 +14819,7 @@ var defaultGitToolingRunner = {
14729
14819
  },
14730
14820
  run(cmd, args2, opts = {}) {
14731
14821
  return new Promise((resolve7) => {
14732
- const child = (0, import_node_child_process13.spawn)(cmd, args2, {
14822
+ const child = (0, import_node_child_process14.spawn)(cmd, args2, {
14733
14823
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
14734
14824
  });
14735
14825
  let stderr = "";
@@ -14769,6 +14859,16 @@ var defaultGitToolingRunner = {
14769
14859
 
14770
14860
  // src/services/headroom/stats-reporter.ts
14771
14861
  var DEFAULT_INPUT_PRICE_PER_MILLION = 3;
14862
+ var HEADROOM_FETCH_TIMEOUT_MS = 1e4;
14863
+ async function fetchWithTimeout(url, init, timeoutMs = HEADROOM_FETCH_TIMEOUT_MS) {
14864
+ const controller = new AbortController();
14865
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
14866
+ try {
14867
+ return await fetch(url, { ...init, signal: controller.signal });
14868
+ } finally {
14869
+ clearTimeout(timer);
14870
+ }
14871
+ }
14772
14872
  var ZERO = {
14773
14873
  rawTokensEst: 0,
14774
14874
  sentTokensEst: 0,
@@ -14831,6 +14931,9 @@ var HeadroomStatsReporter = class {
14831
14931
  deps;
14832
14932
  timer = null;
14833
14933
  prev = ZERO;
14934
+ /** Period spend observed on the previous budgeted post — lets `budgetReached`
14935
+ * fire once per crossing instead of on every post while over the cap. */
14936
+ prevPeriodSpendUsd = null;
14834
14937
  start() {
14835
14938
  const ms = this.deps.intervalMs ?? (Number(process.env.HEADROOM_STATS_POLL_INTERVAL_MS ?? "30000") || 3e4);
14836
14939
  this.timer = setInterval(() => void this.tick(), ms);
@@ -14847,11 +14950,18 @@ var HeadroomStatsReporter = class {
14847
14950
  if (delta.compressionTokens > 0 || delta.compressionSavingsUsd > 0 || delta.rawTokensEst > 0 || delta.cacheReadTokens > 0 || delta.cacheSavingsUsd > 0) {
14848
14951
  const getBudgetEnv = this.deps.getBudgetEnv ?? defaultGetBudgetEnv;
14849
14952
  const budgetEnv = getBudgetEnv();
14850
- const budget = budgetEnv ? {
14851
- periodSpendUsd: stats.cost?.cost_with_headroom_usd ?? 0,
14852
- budgetUsd: budgetEnv.budgetUsd,
14853
- budgetPeriod: budgetEnv.budgetPeriod
14854
- } : void 0;
14953
+ let budget;
14954
+ if (budgetEnv) {
14955
+ const periodSpendUsd = stats.cost?.cost_with_headroom_usd ?? 0;
14956
+ const crossed = periodSpendUsd >= budgetEnv.budgetUsd && (this.prevPeriodSpendUsd === null || this.prevPeriodSpendUsd < budgetEnv.budgetUsd);
14957
+ this.prevPeriodSpendUsd = periodSpendUsd;
14958
+ budget = {
14959
+ periodSpendUsd,
14960
+ budgetUsd: budgetEnv.budgetUsd,
14961
+ budgetPeriod: budgetEnv.budgetPeriod,
14962
+ ...crossed ? { budgetReached: true } : {}
14963
+ };
14964
+ }
14855
14965
  await this.deps.postSavings(delta, budget);
14856
14966
  }
14857
14967
  } catch {
@@ -14866,23 +14976,23 @@ var HeadroomStatsReporter = class {
14866
14976
  };
14867
14977
 
14868
14978
  // src/lib/updateNotifier.ts
14869
- var fs32 = __toESM(require("fs"));
14870
- var os29 = __toESM(require("os"));
14871
- var path36 = __toESM(require("path"));
14979
+ var fs33 = __toESM(require("fs"));
14980
+ var os30 = __toESM(require("os"));
14981
+ var path37 = __toESM(require("path"));
14872
14982
  var https6 = __toESM(require("https"));
14873
- var import_node_child_process14 = require("child_process");
14983
+ var import_node_child_process15 = require("child_process");
14874
14984
  var import_picocolors3 = __toESM(require("picocolors"));
14875
14985
  var PKG_NAME = "codeam-cli";
14876
14986
  var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
14877
14987
  var TTL_MS = 24 * 60 * 60 * 1e3;
14878
14988
  var REQUEST_TIMEOUT_MS = 1500;
14879
14989
  function cachePath() {
14880
- const dir = path36.join(os29.homedir(), ".codeam");
14881
- return path36.join(dir, "update-check.json");
14990
+ const dir = path37.join(os30.homedir(), ".codeam");
14991
+ return path37.join(dir, "update-check.json");
14882
14992
  }
14883
14993
  function readCache() {
14884
14994
  try {
14885
- const raw = fs32.readFileSync(cachePath(), "utf8");
14995
+ const raw = fs33.readFileSync(cachePath(), "utf8");
14886
14996
  const parsed = JSON.parse(raw);
14887
14997
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
14888
14998
  return parsed;
@@ -14893,10 +15003,10 @@ function readCache() {
14893
15003
  function writeCache(cache) {
14894
15004
  try {
14895
15005
  const file = cachePath();
14896
- fs32.mkdirSync(path36.dirname(file), { recursive: true });
15006
+ fs33.mkdirSync(path37.dirname(file), { recursive: true });
14897
15007
  const tmp = `${file}.${process.pid}.tmp`;
14898
- fs32.writeFileSync(tmp, JSON.stringify(cache));
14899
- fs32.renameSync(tmp, file);
15008
+ fs33.writeFileSync(tmp, JSON.stringify(cache));
15009
+ fs33.renameSync(tmp, file);
14900
15010
  } catch {
14901
15011
  }
14902
15012
  }
@@ -14964,14 +15074,14 @@ function notifyIfStale(currentVersion, latest) {
14964
15074
  }
14965
15075
  function isLinkedInstall() {
14966
15076
  try {
14967
- const root = (0, import_node_child_process14.execSync)("npm root -g", {
15077
+ const root = (0, import_node_child_process15.execSync)("npm root -g", {
14968
15078
  encoding: "utf8",
14969
15079
  stdio: ["ignore", "pipe", "ignore"],
14970
15080
  timeout: 2e3
14971
15081
  }).trim();
14972
15082
  if (!root) return false;
14973
- const pkgPath = path36.join(root, PKG_NAME);
14974
- return fs32.lstatSync(pkgPath).isSymbolicLink();
15083
+ const pkgPath = path37.join(root, PKG_NAME);
15084
+ return fs33.lstatSync(pkgPath).isSymbolicLink();
14975
15085
  } catch {
14976
15086
  return false;
14977
15087
  }
@@ -14992,7 +15102,7 @@ function maybeAutoUpdate(currentVersion, latest) {
14992
15102
 
14993
15103
  `
14994
15104
  );
14995
- const install = (0, import_node_child_process14.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
15105
+ const install = (0, import_node_child_process15.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
14996
15106
  stdio: "inherit",
14997
15107
  env: process.env
14998
15108
  });
@@ -15007,13 +15117,13 @@ function maybeAutoUpdate(currentVersion, latest) {
15007
15117
  return;
15008
15118
  }
15009
15119
  try {
15010
- fs32.unlinkSync(cachePath());
15120
+ fs33.unlinkSync(cachePath());
15011
15121
  } catch {
15012
15122
  }
15013
15123
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
15014
15124
 
15015
15125
  `);
15016
- const child = (0, import_node_child_process14.spawnSync)("codeam", process.argv.slice(2), {
15126
+ const child = (0, import_node_child_process15.spawnSync)("codeam", process.argv.slice(2), {
15017
15127
  stdio: "inherit",
15018
15128
  env: process.env
15019
15129
  });
@@ -15023,7 +15133,7 @@ async function autoUpgradeBeforeCriticalCommand() {
15023
15133
  if (process.env.NODE_ENV === "test") return;
15024
15134
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
15025
15135
  if (process.env.CI) return;
15026
- const current = true ? "2.53.2" : null;
15136
+ const current = true ? "2.53.3" : null;
15027
15137
  if (!current) return;
15028
15138
  const cache = readCache();
15029
15139
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -15040,7 +15150,7 @@ function checkForUpdates() {
15040
15150
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
15041
15151
  if (process.env.CI) return;
15042
15152
  if (!process.stdout.isTTY) return;
15043
- const current = true ? "2.53.2" : null;
15153
+ const current = true ? "2.53.3" : null;
15044
15154
  if (!current) return;
15045
15155
  const cache = readCache();
15046
15156
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -15074,11 +15184,11 @@ function maybeStartHeadroomReporter(ctx) {
15074
15184
  process.env["HEADROOM_AGENT"] ?? "claude"
15075
15185
  ),
15076
15186
  fetchStats: async () => {
15077
- const res = await fetch("http://localhost:8787/stats");
15187
+ const res = await fetchWithTimeout("http://localhost:8787/stats");
15078
15188
  return res.json();
15079
15189
  },
15080
15190
  postSavings: async (delta, budget) => {
15081
- await fetch(ingestUrl, {
15191
+ const res = await fetchWithTimeout(ingestUrl, {
15082
15192
  method: "POST",
15083
15193
  headers: {
15084
15194
  "Content-Type": "application/json",
@@ -15092,10 +15202,14 @@ function maybeStartHeadroomReporter(ctx) {
15092
15202
  ...budget ? {
15093
15203
  periodSpendUsd: budget.periodSpendUsd,
15094
15204
  budgetUsd: budget.budgetUsd,
15095
- budgetPeriod: budget.budgetPeriod
15205
+ budgetPeriod: budget.budgetPeriod,
15206
+ budgetReached: budget.budgetReached
15096
15207
  } : {}
15097
15208
  })
15098
15209
  });
15210
+ if (!res.ok) {
15211
+ log.warn("headroom", `savings POST rejected ${res.status} \u2014 delta not credited`);
15212
+ }
15099
15213
  }
15100
15214
  });
15101
15215
  reporter.start();
@@ -15112,22 +15226,22 @@ function maybeResumeLocalHeadroomReporter(ctx) {
15112
15226
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
15113
15227
  try {
15114
15228
  const file = headroomConfigPath();
15115
- if (!fs33.existsSync(file)) return null;
15116
- const cfg = JSON.parse(fs33.readFileSync(file, "utf8"));
15229
+ if (!fs34.existsSync(file)) return null;
15230
+ const cfg = JSON.parse(fs34.readFileSync(file, "utf8"));
15117
15231
  if (!cfg?.enabled) return null;
15118
15232
  const agent = cfg.agent ?? "claude";
15119
15233
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
15120
15234
  const reporter = new HeadroomStatsReporter({
15121
15235
  inputPricePerMillionUsd: resolveInputPricePerMillion(agent),
15122
15236
  fetchStats: async () => {
15123
- const res = await fetch("http://localhost:8787/stats");
15237
+ const res = await fetchWithTimeout("http://localhost:8787/stats");
15124
15238
  return res.json();
15125
15239
  },
15126
15240
  // Body MUST match HeadroomSavingsDto + PluginAuthGuard (sessionId +
15127
15241
  // pluginId in the body) — same shape as the codespace reporter above and
15128
15242
  // the on-demand `startReporter` in handlers.ts.
15129
15243
  postSavings: async (delta, budget) => {
15130
- await fetch(ingestUrl, {
15244
+ const res = await fetchWithTimeout(ingestUrl, {
15131
15245
  method: "POST",
15132
15246
  headers: {
15133
15247
  "Content-Type": "application/json",
@@ -15141,10 +15255,14 @@ function maybeResumeLocalHeadroomReporter(ctx) {
15141
15255
  ...budget ? {
15142
15256
  periodSpendUsd: budget.periodSpendUsd,
15143
15257
  budgetUsd: budget.budgetUsd,
15144
- budgetPeriod: budget.budgetPeriod
15258
+ budgetPeriod: budget.budgetPeriod,
15259
+ budgetReached: budget.budgetReached
15145
15260
  } : {}
15146
15261
  })
15147
15262
  });
15263
+ if (!res.ok) {
15264
+ log.warn("headroom", `savings POST rejected ${res.status} \u2014 delta not credited`);
15265
+ }
15148
15266
  }
15149
15267
  });
15150
15268
  reporter.start();
@@ -15204,7 +15322,7 @@ var HEADROOM_MIN_FREE_DISK_BYTES = 2 * 1024 * 1024 * 1024;
15204
15322
  var defaultHeadroomRunner = {
15205
15323
  which(cmd) {
15206
15324
  try {
15207
- (0, import_node_child_process15.execFileSync)("which", [cmd], { stdio: "ignore" });
15325
+ (0, import_node_child_process16.execFileSync)("which", [cmd], { stdio: "ignore" });
15208
15326
  return true;
15209
15327
  } catch {
15210
15328
  return false;
@@ -15213,7 +15331,7 @@ var defaultHeadroomRunner = {
15213
15331
  run(cmd, args2, opts = {}) {
15214
15332
  return new Promise((resolve7) => {
15215
15333
  const spawnEnv = opts.env ?? process.env;
15216
- const child = (0, import_node_child_process15.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
15334
+ const child = (0, import_node_child_process16.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
15217
15335
  let stderrBuf = "";
15218
15336
  let stdoutBuf = "";
15219
15337
  let settled = false;
@@ -15377,15 +15495,15 @@ function isHeadroomSupportedAgent(agentId) {
15377
15495
  return n.startsWith("claude") || n.startsWith("codex") || n.startsWith("copilot");
15378
15496
  }
15379
15497
  function headroomConfigPath() {
15380
- return path37.join(os30.homedir(), ".codeam", "headroom-config.json");
15498
+ return path38.join(os31.homedir(), ".codeam", "headroom-config.json");
15381
15499
  }
15382
15500
  function persistHeadroomConfig(config) {
15383
15501
  try {
15384
15502
  const file = headroomConfigPath();
15385
- fs33.mkdirSync(path37.dirname(file), { recursive: true, mode: 448 });
15503
+ fs34.mkdirSync(path38.dirname(file), { recursive: true, mode: 448 });
15386
15504
  const tmp = `${file}.tmp-${process.pid}`;
15387
- fs33.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15388
- fs33.renameSync(tmp, file);
15505
+ fs34.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15506
+ fs34.renameSync(tmp, file);
15389
15507
  restrictToOwner(file);
15390
15508
  } catch (err) {
15391
15509
  log.warn(
@@ -15395,21 +15513,21 @@ function persistHeadroomConfig(config) {
15395
15513
  }
15396
15514
  }
15397
15515
  function agentSettingsPath(kind) {
15398
- const home = os30.homedir();
15399
- if (kind === "claude") return path37.join(home, ".claude", "settings.json");
15400
- if (kind === "codex") return path37.join(home, ".codex", "auth.json");
15401
- if (kind === "copilot") return path37.join(home, ".config", "github-copilot", "hosts.json");
15516
+ const home = os31.homedir();
15517
+ if (kind === "claude") return path38.join(home, ".claude", "settings.json");
15518
+ if (kind === "codex") return path38.join(home, ".codex", "auth.json");
15519
+ if (kind === "copilot") return path38.join(home, ".config", "github-copilot", "hosts.json");
15402
15520
  return null;
15403
15521
  }
15404
15522
  function backupAgentHeadroomConfig(kind) {
15405
15523
  const src = agentSettingsPath(kind);
15406
15524
  if (!src) return;
15407
15525
  try {
15408
- if (!fs33.existsSync(src)) return;
15409
- const dest = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15410
- fs33.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
15411
- fs33.copyFileSync(src, dest);
15412
- fs33.chmodSync(dest, 384);
15526
+ if (!fs34.existsSync(src)) return;
15527
+ const dest = path38.join(os31.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15528
+ fs34.mkdirSync(path38.dirname(dest), { recursive: true, mode: 448 });
15529
+ fs34.copyFileSync(src, dest);
15530
+ fs34.chmodSync(dest, 384);
15413
15531
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
15414
15532
  } catch (err) {
15415
15533
  log.warn(
@@ -15421,12 +15539,12 @@ function backupAgentHeadroomConfig(kind) {
15421
15539
  function restoreAgentHeadroomConfig(kind) {
15422
15540
  const dest = agentSettingsPath(kind);
15423
15541
  if (!dest) return false;
15424
- const src = path37.join(os30.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15425
- if (!fs33.existsSync(src)) return false;
15542
+ const src = path38.join(os31.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15543
+ if (!fs34.existsSync(src)) return false;
15426
15544
  try {
15427
- fs33.mkdirSync(path37.dirname(dest), { recursive: true, mode: 448 });
15428
- fs33.copyFileSync(src, dest);
15429
- fs33.chmodSync(dest, 384);
15545
+ fs34.mkdirSync(path38.dirname(dest), { recursive: true, mode: 448 });
15546
+ fs34.copyFileSync(src, dest);
15547
+ fs34.chmodSync(dest, 384);
15430
15548
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
15431
15549
  return true;
15432
15550
  } catch (err) {
@@ -15439,7 +15557,7 @@ function restoreAgentHeadroomConfig(kind) {
15439
15557
  }
15440
15558
  function readHeadroomChildEnv() {
15441
15559
  try {
15442
- const raw = fs33.readFileSync(headroomConfigPath(), "utf8");
15560
+ const raw = fs34.readFileSync(headroomConfigPath(), "utf8");
15443
15561
  const parsed = JSON.parse(raw);
15444
15562
  if (typeof parsed !== "object" || parsed === null) return {};
15445
15563
  const o = parsed;
@@ -15464,37 +15582,37 @@ function bundledClaudeBinDir() {
15464
15582
  const roots = /* @__PURE__ */ new Set();
15465
15583
  let dir = __dirname;
15466
15584
  for (let i = 0; i < 6; i++) {
15467
- roots.add(path37.join(dir, "node_modules"));
15468
- const parent = path37.dirname(dir);
15585
+ roots.add(path38.join(dir, "node_modules"));
15586
+ const parent = path38.dirname(dir);
15469
15587
  if (parent === dir) break;
15470
15588
  dir = parent;
15471
15589
  }
15472
15590
  try {
15473
15591
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
15474
- const marker = `${path37.sep}@anthropic-ai${path37.sep}`;
15592
+ const marker = `${path38.sep}@anthropic-ai${path38.sep}`;
15475
15593
  const idx = main2.lastIndexOf(marker);
15476
15594
  if (idx !== -1) roots.add(main2.slice(0, idx));
15477
15595
  } catch {
15478
15596
  }
15479
15597
  for (const nm of roots) {
15480
- const atAnthropic = path37.join(nm, "@anthropic-ai");
15598
+ const atAnthropic = path38.join(nm, "@anthropic-ai");
15481
15599
  let entries;
15482
15600
  try {
15483
- entries = fs33.readdirSync(atAnthropic);
15601
+ entries = fs34.readdirSync(atAnthropic);
15484
15602
  } catch {
15485
15603
  continue;
15486
15604
  }
15487
15605
  for (const entry of entries) {
15488
15606
  if (!entry.startsWith("claude-agent-sdk-")) continue;
15489
- const bin = path37.join(atAnthropic, entry, "claude");
15490
- if (fs33.existsSync(bin)) return path37.dirname(bin);
15607
+ const bin = path38.join(atAnthropic, entry, "claude");
15608
+ if (fs34.existsSync(bin)) return path38.dirname(bin);
15491
15609
  }
15492
15610
  }
15493
15611
  return null;
15494
15612
  }
15495
15613
  async function getFreeDiskBytes(dir) {
15496
15614
  try {
15497
- const s = await fs33.promises.statfs(dir);
15615
+ const s = await fs34.promises.statfs(dir);
15498
15616
  return s.bsize * s.bavail;
15499
15617
  } catch {
15500
15618
  return null;
@@ -15686,7 +15804,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15686
15804
  if (initKind === "claude") {
15687
15805
  const claudeDir = bundledClaudeBinDir();
15688
15806
  if (claudeDir) {
15689
- initEnv.PATH = `${claudeDir}${path37.delimiter}${process.env["PATH"] ?? ""}`;
15807
+ initEnv.PATH = `${claudeDir}${path38.delimiter}${process.env["PATH"] ?? ""}`;
15690
15808
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
15691
15809
  } else {
15692
15810
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -15710,7 +15828,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15710
15828
  onProgress("proxy");
15711
15829
  try {
15712
15830
  const proxyEnv = { ...process.env, HEADROOM_KOMPRESS_BACKEND: "onnx_cpu" };
15713
- const proxy = (0, import_node_child_process15.spawn)(
15831
+ const proxy = (0, import_node_child_process16.spawn)(
15714
15832
  "headroom",
15715
15833
  ["proxy", "--port", "8787", ...buildBudgetProxyArgs(proxyEnv)],
15716
15834
  {
@@ -15726,6 +15844,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15726
15844
  );
15727
15845
  });
15728
15846
  proxy.unref();
15847
+ writeHeadroomProxyPidfile(proxy.pid);
15729
15848
  } catch (e) {
15730
15849
  log.warn(
15731
15850
  "host-agent",
@@ -15735,18 +15854,18 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15735
15854
  onProgress("ready");
15736
15855
  return true;
15737
15856
  }
15738
- var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process15.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
15857
+ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process16.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
15739
15858
  cwd,
15740
15859
  env: { ...process.env, ...env },
15741
15860
  stdio: ["ignore", "pipe", "pipe"],
15742
15861
  detached: false
15743
15862
  });
15744
15863
  function currentCliVersion() {
15745
- return true ? "2.53.2" : null;
15864
+ return true ? "2.53.3" : null;
15746
15865
  }
15747
15866
  function runCmd(cmd, args2, timeoutMs) {
15748
15867
  return new Promise((resolve7) => {
15749
- (0, import_node_child_process15.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
15868
+ (0, import_node_child_process16.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
15750
15869
  const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
15751
15870
  resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
15752
15871
  });
@@ -15817,22 +15936,19 @@ var defaultOnUpdated = (version3) => {
15817
15936
  };
15818
15937
  var defaultDisableService = () => {
15819
15938
  try {
15820
- (0, import_node_child_process15.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
15939
+ (0, import_node_child_process16.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
15821
15940
  } catch {
15822
15941
  }
15823
15942
  };
15824
15943
  var defaultTeardownHeadroom = () => {
15825
15944
  try {
15826
- const kind = JSON.parse(fs33.readFileSync(headroomConfigPath(), "utf8")).agent;
15945
+ const kind = JSON.parse(fs34.readFileSync(headroomConfigPath(), "utf8")).agent;
15827
15946
  if (kind) {
15828
- (0, import_node_child_process15.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
15947
+ (0, import_node_child_process16.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
15829
15948
  }
15830
15949
  } catch {
15831
15950
  }
15832
- try {
15833
- (0, import_node_child_process15.execFileSync)("pkill", ["-TERM", "-f", "headroom.*proxy"], { stdio: "ignore" });
15834
- } catch {
15835
- }
15951
+ killHeadroomProxy();
15836
15952
  persistHeadroomConfig({ enabled: false });
15837
15953
  };
15838
15954
  var HostAgentSupervisor = class {
@@ -16137,9 +16253,9 @@ var HostAgentSupervisor = class {
16137
16253
  API_TIMEOUT_MS: "3000000",
16138
16254
  CODEAM_AUTO_TOKEN: payload.autoPairToken
16139
16255
  };
16140
- const houseConfigDir = path37.join(os30.homedir(), ".codeam", "house-claude");
16256
+ const houseConfigDir = path38.join(os31.homedir(), ".codeam", "house-claude");
16141
16257
  try {
16142
- fs33.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
16258
+ fs34.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
16143
16259
  } catch {
16144
16260
  }
16145
16261
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -16157,14 +16273,14 @@ var HostAgentSupervisor = class {
16157
16273
  report("installing", "installing agent CLI");
16158
16274
  await this.runAgentInstall(payload.agentInstallScript);
16159
16275
  }
16160
- const home = process.env.HOME || os30.homedir();
16276
+ const home = process.env.HOME || os31.homedir();
16161
16277
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
16162
16278
  if (payload.cloneToken) {
16163
16279
  try {
16164
16280
  report("preparing", "configuring git tooling");
16165
16281
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
16166
16282
  if (ghCmd) {
16167
- childEnv.PATH = `${codeamBinDir()}${path37.delimiter}${childEnv.PATH}`;
16283
+ childEnv.PATH = `${codeamBinDir()}${path38.delimiter}${childEnv.PATH}`;
16168
16284
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
16169
16285
  }
16170
16286
  } catch (e) {
@@ -16180,7 +16296,7 @@ var HostAgentSupervisor = class {
16180
16296
  }
16181
16297
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
16182
16298
  report("headroom", "setting up Headroom proxy");
16183
- const freeBytes = await this.getFreeDisk(os30.homedir());
16299
+ const freeBytes = await this.getFreeDisk(os31.homedir());
16184
16300
  const alreadyInstalled = this.isHeadroomInstalled();
16185
16301
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
16186
16302
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -16302,8 +16418,8 @@ var HostAgentSupervisor = class {
16302
16418
  */
16303
16419
  runAgentInstall(script) {
16304
16420
  return new Promise((resolve7) => {
16305
- const home = process.env.HOME || os30.homedir();
16306
- const child = (0, import_node_child_process15.spawn)("sh", ["-c", script], {
16421
+ const home = process.env.HOME || os31.homedir();
16422
+ const child = (0, import_node_child_process16.spawn)("sh", ["-c", script], {
16307
16423
  env: { ...process.env, HOME: home },
16308
16424
  stdio: ["ignore", "pipe", "pipe"]
16309
16425
  });
@@ -16484,9 +16600,9 @@ async function configureHeadroom(action, ctx, deps) {
16484
16600
  }
16485
16601
 
16486
16602
  // src/services/headroom/budget-relaunch.ts
16487
- var fs34 = __toESM(require("fs"));
16488
- var os31 = __toESM(require("os"));
16489
- var path38 = __toESM(require("path"));
16603
+ var fs35 = __toESM(require("fs"));
16604
+ var os32 = __toESM(require("os"));
16605
+ var path39 = __toESM(require("path"));
16490
16606
  var import_child_process13 = require("child_process");
16491
16607
  function amendDeploymentManifestBudget(manifest, budget) {
16492
16608
  const rawArgs = manifest.proxy_args ?? [];
@@ -16520,7 +16636,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
16520
16636
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
16521
16637
  }
16522
16638
  function findHeadroomDeployments(homeDir2, deps) {
16523
- const deployDir = path38.join(homeDir2, ".headroom", "deploy");
16639
+ const deployDir = path39.join(homeDir2, ".headroom", "deploy");
16524
16640
  let profiles;
16525
16641
  try {
16526
16642
  profiles = deps.readDir(deployDir);
@@ -16529,7 +16645,7 @@ function findHeadroomDeployments(homeDir2, deps) {
16529
16645
  }
16530
16646
  const results = [];
16531
16647
  for (const profile of profiles) {
16532
- const manifestPath = path38.join(deployDir, profile, "manifest.json");
16648
+ const manifestPath = path39.join(deployDir, profile, "manifest.json");
16533
16649
  let raw;
16534
16650
  try {
16535
16651
  raw = deps.readJson(manifestPath);
@@ -16561,8 +16677,8 @@ async function applyBudgetToHeadroom(budget, deps) {
16561
16677
  }
16562
16678
  function writeManifestReal(manifestPath, manifest) {
16563
16679
  const tmp = manifestPath + ".codeam.tmp";
16564
- fs34.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
16565
- fs34.renameSync(tmp, manifestPath);
16680
+ fs35.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
16681
+ fs35.renameSync(tmp, manifestPath);
16566
16682
  }
16567
16683
  function restartDeploymentReal(profile) {
16568
16684
  try {
@@ -16582,16 +16698,7 @@ function restartDeploymentReal(profile) {
16582
16698
  }
16583
16699
  }
16584
16700
  function killProxyReal() {
16585
- try {
16586
- const killer = (0, import_child_process13.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
16587
- detached: true,
16588
- stdio: "ignore"
16589
- });
16590
- killer.once("error", () => {
16591
- });
16592
- killer.unref();
16593
- } catch {
16594
- }
16701
+ killHeadroomProxy();
16595
16702
  }
16596
16703
  function spawnProxyReal2(budget) {
16597
16704
  try {
@@ -16612,6 +16719,7 @@ function spawnProxyReal2(budget) {
16612
16719
  log.warn("headroom-budget", `proxy relaunch error (best-effort): ${e.message}`);
16613
16720
  });
16614
16721
  proxy.unref();
16722
+ writeHeadroomProxyPidfile(proxy.pid);
16615
16723
  } catch (e) {
16616
16724
  log.warn(
16617
16725
  "headroom-budget",
@@ -16620,11 +16728,11 @@ function spawnProxyReal2(budget) {
16620
16728
  }
16621
16729
  }
16622
16730
  function makeRealApplyBudgetDeps() {
16623
- const homeDir2 = os31.homedir();
16731
+ const homeDir2 = os32.homedir();
16624
16732
  return {
16625
16733
  findDeployments: () => findHeadroomDeployments(homeDir2, {
16626
- readDir: (dir) => fs34.readdirSync(dir),
16627
- readJson: (filePath) => JSON.parse(fs34.readFileSync(filePath, "utf8"))
16734
+ readDir: (dir) => fs35.readdirSync(dir),
16735
+ readJson: (filePath) => JSON.parse(fs35.readFileSync(filePath, "utf8"))
16628
16736
  }),
16629
16737
  writeManifest: writeManifestReal,
16630
16738
  restartDeployment: restartDeploymentReal,
@@ -17268,9 +17376,9 @@ function activePreviewSessionIds() {
17268
17376
 
17269
17377
  // src/beads/bd-adapter.ts
17270
17378
  var import_child_process17 = require("child_process");
17271
- var fs39 = __toESM(require("fs"));
17272
- var os33 = __toESM(require("os"));
17273
- var path43 = __toESM(require("path"));
17379
+ var fs40 = __toESM(require("fs"));
17380
+ var os34 = __toESM(require("os"));
17381
+ var path44 = __toESM(require("path"));
17274
17382
  var BD_PACKAGE = "@beads/bd";
17275
17383
  function resolveBundledBdBinary() {
17276
17384
  return _resolveSeam.resolveBundled();
@@ -17282,11 +17390,11 @@ function _defaultResolveBundled() {
17282
17390
  } catch {
17283
17391
  return null;
17284
17392
  }
17285
- const binDir = path43.join(path43.dirname(pkgJsonPath), "bin");
17393
+ const binDir = path44.join(path44.dirname(pkgJsonPath), "bin");
17286
17394
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
17287
- const binaryPath = path43.join(binDir, binaryName);
17395
+ const binaryPath = path44.join(binDir, binaryName);
17288
17396
  try {
17289
- fs39.accessSync(binaryPath, fs39.constants.F_OK);
17397
+ fs40.accessSync(binaryPath, fs40.constants.F_OK);
17290
17398
  return binaryPath;
17291
17399
  } catch {
17292
17400
  return null;
@@ -17296,13 +17404,13 @@ function resolveBdOnPath() {
17296
17404
  return _resolveSeam.resolveOnPath();
17297
17405
  }
17298
17406
  function _defaultResolveOnPath() {
17299
- const dirs = (process.env.PATH ?? "").split(path43.delimiter).filter(Boolean);
17407
+ const dirs = (process.env.PATH ?? "").split(path44.delimiter).filter(Boolean);
17300
17408
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
17301
17409
  for (const dir of dirs) {
17302
17410
  for (const candidate of candidates) {
17303
- const full = path43.join(dir, candidate);
17411
+ const full = path44.join(dir, candidate);
17304
17412
  try {
17305
- fs39.accessSync(full, fs39.constants.F_OK);
17413
+ fs40.accessSync(full, fs40.constants.F_OK);
17306
17414
  return full;
17307
17415
  } catch {
17308
17416
  }
@@ -17387,7 +17495,7 @@ var BdAdapter = class {
17387
17495
  const env = { ...process.env };
17388
17496
  if (!env.HOME) {
17389
17497
  try {
17390
- const home = os33.homedir();
17498
+ const home = os34.homedir();
17391
17499
  if (home) env.HOME = home;
17392
17500
  } catch {
17393
17501
  }
@@ -17476,9 +17584,9 @@ function coerceIssue(row, projectKey) {
17476
17584
 
17477
17585
  // src/beads/provisioner.ts
17478
17586
  var import_child_process21 = require("child_process");
17479
- var fs42 = __toESM(require("fs"));
17480
- var os35 = __toESM(require("os"));
17481
- var path46 = __toESM(require("path"));
17587
+ var fs43 = __toESM(require("fs"));
17588
+ var os36 = __toESM(require("os"));
17589
+ var path47 = __toESM(require("path"));
17482
17590
 
17483
17591
  // src/beads/install-bd.ts
17484
17592
  var import_child_process18 = require("child_process");
@@ -17543,9 +17651,9 @@ async function installBd(platform3 = process.platform) {
17543
17651
 
17544
17652
  // src/beads/install-dolt.ts
17545
17653
  var import_child_process19 = require("child_process");
17546
- var fs40 = __toESM(require("fs"));
17547
- var os34 = __toESM(require("os"));
17548
- var path44 = __toESM(require("path"));
17654
+ var fs41 = __toESM(require("fs"));
17655
+ var os35 = __toESM(require("os"));
17656
+ var path45 = __toESM(require("path"));
17549
17657
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
17550
17658
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
17551
17659
  function resolveDoltInstallStrategy(platform3) {
@@ -17585,11 +17693,11 @@ function resolveDoltInstallStrategy(platform3) {
17585
17693
  }
17586
17694
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
17587
17695
  function doltPlatformTuple(platform3, arch2) {
17588
- const os44 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17696
+ const os45 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17589
17697
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
17590
17698
  if (!a) return null;
17591
- if (os44 === "windows" && a !== "amd64") return null;
17592
- return `${os44}-${a}`;
17699
+ if (os45 === "windows" && a !== "amd64") return null;
17700
+ return `${os45}-${a}`;
17593
17701
  }
17594
17702
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
17595
17703
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -17634,14 +17742,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
17634
17742
  return result;
17635
17743
  }
17636
17744
  var _doltPathSeam = {
17637
- homedir: () => os34.homedir(),
17745
+ homedir: () => os35.homedir(),
17638
17746
  getPath: () => process.env.PATH ?? "",
17639
17747
  setPath: (p2) => {
17640
17748
  process.env.PATH = p2;
17641
17749
  },
17642
17750
  exists: (p2) => {
17643
17751
  try {
17644
- fs40.accessSync(p2, fs40.constants.F_OK);
17752
+ fs41.accessSync(p2, fs41.constants.F_OK);
17645
17753
  return true;
17646
17754
  } catch {
17647
17755
  return false;
@@ -17652,7 +17760,7 @@ function doltBinaryNames(platform3) {
17652
17760
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
17653
17761
  }
17654
17762
  function knownDoltDirs(platform3) {
17655
- const P3 = platform3 === "win32" ? path44.win32 : path44.posix;
17763
+ const P3 = platform3 === "win32" ? path45.win32 : path45.posix;
17656
17764
  const home = _doltPathSeam.homedir();
17657
17765
  if (platform3 === "win32") {
17658
17766
  return [
@@ -17668,7 +17776,7 @@ function knownDoltDirs(platform3) {
17668
17776
  ].filter(Boolean);
17669
17777
  }
17670
17778
  function ensureDoltResolvable(platform3 = process.platform) {
17671
- const P3 = platform3 === "win32" ? path44.win32 : path44.posix;
17779
+ const P3 = platform3 === "win32" ? path45.win32 : path45.posix;
17672
17780
  const delim = platform3 === "win32" ? ";" : ":";
17673
17781
  const names = doltBinaryNames(platform3);
17674
17782
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -17804,8 +17912,8 @@ async function ensureSharedServer(adapter, options = {}) {
17804
17912
  // src/beads/project-key.ts
17805
17913
  var import_child_process20 = require("child_process");
17806
17914
  var crypto2 = __toESM(require("crypto"));
17807
- var fs41 = __toESM(require("fs"));
17808
- var path45 = __toESM(require("path"));
17915
+ var fs42 = __toESM(require("fs"));
17916
+ var path46 = __toESM(require("path"));
17809
17917
  function normalizeOrigin(raw) {
17810
17918
  const trimmed = raw.trim();
17811
17919
  if (!trimmed) return null;
@@ -17831,17 +17939,17 @@ function normalizeOrigin(raw) {
17831
17939
  return `${host2}/${pathPart}`;
17832
17940
  }
17833
17941
  function findRepoRoot(cwd) {
17834
- let dir = path45.resolve(cwd);
17942
+ let dir = path46.resolve(cwd);
17835
17943
  const seen = /* @__PURE__ */ new Set();
17836
17944
  for (let i = 0; i < 256; i++) {
17837
17945
  if (seen.has(dir)) return null;
17838
17946
  seen.add(dir);
17839
17947
  try {
17840
- const stat3 = fs41.statSync(path45.join(dir, ".git"), { throwIfNoEntry: false });
17948
+ const stat3 = fs42.statSync(path46.join(dir, ".git"), { throwIfNoEntry: false });
17841
17949
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
17842
17950
  } catch {
17843
17951
  }
17844
- const parent = path45.dirname(dir);
17952
+ const parent = path46.dirname(dir);
17845
17953
  if (parent === dir) return null;
17846
17954
  dir = parent;
17847
17955
  }
@@ -17852,7 +17960,7 @@ var _execSeam2 = {
17852
17960
  const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
17853
17961
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
17854
17962
  },
17855
- realpath: (p2) => fs41.realpathSync(p2)
17963
+ realpath: (p2) => fs42.realpathSync(p2)
17856
17964
  };
17857
17965
  function readOrigin(cwd) {
17858
17966
  try {
@@ -17881,7 +17989,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
17881
17989
  } catch {
17882
17990
  }
17883
17991
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
17884
- return { projectKey: `path:${hash}`, projectLabel: path45.basename(real) || "project" };
17992
+ return { projectKey: `path:${hash}`, projectLabel: path46.basename(real) || "project" };
17885
17993
  }
17886
17994
 
17887
17995
  // src/beads/project-prefix.ts
@@ -17923,17 +18031,17 @@ var _provisionSeam = {
17923
18031
  };
17924
18032
  var _linkSeam = {
17925
18033
  platform: () => process.platform,
17926
- homedir: () => os35.homedir(),
18034
+ homedir: () => os36.homedir(),
17927
18035
  isWritableDir: (dir) => {
17928
18036
  try {
17929
- fs42.accessSync(dir, fs42.constants.W_OK);
18037
+ fs43.accessSync(dir, fs43.constants.W_OK);
17930
18038
  return true;
17931
18039
  } catch {
17932
18040
  return false;
17933
18041
  }
17934
18042
  },
17935
18043
  ensureDir: (dir) => {
17936
- fs42.mkdirSync(dir, { recursive: true });
18044
+ fs43.mkdirSync(dir, { recursive: true });
17937
18045
  },
17938
18046
  /**
17939
18047
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -17954,9 +18062,9 @@ var _linkSeam = {
17954
18062
  * which `linkBdOntoPath` creates if missing.
17955
18063
  */
17956
18064
  cliBinDir: () => {
17957
- const pathDirs = (process.env.PATH ?? "").split(path46.delimiter).filter(Boolean);
18065
+ const pathDirs = (process.env.PATH ?? "").split(path47.delimiter).filter(Boolean);
17958
18066
  const home = _linkSeam.homedir();
17959
- const localBin = home ? path46.join(home, ".local", "bin") : null;
18067
+ const localBin = home ? path47.join(home, ".local", "bin") : null;
17960
18068
  if (localBin) {
17961
18069
  try {
17962
18070
  _linkSeam.ensureDir(localBin);
@@ -17966,16 +18074,16 @@ var _linkSeam = {
17966
18074
  const candidates = [];
17967
18075
  if (localBin) candidates.push(localBin);
17968
18076
  try {
17969
- candidates.push(path46.dirname(process.execPath));
18077
+ candidates.push(path47.dirname(process.execPath));
17970
18078
  } catch {
17971
18079
  }
17972
18080
  candidates.push("/usr/local/bin");
17973
18081
  const entry = process.argv[1];
17974
18082
  if (entry) {
17975
18083
  try {
17976
- candidates.push(path46.dirname(fs42.realpathSync(entry)));
18084
+ candidates.push(path47.dirname(fs43.realpathSync(entry)));
17977
18085
  } catch {
17978
- candidates.push(path46.dirname(entry));
18086
+ candidates.push(path47.dirname(entry));
17979
18087
  }
17980
18088
  }
17981
18089
  const onPathWritable = candidates.find(
@@ -17987,20 +18095,20 @@ var _linkSeam = {
17987
18095
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
17988
18096
  readlink: (linkPath) => {
17989
18097
  try {
17990
- return fs42.readlinkSync(linkPath);
18098
+ return fs43.readlinkSync(linkPath);
17991
18099
  } catch {
17992
18100
  return null;
17993
18101
  }
17994
18102
  },
17995
- unlink: (linkPath) => fs42.unlinkSync(linkPath),
17996
- symlink: (target, linkPath) => fs42.symlinkSync(target, linkPath)
18103
+ unlink: (linkPath) => fs43.unlinkSync(linkPath),
18104
+ symlink: (target, linkPath) => fs43.symlinkSync(target, linkPath)
17997
18105
  };
17998
18106
  function linkBdOntoPath(binaryPath) {
17999
18107
  if (_linkSeam.platform() === "win32") return;
18000
18108
  const binDir = _linkSeam.cliBinDir();
18001
18109
  if (!binDir) return;
18002
18110
  _linkSeam.ensureDir(binDir);
18003
- const linkPath = path46.join(binDir, "bd");
18111
+ const linkPath = path47.join(binDir, "bd");
18004
18112
  if (linkPath === binaryPath) return;
18005
18113
  const current = _linkSeam.readlink(linkPath);
18006
18114
  if (current === binaryPath) return;
@@ -18195,7 +18303,7 @@ function dedupeRecipes(agents) {
18195
18303
 
18196
18304
  // src/beads/watcher.ts
18197
18305
  var crypto4 = __toESM(require("crypto"));
18198
- var path47 = __toESM(require("path"));
18306
+ var path48 = __toESM(require("path"));
18199
18307
  var API_BASE6 = resolveApiBaseUrl();
18200
18308
  var DEBOUNCE_MS2 = 400;
18201
18309
  var ZERO_SUMMARY = {
@@ -18219,7 +18327,7 @@ var BeadsWatcher = class {
18219
18327
  constructor(opts) {
18220
18328
  this.opts = opts;
18221
18329
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
18222
- this.feedPath = opts.feedPath ?? path47.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
18330
+ this.feedPath = opts.feedPath ?? path48.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
18223
18331
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
18224
18332
  }
18225
18333
  opts;
@@ -18629,7 +18737,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18629
18737
  function cleanupAttachmentTempFiles() {
18630
18738
  for (const p2 of pendingAttachmentFiles) {
18631
18739
  try {
18632
- fs44.unlinkSync(p2);
18740
+ fs45.unlinkSync(p2);
18633
18741
  } catch {
18634
18742
  }
18635
18743
  }
@@ -18638,8 +18746,8 @@ function cleanupAttachmentTempFiles() {
18638
18746
  function saveFilesTemp(files) {
18639
18747
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18640
18748
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18641
- const tmpPath = path49.join(os37.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18642
- fs44.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18749
+ const tmpPath = path50.join(os38.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18750
+ fs45.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18643
18751
  pendingAttachmentFiles.add(tmpPath);
18644
18752
  return tmpPath;
18645
18753
  });
@@ -18659,7 +18767,7 @@ var startTask = (ctx, _cmd, parsed) => {
18659
18767
  setTimeout(() => {
18660
18768
  for (const p2 of paths) {
18661
18769
  try {
18662
- fs44.unlinkSync(p2);
18770
+ fs45.unlinkSync(p2);
18663
18771
  } catch {
18664
18772
  }
18665
18773
  pendingAttachmentFiles.delete(p2);
@@ -18860,9 +18968,9 @@ var listFiles = async (ctx, cmd, parsed) => {
18860
18968
  await ctx.relay.sendResult(cmd.id, "completed", result);
18861
18969
  };
18862
18970
  var envReadH = async (ctx, cmd) => {
18863
- const envPath = path49.join(process.cwd(), ".env");
18971
+ const envPath = path50.join(process.cwd(), ".env");
18864
18972
  try {
18865
- const raw = await fs44.promises.readFile(envPath, "utf8");
18973
+ const raw = await fs45.promises.readFile(envPath, "utf8");
18866
18974
  await ctx.relay.sendResult(cmd.id, "completed", {
18867
18975
  exists: true,
18868
18976
  vars: parseDotenv(raw)
@@ -18893,14 +19001,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
18893
19001
  }
18894
19002
  seen.add(v.key);
18895
19003
  }
18896
- const envPath = path49.join(process.cwd(), ".env");
18897
- const tmpPath = path49.join(process.cwd(), ".env.codeam.tmp");
19004
+ const envPath = path50.join(process.cwd(), ".env");
19005
+ const tmpPath = path50.join(process.cwd(), ".env.codeam.tmp");
18898
19006
  try {
18899
- await fs44.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18900
- await fs44.promises.rename(tmpPath, envPath);
19007
+ await fs45.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
19008
+ await fs45.promises.rename(tmpPath, envPath);
18901
19009
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
18902
19010
  } catch (err) {
18903
- await fs44.promises.rm(tmpPath, { force: true }).catch(() => void 0);
19011
+ await fs45.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18904
19012
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
18905
19013
  }
18906
19014
  };
@@ -18918,7 +19026,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18918
19026
  let configuredAgent = rawAgentId;
18919
19027
  if (!configuredAgent) {
18920
19028
  try {
18921
- const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19029
+ const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
18922
19030
  configuredAgent = raw.agent ?? "";
18923
19031
  } catch {
18924
19032
  }
@@ -18931,7 +19039,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18931
19039
  setup: setupHeadroomForSelfHosted,
18932
19040
  probeStats: async () => {
18933
19041
  try {
18934
- const res = await fetch("http://localhost:8787/stats");
19042
+ const res = await fetchWithTimeout("http://localhost:8787/stats");
18935
19043
  if (!res.ok) return null;
18936
19044
  const raw = await res.json();
18937
19045
  return mapStatsToSavings(raw, {
@@ -18952,7 +19060,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18952
19060
  persist: persistHeadroomConfig,
18953
19061
  readEnabled: () => {
18954
19062
  try {
18955
- const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19063
+ const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
18956
19064
  return raw.enabled === true;
18957
19065
  } catch {
18958
19066
  return false;
@@ -18962,12 +19070,12 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18962
19070
  _activeReporter?.stop();
18963
19071
  const reporter = new HeadroomStatsReporter({
18964
19072
  fetchStats: async () => {
18965
- const res = await fetch("http://localhost:8787/stats");
19073
+ const res = await fetchWithTimeout("http://localhost:8787/stats");
18966
19074
  return res.json();
18967
19075
  },
18968
19076
  postSavings: async (delta, budget) => {
18969
19077
  if (!opts.ingestUrl) return;
18970
- await fetch(opts.ingestUrl, {
19078
+ const res = await fetchWithTimeout(opts.ingestUrl, {
18971
19079
  method: "POST",
18972
19080
  headers: {
18973
19081
  "Content-Type": "application/json",
@@ -18988,10 +19096,14 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18988
19096
  ...budget ? {
18989
19097
  periodSpendUsd: budget.periodSpendUsd,
18990
19098
  budgetUsd: budget.budgetUsd,
18991
- budgetPeriod: budget.budgetPeriod
19099
+ budgetPeriod: budget.budgetPeriod,
19100
+ budgetReached: budget.budgetReached
18992
19101
  } : {}
18993
19102
  })
18994
19103
  });
19104
+ if (!res.ok) {
19105
+ log.warn("headroom", `savings POST rejected ${res.status} \u2014 delta not credited`);
19106
+ }
18995
19107
  }
18996
19108
  });
18997
19109
  reporter.start();
@@ -19002,18 +19114,9 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
19002
19114
  _activeReporter = null;
19003
19115
  },
19004
19116
  restoreAgentHeadroomConfig: (kind) => restoreAgentHeadroomConfig(kind),
19005
- stopProxy: () => {
19006
- try {
19007
- const p2 = (0, import_child_process22.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
19008
- detached: true,
19009
- stdio: "ignore"
19010
- });
19011
- p2.on("error", () => {
19012
- });
19013
- p2.unref();
19014
- } catch {
19015
- }
19016
- },
19117
+ // Targeted pidfile kill; falls back to the legacy pkill pattern only when
19118
+ // no live recorded pid exists. Best-effort — never throws.
19119
+ stopProxy: () => killHeadroomProxy(),
19017
19120
  emit: (event) => {
19018
19121
  const token = ctx.pluginAuthToken;
19019
19122
  if (!token) return;
@@ -19046,7 +19149,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19046
19149
  }
19047
19150
  let headroomActive = false;
19048
19151
  try {
19049
- const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19152
+ const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
19050
19153
  headroomActive = raw.enabled === true;
19051
19154
  } catch {
19052
19155
  }
@@ -19056,7 +19159,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19056
19159
  }
19057
19160
  let existingConfig = { enabled: true };
19058
19161
  try {
19059
- existingConfig = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19162
+ existingConfig = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
19060
19163
  } catch {
19061
19164
  }
19062
19165
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -19174,13 +19277,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
19174
19277
  function buildNpmInstallInvocation(opts) {
19175
19278
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
19176
19279
  const execPath = opts?.execPath ?? process.execPath;
19177
- const exists2 = opts?.existsSync ?? fs44.existsSync;
19178
- const normalized = entryScript.split(path49.sep).join("/");
19280
+ const exists2 = opts?.existsSync ?? fs45.existsSync;
19281
+ const normalized = entryScript.split(path50.sep).join("/");
19179
19282
  const marker = "/lib/node_modules/codeam-cli/";
19180
19283
  const markerIdx = normalized.indexOf(marker);
19181
19284
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
19182
- const siblingNpm = path49.join(
19183
- path49.dirname(execPath),
19285
+ const siblingNpm = path50.join(
19286
+ path50.dirname(execPath),
19184
19287
  process.platform === "win32" ? "npm.cmd" : "npm"
19185
19288
  );
19186
19289
  const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
@@ -19687,8 +19790,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
19687
19790
  if (args2.length === 0) return detection;
19688
19791
  const binName = args2[0];
19689
19792
  if (binName.startsWith("-")) return detection;
19690
- const binPath = path49.join(cwd, "node_modules", ".bin", binName);
19691
- if (!fs44.existsSync(binPath)) return detection;
19793
+ const binPath = path50.join(cwd, "node_modules", ".bin", binName);
19794
+ if (!fs45.existsSync(binPath)) return detection;
19692
19795
  return {
19693
19796
  ...detection,
19694
19797
  command: binPath,
@@ -20507,12 +20610,12 @@ function readTokenFromArgs(args2) {
20507
20610
  }
20508
20611
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
20509
20612
  if (fileFlag) {
20510
- const path64 = fileFlag.slice("--token-file=".length);
20613
+ const path65 = fileFlag.slice("--token-file=".length);
20511
20614
  try {
20512
- const content = fs45.readFileSync(path64, "utf8").trim();
20513
- if (content.length === 0) fail(`--token-file ${path64} is empty`);
20615
+ const content = fs46.readFileSync(path65, "utf8").trim();
20616
+ if (content.length === 0) fail(`--token-file ${path65} is empty`);
20514
20617
  try {
20515
- fs45.unlinkSync(path64);
20618
+ fs46.unlinkSync(path65);
20516
20619
  } catch {
20517
20620
  }
20518
20621
  return content;
@@ -20538,7 +20641,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
20538
20641
  pluginId,
20539
20642
  ideName: "codeam-cli (codespace)",
20540
20643
  ideVersion: process.env.npm_package_version ?? "unknown",
20541
- hostname: os38.hostname(),
20644
+ hostname: os39.hostname(),
20542
20645
  codespaceName: process.env.CODESPACE_NAME ?? "",
20543
20646
  // Current git branch of the codespace's working directory, so the
20544
20647
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -20599,7 +20702,7 @@ async function claim(token, pluginId, pluginSecretHash) {
20599
20702
  }
20600
20703
  }
20601
20704
  function pairAutoLockPath() {
20602
- return path50.join(os38.homedir(), ".codeam", "pair-auto.lock");
20705
+ return path51.join(os39.homedir(), ".codeam", "pair-auto.lock");
20603
20706
  }
20604
20707
  function isLivePairAuto(pid) {
20605
20708
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -20609,7 +20712,7 @@ function isLivePairAuto(pid) {
20609
20712
  if (e.code !== "EPERM") return false;
20610
20713
  }
20611
20714
  try {
20612
- return fs45.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20715
+ return fs46.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20613
20716
  } catch {
20614
20717
  return true;
20615
20718
  }
@@ -20619,24 +20722,24 @@ function isLiveCodeam(pid) {
20619
20722
  }
20620
20723
  function daemonLockPath(sessionId) {
20621
20724
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
20622
- return path50.join(os38.homedir(), ".codeam", `daemon-${safe}.lock`);
20725
+ return path51.join(os39.homedir(), ".codeam", `daemon-${safe}.lock`);
20623
20726
  }
20624
20727
  function acquireDaemonLock(sessionId) {
20625
20728
  const lockPath = daemonLockPath(sessionId);
20626
20729
  try {
20627
- fs45.mkdirSync(path50.dirname(lockPath), { recursive: true });
20730
+ fs46.mkdirSync(path51.dirname(lockPath), { recursive: true });
20628
20731
  try {
20629
- fs45.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20732
+ fs46.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20630
20733
  } catch (e) {
20631
20734
  if (e.code !== "EEXIST") throw e;
20632
- const holder = Number(fs45.readFileSync(lockPath, "utf8").trim());
20735
+ const holder = Number(fs46.readFileSync(lockPath, "utf8").trim());
20633
20736
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
20634
- fs45.writeFileSync(lockPath, String(process.pid));
20737
+ fs46.writeFileSync(lockPath, String(process.pid));
20635
20738
  }
20636
20739
  const release3 = () => {
20637
20740
  try {
20638
- if (fs45.existsSync(lockPath) && Number(fs45.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20639
- fs45.unlinkSync(lockPath);
20741
+ if (fs46.existsSync(lockPath) && Number(fs46.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20742
+ fs46.unlinkSync(lockPath);
20640
20743
  }
20641
20744
  } catch {
20642
20745
  }
@@ -20658,19 +20761,19 @@ function acquireDaemonLock(sessionId) {
20658
20761
  function acquireSingletonLock() {
20659
20762
  const lockPath = pairAutoLockPath();
20660
20763
  try {
20661
- fs45.mkdirSync(path50.dirname(lockPath), { recursive: true });
20764
+ fs46.mkdirSync(path51.dirname(lockPath), { recursive: true });
20662
20765
  try {
20663
- fs45.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20766
+ fs46.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20664
20767
  } catch (e) {
20665
20768
  if (e.code !== "EEXIST") throw e;
20666
- const holder = Number(fs45.readFileSync(lockPath, "utf8").trim());
20769
+ const holder = Number(fs46.readFileSync(lockPath, "utf8").trim());
20667
20770
  if (isLivePairAuto(holder)) return false;
20668
- fs45.writeFileSync(lockPath, String(process.pid));
20771
+ fs46.writeFileSync(lockPath, String(process.pid));
20669
20772
  }
20670
20773
  process.once("exit", () => {
20671
20774
  try {
20672
- if (fs45.existsSync(lockPath) && Number(fs45.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20673
- fs45.unlinkSync(lockPath);
20775
+ if (fs46.existsSync(lockPath) && Number(fs46.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20776
+ fs46.unlinkSync(lockPath);
20674
20777
  }
20675
20778
  } catch {
20676
20779
  }
@@ -20752,7 +20855,7 @@ async function pairAuto(args2) {
20752
20855
  }
20753
20856
 
20754
20857
  // src/services/headroom/wrap-launch.ts
20755
- var import_node_child_process16 = require("child_process");
20858
+ var import_node_child_process17 = require("child_process");
20756
20859
  function wrapWithHeadroom(launch, opts) {
20757
20860
  if (!opts.enabled || !opts.headroomPresent) return launch;
20758
20861
  return {
@@ -20765,7 +20868,7 @@ var _present;
20765
20868
  function headroomPresent() {
20766
20869
  if (_present !== void 0) return Promise.resolve(_present);
20767
20870
  return new Promise((resolve7) => {
20768
- (0, import_node_child_process16.execFile)("headroom", ["--version"], (err) => {
20871
+ (0, import_node_child_process17.execFile)("headroom", ["--version"], (err) => {
20769
20872
  _present = !err;
20770
20873
  resolve7(_present);
20771
20874
  });
@@ -21115,7 +21218,7 @@ var AgentService = class _AgentService {
21115
21218
  };
21116
21219
 
21117
21220
  // src/agents/acp/adapters.ts
21118
- var path52 = __toESM(require("path"));
21221
+ var path53 = __toESM(require("path"));
21119
21222
 
21120
21223
  // src/agents/acp/agent-binary.ts
21121
21224
  var import_fs4 = __toESM(require("fs"));
@@ -21268,13 +21371,13 @@ function resolveBin(pkgName, binName) {
21268
21371
  try {
21269
21372
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
21270
21373
  const manifest = require_(`${pkgName}/package.json`);
21271
- const pkgDir = path52.dirname(manifestPath);
21374
+ const pkgDir = path53.dirname(manifestPath);
21272
21375
  const bin = manifest.bin;
21273
21376
  if (!bin) return null;
21274
- if (typeof bin === "string") return path52.resolve(pkgDir, bin);
21377
+ if (typeof bin === "string") return path53.resolve(pkgDir, bin);
21275
21378
  const target = binName ?? Object.keys(bin)[0];
21276
21379
  if (!target || !bin[target]) return null;
21277
- return path52.resolve(pkgDir, bin[target]);
21380
+ return path53.resolve(pkgDir, bin[target]);
21278
21381
  } catch {
21279
21382
  return null;
21280
21383
  }
@@ -21349,9 +21452,9 @@ function requiresAcp(agent) {
21349
21452
  var import_node_crypto7 = require("crypto");
21350
21453
 
21351
21454
  // src/services/history.service.ts
21352
- var fs47 = __toESM(require("fs"));
21353
- var path53 = __toESM(require("path"));
21354
- var os39 = __toESM(require("os"));
21455
+ var fs48 = __toESM(require("fs"));
21456
+ var path54 = __toESM(require("path"));
21457
+ var os40 = __toESM(require("os"));
21355
21458
  var https7 = __toESM(require("https"));
21356
21459
  var http6 = __toESM(require("http"));
21357
21460
  var import_zod2 = require("zod");
@@ -21378,7 +21481,7 @@ function parseJsonl(filePath) {
21378
21481
  const messages = [];
21379
21482
  let raw;
21380
21483
  try {
21381
- raw = fs47.readFileSync(filePath, "utf8");
21484
+ raw = fs48.readFileSync(filePath, "utf8");
21382
21485
  } catch (err) {
21383
21486
  if (err.code !== "ENOENT") {
21384
21487
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -21519,7 +21622,7 @@ var HistoryService = class _HistoryService {
21519
21622
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
21520
21623
  }
21521
21624
  get projectDir() {
21522
- return this.runtime.resolveHistoryDir(this.cwd) ?? path53.join(os39.homedir(), ".claude", "projects", encodeCwd(this.cwd));
21625
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path54.join(os40.homedir(), ".claude", "projects", encodeCwd(this.cwd));
21523
21626
  }
21524
21627
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
21525
21628
  setCurrentConversationId(id) {
@@ -21531,7 +21634,7 @@ var HistoryService = class _HistoryService {
21531
21634
  /** Return the current message count in the active conversation. */
21532
21635
  getCurrentMessageCount() {
21533
21636
  if (!this.currentConversationId) return 0;
21534
- const filePath = path53.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21637
+ const filePath = path54.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21535
21638
  return parseJsonl(filePath).length;
21536
21639
  }
21537
21640
  /**
@@ -21542,7 +21645,7 @@ var HistoryService = class _HistoryService {
21542
21645
  const deadline = Date.now() + timeoutMs;
21543
21646
  while (Date.now() < deadline) {
21544
21647
  if (!this.currentConversationId) return null;
21545
- const filePath = path53.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21648
+ const filePath = path54.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21546
21649
  const messages = parseJsonl(filePath);
21547
21650
  if (messages.length > previousCount) {
21548
21651
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -21568,16 +21671,16 @@ var HistoryService = class _HistoryService {
21568
21671
  const dir = this.projectDir;
21569
21672
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21570
21673
  try {
21571
- const files = fs47.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21674
+ const files = fs48.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21572
21675
  try {
21573
- const stat3 = fs47.statSync(path53.join(dir, e.name));
21676
+ const stat3 = fs48.statSync(path54.join(dir, e.name));
21574
21677
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
21575
21678
  } catch {
21576
21679
  return { name: e.name, mtime: 0, birthtime: 0 };
21577
21680
  }
21578
21681
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
21579
21682
  if (files.length > 0) {
21580
- this.currentConversationId = path53.basename(files[0].name, ".jsonl");
21683
+ this.currentConversationId = path54.basename(files[0].name, ".jsonl");
21581
21684
  }
21582
21685
  } catch {
21583
21686
  }
@@ -21611,13 +21714,13 @@ var HistoryService = class _HistoryService {
21611
21714
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21612
21715
  let entries;
21613
21716
  try {
21614
- entries = fs47.readdirSync(dir, { withFileTypes: true });
21717
+ entries = fs48.readdirSync(dir, { withFileTypes: true });
21615
21718
  } catch {
21616
21719
  return null;
21617
21720
  }
21618
21721
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21619
21722
  try {
21620
- const stat3 = fs47.statSync(path53.join(dir, e.name));
21723
+ const stat3 = fs48.statSync(path54.join(dir, e.name));
21621
21724
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
21622
21725
  } catch {
21623
21726
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -21626,12 +21729,12 @@ var HistoryService = class _HistoryService {
21626
21729
  if (files.length === 0) return null;
21627
21730
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
21628
21731
  if (!files.some((f) => f.name === targetFile)) return null;
21629
- return this.extractUsageFromFile(path53.join(dir, targetFile));
21732
+ return this.extractUsageFromFile(path54.join(dir, targetFile));
21630
21733
  }
21631
21734
  extractUsageFromFile(filePath) {
21632
21735
  let raw;
21633
21736
  try {
21634
- raw = fs47.readFileSync(filePath, "utf8");
21737
+ raw = fs48.readFileSync(filePath, "utf8");
21635
21738
  } catch {
21636
21739
  return null;
21637
21740
  }
@@ -21676,9 +21779,9 @@ var HistoryService = class _HistoryService {
21676
21779
  let totalCost = 0;
21677
21780
  let files;
21678
21781
  try {
21679
- files = fs47.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21782
+ files = fs48.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21680
21783
  try {
21681
- return fs47.statSync(path53.join(projectDir, f)).mtimeMs >= monthStartMs;
21784
+ return fs48.statSync(path54.join(projectDir, f)).mtimeMs >= monthStartMs;
21682
21785
  } catch {
21683
21786
  return false;
21684
21787
  }
@@ -21689,7 +21792,7 @@ var HistoryService = class _HistoryService {
21689
21792
  for (const file of files) {
21690
21793
  let raw;
21691
21794
  try {
21692
- raw = fs47.readFileSync(path53.join(projectDir, file), "utf8");
21795
+ raw = fs48.readFileSync(path54.join(projectDir, file), "utf8");
21693
21796
  } catch {
21694
21797
  continue;
21695
21798
  }
@@ -21768,7 +21871,7 @@ var HistoryService = class _HistoryService {
21768
21871
  if (this.runtime.resolveHistoryFile) {
21769
21872
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
21770
21873
  }
21771
- return path53.join(this.projectDir, `${sessionId}.jsonl`);
21874
+ return path54.join(this.projectDir, `${sessionId}.jsonl`);
21772
21875
  }
21773
21876
  /**
21774
21877
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -21802,7 +21905,7 @@ var HistoryService = class _HistoryService {
21802
21905
  };
21803
21906
  });
21804
21907
  }
21805
- return parseJsonl(path53.join(this.projectDir, `${sessionId}.jsonl`));
21908
+ return parseJsonl(path54.join(this.projectDir, `${sessionId}.jsonl`));
21806
21909
  }
21807
21910
  async loadConversation(sessionId) {
21808
21911
  const messages = this.readConversation(sessionId);
@@ -21858,7 +21961,7 @@ var HistoryService = class _HistoryService {
21858
21961
  if (!filePath) return false;
21859
21962
  let mtimeMs;
21860
21963
  try {
21861
- mtimeMs = fs47.statSync(filePath).mtimeMs;
21964
+ mtimeMs = fs48.statSync(filePath).mtimeMs;
21862
21965
  } catch {
21863
21966
  return false;
21864
21967
  }
@@ -21926,11 +22029,11 @@ var HistoryService = class _HistoryService {
21926
22029
  };
21927
22030
 
21928
22031
  // src/agents/acp/client.ts
21929
- var import_node_child_process17 = require("child_process");
21930
- var fs48 = __toESM(require("fs/promises"));
22032
+ var import_node_child_process18 = require("child_process");
22033
+ var fs49 = __toESM(require("fs/promises"));
21931
22034
  var fsSync = __toESM(require("fs"));
21932
- var os40 = __toESM(require("os"));
21933
- var path54 = __toESM(require("path"));
22035
+ var os41 = __toESM(require("os"));
22036
+ var path55 = __toESM(require("path"));
21934
22037
  var import_node_stream = require("stream");
21935
22038
 
21936
22039
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -24477,7 +24580,7 @@ var AcpClient = class {
24477
24580
  "acpClient",
24478
24581
  `spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
24479
24582
  );
24480
- const child = (0, import_node_child_process17.spawn)(adapter.command, adapter.args, {
24583
+ const child = (0, import_node_child_process18.spawn)(adapter.command, adapter.args, {
24481
24584
  cwd,
24482
24585
  // extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
24483
24586
  // re-spawn) layers over process.env; PATH stays last so the augmented
@@ -24763,7 +24866,7 @@ var AcpClient = class {
24763
24866
  },
24764
24867
  readTextFile: async (params) => {
24765
24868
  try {
24766
- const content = await fs48.readFile(params.path, "utf8");
24869
+ const content = await fs49.readFile(params.path, "utf8");
24767
24870
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
24768
24871
  } catch (err) {
24769
24872
  const code = err.code;
@@ -24783,7 +24886,7 @@ var AcpClient = class {
24783
24886
  },
24784
24887
  writeTextFile: async (params) => {
24785
24888
  try {
24786
- await fs48.writeFile(params.path, params.content, "utf8");
24889
+ await fs49.writeFile(params.path, params.content, "utf8");
24787
24890
  return {};
24788
24891
  } catch (err) {
24789
24892
  const code = err.code;
@@ -24832,25 +24935,25 @@ function applyLineRange(content, line, limit) {
24832
24935
  return { content: lines.slice(start2, end).join("\n") };
24833
24936
  }
24834
24937
  function knownAgentBinaryDirs() {
24835
- const home = os40.homedir();
24938
+ const home = os41.homedir();
24836
24939
  const out2 = [];
24837
24940
  out2.push("/tmp/codeam-node20/bin");
24838
24941
  for (const root of [
24839
24942
  "/usr/local/share/nvm/versions/node",
24840
- path54.join(home, ".nvm/versions/node")
24943
+ path55.join(home, ".nvm/versions/node")
24841
24944
  ]) {
24842
24945
  try {
24843
24946
  for (const child of fsSync.readdirSync(root)) {
24844
- out2.push(path54.join(root, child, "bin"));
24947
+ out2.push(path55.join(root, child, "bin"));
24845
24948
  }
24846
24949
  } catch {
24847
24950
  }
24848
24951
  }
24849
- out2.push(path54.join(home, ".volta/bin"));
24952
+ out2.push(path55.join(home, ".volta/bin"));
24850
24953
  out2.push("/usr/local/bin");
24851
24954
  out2.push("/usr/bin");
24852
- out2.push(path54.join(home, ".local/bin"));
24853
- out2.push(path54.join(home, "bin"));
24955
+ out2.push(path55.join(home, ".local/bin"));
24956
+ out2.push(path55.join(home, "bin"));
24854
24957
  return out2.filter((p2) => {
24855
24958
  try {
24856
24959
  return fsSync.statSync(p2).isDirectory();
@@ -24861,7 +24964,7 @@ function knownAgentBinaryDirs() {
24861
24964
  }
24862
24965
  function expandPathForAgentBinaries(existingPath) {
24863
24966
  const existing = new Set(
24864
- existingPath.split(path54.delimiter).filter((p2) => p2.length > 0)
24967
+ existingPath.split(path55.delimiter).filter((p2) => p2.length > 0)
24865
24968
  );
24866
24969
  const additions = [];
24867
24970
  for (const dir of knownAgentBinaryDirs()) {
@@ -24871,7 +24974,7 @@ function expandPathForAgentBinaries(existingPath) {
24871
24974
  }
24872
24975
  }
24873
24976
  if (additions.length === 0) return existingPath;
24874
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path54.delimiter);
24977
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path55.delimiter);
24875
24978
  }
24876
24979
 
24877
24980
  // src/services/streaming/transport.ts
@@ -25416,15 +25519,15 @@ function commonPrefixLength(a, b) {
25416
25519
 
25417
25520
  // src/agents/acp/onboarding.ts
25418
25521
  var import_child_process25 = require("child_process");
25419
- var fs49 = __toESM(require("fs"));
25420
- var os41 = __toESM(require("os"));
25421
- var path55 = __toESM(require("path"));
25522
+ var fs50 = __toESM(require("fs"));
25523
+ var os42 = __toESM(require("os"));
25524
+ var path56 = __toESM(require("path"));
25422
25525
  var _onboardingSeam = {
25423
- markerPath: (sessionId) => path55.join(os41.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25424
- exists: (p2) => fs49.existsSync(p2),
25526
+ markerPath: (sessionId) => path56.join(os42.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25527
+ exists: (p2) => fs50.existsSync(p2),
25425
25528
  write: (p2) => {
25426
- fs49.mkdirSync(path55.dirname(p2), { recursive: true });
25427
- fs49.writeFileSync(p2, "");
25529
+ fs50.mkdirSync(path56.dirname(p2), { recursive: true });
25530
+ fs50.writeFileSync(p2, "");
25428
25531
  },
25429
25532
  disabled: () => {
25430
25533
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -25461,7 +25564,7 @@ function resolveRepoName(cwd) {
25461
25564
  if (name) return name;
25462
25565
  }
25463
25566
  }
25464
- const base = path55.basename(cwd || "");
25567
+ const base = path56.basename(cwd || "");
25465
25568
  if (base && !isUuid(base)) return base;
25466
25569
  return "this project";
25467
25570
  }
@@ -25739,8 +25842,8 @@ var import_crypto5 = require("crypto");
25739
25842
 
25740
25843
  // src/services/turn-files/git-changeset.ts
25741
25844
  var import_child_process26 = require("child_process");
25742
- var fs50 = __toESM(require("fs/promises"));
25743
- var path56 = __toESM(require("path"));
25845
+ var fs51 = __toESM(require("fs/promises"));
25846
+ var path57 = __toESM(require("path"));
25744
25847
  async function collectRepoChangeset(opts) {
25745
25848
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
25746
25849
  if (status2 === null) return null;
@@ -25758,7 +25861,7 @@ async function collectRepoChangeset(opts) {
25758
25861
  let stats;
25759
25862
  if (row.fileStatus === "added" && numstatEntry === void 0) {
25760
25863
  const lineCount = await readUntrackedLineCount(
25761
- path56.join(opts.repoRoot, row.filePath)
25864
+ path57.join(opts.repoRoot, row.filePath)
25762
25865
  );
25763
25866
  stats = { added: lineCount, removed: 0 };
25764
25867
  } else {
@@ -25789,7 +25892,7 @@ function readUntrackedLineCount(absPath) {
25789
25892
  }
25790
25893
  async function defaultReadUntrackedLineCount(absPath) {
25791
25894
  try {
25792
- const content = await fs50.readFile(absPath, "utf8");
25895
+ const content = await fs51.readFile(absPath, "utf8");
25793
25896
  let count = 0;
25794
25897
  let pos = -1;
25795
25898
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -25881,7 +25984,7 @@ function defaultRunGit(cwd, args2) {
25881
25984
  });
25882
25985
  }
25883
25986
  async function discoverRepos(workingDir, maxDepth = 4) {
25884
- const fs54 = await import("fs/promises");
25987
+ const fs55 = await import("fs/promises");
25885
25988
  const out2 = [];
25886
25989
  await walk(workingDir, 0);
25887
25990
  return out2;
@@ -25889,7 +25992,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25889
25992
  if (depth > maxDepth) return;
25890
25993
  let entries = [];
25891
25994
  try {
25892
- const dirents = await fs54.readdir(dir, { withFileTypes: true });
25995
+ const dirents = await fs55.readdir(dir, { withFileTypes: true });
25893
25996
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
25894
25997
  } catch {
25895
25998
  return;
@@ -25900,8 +26003,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25900
26003
  if (hasGit) {
25901
26004
  out2.push({
25902
26005
  repoRoot: dir,
25903
- repoPath: path56.relative(workingDir, dir),
25904
- repoName: path56.basename(dir)
26006
+ repoPath: path57.relative(workingDir, dir),
26007
+ repoName: path57.basename(dir)
25905
26008
  });
25906
26009
  return;
25907
26010
  }
@@ -25909,14 +26012,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25909
26012
  if (!entry.isDirectory) continue;
25910
26013
  if (entry.name === "node_modules") continue;
25911
26014
  if (entry.name === "dist" || entry.name === "build") continue;
25912
- await walk(path56.join(dir, entry.name), depth + 1);
26015
+ await walk(path57.join(dir, entry.name), depth + 1);
25913
26016
  }
25914
26017
  }
25915
26018
  }
25916
26019
 
25917
26020
  // src/services/turn-files/files-outbox.ts
25918
- var fs51 = __toESM(require("fs/promises"));
25919
- var path57 = __toESM(require("path"));
26021
+ var fs52 = __toESM(require("fs/promises"));
26022
+ var path58 = __toESM(require("path"));
25920
26023
  var import_os7 = require("os");
25921
26024
  var HOME_OUTBOX_DIR = ".codeam/outbox";
25922
26025
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -25949,16 +26052,16 @@ var FilesOutbox = class {
25949
26052
  backoffIndex = 0;
25950
26053
  stopped = false;
25951
26054
  constructor(opts) {
25952
- const base = opts.baseDir ?? path57.join(homeDir(), HOME_OUTBOX_DIR);
25953
- this.filePath = path57.join(base, `${opts.sessionId}.jsonl`);
26055
+ const base = opts.baseDir ?? path58.join(homeDir(), HOME_OUTBOX_DIR);
26056
+ this.filePath = path58.join(base, `${opts.sessionId}.jsonl`);
25954
26057
  this.post = opts.post;
25955
26058
  this.autoSchedule = opts.autoSchedule !== false;
25956
26059
  }
25957
26060
  /** Persist the entry to disk and trigger a flush. Returns once the
25958
26061
  * line is durable on disk (not once the POST succeeds). */
25959
26062
  async enqueue(entry) {
25960
- await fs51.mkdir(path57.dirname(this.filePath), { recursive: true });
25961
- await fs51.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
26063
+ await fs52.mkdir(path58.dirname(this.filePath), { recursive: true });
26064
+ await fs52.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25962
26065
  this.backoffIndex = 0;
25963
26066
  if (this.autoSchedule) this.scheduleFlush(0);
25964
26067
  }
@@ -26047,7 +26150,7 @@ var FilesOutbox = class {
26047
26150
  async readAll() {
26048
26151
  let raw = "";
26049
26152
  try {
26050
- raw = await fs51.readFile(this.filePath, "utf8");
26153
+ raw = await fs52.readFile(this.filePath, "utf8");
26051
26154
  } catch {
26052
26155
  return [];
26053
26156
  }
@@ -26071,12 +26174,12 @@ var FilesOutbox = class {
26071
26174
  async rewrite(entries) {
26072
26175
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
26073
26176
  if (entries.length === 0) {
26074
- await fs51.unlink(this.filePath).catch(() => void 0);
26177
+ await fs52.unlink(this.filePath).catch(() => void 0);
26075
26178
  return;
26076
26179
  }
26077
26180
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
26078
- await fs51.writeFile(tmpPath, payload, "utf8");
26079
- await fs51.rename(tmpPath, this.filePath);
26181
+ await fs52.writeFile(tmpPath, payload, "utf8");
26182
+ await fs52.rename(tmpPath, this.filePath);
26080
26183
  }
26081
26184
  };
26082
26185
  function applyJitter(ms) {
@@ -27066,21 +27169,12 @@ async function runAcpSession(opts) {
27066
27169
  });
27067
27170
  let _budgetReachedPosted = false;
27068
27171
  const relaunchProxyWithoutBudget = async () => {
27069
- const { spawn: spawn35 } = await import("child_process");
27070
- try {
27071
- const killer = spawn35("pkill", ["-TERM", "-f", "headroom.*proxy"], {
27072
- detached: true,
27073
- stdio: "ignore"
27074
- });
27075
- killer.once("error", () => {
27076
- });
27077
- killer.unref();
27078
- } catch {
27079
- }
27172
+ const { spawn: spawn36 } = await import("child_process");
27173
+ killHeadroomProxy();
27080
27174
  await new Promise((r) => setTimeout(r, 500));
27081
27175
  const proxyEnv = buildRelaunchProxyEnv(process.env);
27082
27176
  try {
27083
- const proxy = spawn35(
27177
+ const proxy = spawn36(
27084
27178
  "headroom",
27085
27179
  ["proxy", "--port", "8787"],
27086
27180
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -27089,6 +27183,7 @@ async function runAcpSession(opts) {
27089
27183
  log.warn("acpRunner", `budget recovery proxy relaunch error (best-effort): ${e.message}`);
27090
27184
  });
27091
27185
  proxy.unref();
27186
+ writeHeadroomProxyPidfile(proxy.pid);
27092
27187
  } catch (e) {
27093
27188
  log.warn(
27094
27189
  "acpRunner",
@@ -28733,15 +28828,15 @@ function fetchQuotaUsage(runtime, historySvc) {
28733
28828
  }
28734
28829
 
28735
28830
  // src/agents/claude/onboarding.ts
28736
- var fs52 = __toESM(require("fs"));
28737
- var os42 = __toESM(require("os"));
28738
- var path58 = __toESM(require("path"));
28831
+ var fs53 = __toESM(require("fs"));
28832
+ var os43 = __toESM(require("os"));
28833
+ var path59 = __toESM(require("path"));
28739
28834
  function ensureClaudeOnboarded() {
28740
28835
  try {
28741
- const file = path58.join(os42.homedir(), ".claude.json");
28836
+ const file = path59.join(os43.homedir(), ".claude.json");
28742
28837
  let config = {};
28743
28838
  try {
28744
- config = JSON.parse(fs52.readFileSync(file, "utf8"));
28839
+ config = JSON.parse(fs53.readFileSync(file, "utf8"));
28745
28840
  } catch {
28746
28841
  }
28747
28842
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -28752,8 +28847,8 @@ function ensureClaudeOnboarded() {
28752
28847
  if (typeof config.lastOnboardingVersion !== "string") {
28753
28848
  config.lastOnboardingVersion = "2.1.177";
28754
28849
  }
28755
- fs52.mkdirSync(path58.dirname(file), { recursive: true });
28756
- fs52.writeFileSync(file, JSON.stringify(config, null, 2));
28850
+ fs53.mkdirSync(path59.dirname(file), { recursive: true });
28851
+ fs53.writeFileSync(file, JSON.stringify(config, null, 2));
28757
28852
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
28758
28853
  } catch (err) {
28759
28854
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -29410,7 +29505,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
29410
29505
  var import_child_process27 = require("child_process");
29411
29506
  var import_util4 = require("util");
29412
29507
  var import_picocolors9 = __toESM(require("picocolors"));
29413
- var path59 = __toESM(require("path"));
29508
+ var path60 = __toESM(require("path"));
29414
29509
  var execFileP6 = (0, import_util4.promisify)(import_child_process27.execFile);
29415
29510
  var MAX_BUFFER = 8 * 1024 * 1024;
29416
29511
  function resetStdinForChild() {
@@ -29899,7 +29994,7 @@ var GitHubCodespacesProvider = class {
29899
29994
  });
29900
29995
  }
29901
29996
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29902
- const remoteDir = path59.posix.dirname(remotePath);
29997
+ const remoteDir = path60.posix.dirname(remotePath);
29903
29998
  const parts = [
29904
29999
  `mkdir -p ${shellQuote(remoteDir)}`,
29905
30000
  `cat > ${shellQuote(remotePath)}`
@@ -29969,7 +30064,7 @@ function shellQuote(s) {
29969
30064
  // src/services/providers/gitpod.ts
29970
30065
  var import_child_process28 = require("child_process");
29971
30066
  var import_util5 = require("util");
29972
- var path60 = __toESM(require("path"));
30067
+ var path61 = __toESM(require("path"));
29973
30068
  var import_picocolors10 = __toESM(require("picocolors"));
29974
30069
  var execFileP7 = (0, import_util5.promisify)(import_child_process28.execFile);
29975
30070
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -30209,7 +30304,7 @@ var GitpodProvider = class {
30209
30304
  });
30210
30305
  }
30211
30306
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
30212
- const remoteDir = path60.posix.dirname(remotePath);
30307
+ const remoteDir = path61.posix.dirname(remotePath);
30213
30308
  const parts = [
30214
30309
  `mkdir -p ${shellQuote2(remoteDir)}`,
30215
30310
  `cat > ${shellQuote2(remotePath)}`
@@ -30245,7 +30340,7 @@ function shellQuote2(s) {
30245
30340
  // src/services/providers/gitlab-workspaces.ts
30246
30341
  var import_child_process29 = require("child_process");
30247
30342
  var import_util6 = require("util");
30248
- var path61 = __toESM(require("path"));
30343
+ var path62 = __toESM(require("path"));
30249
30344
  var execFileP8 = (0, import_util6.promisify)(import_child_process29.execFile);
30250
30345
  var MAX_BUFFER3 = 8 * 1024 * 1024;
30251
30346
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -30505,7 +30600,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
30505
30600
  }
30506
30601
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
30507
30602
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
30508
- const remoteDir = path61.posix.dirname(remotePath);
30603
+ const remoteDir = path62.posix.dirname(remotePath);
30509
30604
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
30510
30605
  if (options.mode != null) {
30511
30606
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -30573,7 +30668,7 @@ function shellQuote3(s) {
30573
30668
  // src/services/providers/railway.ts
30574
30669
  var import_child_process30 = require("child_process");
30575
30670
  var import_util7 = require("util");
30576
- var path62 = __toESM(require("path"));
30671
+ var path63 = __toESM(require("path"));
30577
30672
  var execFileP9 = (0, import_util7.promisify)(import_child_process30.execFile);
30578
30673
  var MAX_BUFFER4 = 8 * 1024 * 1024;
30579
30674
  function resetStdinForChild4() {
@@ -30809,7 +30904,7 @@ var RailwayProvider = class {
30809
30904
  if (!projectId || !serviceId) {
30810
30905
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
30811
30906
  }
30812
- const remoteDir = path62.posix.dirname(remotePath);
30907
+ const remoteDir = path63.posix.dirname(remotePath);
30813
30908
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
30814
30909
  if (options.mode != null) {
30815
30910
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -31455,8 +31550,8 @@ async function invite() {
31455
31550
  var import_node_dns = require("dns");
31456
31551
  var import_node_util5 = require("util");
31457
31552
  var import_node_crypto8 = require("crypto");
31458
- var fs53 = __toESM(require("fs"));
31459
- var path63 = __toESM(require("path"));
31553
+ var fs54 = __toESM(require("fs"));
31554
+ var path64 = __toESM(require("path"));
31460
31555
  var import_picocolors14 = __toESM(require("picocolors"));
31461
31556
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
31462
31557
  async function checkDns(apiBase2) {
@@ -31512,13 +31607,13 @@ async function checkHealth(apiBase2) {
31512
31607
  }
31513
31608
  }
31514
31609
  function checkConfigDir() {
31515
- const dir = path63.join(require("os").homedir(), ".codeam");
31610
+ const dir = path64.join(require("os").homedir(), ".codeam");
31516
31611
  try {
31517
- fs53.mkdirSync(dir, { recursive: true, mode: 448 });
31518
- const probe = path63.join(dir, ".doctor-probe");
31519
- fs53.writeFileSync(probe, "ok", { mode: 384 });
31520
- const read2 = fs53.readFileSync(probe, "utf8");
31521
- fs53.unlinkSync(probe);
31612
+ fs54.mkdirSync(dir, { recursive: true, mode: 448 });
31613
+ const probe = path64.join(dir, ".doctor-probe");
31614
+ fs54.writeFileSync(probe, "ok", { mode: 384 });
31615
+ const read2 = fs54.readFileSync(probe, "utf8");
31616
+ fs54.unlinkSync(probe);
31522
31617
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
31523
31618
  return {
31524
31619
  id: "config-dir",
@@ -31558,9 +31653,9 @@ function checkSessions() {
31558
31653
  }
31559
31654
  }
31560
31655
  function checkAgentBinaries() {
31561
- const os44 = createOsStrategy();
31656
+ const os45 = createOsStrategy();
31562
31657
  return getEnabledAgents().map((meta) => {
31563
- const found = os44.findInPath(meta.binaryName);
31658
+ const found = os45.findInPath(meta.binaryName);
31564
31659
  return {
31565
31660
  id: `agent-${meta.id}`,
31566
31661
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -31582,7 +31677,7 @@ function checkNodePty() {
31582
31677
  detail: "not required on this platform"
31583
31678
  };
31584
31679
  }
31585
- const vendoredPath = path63.join(__dirname, "vendor", "node-pty");
31680
+ const vendoredPath = path64.join(__dirname, "vendor", "node-pty");
31586
31681
  for (const target of [vendoredPath, "node-pty"]) {
31587
31682
  try {
31588
31683
  require(target);
@@ -31624,7 +31719,7 @@ function checkChokidar() {
31624
31719
  }
31625
31720
  async function doctor(args2 = []) {
31626
31721
  const json = args2.includes("--json");
31627
- const cliVersion = true ? "2.53.2" : "0.0.0-dev";
31722
+ const cliVersion = true ? "2.53.3" : "0.0.0-dev";
31628
31723
  const apiBase2 = resolveApiBaseUrl();
31629
31724
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
31630
31725
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -31823,7 +31918,7 @@ async function completion(args2) {
31823
31918
  // src/commands/version.ts
31824
31919
  var import_picocolors15 = __toESM(require("picocolors"));
31825
31920
  function version2() {
31826
- const v = true ? "2.53.2" : "unknown";
31921
+ const v = true ? "2.53.3" : "unknown";
31827
31922
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
31828
31923
  }
31829
31924
 
@@ -31972,10 +32067,10 @@ var EXIT_CODE_NAMES = {
31972
32067
  };
31973
32068
 
31974
32069
  // src/index.ts
31975
- var os43 = __toESM(require("os"));
32070
+ var os44 = __toESM(require("os"));
31976
32071
  if (!process.env.HOME) {
31977
32072
  try {
31978
- const home = os43.homedir();
32073
+ const home = os44.homedir();
31979
32074
  if (home) process.env.HOME = home;
31980
32075
  } catch {
31981
32076
  }