codeam-cli 2.53.1 → 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 +13 -0
  2. package/dist/index.js +787 -677
  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.1" : "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.1",
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.1" ? { ideVersion: "2.53.1" } : {}
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.1" : 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.1" : 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.1" : 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
  });
@@ -16465,7 +16581,13 @@ async function configureHeadroom(action, ctx, deps) {
16465
16581
  return { enabled: false };
16466
16582
  }
16467
16583
  deps.persist({ enabled: true, agent: kind, ingestUrl: ctx.savingsIngestUrl });
16468
- deps.startReporter({ agent: kind, ingestUrl: ctx.savingsIngestUrl, pluginAuthToken: ctx.pluginAuthToken });
16584
+ if (ctx.pluginAuthToken) {
16585
+ deps.startReporter({
16586
+ agent: kind,
16587
+ ingestUrl: ctx.savingsIngestUrl,
16588
+ pluginAuthToken: ctx.pluginAuthToken
16589
+ });
16590
+ }
16469
16591
  deps.emit({ type: "headroom_status", state: "enabled" });
16470
16592
  return { enabled: true };
16471
16593
  }
@@ -16478,9 +16600,9 @@ async function configureHeadroom(action, ctx, deps) {
16478
16600
  }
16479
16601
 
16480
16602
  // src/services/headroom/budget-relaunch.ts
16481
- var fs34 = __toESM(require("fs"));
16482
- var os31 = __toESM(require("os"));
16483
- var path38 = __toESM(require("path"));
16603
+ var fs35 = __toESM(require("fs"));
16604
+ var os32 = __toESM(require("os"));
16605
+ var path39 = __toESM(require("path"));
16484
16606
  var import_child_process13 = require("child_process");
16485
16607
  function amendDeploymentManifestBudget(manifest, budget) {
16486
16608
  const rawArgs = manifest.proxy_args ?? [];
@@ -16514,7 +16636,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
16514
16636
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
16515
16637
  }
16516
16638
  function findHeadroomDeployments(homeDir2, deps) {
16517
- const deployDir = path38.join(homeDir2, ".headroom", "deploy");
16639
+ const deployDir = path39.join(homeDir2, ".headroom", "deploy");
16518
16640
  let profiles;
16519
16641
  try {
16520
16642
  profiles = deps.readDir(deployDir);
@@ -16523,7 +16645,7 @@ function findHeadroomDeployments(homeDir2, deps) {
16523
16645
  }
16524
16646
  const results = [];
16525
16647
  for (const profile of profiles) {
16526
- const manifestPath = path38.join(deployDir, profile, "manifest.json");
16648
+ const manifestPath = path39.join(deployDir, profile, "manifest.json");
16527
16649
  let raw;
16528
16650
  try {
16529
16651
  raw = deps.readJson(manifestPath);
@@ -16555,8 +16677,8 @@ async function applyBudgetToHeadroom(budget, deps) {
16555
16677
  }
16556
16678
  function writeManifestReal(manifestPath, manifest) {
16557
16679
  const tmp = manifestPath + ".codeam.tmp";
16558
- fs34.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
16559
- fs34.renameSync(tmp, manifestPath);
16680
+ fs35.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
16681
+ fs35.renameSync(tmp, manifestPath);
16560
16682
  }
16561
16683
  function restartDeploymentReal(profile) {
16562
16684
  try {
@@ -16576,16 +16698,7 @@ function restartDeploymentReal(profile) {
16576
16698
  }
16577
16699
  }
16578
16700
  function killProxyReal() {
16579
- try {
16580
- const killer = (0, import_child_process13.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
16581
- detached: true,
16582
- stdio: "ignore"
16583
- });
16584
- killer.once("error", () => {
16585
- });
16586
- killer.unref();
16587
- } catch {
16588
- }
16701
+ killHeadroomProxy();
16589
16702
  }
16590
16703
  function spawnProxyReal2(budget) {
16591
16704
  try {
@@ -16606,6 +16719,7 @@ function spawnProxyReal2(budget) {
16606
16719
  log.warn("headroom-budget", `proxy relaunch error (best-effort): ${e.message}`);
16607
16720
  });
16608
16721
  proxy.unref();
16722
+ writeHeadroomProxyPidfile(proxy.pid);
16609
16723
  } catch (e) {
16610
16724
  log.warn(
16611
16725
  "headroom-budget",
@@ -16614,11 +16728,11 @@ function spawnProxyReal2(budget) {
16614
16728
  }
16615
16729
  }
16616
16730
  function makeRealApplyBudgetDeps() {
16617
- const homeDir2 = os31.homedir();
16731
+ const homeDir2 = os32.homedir();
16618
16732
  return {
16619
16733
  findDeployments: () => findHeadroomDeployments(homeDir2, {
16620
- readDir: (dir) => fs34.readdirSync(dir),
16621
- readJson: (filePath) => JSON.parse(fs34.readFileSync(filePath, "utf8"))
16734
+ readDir: (dir) => fs35.readdirSync(dir),
16735
+ readJson: (filePath) => JSON.parse(fs35.readFileSync(filePath, "utf8"))
16622
16736
  }),
16623
16737
  writeManifest: writeManifestReal,
16624
16738
  restartDeployment: restartDeploymentReal,
@@ -17262,9 +17376,9 @@ function activePreviewSessionIds() {
17262
17376
 
17263
17377
  // src/beads/bd-adapter.ts
17264
17378
  var import_child_process17 = require("child_process");
17265
- var fs39 = __toESM(require("fs"));
17266
- var os33 = __toESM(require("os"));
17267
- var path43 = __toESM(require("path"));
17379
+ var fs40 = __toESM(require("fs"));
17380
+ var os34 = __toESM(require("os"));
17381
+ var path44 = __toESM(require("path"));
17268
17382
  var BD_PACKAGE = "@beads/bd";
17269
17383
  function resolveBundledBdBinary() {
17270
17384
  return _resolveSeam.resolveBundled();
@@ -17276,11 +17390,11 @@ function _defaultResolveBundled() {
17276
17390
  } catch {
17277
17391
  return null;
17278
17392
  }
17279
- const binDir = path43.join(path43.dirname(pkgJsonPath), "bin");
17393
+ const binDir = path44.join(path44.dirname(pkgJsonPath), "bin");
17280
17394
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
17281
- const binaryPath = path43.join(binDir, binaryName);
17395
+ const binaryPath = path44.join(binDir, binaryName);
17282
17396
  try {
17283
- fs39.accessSync(binaryPath, fs39.constants.F_OK);
17397
+ fs40.accessSync(binaryPath, fs40.constants.F_OK);
17284
17398
  return binaryPath;
17285
17399
  } catch {
17286
17400
  return null;
@@ -17290,13 +17404,13 @@ function resolveBdOnPath() {
17290
17404
  return _resolveSeam.resolveOnPath();
17291
17405
  }
17292
17406
  function _defaultResolveOnPath() {
17293
- const dirs = (process.env.PATH ?? "").split(path43.delimiter).filter(Boolean);
17407
+ const dirs = (process.env.PATH ?? "").split(path44.delimiter).filter(Boolean);
17294
17408
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
17295
17409
  for (const dir of dirs) {
17296
17410
  for (const candidate of candidates) {
17297
- const full = path43.join(dir, candidate);
17411
+ const full = path44.join(dir, candidate);
17298
17412
  try {
17299
- fs39.accessSync(full, fs39.constants.F_OK);
17413
+ fs40.accessSync(full, fs40.constants.F_OK);
17300
17414
  return full;
17301
17415
  } catch {
17302
17416
  }
@@ -17381,7 +17495,7 @@ var BdAdapter = class {
17381
17495
  const env = { ...process.env };
17382
17496
  if (!env.HOME) {
17383
17497
  try {
17384
- const home = os33.homedir();
17498
+ const home = os34.homedir();
17385
17499
  if (home) env.HOME = home;
17386
17500
  } catch {
17387
17501
  }
@@ -17470,9 +17584,9 @@ function coerceIssue(row, projectKey) {
17470
17584
 
17471
17585
  // src/beads/provisioner.ts
17472
17586
  var import_child_process21 = require("child_process");
17473
- var fs42 = __toESM(require("fs"));
17474
- var os35 = __toESM(require("os"));
17475
- var path46 = __toESM(require("path"));
17587
+ var fs43 = __toESM(require("fs"));
17588
+ var os36 = __toESM(require("os"));
17589
+ var path47 = __toESM(require("path"));
17476
17590
 
17477
17591
  // src/beads/install-bd.ts
17478
17592
  var import_child_process18 = require("child_process");
@@ -17537,9 +17651,9 @@ async function installBd(platform3 = process.platform) {
17537
17651
 
17538
17652
  // src/beads/install-dolt.ts
17539
17653
  var import_child_process19 = require("child_process");
17540
- var fs40 = __toESM(require("fs"));
17541
- var os34 = __toESM(require("os"));
17542
- var path44 = __toESM(require("path"));
17654
+ var fs41 = __toESM(require("fs"));
17655
+ var os35 = __toESM(require("os"));
17656
+ var path45 = __toESM(require("path"));
17543
17657
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
17544
17658
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
17545
17659
  function resolveDoltInstallStrategy(platform3) {
@@ -17579,11 +17693,11 @@ function resolveDoltInstallStrategy(platform3) {
17579
17693
  }
17580
17694
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
17581
17695
  function doltPlatformTuple(platform3, arch2) {
17582
- const os44 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17696
+ const os45 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17583
17697
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
17584
17698
  if (!a) return null;
17585
- if (os44 === "windows" && a !== "amd64") return null;
17586
- return `${os44}-${a}`;
17699
+ if (os45 === "windows" && a !== "amd64") return null;
17700
+ return `${os45}-${a}`;
17587
17701
  }
17588
17702
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
17589
17703
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -17628,14 +17742,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
17628
17742
  return result;
17629
17743
  }
17630
17744
  var _doltPathSeam = {
17631
- homedir: () => os34.homedir(),
17745
+ homedir: () => os35.homedir(),
17632
17746
  getPath: () => process.env.PATH ?? "",
17633
17747
  setPath: (p2) => {
17634
17748
  process.env.PATH = p2;
17635
17749
  },
17636
17750
  exists: (p2) => {
17637
17751
  try {
17638
- fs40.accessSync(p2, fs40.constants.F_OK);
17752
+ fs41.accessSync(p2, fs41.constants.F_OK);
17639
17753
  return true;
17640
17754
  } catch {
17641
17755
  return false;
@@ -17646,7 +17760,7 @@ function doltBinaryNames(platform3) {
17646
17760
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
17647
17761
  }
17648
17762
  function knownDoltDirs(platform3) {
17649
- const P3 = platform3 === "win32" ? path44.win32 : path44.posix;
17763
+ const P3 = platform3 === "win32" ? path45.win32 : path45.posix;
17650
17764
  const home = _doltPathSeam.homedir();
17651
17765
  if (platform3 === "win32") {
17652
17766
  return [
@@ -17662,7 +17776,7 @@ function knownDoltDirs(platform3) {
17662
17776
  ].filter(Boolean);
17663
17777
  }
17664
17778
  function ensureDoltResolvable(platform3 = process.platform) {
17665
- const P3 = platform3 === "win32" ? path44.win32 : path44.posix;
17779
+ const P3 = platform3 === "win32" ? path45.win32 : path45.posix;
17666
17780
  const delim = platform3 === "win32" ? ";" : ":";
17667
17781
  const names = doltBinaryNames(platform3);
17668
17782
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -17798,8 +17912,8 @@ async function ensureSharedServer(adapter, options = {}) {
17798
17912
  // src/beads/project-key.ts
17799
17913
  var import_child_process20 = require("child_process");
17800
17914
  var crypto2 = __toESM(require("crypto"));
17801
- var fs41 = __toESM(require("fs"));
17802
- var path45 = __toESM(require("path"));
17915
+ var fs42 = __toESM(require("fs"));
17916
+ var path46 = __toESM(require("path"));
17803
17917
  function normalizeOrigin(raw) {
17804
17918
  const trimmed = raw.trim();
17805
17919
  if (!trimmed) return null;
@@ -17825,17 +17939,17 @@ function normalizeOrigin(raw) {
17825
17939
  return `${host2}/${pathPart}`;
17826
17940
  }
17827
17941
  function findRepoRoot(cwd) {
17828
- let dir = path45.resolve(cwd);
17942
+ let dir = path46.resolve(cwd);
17829
17943
  const seen = /* @__PURE__ */ new Set();
17830
17944
  for (let i = 0; i < 256; i++) {
17831
17945
  if (seen.has(dir)) return null;
17832
17946
  seen.add(dir);
17833
17947
  try {
17834
- const stat3 = fs41.statSync(path45.join(dir, ".git"), { throwIfNoEntry: false });
17948
+ const stat3 = fs42.statSync(path46.join(dir, ".git"), { throwIfNoEntry: false });
17835
17949
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
17836
17950
  } catch {
17837
17951
  }
17838
- const parent = path45.dirname(dir);
17952
+ const parent = path46.dirname(dir);
17839
17953
  if (parent === dir) return null;
17840
17954
  dir = parent;
17841
17955
  }
@@ -17846,7 +17960,7 @@ var _execSeam2 = {
17846
17960
  const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
17847
17961
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
17848
17962
  },
17849
- realpath: (p2) => fs41.realpathSync(p2)
17963
+ realpath: (p2) => fs42.realpathSync(p2)
17850
17964
  };
17851
17965
  function readOrigin(cwd) {
17852
17966
  try {
@@ -17875,7 +17989,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
17875
17989
  } catch {
17876
17990
  }
17877
17991
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
17878
- return { projectKey: `path:${hash}`, projectLabel: path45.basename(real) || "project" };
17992
+ return { projectKey: `path:${hash}`, projectLabel: path46.basename(real) || "project" };
17879
17993
  }
17880
17994
 
17881
17995
  // src/beads/project-prefix.ts
@@ -17917,17 +18031,17 @@ var _provisionSeam = {
17917
18031
  };
17918
18032
  var _linkSeam = {
17919
18033
  platform: () => process.platform,
17920
- homedir: () => os35.homedir(),
18034
+ homedir: () => os36.homedir(),
17921
18035
  isWritableDir: (dir) => {
17922
18036
  try {
17923
- fs42.accessSync(dir, fs42.constants.W_OK);
18037
+ fs43.accessSync(dir, fs43.constants.W_OK);
17924
18038
  return true;
17925
18039
  } catch {
17926
18040
  return false;
17927
18041
  }
17928
18042
  },
17929
18043
  ensureDir: (dir) => {
17930
- fs42.mkdirSync(dir, { recursive: true });
18044
+ fs43.mkdirSync(dir, { recursive: true });
17931
18045
  },
17932
18046
  /**
17933
18047
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -17948,9 +18062,9 @@ var _linkSeam = {
17948
18062
  * which `linkBdOntoPath` creates if missing.
17949
18063
  */
17950
18064
  cliBinDir: () => {
17951
- const pathDirs = (process.env.PATH ?? "").split(path46.delimiter).filter(Boolean);
18065
+ const pathDirs = (process.env.PATH ?? "").split(path47.delimiter).filter(Boolean);
17952
18066
  const home = _linkSeam.homedir();
17953
- const localBin = home ? path46.join(home, ".local", "bin") : null;
18067
+ const localBin = home ? path47.join(home, ".local", "bin") : null;
17954
18068
  if (localBin) {
17955
18069
  try {
17956
18070
  _linkSeam.ensureDir(localBin);
@@ -17960,16 +18074,16 @@ var _linkSeam = {
17960
18074
  const candidates = [];
17961
18075
  if (localBin) candidates.push(localBin);
17962
18076
  try {
17963
- candidates.push(path46.dirname(process.execPath));
18077
+ candidates.push(path47.dirname(process.execPath));
17964
18078
  } catch {
17965
18079
  }
17966
18080
  candidates.push("/usr/local/bin");
17967
18081
  const entry = process.argv[1];
17968
18082
  if (entry) {
17969
18083
  try {
17970
- candidates.push(path46.dirname(fs42.realpathSync(entry)));
18084
+ candidates.push(path47.dirname(fs43.realpathSync(entry)));
17971
18085
  } catch {
17972
- candidates.push(path46.dirname(entry));
18086
+ candidates.push(path47.dirname(entry));
17973
18087
  }
17974
18088
  }
17975
18089
  const onPathWritable = candidates.find(
@@ -17981,20 +18095,20 @@ var _linkSeam = {
17981
18095
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
17982
18096
  readlink: (linkPath) => {
17983
18097
  try {
17984
- return fs42.readlinkSync(linkPath);
18098
+ return fs43.readlinkSync(linkPath);
17985
18099
  } catch {
17986
18100
  return null;
17987
18101
  }
17988
18102
  },
17989
- unlink: (linkPath) => fs42.unlinkSync(linkPath),
17990
- symlink: (target, linkPath) => fs42.symlinkSync(target, linkPath)
18103
+ unlink: (linkPath) => fs43.unlinkSync(linkPath),
18104
+ symlink: (target, linkPath) => fs43.symlinkSync(target, linkPath)
17991
18105
  };
17992
18106
  function linkBdOntoPath(binaryPath) {
17993
18107
  if (_linkSeam.platform() === "win32") return;
17994
18108
  const binDir = _linkSeam.cliBinDir();
17995
18109
  if (!binDir) return;
17996
18110
  _linkSeam.ensureDir(binDir);
17997
- const linkPath = path46.join(binDir, "bd");
18111
+ const linkPath = path47.join(binDir, "bd");
17998
18112
  if (linkPath === binaryPath) return;
17999
18113
  const current = _linkSeam.readlink(linkPath);
18000
18114
  if (current === binaryPath) return;
@@ -18189,7 +18303,7 @@ function dedupeRecipes(agents) {
18189
18303
 
18190
18304
  // src/beads/watcher.ts
18191
18305
  var crypto4 = __toESM(require("crypto"));
18192
- var path47 = __toESM(require("path"));
18306
+ var path48 = __toESM(require("path"));
18193
18307
  var API_BASE6 = resolveApiBaseUrl();
18194
18308
  var DEBOUNCE_MS2 = 400;
18195
18309
  var ZERO_SUMMARY = {
@@ -18213,7 +18327,7 @@ var BeadsWatcher = class {
18213
18327
  constructor(opts) {
18214
18328
  this.opts = opts;
18215
18329
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
18216
- 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");
18217
18331
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
18218
18332
  }
18219
18333
  opts;
@@ -18623,7 +18737,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18623
18737
  function cleanupAttachmentTempFiles() {
18624
18738
  for (const p2 of pendingAttachmentFiles) {
18625
18739
  try {
18626
- fs44.unlinkSync(p2);
18740
+ fs45.unlinkSync(p2);
18627
18741
  } catch {
18628
18742
  }
18629
18743
  }
@@ -18632,8 +18746,8 @@ function cleanupAttachmentTempFiles() {
18632
18746
  function saveFilesTemp(files) {
18633
18747
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18634
18748
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18635
- const tmpPath = path49.join(os37.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18636
- 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"));
18637
18751
  pendingAttachmentFiles.add(tmpPath);
18638
18752
  return tmpPath;
18639
18753
  });
@@ -18653,7 +18767,7 @@ var startTask = (ctx, _cmd, parsed) => {
18653
18767
  setTimeout(() => {
18654
18768
  for (const p2 of paths) {
18655
18769
  try {
18656
- fs44.unlinkSync(p2);
18770
+ fs45.unlinkSync(p2);
18657
18771
  } catch {
18658
18772
  }
18659
18773
  pendingAttachmentFiles.delete(p2);
@@ -18854,9 +18968,9 @@ var listFiles = async (ctx, cmd, parsed) => {
18854
18968
  await ctx.relay.sendResult(cmd.id, "completed", result);
18855
18969
  };
18856
18970
  var envReadH = async (ctx, cmd) => {
18857
- const envPath = path49.join(process.cwd(), ".env");
18971
+ const envPath = path50.join(process.cwd(), ".env");
18858
18972
  try {
18859
- const raw = await fs44.promises.readFile(envPath, "utf8");
18973
+ const raw = await fs45.promises.readFile(envPath, "utf8");
18860
18974
  await ctx.relay.sendResult(cmd.id, "completed", {
18861
18975
  exists: true,
18862
18976
  vars: parseDotenv(raw)
@@ -18887,14 +19001,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
18887
19001
  }
18888
19002
  seen.add(v.key);
18889
19003
  }
18890
- const envPath = path49.join(process.cwd(), ".env");
18891
- 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");
18892
19006
  try {
18893
- await fs44.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18894
- await fs44.promises.rename(tmpPath, envPath);
19007
+ await fs45.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
19008
+ await fs45.promises.rename(tmpPath, envPath);
18895
19009
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
18896
19010
  } catch (err) {
18897
- await fs44.promises.rm(tmpPath, { force: true }).catch(() => void 0);
19011
+ await fs45.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18898
19012
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
18899
19013
  }
18900
19014
  };
@@ -18912,7 +19026,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18912
19026
  let configuredAgent = rawAgentId;
18913
19027
  if (!configuredAgent) {
18914
19028
  try {
18915
- const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19029
+ const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
18916
19030
  configuredAgent = raw.agent ?? "";
18917
19031
  } catch {
18918
19032
  }
@@ -18925,7 +19039,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18925
19039
  setup: setupHeadroomForSelfHosted,
18926
19040
  probeStats: async () => {
18927
19041
  try {
18928
- const res = await fetch("http://localhost:8787/stats");
19042
+ const res = await fetchWithTimeout("http://localhost:8787/stats");
18929
19043
  if (!res.ok) return null;
18930
19044
  const raw = await res.json();
18931
19045
  return mapStatsToSavings(raw, {
@@ -18946,7 +19060,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18946
19060
  persist: persistHeadroomConfig,
18947
19061
  readEnabled: () => {
18948
19062
  try {
18949
- const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19063
+ const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
18950
19064
  return raw.enabled === true;
18951
19065
  } catch {
18952
19066
  return false;
@@ -18956,12 +19070,12 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18956
19070
  _activeReporter?.stop();
18957
19071
  const reporter = new HeadroomStatsReporter({
18958
19072
  fetchStats: async () => {
18959
- const res = await fetch("http://localhost:8787/stats");
19073
+ const res = await fetchWithTimeout("http://localhost:8787/stats");
18960
19074
  return res.json();
18961
19075
  },
18962
19076
  postSavings: async (delta, budget) => {
18963
19077
  if (!opts.ingestUrl) return;
18964
- await fetch(opts.ingestUrl, {
19078
+ const res = await fetchWithTimeout(opts.ingestUrl, {
18965
19079
  method: "POST",
18966
19080
  headers: {
18967
19081
  "Content-Type": "application/json",
@@ -18982,10 +19096,14 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18982
19096
  ...budget ? {
18983
19097
  periodSpendUsd: budget.periodSpendUsd,
18984
19098
  budgetUsd: budget.budgetUsd,
18985
- budgetPeriod: budget.budgetPeriod
19099
+ budgetPeriod: budget.budgetPeriod,
19100
+ budgetReached: budget.budgetReached
18986
19101
  } : {}
18987
19102
  })
18988
19103
  });
19104
+ if (!res.ok) {
19105
+ log.warn("headroom", `savings POST rejected ${res.status} \u2014 delta not credited`);
19106
+ }
18989
19107
  }
18990
19108
  });
18991
19109
  reporter.start();
@@ -18996,18 +19114,9 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18996
19114
  _activeReporter = null;
18997
19115
  },
18998
19116
  restoreAgentHeadroomConfig: (kind) => restoreAgentHeadroomConfig(kind),
18999
- stopProxy: () => {
19000
- try {
19001
- const p2 = (0, import_child_process22.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
19002
- detached: true,
19003
- stdio: "ignore"
19004
- });
19005
- p2.on("error", () => {
19006
- });
19007
- p2.unref();
19008
- } catch {
19009
- }
19010
- },
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(),
19011
19120
  emit: (event) => {
19012
19121
  const token = ctx.pluginAuthToken;
19013
19122
  if (!token) return;
@@ -19040,7 +19149,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19040
19149
  }
19041
19150
  let headroomActive = false;
19042
19151
  try {
19043
- const raw = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19152
+ const raw = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
19044
19153
  headroomActive = raw.enabled === true;
19045
19154
  } catch {
19046
19155
  }
@@ -19050,7 +19159,7 @@ var headroomBudgetH = async (ctx, cmd) => {
19050
19159
  }
19051
19160
  let existingConfig = { enabled: true };
19052
19161
  try {
19053
- existingConfig = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8"));
19162
+ existingConfig = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8"));
19054
19163
  } catch {
19055
19164
  }
19056
19165
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -19168,13 +19277,13 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
19168
19277
  function buildNpmInstallInvocation(opts) {
19169
19278
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
19170
19279
  const execPath = opts?.execPath ?? process.execPath;
19171
- const exists2 = opts?.existsSync ?? fs44.existsSync;
19172
- const normalized = entryScript.split(path49.sep).join("/");
19280
+ const exists2 = opts?.existsSync ?? fs45.existsSync;
19281
+ const normalized = entryScript.split(path50.sep).join("/");
19173
19282
  const marker = "/lib/node_modules/codeam-cli/";
19174
19283
  const markerIdx = normalized.indexOf(marker);
19175
19284
  const prefix = markerIdx > 0 ? entryScript.slice(0, markerIdx) : null;
19176
- const siblingNpm = path49.join(
19177
- path49.dirname(execPath),
19285
+ const siblingNpm = path50.join(
19286
+ path50.dirname(execPath),
19178
19287
  process.platform === "win32" ? "npm.cmd" : "npm"
19179
19288
  );
19180
19289
  const command2 = exists2(siblingNpm) ? siblingNpm : "npm";
@@ -19681,8 +19790,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
19681
19790
  if (args2.length === 0) return detection;
19682
19791
  const binName = args2[0];
19683
19792
  if (binName.startsWith("-")) return detection;
19684
- const binPath = path49.join(cwd, "node_modules", ".bin", binName);
19685
- if (!fs44.existsSync(binPath)) return detection;
19793
+ const binPath = path50.join(cwd, "node_modules", ".bin", binName);
19794
+ if (!fs45.existsSync(binPath)) return detection;
19686
19795
  return {
19687
19796
  ...detection,
19688
19797
  command: binPath,
@@ -20501,12 +20610,12 @@ function readTokenFromArgs(args2) {
20501
20610
  }
20502
20611
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
20503
20612
  if (fileFlag) {
20504
- const path64 = fileFlag.slice("--token-file=".length);
20613
+ const path65 = fileFlag.slice("--token-file=".length);
20505
20614
  try {
20506
- const content = fs45.readFileSync(path64, "utf8").trim();
20507
- 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`);
20508
20617
  try {
20509
- fs45.unlinkSync(path64);
20618
+ fs46.unlinkSync(path65);
20510
20619
  } catch {
20511
20620
  }
20512
20621
  return content;
@@ -20532,7 +20641,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
20532
20641
  pluginId,
20533
20642
  ideName: "codeam-cli (codespace)",
20534
20643
  ideVersion: process.env.npm_package_version ?? "unknown",
20535
- hostname: os38.hostname(),
20644
+ hostname: os39.hostname(),
20536
20645
  codespaceName: process.env.CODESPACE_NAME ?? "",
20537
20646
  // Current git branch of the codespace's working directory, so the
20538
20647
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -20593,7 +20702,7 @@ async function claim(token, pluginId, pluginSecretHash) {
20593
20702
  }
20594
20703
  }
20595
20704
  function pairAutoLockPath() {
20596
- return path50.join(os38.homedir(), ".codeam", "pair-auto.lock");
20705
+ return path51.join(os39.homedir(), ".codeam", "pair-auto.lock");
20597
20706
  }
20598
20707
  function isLivePairAuto(pid) {
20599
20708
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -20603,7 +20712,7 @@ function isLivePairAuto(pid) {
20603
20712
  if (e.code !== "EPERM") return false;
20604
20713
  }
20605
20714
  try {
20606
- return fs45.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20715
+ return fs46.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20607
20716
  } catch {
20608
20717
  return true;
20609
20718
  }
@@ -20613,24 +20722,24 @@ function isLiveCodeam(pid) {
20613
20722
  }
20614
20723
  function daemonLockPath(sessionId) {
20615
20724
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
20616
- return path50.join(os38.homedir(), ".codeam", `daemon-${safe}.lock`);
20725
+ return path51.join(os39.homedir(), ".codeam", `daemon-${safe}.lock`);
20617
20726
  }
20618
20727
  function acquireDaemonLock(sessionId) {
20619
20728
  const lockPath = daemonLockPath(sessionId);
20620
20729
  try {
20621
- fs45.mkdirSync(path50.dirname(lockPath), { recursive: true });
20730
+ fs46.mkdirSync(path51.dirname(lockPath), { recursive: true });
20622
20731
  try {
20623
- fs45.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20732
+ fs46.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20624
20733
  } catch (e) {
20625
20734
  if (e.code !== "EEXIST") throw e;
20626
- const holder = Number(fs45.readFileSync(lockPath, "utf8").trim());
20735
+ const holder = Number(fs46.readFileSync(lockPath, "utf8").trim());
20627
20736
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
20628
- fs45.writeFileSync(lockPath, String(process.pid));
20737
+ fs46.writeFileSync(lockPath, String(process.pid));
20629
20738
  }
20630
20739
  const release3 = () => {
20631
20740
  try {
20632
- if (fs45.existsSync(lockPath) && Number(fs45.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20633
- fs45.unlinkSync(lockPath);
20741
+ if (fs46.existsSync(lockPath) && Number(fs46.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20742
+ fs46.unlinkSync(lockPath);
20634
20743
  }
20635
20744
  } catch {
20636
20745
  }
@@ -20652,19 +20761,19 @@ function acquireDaemonLock(sessionId) {
20652
20761
  function acquireSingletonLock() {
20653
20762
  const lockPath = pairAutoLockPath();
20654
20763
  try {
20655
- fs45.mkdirSync(path50.dirname(lockPath), { recursive: true });
20764
+ fs46.mkdirSync(path51.dirname(lockPath), { recursive: true });
20656
20765
  try {
20657
- fs45.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20766
+ fs46.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20658
20767
  } catch (e) {
20659
20768
  if (e.code !== "EEXIST") throw e;
20660
- const holder = Number(fs45.readFileSync(lockPath, "utf8").trim());
20769
+ const holder = Number(fs46.readFileSync(lockPath, "utf8").trim());
20661
20770
  if (isLivePairAuto(holder)) return false;
20662
- fs45.writeFileSync(lockPath, String(process.pid));
20771
+ fs46.writeFileSync(lockPath, String(process.pid));
20663
20772
  }
20664
20773
  process.once("exit", () => {
20665
20774
  try {
20666
- if (fs45.existsSync(lockPath) && Number(fs45.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20667
- fs45.unlinkSync(lockPath);
20775
+ if (fs46.existsSync(lockPath) && Number(fs46.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20776
+ fs46.unlinkSync(lockPath);
20668
20777
  }
20669
20778
  } catch {
20670
20779
  }
@@ -20746,7 +20855,7 @@ async function pairAuto(args2) {
20746
20855
  }
20747
20856
 
20748
20857
  // src/services/headroom/wrap-launch.ts
20749
- var import_node_child_process16 = require("child_process");
20858
+ var import_node_child_process17 = require("child_process");
20750
20859
  function wrapWithHeadroom(launch, opts) {
20751
20860
  if (!opts.enabled || !opts.headroomPresent) return launch;
20752
20861
  return {
@@ -20759,7 +20868,7 @@ var _present;
20759
20868
  function headroomPresent() {
20760
20869
  if (_present !== void 0) return Promise.resolve(_present);
20761
20870
  return new Promise((resolve7) => {
20762
- (0, import_node_child_process16.execFile)("headroom", ["--version"], (err) => {
20871
+ (0, import_node_child_process17.execFile)("headroom", ["--version"], (err) => {
20763
20872
  _present = !err;
20764
20873
  resolve7(_present);
20765
20874
  });
@@ -21109,7 +21218,7 @@ var AgentService = class _AgentService {
21109
21218
  };
21110
21219
 
21111
21220
  // src/agents/acp/adapters.ts
21112
- var path52 = __toESM(require("path"));
21221
+ var path53 = __toESM(require("path"));
21113
21222
 
21114
21223
  // src/agents/acp/agent-binary.ts
21115
21224
  var import_fs4 = __toESM(require("fs"));
@@ -21262,13 +21371,13 @@ function resolveBin(pkgName, binName) {
21262
21371
  try {
21263
21372
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
21264
21373
  const manifest = require_(`${pkgName}/package.json`);
21265
- const pkgDir = path52.dirname(manifestPath);
21374
+ const pkgDir = path53.dirname(manifestPath);
21266
21375
  const bin = manifest.bin;
21267
21376
  if (!bin) return null;
21268
- if (typeof bin === "string") return path52.resolve(pkgDir, bin);
21377
+ if (typeof bin === "string") return path53.resolve(pkgDir, bin);
21269
21378
  const target = binName ?? Object.keys(bin)[0];
21270
21379
  if (!target || !bin[target]) return null;
21271
- return path52.resolve(pkgDir, bin[target]);
21380
+ return path53.resolve(pkgDir, bin[target]);
21272
21381
  } catch {
21273
21382
  return null;
21274
21383
  }
@@ -21343,9 +21452,9 @@ function requiresAcp(agent) {
21343
21452
  var import_node_crypto7 = require("crypto");
21344
21453
 
21345
21454
  // src/services/history.service.ts
21346
- var fs47 = __toESM(require("fs"));
21347
- var path53 = __toESM(require("path"));
21348
- var os39 = __toESM(require("os"));
21455
+ var fs48 = __toESM(require("fs"));
21456
+ var path54 = __toESM(require("path"));
21457
+ var os40 = __toESM(require("os"));
21349
21458
  var https7 = __toESM(require("https"));
21350
21459
  var http6 = __toESM(require("http"));
21351
21460
  var import_zod2 = require("zod");
@@ -21372,7 +21481,7 @@ function parseJsonl(filePath) {
21372
21481
  const messages = [];
21373
21482
  let raw;
21374
21483
  try {
21375
- raw = fs47.readFileSync(filePath, "utf8");
21484
+ raw = fs48.readFileSync(filePath, "utf8");
21376
21485
  } catch (err) {
21377
21486
  if (err.code !== "ENOENT") {
21378
21487
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -21513,7 +21622,7 @@ var HistoryService = class _HistoryService {
21513
21622
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
21514
21623
  }
21515
21624
  get projectDir() {
21516
- 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));
21517
21626
  }
21518
21627
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
21519
21628
  setCurrentConversationId(id) {
@@ -21525,7 +21634,7 @@ var HistoryService = class _HistoryService {
21525
21634
  /** Return the current message count in the active conversation. */
21526
21635
  getCurrentMessageCount() {
21527
21636
  if (!this.currentConversationId) return 0;
21528
- const filePath = path53.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21637
+ const filePath = path54.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21529
21638
  return parseJsonl(filePath).length;
21530
21639
  }
21531
21640
  /**
@@ -21536,7 +21645,7 @@ var HistoryService = class _HistoryService {
21536
21645
  const deadline = Date.now() + timeoutMs;
21537
21646
  while (Date.now() < deadline) {
21538
21647
  if (!this.currentConversationId) return null;
21539
- const filePath = path53.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21648
+ const filePath = path54.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21540
21649
  const messages = parseJsonl(filePath);
21541
21650
  if (messages.length > previousCount) {
21542
21651
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -21562,16 +21671,16 @@ var HistoryService = class _HistoryService {
21562
21671
  const dir = this.projectDir;
21563
21672
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21564
21673
  try {
21565
- 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) => {
21566
21675
  try {
21567
- const stat3 = fs47.statSync(path53.join(dir, e.name));
21676
+ const stat3 = fs48.statSync(path54.join(dir, e.name));
21568
21677
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
21569
21678
  } catch {
21570
21679
  return { name: e.name, mtime: 0, birthtime: 0 };
21571
21680
  }
21572
21681
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
21573
21682
  if (files.length > 0) {
21574
- this.currentConversationId = path53.basename(files[0].name, ".jsonl");
21683
+ this.currentConversationId = path54.basename(files[0].name, ".jsonl");
21575
21684
  }
21576
21685
  } catch {
21577
21686
  }
@@ -21605,13 +21714,13 @@ var HistoryService = class _HistoryService {
21605
21714
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21606
21715
  let entries;
21607
21716
  try {
21608
- entries = fs47.readdirSync(dir, { withFileTypes: true });
21717
+ entries = fs48.readdirSync(dir, { withFileTypes: true });
21609
21718
  } catch {
21610
21719
  return null;
21611
21720
  }
21612
21721
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21613
21722
  try {
21614
- const stat3 = fs47.statSync(path53.join(dir, e.name));
21723
+ const stat3 = fs48.statSync(path54.join(dir, e.name));
21615
21724
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
21616
21725
  } catch {
21617
21726
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -21620,12 +21729,12 @@ var HistoryService = class _HistoryService {
21620
21729
  if (files.length === 0) return null;
21621
21730
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
21622
21731
  if (!files.some((f) => f.name === targetFile)) return null;
21623
- return this.extractUsageFromFile(path53.join(dir, targetFile));
21732
+ return this.extractUsageFromFile(path54.join(dir, targetFile));
21624
21733
  }
21625
21734
  extractUsageFromFile(filePath) {
21626
21735
  let raw;
21627
21736
  try {
21628
- raw = fs47.readFileSync(filePath, "utf8");
21737
+ raw = fs48.readFileSync(filePath, "utf8");
21629
21738
  } catch {
21630
21739
  return null;
21631
21740
  }
@@ -21670,9 +21779,9 @@ var HistoryService = class _HistoryService {
21670
21779
  let totalCost = 0;
21671
21780
  let files;
21672
21781
  try {
21673
- files = fs47.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21782
+ files = fs48.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21674
21783
  try {
21675
- return fs47.statSync(path53.join(projectDir, f)).mtimeMs >= monthStartMs;
21784
+ return fs48.statSync(path54.join(projectDir, f)).mtimeMs >= monthStartMs;
21676
21785
  } catch {
21677
21786
  return false;
21678
21787
  }
@@ -21683,7 +21792,7 @@ var HistoryService = class _HistoryService {
21683
21792
  for (const file of files) {
21684
21793
  let raw;
21685
21794
  try {
21686
- raw = fs47.readFileSync(path53.join(projectDir, file), "utf8");
21795
+ raw = fs48.readFileSync(path54.join(projectDir, file), "utf8");
21687
21796
  } catch {
21688
21797
  continue;
21689
21798
  }
@@ -21762,7 +21871,7 @@ var HistoryService = class _HistoryService {
21762
21871
  if (this.runtime.resolveHistoryFile) {
21763
21872
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
21764
21873
  }
21765
- return path53.join(this.projectDir, `${sessionId}.jsonl`);
21874
+ return path54.join(this.projectDir, `${sessionId}.jsonl`);
21766
21875
  }
21767
21876
  /**
21768
21877
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -21796,7 +21905,7 @@ var HistoryService = class _HistoryService {
21796
21905
  };
21797
21906
  });
21798
21907
  }
21799
- return parseJsonl(path53.join(this.projectDir, `${sessionId}.jsonl`));
21908
+ return parseJsonl(path54.join(this.projectDir, `${sessionId}.jsonl`));
21800
21909
  }
21801
21910
  async loadConversation(sessionId) {
21802
21911
  const messages = this.readConversation(sessionId);
@@ -21852,7 +21961,7 @@ var HistoryService = class _HistoryService {
21852
21961
  if (!filePath) return false;
21853
21962
  let mtimeMs;
21854
21963
  try {
21855
- mtimeMs = fs47.statSync(filePath).mtimeMs;
21964
+ mtimeMs = fs48.statSync(filePath).mtimeMs;
21856
21965
  } catch {
21857
21966
  return false;
21858
21967
  }
@@ -21920,11 +22029,11 @@ var HistoryService = class _HistoryService {
21920
22029
  };
21921
22030
 
21922
22031
  // src/agents/acp/client.ts
21923
- var import_node_child_process17 = require("child_process");
21924
- var fs48 = __toESM(require("fs/promises"));
22032
+ var import_node_child_process18 = require("child_process");
22033
+ var fs49 = __toESM(require("fs/promises"));
21925
22034
  var fsSync = __toESM(require("fs"));
21926
- var os40 = __toESM(require("os"));
21927
- var path54 = __toESM(require("path"));
22035
+ var os41 = __toESM(require("os"));
22036
+ var path55 = __toESM(require("path"));
21928
22037
  var import_node_stream = require("stream");
21929
22038
 
21930
22039
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -24471,7 +24580,7 @@ var AcpClient = class {
24471
24580
  "acpClient",
24472
24581
  `spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
24473
24582
  );
24474
- 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, {
24475
24584
  cwd,
24476
24585
  // extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
24477
24586
  // re-spawn) layers over process.env; PATH stays last so the augmented
@@ -24757,7 +24866,7 @@ var AcpClient = class {
24757
24866
  },
24758
24867
  readTextFile: async (params) => {
24759
24868
  try {
24760
- const content = await fs48.readFile(params.path, "utf8");
24869
+ const content = await fs49.readFile(params.path, "utf8");
24761
24870
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
24762
24871
  } catch (err) {
24763
24872
  const code = err.code;
@@ -24777,7 +24886,7 @@ var AcpClient = class {
24777
24886
  },
24778
24887
  writeTextFile: async (params) => {
24779
24888
  try {
24780
- await fs48.writeFile(params.path, params.content, "utf8");
24889
+ await fs49.writeFile(params.path, params.content, "utf8");
24781
24890
  return {};
24782
24891
  } catch (err) {
24783
24892
  const code = err.code;
@@ -24826,25 +24935,25 @@ function applyLineRange(content, line, limit) {
24826
24935
  return { content: lines.slice(start2, end).join("\n") };
24827
24936
  }
24828
24937
  function knownAgentBinaryDirs() {
24829
- const home = os40.homedir();
24938
+ const home = os41.homedir();
24830
24939
  const out2 = [];
24831
24940
  out2.push("/tmp/codeam-node20/bin");
24832
24941
  for (const root of [
24833
24942
  "/usr/local/share/nvm/versions/node",
24834
- path54.join(home, ".nvm/versions/node")
24943
+ path55.join(home, ".nvm/versions/node")
24835
24944
  ]) {
24836
24945
  try {
24837
24946
  for (const child of fsSync.readdirSync(root)) {
24838
- out2.push(path54.join(root, child, "bin"));
24947
+ out2.push(path55.join(root, child, "bin"));
24839
24948
  }
24840
24949
  } catch {
24841
24950
  }
24842
24951
  }
24843
- out2.push(path54.join(home, ".volta/bin"));
24952
+ out2.push(path55.join(home, ".volta/bin"));
24844
24953
  out2.push("/usr/local/bin");
24845
24954
  out2.push("/usr/bin");
24846
- out2.push(path54.join(home, ".local/bin"));
24847
- out2.push(path54.join(home, "bin"));
24955
+ out2.push(path55.join(home, ".local/bin"));
24956
+ out2.push(path55.join(home, "bin"));
24848
24957
  return out2.filter((p2) => {
24849
24958
  try {
24850
24959
  return fsSync.statSync(p2).isDirectory();
@@ -24855,7 +24964,7 @@ function knownAgentBinaryDirs() {
24855
24964
  }
24856
24965
  function expandPathForAgentBinaries(existingPath) {
24857
24966
  const existing = new Set(
24858
- existingPath.split(path54.delimiter).filter((p2) => p2.length > 0)
24967
+ existingPath.split(path55.delimiter).filter((p2) => p2.length > 0)
24859
24968
  );
24860
24969
  const additions = [];
24861
24970
  for (const dir of knownAgentBinaryDirs()) {
@@ -24865,7 +24974,7 @@ function expandPathForAgentBinaries(existingPath) {
24865
24974
  }
24866
24975
  }
24867
24976
  if (additions.length === 0) return existingPath;
24868
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path54.delimiter);
24977
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path55.delimiter);
24869
24978
  }
24870
24979
 
24871
24980
  // src/services/streaming/transport.ts
@@ -25410,15 +25519,15 @@ function commonPrefixLength(a, b) {
25410
25519
 
25411
25520
  // src/agents/acp/onboarding.ts
25412
25521
  var import_child_process25 = require("child_process");
25413
- var fs49 = __toESM(require("fs"));
25414
- var os41 = __toESM(require("os"));
25415
- var path55 = __toESM(require("path"));
25522
+ var fs50 = __toESM(require("fs"));
25523
+ var os42 = __toESM(require("os"));
25524
+ var path56 = __toESM(require("path"));
25416
25525
  var _onboardingSeam = {
25417
- markerPath: (sessionId) => path55.join(os41.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25418
- exists: (p2) => fs49.existsSync(p2),
25526
+ markerPath: (sessionId) => path56.join(os42.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
25527
+ exists: (p2) => fs50.existsSync(p2),
25419
25528
  write: (p2) => {
25420
- fs49.mkdirSync(path55.dirname(p2), { recursive: true });
25421
- fs49.writeFileSync(p2, "");
25529
+ fs50.mkdirSync(path56.dirname(p2), { recursive: true });
25530
+ fs50.writeFileSync(p2, "");
25422
25531
  },
25423
25532
  disabled: () => {
25424
25533
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -25455,7 +25564,7 @@ function resolveRepoName(cwd) {
25455
25564
  if (name) return name;
25456
25565
  }
25457
25566
  }
25458
- const base = path55.basename(cwd || "");
25567
+ const base = path56.basename(cwd || "");
25459
25568
  if (base && !isUuid(base)) return base;
25460
25569
  return "this project";
25461
25570
  }
@@ -25733,8 +25842,8 @@ var import_crypto5 = require("crypto");
25733
25842
 
25734
25843
  // src/services/turn-files/git-changeset.ts
25735
25844
  var import_child_process26 = require("child_process");
25736
- var fs50 = __toESM(require("fs/promises"));
25737
- var path56 = __toESM(require("path"));
25845
+ var fs51 = __toESM(require("fs/promises"));
25846
+ var path57 = __toESM(require("path"));
25738
25847
  async function collectRepoChangeset(opts) {
25739
25848
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
25740
25849
  if (status2 === null) return null;
@@ -25752,7 +25861,7 @@ async function collectRepoChangeset(opts) {
25752
25861
  let stats;
25753
25862
  if (row.fileStatus === "added" && numstatEntry === void 0) {
25754
25863
  const lineCount = await readUntrackedLineCount(
25755
- path56.join(opts.repoRoot, row.filePath)
25864
+ path57.join(opts.repoRoot, row.filePath)
25756
25865
  );
25757
25866
  stats = { added: lineCount, removed: 0 };
25758
25867
  } else {
@@ -25783,7 +25892,7 @@ function readUntrackedLineCount(absPath) {
25783
25892
  }
25784
25893
  async function defaultReadUntrackedLineCount(absPath) {
25785
25894
  try {
25786
- const content = await fs50.readFile(absPath, "utf8");
25895
+ const content = await fs51.readFile(absPath, "utf8");
25787
25896
  let count = 0;
25788
25897
  let pos = -1;
25789
25898
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -25875,7 +25984,7 @@ function defaultRunGit(cwd, args2) {
25875
25984
  });
25876
25985
  }
25877
25986
  async function discoverRepos(workingDir, maxDepth = 4) {
25878
- const fs54 = await import("fs/promises");
25987
+ const fs55 = await import("fs/promises");
25879
25988
  const out2 = [];
25880
25989
  await walk(workingDir, 0);
25881
25990
  return out2;
@@ -25883,7 +25992,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25883
25992
  if (depth > maxDepth) return;
25884
25993
  let entries = [];
25885
25994
  try {
25886
- const dirents = await fs54.readdir(dir, { withFileTypes: true });
25995
+ const dirents = await fs55.readdir(dir, { withFileTypes: true });
25887
25996
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
25888
25997
  } catch {
25889
25998
  return;
@@ -25894,8 +26003,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25894
26003
  if (hasGit) {
25895
26004
  out2.push({
25896
26005
  repoRoot: dir,
25897
- repoPath: path56.relative(workingDir, dir),
25898
- repoName: path56.basename(dir)
26006
+ repoPath: path57.relative(workingDir, dir),
26007
+ repoName: path57.basename(dir)
25899
26008
  });
25900
26009
  return;
25901
26010
  }
@@ -25903,14 +26012,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25903
26012
  if (!entry.isDirectory) continue;
25904
26013
  if (entry.name === "node_modules") continue;
25905
26014
  if (entry.name === "dist" || entry.name === "build") continue;
25906
- await walk(path56.join(dir, entry.name), depth + 1);
26015
+ await walk(path57.join(dir, entry.name), depth + 1);
25907
26016
  }
25908
26017
  }
25909
26018
  }
25910
26019
 
25911
26020
  // src/services/turn-files/files-outbox.ts
25912
- var fs51 = __toESM(require("fs/promises"));
25913
- var path57 = __toESM(require("path"));
26021
+ var fs52 = __toESM(require("fs/promises"));
26022
+ var path58 = __toESM(require("path"));
25914
26023
  var import_os7 = require("os");
25915
26024
  var HOME_OUTBOX_DIR = ".codeam/outbox";
25916
26025
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -25943,16 +26052,16 @@ var FilesOutbox = class {
25943
26052
  backoffIndex = 0;
25944
26053
  stopped = false;
25945
26054
  constructor(opts) {
25946
- const base = opts.baseDir ?? path57.join(homeDir(), HOME_OUTBOX_DIR);
25947
- 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`);
25948
26057
  this.post = opts.post;
25949
26058
  this.autoSchedule = opts.autoSchedule !== false;
25950
26059
  }
25951
26060
  /** Persist the entry to disk and trigger a flush. Returns once the
25952
26061
  * line is durable on disk (not once the POST succeeds). */
25953
26062
  async enqueue(entry) {
25954
- await fs51.mkdir(path57.dirname(this.filePath), { recursive: true });
25955
- 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");
25956
26065
  this.backoffIndex = 0;
25957
26066
  if (this.autoSchedule) this.scheduleFlush(0);
25958
26067
  }
@@ -26041,7 +26150,7 @@ var FilesOutbox = class {
26041
26150
  async readAll() {
26042
26151
  let raw = "";
26043
26152
  try {
26044
- raw = await fs51.readFile(this.filePath, "utf8");
26153
+ raw = await fs52.readFile(this.filePath, "utf8");
26045
26154
  } catch {
26046
26155
  return [];
26047
26156
  }
@@ -26065,12 +26174,12 @@ var FilesOutbox = class {
26065
26174
  async rewrite(entries) {
26066
26175
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
26067
26176
  if (entries.length === 0) {
26068
- await fs51.unlink(this.filePath).catch(() => void 0);
26177
+ await fs52.unlink(this.filePath).catch(() => void 0);
26069
26178
  return;
26070
26179
  }
26071
26180
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
26072
- await fs51.writeFile(tmpPath, payload, "utf8");
26073
- await fs51.rename(tmpPath, this.filePath);
26181
+ await fs52.writeFile(tmpPath, payload, "utf8");
26182
+ await fs52.rename(tmpPath, this.filePath);
26074
26183
  }
26075
26184
  };
26076
26185
  function applyJitter(ms) {
@@ -26726,6 +26835,7 @@ function replyIsCursorUpgradeRequired(finalText) {
26726
26835
  return t2.includes("upgrade your plan to continue") || t2.includes("upgrade your plan") && t2.includes("continue");
26727
26836
  }
26728
26837
  var CURSOR_UPGRADE_MESSAGE = "\u26A1 **Cursor needs a paid plan to run the agent.**\n\nThe headless Cursor Agent requires Cursor **Pro** \u2014 your Free plan\u2019s included usage does NOT cover Agent runs, even with quota left. This is your Cursor account (not CodeAgent). Upgrade, then send your message again:\n\n[Upgrade to Cursor Pro \u2192](https://cursor.com/dashboard)";
26838
+ var ONE_M_CREDITS_MESSAGE = "\u{1F504} **Reconnect your Claude subscription to continue.**\n\nClaude requested 1M-context but your account doesn\u2019t have the usage credits for it on this credential. Reconnecting refreshes your subscription so the agent can keep going \u2014 disabling 1M context won\u2019t fix a credits gate.\n\nTap [Reconnect this agent](codeam://reauth) to reconnect your Claude subscription in Profile \u203A Agents, then send your message again.";
26729
26839
  var TURN_FAILURE_MESSAGE = "\u26A0\uFE0F **The agent hit an error and couldn\u2019t finish this turn.** Please send your message again.";
26730
26840
  var ACP_QUICK_REPLIES = ["Continue", "Yes, go ahead", "Explain"];
26731
26841
  var PROVIDER_OUTAGE_RE = /overloaded_error|\boverloaded\b|service[ _]unavailable|temporarily[ _]unavailable|(?:api error|http|status)[:\s]+(?:529|503|502|504)\b|\b(?:529|503|502|504)\b[^\n]{0,40}(?:overload|unavailable|gateway|upstream|server error)|bad gateway|gateway time-?out|upstream (?:error|connect|timeout)/i;
@@ -26825,6 +26935,9 @@ function failureBubble(opts) {
26825
26935
  if (looksLikeAuthFailure(opts.detail) || looksLikeAuthFailure(opts.recentStderr)) {
26826
26936
  return AUTH_FAILURE_MESSAGE;
26827
26937
  }
26938
+ if (looksLike1mContextCreditsError(opts.detail) || looksLike1mContextCreditsError(opts.recentStderr)) {
26939
+ return ONE_M_CREDITS_MESSAGE;
26940
+ }
26828
26941
  const budgetHaystack = `${opts.detail}
26829
26942
  ${opts.recentStderr}`;
26830
26943
  if (looksLikeBudgetExceeded(budgetHaystack)) {
@@ -27056,21 +27169,12 @@ async function runAcpSession(opts) {
27056
27169
  });
27057
27170
  let _budgetReachedPosted = false;
27058
27171
  const relaunchProxyWithoutBudget = async () => {
27059
- const { spawn: spawn35 } = await import("child_process");
27060
- try {
27061
- const killer = spawn35("pkill", ["-TERM", "-f", "headroom.*proxy"], {
27062
- detached: true,
27063
- stdio: "ignore"
27064
- });
27065
- killer.once("error", () => {
27066
- });
27067
- killer.unref();
27068
- } catch {
27069
- }
27172
+ const { spawn: spawn36 } = await import("child_process");
27173
+ killHeadroomProxy();
27070
27174
  await new Promise((r) => setTimeout(r, 500));
27071
27175
  const proxyEnv = buildRelaunchProxyEnv(process.env);
27072
27176
  try {
27073
- const proxy = spawn35(
27177
+ const proxy = spawn36(
27074
27178
  "headroom",
27075
27179
  ["proxy", "--port", "8787"],
27076
27180
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -27079,6 +27183,7 @@ async function runAcpSession(opts) {
27079
27183
  log.warn("acpRunner", `budget recovery proxy relaunch error (best-effort): ${e.message}`);
27080
27184
  });
27081
27185
  proxy.unref();
27186
+ writeHeadroomProxyPidfile(proxy.pid);
27082
27187
  } catch (e) {
27083
27188
  log.warn(
27084
27189
  "acpRunner",
@@ -27312,7 +27417,17 @@ async function handleCommand(cmd, client2, relay, acpSessionId, models, streamin
27312
27417
  log.info("acpRunner", `start_task \u2190 auth-failure-in-reply id=${cmd.id.slice(0, 8)}`);
27313
27418
  await relay.sendResult(cmd.id, "failed", { error: "agent reply reported auth failure" });
27314
27419
  } else if (shouldOfferOneMRecovery({ detail: "", recentStderr: recentStderr.join("\n"), finalText })) {
27315
- await oneMRecovery.offer(cmd.id, blocks);
27420
+ await streaming.closeWithBubble(ONE_M_CREDITS_MESSAGE);
27421
+ history.appendAgentReply(ONE_M_CREDITS_MESSAGE);
27422
+ void history.flush();
27423
+ turnFiles.flushTurn().catch((err) => {
27424
+ log.warn("acpRunner", `turnFiles.flushTurn failed: ${describeError(err)}`);
27425
+ });
27426
+ void reportCredentialInvalid(opts);
27427
+ log.info("acpRunner", `start_task \u2190 1m-credits-reconnect id=${cmd.id.slice(0, 8)}`);
27428
+ await relay.sendResult(cmd.id, "failed", {
27429
+ error: "agent reply reported 1M-context usage-credits gate"
27430
+ });
27316
27431
  } else {
27317
27432
  await streaming.closeTurnWithInteractiveDetection();
27318
27433
  const replyLine = formatAgentReplyLine(finalText);
@@ -27355,11 +27470,6 @@ ${recentStderr.join("\n")}`)
27355
27470
  ${recentStderr.join("\n")}`);
27356
27471
  return;
27357
27472
  }
27358
- if (shouldOfferOneMRecovery({ detail, recentStderr: recentStderr.join("\n"), finalText: "" })) {
27359
- await streaming.closeAll();
27360
- await oneMRecovery.offer(cmd.id, blocks);
27361
- return;
27362
- }
27363
27473
  const bubble = failureBubble({
27364
27474
  detail,
27365
27475
  recentStderr: recentStderr.join("\n"),
@@ -27373,7 +27483,7 @@ ${recentStderr.join("\n")}`);
27373
27483
  } else {
27374
27484
  await streaming.closeAll();
27375
27485
  }
27376
- if (bubble === AUTH_FAILURE_MESSAGE) {
27486
+ if (bubble === AUTH_FAILURE_MESSAGE || bubble === ONE_M_CREDITS_MESSAGE) {
27377
27487
  void reportCredentialInvalid(opts);
27378
27488
  }
27379
27489
  await relay.sendResult(cmd.id, "failed", { error: detail });
@@ -28718,15 +28828,15 @@ function fetchQuotaUsage(runtime, historySvc) {
28718
28828
  }
28719
28829
 
28720
28830
  // src/agents/claude/onboarding.ts
28721
- var fs52 = __toESM(require("fs"));
28722
- var os42 = __toESM(require("os"));
28723
- var path58 = __toESM(require("path"));
28831
+ var fs53 = __toESM(require("fs"));
28832
+ var os43 = __toESM(require("os"));
28833
+ var path59 = __toESM(require("path"));
28724
28834
  function ensureClaudeOnboarded() {
28725
28835
  try {
28726
- const file = path58.join(os42.homedir(), ".claude.json");
28836
+ const file = path59.join(os43.homedir(), ".claude.json");
28727
28837
  let config = {};
28728
28838
  try {
28729
- config = JSON.parse(fs52.readFileSync(file, "utf8"));
28839
+ config = JSON.parse(fs53.readFileSync(file, "utf8"));
28730
28840
  } catch {
28731
28841
  }
28732
28842
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -28737,8 +28847,8 @@ function ensureClaudeOnboarded() {
28737
28847
  if (typeof config.lastOnboardingVersion !== "string") {
28738
28848
  config.lastOnboardingVersion = "2.1.177";
28739
28849
  }
28740
- fs52.mkdirSync(path58.dirname(file), { recursive: true });
28741
- 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));
28742
28852
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
28743
28853
  } catch (err) {
28744
28854
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -29395,7 +29505,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
29395
29505
  var import_child_process27 = require("child_process");
29396
29506
  var import_util4 = require("util");
29397
29507
  var import_picocolors9 = __toESM(require("picocolors"));
29398
- var path59 = __toESM(require("path"));
29508
+ var path60 = __toESM(require("path"));
29399
29509
  var execFileP6 = (0, import_util4.promisify)(import_child_process27.execFile);
29400
29510
  var MAX_BUFFER = 8 * 1024 * 1024;
29401
29511
  function resetStdinForChild() {
@@ -29884,7 +29994,7 @@ var GitHubCodespacesProvider = class {
29884
29994
  });
29885
29995
  }
29886
29996
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29887
- const remoteDir = path59.posix.dirname(remotePath);
29997
+ const remoteDir = path60.posix.dirname(remotePath);
29888
29998
  const parts = [
29889
29999
  `mkdir -p ${shellQuote(remoteDir)}`,
29890
30000
  `cat > ${shellQuote(remotePath)}`
@@ -29954,7 +30064,7 @@ function shellQuote(s) {
29954
30064
  // src/services/providers/gitpod.ts
29955
30065
  var import_child_process28 = require("child_process");
29956
30066
  var import_util5 = require("util");
29957
- var path60 = __toESM(require("path"));
30067
+ var path61 = __toESM(require("path"));
29958
30068
  var import_picocolors10 = __toESM(require("picocolors"));
29959
30069
  var execFileP7 = (0, import_util5.promisify)(import_child_process28.execFile);
29960
30070
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -30194,7 +30304,7 @@ var GitpodProvider = class {
30194
30304
  });
30195
30305
  }
30196
30306
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
30197
- const remoteDir = path60.posix.dirname(remotePath);
30307
+ const remoteDir = path61.posix.dirname(remotePath);
30198
30308
  const parts = [
30199
30309
  `mkdir -p ${shellQuote2(remoteDir)}`,
30200
30310
  `cat > ${shellQuote2(remotePath)}`
@@ -30230,7 +30340,7 @@ function shellQuote2(s) {
30230
30340
  // src/services/providers/gitlab-workspaces.ts
30231
30341
  var import_child_process29 = require("child_process");
30232
30342
  var import_util6 = require("util");
30233
- var path61 = __toESM(require("path"));
30343
+ var path62 = __toESM(require("path"));
30234
30344
  var execFileP8 = (0, import_util6.promisify)(import_child_process29.execFile);
30235
30345
  var MAX_BUFFER3 = 8 * 1024 * 1024;
30236
30346
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -30490,7 +30600,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
30490
30600
  }
30491
30601
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
30492
30602
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
30493
- const remoteDir = path61.posix.dirname(remotePath);
30603
+ const remoteDir = path62.posix.dirname(remotePath);
30494
30604
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
30495
30605
  if (options.mode != null) {
30496
30606
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -30558,7 +30668,7 @@ function shellQuote3(s) {
30558
30668
  // src/services/providers/railway.ts
30559
30669
  var import_child_process30 = require("child_process");
30560
30670
  var import_util7 = require("util");
30561
- var path62 = __toESM(require("path"));
30671
+ var path63 = __toESM(require("path"));
30562
30672
  var execFileP9 = (0, import_util7.promisify)(import_child_process30.execFile);
30563
30673
  var MAX_BUFFER4 = 8 * 1024 * 1024;
30564
30674
  function resetStdinForChild4() {
@@ -30794,7 +30904,7 @@ var RailwayProvider = class {
30794
30904
  if (!projectId || !serviceId) {
30795
30905
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
30796
30906
  }
30797
- const remoteDir = path62.posix.dirname(remotePath);
30907
+ const remoteDir = path63.posix.dirname(remotePath);
30798
30908
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
30799
30909
  if (options.mode != null) {
30800
30910
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -31440,8 +31550,8 @@ async function invite() {
31440
31550
  var import_node_dns = require("dns");
31441
31551
  var import_node_util5 = require("util");
31442
31552
  var import_node_crypto8 = require("crypto");
31443
- var fs53 = __toESM(require("fs"));
31444
- var path63 = __toESM(require("path"));
31553
+ var fs54 = __toESM(require("fs"));
31554
+ var path64 = __toESM(require("path"));
31445
31555
  var import_picocolors14 = __toESM(require("picocolors"));
31446
31556
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
31447
31557
  async function checkDns(apiBase2) {
@@ -31497,13 +31607,13 @@ async function checkHealth(apiBase2) {
31497
31607
  }
31498
31608
  }
31499
31609
  function checkConfigDir() {
31500
- const dir = path63.join(require("os").homedir(), ".codeam");
31610
+ const dir = path64.join(require("os").homedir(), ".codeam");
31501
31611
  try {
31502
- fs53.mkdirSync(dir, { recursive: true, mode: 448 });
31503
- const probe = path63.join(dir, ".doctor-probe");
31504
- fs53.writeFileSync(probe, "ok", { mode: 384 });
31505
- const read2 = fs53.readFileSync(probe, "utf8");
31506
- 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);
31507
31617
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
31508
31618
  return {
31509
31619
  id: "config-dir",
@@ -31543,9 +31653,9 @@ function checkSessions() {
31543
31653
  }
31544
31654
  }
31545
31655
  function checkAgentBinaries() {
31546
- const os44 = createOsStrategy();
31656
+ const os45 = createOsStrategy();
31547
31657
  return getEnabledAgents().map((meta) => {
31548
- const found = os44.findInPath(meta.binaryName);
31658
+ const found = os45.findInPath(meta.binaryName);
31549
31659
  return {
31550
31660
  id: `agent-${meta.id}`,
31551
31661
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -31567,7 +31677,7 @@ function checkNodePty() {
31567
31677
  detail: "not required on this platform"
31568
31678
  };
31569
31679
  }
31570
- const vendoredPath = path63.join(__dirname, "vendor", "node-pty");
31680
+ const vendoredPath = path64.join(__dirname, "vendor", "node-pty");
31571
31681
  for (const target of [vendoredPath, "node-pty"]) {
31572
31682
  try {
31573
31683
  require(target);
@@ -31609,7 +31719,7 @@ function checkChokidar() {
31609
31719
  }
31610
31720
  async function doctor(args2 = []) {
31611
31721
  const json = args2.includes("--json");
31612
- const cliVersion = true ? "2.53.1" : "0.0.0-dev";
31722
+ const cliVersion = true ? "2.53.3" : "0.0.0-dev";
31613
31723
  const apiBase2 = resolveApiBaseUrl();
31614
31724
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
31615
31725
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -31808,7 +31918,7 @@ async function completion(args2) {
31808
31918
  // src/commands/version.ts
31809
31919
  var import_picocolors15 = __toESM(require("picocolors"));
31810
31920
  function version2() {
31811
- const v = true ? "2.53.1" : "unknown";
31921
+ const v = true ? "2.53.3" : "unknown";
31812
31922
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
31813
31923
  }
31814
31924
 
@@ -31957,10 +32067,10 @@ var EXIT_CODE_NAMES = {
31957
32067
  };
31958
32068
 
31959
32069
  // src/index.ts
31960
- var os43 = __toESM(require("os"));
32070
+ var os44 = __toESM(require("os"));
31961
32071
  if (!process.env.HOME) {
31962
32072
  try {
31963
- const home = os43.homedir();
32073
+ const home = os44.homedir();
31964
32074
  if (home) process.env.HOME = home;
31965
32075
  } catch {
31966
32076
  }