codeam-cli 2.51.1 → 2.51.2

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 +11 -0
  2. package/dist/index.js +466 -342
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -522,9 +522,9 @@ var _default = makeConfig();
522
522
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
523
523
 
524
524
  // src/commands/pair-auto.ts
525
- var fs43 = __toESM(require("fs"));
526
- var os36 = __toESM(require("os"));
527
- var path48 = __toESM(require("path"));
525
+ var fs44 = __toESM(require("fs"));
526
+ var os37 = __toESM(require("os"));
527
+ var path49 = __toESM(require("path"));
528
528
  var import_crypto4 = require("crypto");
529
529
 
530
530
  // src/services/telemetry.service.ts
@@ -560,8 +560,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
560
560
  return decodedFile;
561
561
  };
562
562
  }
563
- function normalizeWindowsPath(path61) {
564
- return path61.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
563
+ function normalizeWindowsPath(path62) {
564
+ return path62.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
565
565
  }
566
566
 
567
567
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3041,9 +3041,9 @@ async function addSourceContext(frames) {
3041
3041
  LRU_FILE_CONTENTS_CACHE.reduce();
3042
3042
  return frames;
3043
3043
  }
3044
- function getContextLinesFromFile(path61, ranges, output) {
3044
+ function getContextLinesFromFile(path62, ranges, output) {
3045
3045
  return new Promise((resolve7) => {
3046
- const stream = (0, import_node_fs.createReadStream)(path61);
3046
+ const stream = (0, import_node_fs.createReadStream)(path62);
3047
3047
  const lineReaded = (0, import_node_readline.createInterface)({
3048
3048
  input: stream
3049
3049
  });
@@ -3058,7 +3058,7 @@ function getContextLinesFromFile(path61, ranges, output) {
3058
3058
  let rangeStart = range[0];
3059
3059
  let rangeEnd = range[1];
3060
3060
  function onStreamError() {
3061
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path61, 1);
3061
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path62, 1);
3062
3062
  lineReaded.close();
3063
3063
  lineReaded.removeAllListeners();
3064
3064
  destroyStreamAndResolve();
@@ -3119,8 +3119,8 @@ function clearLineContext(frame) {
3119
3119
  delete frame.context_line;
3120
3120
  delete frame.post_context;
3121
3121
  }
3122
- function shouldSkipContextLinesForFile(path61) {
3123
- return path61.startsWith("node:") || path61.endsWith(".min.js") || path61.endsWith(".min.cjs") || path61.endsWith(".min.mjs") || path61.startsWith("data:");
3122
+ function shouldSkipContextLinesForFile(path62) {
3123
+ return path62.startsWith("node:") || path62.endsWith(".min.js") || path62.endsWith(".min.cjs") || path62.endsWith(".min.mjs") || path62.startsWith("data:");
3124
3124
  }
3125
3125
  function shouldSkipContextLinesForFrame(frame) {
3126
3126
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5397,7 +5397,7 @@ function readAnonId() {
5397
5397
  }
5398
5398
  function superProperties() {
5399
5399
  return {
5400
- cliVersion: true ? "2.51.1" : "0.0.0-dev",
5400
+ cliVersion: true ? "2.51.2" : "0.0.0-dev",
5401
5401
  nodeVersion: process.version,
5402
5402
  platform: process.platform,
5403
5403
  arch: process.arch,
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
5578
5578
  // package.json
5579
5579
  var package_default = {
5580
5580
  name: "codeam-cli",
5581
- version: "2.51.1",
5581
+ version: "2.51.2",
5582
5582
  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
5583
  type: "commonjs",
5584
5584
  main: "dist/index.js",
@@ -6610,10 +6610,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
6610
6610
  /[\\/]Start Menu([\\/]|$)/i,
6611
6611
  /[\\/]Templates([\\/]|$)/i
6612
6612
  ];
6613
- function isUnsafeWindowsWatchRoot(dir, homedir33) {
6613
+ function isUnsafeWindowsWatchRoot(dir, homedir34) {
6614
6614
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
6615
6615
  const cwd = norm(dir);
6616
- const home = norm(homedir33);
6616
+ const home = norm(homedir34);
6617
6617
  if (cwd === home) return true;
6618
6618
  if (/^[a-z]:$/.test(cwd)) return true;
6619
6619
  const sysRoots = [
@@ -7728,11 +7728,11 @@ function closeAllTerminals() {
7728
7728
  }
7729
7729
 
7730
7730
  // src/commands/start/handlers.ts
7731
- var fs42 = __toESM(require("fs"));
7732
- var os35 = __toESM(require("os"));
7733
- var path47 = __toESM(require("path"));
7731
+ var fs43 = __toESM(require("fs"));
7732
+ var os36 = __toESM(require("os"));
7733
+ var path48 = __toESM(require("path"));
7734
7734
  var import_crypto3 = require("crypto");
7735
- var import_child_process20 = require("child_process");
7735
+ var import_child_process21 = require("child_process");
7736
7736
  var import_which2 = __toESM(require("which"));
7737
7737
 
7738
7738
  // src/lib/payload.ts
@@ -11164,10 +11164,10 @@ function buildForPlatform(platform3) {
11164
11164
  var import_node_crypto4 = require("crypto");
11165
11165
 
11166
11166
  // src/agents/claude/resolver.ts
11167
- function buildClaudeLaunch(extraArgs = [], os42 = createOsStrategy()) {
11168
- const found = os42.findInPath("claude") ?? os42.findInPath("claude-code");
11167
+ function buildClaudeLaunch(extraArgs = [], os43 = createOsStrategy()) {
11168
+ const found = os43.findInPath("claude") ?? os43.findInPath("claude-code");
11169
11169
  if (!found) return null;
11170
- return os42.buildLaunch(found, extraArgs);
11170
+ return os43.buildLaunch(found, extraArgs);
11171
11171
  }
11172
11172
 
11173
11173
  // src/agents/claude/installer.ts
@@ -11760,8 +11760,8 @@ var ClaudeRuntimeStrategy = class {
11760
11760
  meta = getAgent("claude");
11761
11761
  mode = "interactive";
11762
11762
  os;
11763
- constructor(os42) {
11764
- this.os = os42;
11763
+ constructor(os43) {
11764
+ this.os = os43;
11765
11765
  }
11766
11766
  /**
11767
11767
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -12438,8 +12438,8 @@ function codexCredentialLocator() {
12438
12438
  function codexLoginLauncher() {
12439
12439
  return {
12440
12440
  async ensureInstalled() {
12441
- const os42 = createOsStrategy();
12442
- return os42.findInPath("codex") !== null;
12441
+ const os43 = createOsStrategy();
12442
+ return os43.findInPath("codex") !== null;
12443
12443
  },
12444
12444
  launch() {
12445
12445
  return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -12462,8 +12462,8 @@ var CodexRuntimeStrategy = class {
12462
12462
  meta = getAgent("codex");
12463
12463
  mode = "interactive";
12464
12464
  os;
12465
- constructor(os42) {
12466
- this.os = os42;
12465
+ constructor(os43) {
12466
+ this.os = os43;
12467
12467
  }
12468
12468
  async prepareLaunch() {
12469
12469
  let binary = this.os.findInPath("codex");
@@ -12562,12 +12562,12 @@ var CodexRuntimeStrategy = class {
12562
12562
  });
12563
12563
  }
12564
12564
  };
12565
- function resolveNpm(os42) {
12566
- return os42.id === "win32" ? "npm.cmd" : "npm";
12565
+ function resolveNpm(os43) {
12566
+ return os43.id === "win32" ? "npm.cmd" : "npm";
12567
12567
  }
12568
- async function installCodexViaNpm(os42) {
12568
+ async function installCodexViaNpm(os43) {
12569
12569
  return new Promise((resolve7, reject) => {
12570
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os42), ["install", "-g", "@openai/codex"], {
12570
+ const proc = (0, import_node_child_process4.spawn)(resolveNpm(os43), ["install", "-g", "@openai/codex"], {
12571
12571
  stdio: "inherit"
12572
12572
  });
12573
12573
  proc.on("close", (code) => {
@@ -12584,16 +12584,16 @@ async function installCodexViaNpm(os42) {
12584
12584
  });
12585
12585
  });
12586
12586
  }
12587
- function augmentNpmGlobalBin(os42) {
12587
+ function augmentNpmGlobalBin(os43) {
12588
12588
  try {
12589
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os42), ["prefix", "-g"], {
12589
+ const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os43), ["prefix", "-g"], {
12590
12590
  stdio: ["ignore", "pipe", "ignore"]
12591
12591
  });
12592
12592
  if (result.status !== 0) return;
12593
12593
  const prefix = result.stdout.toString().trim();
12594
12594
  if (!prefix) return;
12595
- const binDir = os42.id === "win32" ? prefix : path22.join(prefix, "bin");
12596
- os42.augmentPath([binDir]);
12595
+ const binDir = os43.id === "win32" ? prefix : path22.join(prefix, "bin");
12596
+ os43.augmentPath([binDir]);
12597
12597
  } catch {
12598
12598
  }
12599
12599
  }
@@ -12677,9 +12677,9 @@ var import_node_child_process7 = require("child_process");
12677
12677
  // src/agents/coderabbit/installer.ts
12678
12678
  var import_node_child_process5 = require("child_process");
12679
12679
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
12680
- async function ensureCoderabbitInstalled(os42) {
12681
- if (os42.findInPath("coderabbit")) return true;
12682
- if (os42.id === "win32") {
12680
+ async function ensureCoderabbitInstalled(os43) {
12681
+ if (os43.findInPath("coderabbit")) return true;
12682
+ if (os43.id === "win32") {
12683
12683
  console.error(
12684
12684
  "\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"
12685
12685
  );
@@ -12694,8 +12694,8 @@ async function ensureCoderabbitInstalled(os42) {
12694
12694
  proc.on("error", () => resolve7(false));
12695
12695
  });
12696
12696
  if (!ok) return false;
12697
- os42.augmentPath([`${os42.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12698
- return os42.findInPath("coderabbit") !== null;
12697
+ os43.augmentPath([`${os43.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12698
+ return os43.findInPath("coderabbit") !== null;
12699
12699
  }
12700
12700
 
12701
12701
  // src/agents/coderabbit/link.ts
@@ -12730,10 +12730,10 @@ function coderabbitCredentialLocator() {
12730
12730
  validate: validateNonEmptyCredential
12731
12731
  };
12732
12732
  }
12733
- function coderabbitLoginLauncher(os42) {
12733
+ function coderabbitLoginLauncher(os43) {
12734
12734
  return {
12735
12735
  async ensureInstalled() {
12736
- return ensureCoderabbitInstalled(os42);
12736
+ return ensureCoderabbitInstalled(os43);
12737
12737
  },
12738
12738
  launch() {
12739
12739
  return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
@@ -12756,11 +12756,11 @@ function parseReview(stdout) {
12756
12756
  for (const line of lines) {
12757
12757
  const m = line.match(HUNK_LINE_RE);
12758
12758
  if (!m) continue;
12759
- const [, path61, lineNo, sevToken, message] = m;
12760
- if (!path61 || !lineNo || !message) continue;
12759
+ const [, path62, lineNo, sevToken, message] = m;
12760
+ if (!path62 || !lineNo || !message) continue;
12761
12761
  const cleanedMessage = message.trim().replace(/^[*-]\s+/, "");
12762
12762
  hunks.push({
12763
- path: path61.trim(),
12763
+ path: path62.trim(),
12764
12764
  line: Number(lineNo),
12765
12765
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
12766
12766
  message: cleanedMessage
@@ -12779,8 +12779,8 @@ var CoderabbitRuntimeStrategy = class {
12779
12779
  meta = getAgent("coderabbit");
12780
12780
  mode = "batch";
12781
12781
  os;
12782
- constructor(os42) {
12783
- this.os = os42;
12782
+ constructor(os43) {
12783
+ this.os = os43;
12784
12784
  }
12785
12785
  getDefaultArgs() {
12786
12786
  return ["review"];
@@ -12896,10 +12896,10 @@ function cursorCredentialLocator() {
12896
12896
  validate: validateNonEmptyCredential
12897
12897
  };
12898
12898
  }
12899
- function cursorLoginLauncher(os42) {
12899
+ function cursorLoginLauncher(os43) {
12900
12900
  return {
12901
12901
  async ensureInstalled() {
12902
- if (os42.findInPath("cursor-agent")) return true;
12902
+ if (os43.findInPath("cursor-agent")) return true;
12903
12903
  console.error(
12904
12904
  "\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"
12905
12905
  );
@@ -12961,8 +12961,8 @@ var CursorRuntimeStrategy = class {
12961
12961
  meta = getAgent("cursor");
12962
12962
  mode = "interactive";
12963
12963
  os;
12964
- constructor(os42) {
12965
- this.os = os42;
12964
+ constructor(os43) {
12965
+ this.os = os43;
12966
12966
  }
12967
12967
  async prepareLaunch() {
12968
12968
  const binary = this.os.findInPath("cursor-agent");
@@ -13101,10 +13101,10 @@ function aiderCredentialLocator() {
13101
13101
  validate: validateNonEmptyCredential
13102
13102
  };
13103
13103
  }
13104
- function aiderLoginLauncher(os42) {
13104
+ function aiderLoginLauncher(os43) {
13105
13105
  return {
13106
13106
  async ensureInstalled() {
13107
- if (os42.findInPath("aider")) return true;
13107
+ if (os43.findInPath("aider")) return true;
13108
13108
  console.error(
13109
13109
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
13110
13110
  );
@@ -13114,7 +13114,7 @@ function aiderLoginLauncher(os42) {
13114
13114
  console.error(
13115
13115
  "\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"
13116
13116
  );
13117
- return (0, import_node_child_process9.spawn)(os42.id === "win32" ? "cmd.exe" : "sh", os42.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13117
+ return (0, import_node_child_process9.spawn)(os43.id === "win32" ? "cmd.exe" : "sh", os43.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13118
13118
  stdio: "ignore"
13119
13119
  });
13120
13120
  }
@@ -13186,8 +13186,8 @@ var AiderRuntimeStrategy = class {
13186
13186
  meta = getAgent("aider");
13187
13187
  mode = "interactive";
13188
13188
  os;
13189
- constructor(os42) {
13190
- this.os = os42;
13189
+ constructor(os43) {
13190
+ this.os = os43;
13191
13191
  }
13192
13192
  async prepareLaunch() {
13193
13193
  const binary = this.os.findInPath("aider");
@@ -13316,8 +13316,8 @@ function geminiCredentialLocator() {
13316
13316
  function geminiLoginLauncher() {
13317
13317
  return {
13318
13318
  async ensureInstalled() {
13319
- const os42 = createOsStrategy();
13320
- return os42.findInPath("gemini") !== null;
13319
+ const os43 = createOsStrategy();
13320
+ return os43.findInPath("gemini") !== null;
13321
13321
  },
13322
13322
  launch() {
13323
13323
  return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -13350,8 +13350,8 @@ var GeminiRuntimeStrategy = class {
13350
13350
  meta = getAgent("gemini");
13351
13351
  mode = "interactive";
13352
13352
  os;
13353
- constructor(os42) {
13354
- this.os = os42;
13353
+ constructor(os43) {
13354
+ this.os = os43;
13355
13355
  }
13356
13356
  async prepareLaunch() {
13357
13357
  const binary = this.os.findInPath("gemini");
@@ -13450,18 +13450,18 @@ var GeminiRuntimeStrategy = class {
13450
13450
 
13451
13451
  // src/agents/registry.ts
13452
13452
  var runtimeBuilders = {
13453
- claude: (os42) => new ClaudeRuntimeStrategy(os42),
13454
- codex: (os42) => new CodexRuntimeStrategy(os42),
13455
- coderabbit: (os42) => new CoderabbitRuntimeStrategy(os42),
13456
- cursor: (os42) => new CursorRuntimeStrategy(os42),
13457
- aider: (os42) => new AiderRuntimeStrategy(os42),
13458
- gemini: (os42) => new GeminiRuntimeStrategy(os42)
13453
+ claude: (os43) => new ClaudeRuntimeStrategy(os43),
13454
+ codex: (os43) => new CodexRuntimeStrategy(os43),
13455
+ coderabbit: (os43) => new CoderabbitRuntimeStrategy(os43),
13456
+ cursor: (os43) => new CursorRuntimeStrategy(os43),
13457
+ aider: (os43) => new AiderRuntimeStrategy(os43),
13458
+ gemini: (os43) => new GeminiRuntimeStrategy(os43)
13459
13459
  };
13460
13460
  var deployBuilders = {
13461
13461
  claude: () => new ClaudeDeployStrategy(),
13462
13462
  codex: () => new CodexDeployStrategy()
13463
13463
  };
13464
- function createAgentStrategy(agent, os42 = createOsStrategy()) {
13464
+ function createAgentStrategy(agent, os43 = createOsStrategy()) {
13465
13465
  if (!AGENT_REGISTRY[agent]?.enabled) {
13466
13466
  throw new Error(
13467
13467
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -13471,10 +13471,10 @@ function createAgentStrategy(agent, os42 = createOsStrategy()) {
13471
13471
  if (!build) {
13472
13472
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
13473
13473
  }
13474
- return build(os42);
13474
+ return build(os43);
13475
13475
  }
13476
- function createInteractiveAgentStrategy(agent, os42 = createOsStrategy()) {
13477
- const s = createAgentStrategy(agent, os42);
13476
+ function createInteractiveAgentStrategy(agent, os43 = createOsStrategy()) {
13477
+ const s = createAgentStrategy(agent, os43);
13478
13478
  if (s.mode !== "interactive") {
13479
13479
  throw new Error(
13480
13480
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -14810,7 +14810,7 @@ async function autoUpgradeBeforeCriticalCommand() {
14810
14810
  if (process.env.NODE_ENV === "test") return;
14811
14811
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14812
14812
  if (process.env.CI) return;
14813
- const current = true ? "2.51.1" : null;
14813
+ const current = true ? "2.51.2" : null;
14814
14814
  if (!current) return;
14815
14815
  const cache = readCache();
14816
14816
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -14827,7 +14827,7 @@ function checkForUpdates() {
14827
14827
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14828
14828
  if (process.env.CI) return;
14829
14829
  if (!process.stdout.isTTY) return;
14830
- const current = true ? "2.51.1" : null;
14830
+ const current = true ? "2.51.2" : null;
14831
14831
  if (!current) return;
14832
14832
  const cache = readCache();
14833
14833
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -15529,7 +15529,7 @@ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process15.s
15529
15529
  detached: false
15530
15530
  });
15531
15531
  function currentCliVersion() {
15532
- return true ? "2.51.1" : null;
15532
+ return true ? "2.51.2" : null;
15533
15533
  }
15534
15534
  function runCmd(cmd, args2, timeoutMs) {
15535
15535
  return new Promise((resolve7) => {
@@ -16258,8 +16258,158 @@ async function configureHeadroom(action, ctx, deps) {
16258
16258
  return { enabled: false };
16259
16259
  }
16260
16260
 
16261
- // src/services/preview/cloudflared.ts
16261
+ // src/services/headroom/budget-relaunch.ts
16262
+ var fs33 = __toESM(require("fs"));
16263
+ var os30 = __toESM(require("os"));
16264
+ var path37 = __toESM(require("path"));
16262
16265
  var import_child_process12 = require("child_process");
16266
+ function amendDeploymentManifestBudget(manifest, budget) {
16267
+ const rawArgs = manifest.proxy_args ?? [];
16268
+ const strippedArgs = [];
16269
+ for (let i = 0; i < rawArgs.length; i++) {
16270
+ if (rawArgs[i] === "--budget" || rawArgs[i] === "--budget-period") {
16271
+ i++;
16272
+ continue;
16273
+ }
16274
+ strippedArgs.push(rawArgs[i]);
16275
+ }
16276
+ const rawEnv = manifest.base_env ?? {};
16277
+ const strippedEnv = { ...rawEnv };
16278
+ delete strippedEnv["HEADROOM_BUDGET"];
16279
+ delete strippedEnv["HEADROOM_BUDGET_PERIOD"];
16280
+ if (!budget) {
16281
+ return { ...manifest, proxy_args: strippedArgs, base_env: strippedEnv };
16282
+ }
16283
+ const newArgs = [
16284
+ ...strippedArgs,
16285
+ "--budget",
16286
+ String(budget.budgetUsd),
16287
+ "--budget-period",
16288
+ budget.budgetPeriod
16289
+ ];
16290
+ const newEnv = {
16291
+ ...strippedEnv,
16292
+ HEADROOM_BUDGET: String(budget.budgetUsd),
16293
+ HEADROOM_BUDGET_PERIOD: budget.budgetPeriod
16294
+ };
16295
+ return { ...manifest, proxy_args: newArgs, base_env: newEnv };
16296
+ }
16297
+ function findHeadroomDeployments(homeDir2, deps) {
16298
+ const deployDir = path37.join(homeDir2, ".headroom", "deploy");
16299
+ let profiles;
16300
+ try {
16301
+ profiles = deps.readDir(deployDir);
16302
+ } catch {
16303
+ return [];
16304
+ }
16305
+ const results = [];
16306
+ for (const profile of profiles) {
16307
+ const manifestPath = path37.join(deployDir, profile, "manifest.json");
16308
+ let raw;
16309
+ try {
16310
+ raw = deps.readJson(manifestPath);
16311
+ } catch {
16312
+ continue;
16313
+ }
16314
+ if (!raw || typeof raw !== "object") continue;
16315
+ const manifest = raw;
16316
+ const port = typeof manifest.port === "number" ? manifest.port : 0;
16317
+ results.push({ profile, manifestPath, port, manifest });
16318
+ }
16319
+ return results;
16320
+ }
16321
+ async function applyBudgetToHeadroom(budget, deps) {
16322
+ const supervised = deps.findDeployments().filter((d3) => d3.port === 8787);
16323
+ if (supervised.length > 0) {
16324
+ log.info("headroom-budget", `supervised path \u2014 amending ${supervised.length} deployment(s)`);
16325
+ for (const d3 of supervised) {
16326
+ const amended = amendDeploymentManifestBudget(d3.manifest, budget);
16327
+ deps.writeManifest(d3.manifestPath, amended);
16328
+ deps.restartDeployment(d3.profile);
16329
+ }
16330
+ return { path: "supervised", profiles: supervised.map((d3) => d3.profile) };
16331
+ }
16332
+ log.info("headroom-budget", "direct path \u2014 kill + respawn proxy");
16333
+ deps.killProxy();
16334
+ deps.spawnProxy(budget);
16335
+ return { path: "direct" };
16336
+ }
16337
+ function writeManifestReal(manifestPath, manifest) {
16338
+ const tmp = manifestPath + ".codeam.tmp";
16339
+ fs33.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
16340
+ fs33.renameSync(tmp, manifestPath);
16341
+ }
16342
+ function restartDeploymentReal(profile) {
16343
+ try {
16344
+ const proc = (0, import_child_process12.spawn)("headroom", ["install", "restart", "--profile", profile], {
16345
+ detached: true,
16346
+ stdio: "ignore"
16347
+ });
16348
+ proc.once("error", (e) => {
16349
+ log.warn("headroom-budget", `restart deployment '${profile}' error (best-effort): ${e.message}`);
16350
+ });
16351
+ proc.unref();
16352
+ } catch (e) {
16353
+ log.warn(
16354
+ "headroom-budget",
16355
+ `restart deployment '${profile}' failed (best-effort): ${e instanceof Error ? e.message : String(e)}`
16356
+ );
16357
+ }
16358
+ }
16359
+ function killProxyReal() {
16360
+ try {
16361
+ const killer = (0, import_child_process12.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
16362
+ detached: true,
16363
+ stdio: "ignore"
16364
+ });
16365
+ killer.once("error", () => {
16366
+ });
16367
+ killer.unref();
16368
+ } catch {
16369
+ }
16370
+ }
16371
+ function spawnProxyReal(budget) {
16372
+ try {
16373
+ const proxyEnv = {
16374
+ ...process.env,
16375
+ HEADROOM_KOMPRESS_BACKEND: "onnx_cpu"
16376
+ };
16377
+ const proxy = (0, import_child_process12.spawn)(
16378
+ "headroom",
16379
+ ["proxy", "--port", "8787", ...buildBudgetProxyArgs(proxyEnv)],
16380
+ {
16381
+ stdio: "ignore",
16382
+ detached: true,
16383
+ env: proxyEnv
16384
+ }
16385
+ );
16386
+ proxy.once("error", (e) => {
16387
+ log.warn("headroom-budget", `proxy relaunch error (best-effort): ${e.message}`);
16388
+ });
16389
+ proxy.unref();
16390
+ } catch (e) {
16391
+ log.warn(
16392
+ "headroom-budget",
16393
+ `proxy relaunch failed (best-effort): ${e instanceof Error ? e.message : String(e)}`
16394
+ );
16395
+ }
16396
+ }
16397
+ function makeRealApplyBudgetDeps() {
16398
+ const homeDir2 = os30.homedir();
16399
+ return {
16400
+ findDeployments: () => findHeadroomDeployments(homeDir2, {
16401
+ readDir: (dir) => fs33.readdirSync(dir),
16402
+ readJson: (filePath) => JSON.parse(fs33.readFileSync(filePath, "utf8"))
16403
+ }),
16404
+ writeManifest: writeManifestReal,
16405
+ restartDeployment: restartDeploymentReal,
16406
+ killProxy: killProxyReal,
16407
+ spawnProxy: spawnProxyReal
16408
+ };
16409
+ }
16410
+
16411
+ // src/services/preview/cloudflared.ts
16412
+ var import_child_process13 = require("child_process");
16263
16413
  var import_fs = require("fs");
16264
16414
  var import_promises = __toESM(require("fs/promises"));
16265
16415
  var import_os6 = __toESM(require("os"));
@@ -16336,7 +16486,7 @@ async function isExecutableBinary(p2) {
16336
16486
  }
16337
16487
  function extractTgz(tgzPath, destDir) {
16338
16488
  return new Promise((resolve7, reject) => {
16339
- const child = (0, import_child_process12.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
16489
+ const child = (0, import_child_process13.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
16340
16490
  child.on("error", (err) => reject(err));
16341
16491
  child.on(
16342
16492
  "exit",
@@ -16370,7 +16520,7 @@ async function spawnNamedTunnel(bin, token, port) {
16370
16520
  await import_promises.default.mkdir(credDir, { recursive: true });
16371
16521
  const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
16372
16522
  await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
16373
- return (0, import_child_process12.spawn)(
16523
+ return (0, import_child_process13.spawn)(
16374
16524
  bin,
16375
16525
  [
16376
16526
  "tunnel",
@@ -16386,9 +16536,9 @@ async function spawnNamedTunnel(bin, token, port) {
16386
16536
  }
16387
16537
 
16388
16538
  // src/services/preview/codespace.ts
16389
- var import_child_process13 = require("child_process");
16539
+ var import_child_process14 = require("child_process");
16390
16540
  var import_util3 = require("util");
16391
- var execFileP5 = (0, import_util3.promisify)(import_child_process13.execFile);
16541
+ var execFileP5 = (0, import_util3.promisify)(import_child_process14.execFile);
16392
16542
 
16393
16543
  // src/services/preview/config-file.ts
16394
16544
  var import_promises3 = __toESM(require("fs/promises"));
@@ -16583,10 +16733,10 @@ var import_fs2 = require("fs");
16583
16733
  var import_path6 = __toESM(require("path"));
16584
16734
 
16585
16735
  // src/services/preview/run-setup.ts
16586
- var import_child_process14 = require("child_process");
16736
+ var import_child_process15 = require("child_process");
16587
16737
  function runSetupCommand(cmd, args2, cwd, env, opts) {
16588
16738
  return new Promise((resolve7) => {
16589
- const child = (0, import_child_process14.spawn)(cmd, args2, {
16739
+ const child = (0, import_child_process15.spawn)(cmd, args2, {
16590
16740
  cwd,
16591
16741
  env: { ...process.env, ...env ?? {} },
16592
16742
  stdio: ["ignore", "pipe", "pipe"]
@@ -16892,10 +17042,10 @@ function activePreviewSessionIds() {
16892
17042
  }
16893
17043
 
16894
17044
  // src/beads/bd-adapter.ts
16895
- var import_child_process15 = require("child_process");
16896
- var fs37 = __toESM(require("fs"));
16897
- var os31 = __toESM(require("os"));
16898
- var path41 = __toESM(require("path"));
17045
+ var import_child_process16 = require("child_process");
17046
+ var fs38 = __toESM(require("fs"));
17047
+ var os32 = __toESM(require("os"));
17048
+ var path42 = __toESM(require("path"));
16899
17049
  var BD_PACKAGE = "@beads/bd";
16900
17050
  function resolveBundledBdBinary() {
16901
17051
  return _resolveSeam.resolveBundled();
@@ -16907,11 +17057,11 @@ function _defaultResolveBundled() {
16907
17057
  } catch {
16908
17058
  return null;
16909
17059
  }
16910
- const binDir = path41.join(path41.dirname(pkgJsonPath), "bin");
17060
+ const binDir = path42.join(path42.dirname(pkgJsonPath), "bin");
16911
17061
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
16912
- const binaryPath = path41.join(binDir, binaryName);
17062
+ const binaryPath = path42.join(binDir, binaryName);
16913
17063
  try {
16914
- fs37.accessSync(binaryPath, fs37.constants.F_OK);
17064
+ fs38.accessSync(binaryPath, fs38.constants.F_OK);
16915
17065
  return binaryPath;
16916
17066
  } catch {
16917
17067
  return null;
@@ -16921,13 +17071,13 @@ function resolveBdOnPath() {
16921
17071
  return _resolveSeam.resolveOnPath();
16922
17072
  }
16923
17073
  function _defaultResolveOnPath() {
16924
- const dirs = (process.env.PATH ?? "").split(path41.delimiter).filter(Boolean);
17074
+ const dirs = (process.env.PATH ?? "").split(path42.delimiter).filter(Boolean);
16925
17075
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
16926
17076
  for (const dir of dirs) {
16927
17077
  for (const candidate of candidates) {
16928
- const full = path41.join(dir, candidate);
17078
+ const full = path42.join(dir, candidate);
16929
17079
  try {
16930
- fs37.accessSync(full, fs37.constants.F_OK);
17080
+ fs38.accessSync(full, fs38.constants.F_OK);
16931
17081
  return full;
16932
17082
  } catch {
16933
17083
  }
@@ -16946,7 +17096,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
16946
17096
  return new Promise((resolve7) => {
16947
17097
  let proc;
16948
17098
  try {
16949
- proc = (0, import_child_process15.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
17099
+ proc = (0, import_child_process16.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
16950
17100
  } catch (err) {
16951
17101
  resolve7({ code: -1, stdout: "", stderr: err.message });
16952
17102
  return;
@@ -17012,7 +17162,7 @@ var BdAdapter = class {
17012
17162
  const env = { ...process.env };
17013
17163
  if (!env.HOME) {
17014
17164
  try {
17015
- const home = os31.homedir();
17165
+ const home = os32.homedir();
17016
17166
  if (home) env.HOME = home;
17017
17167
  } catch {
17018
17168
  }
@@ -17100,13 +17250,13 @@ function coerceIssue(row, projectKey) {
17100
17250
  }
17101
17251
 
17102
17252
  // src/beads/provisioner.ts
17103
- var import_child_process19 = require("child_process");
17104
- var fs40 = __toESM(require("fs"));
17105
- var os33 = __toESM(require("os"));
17106
- var path44 = __toESM(require("path"));
17253
+ var import_child_process20 = require("child_process");
17254
+ var fs41 = __toESM(require("fs"));
17255
+ var os34 = __toESM(require("os"));
17256
+ var path45 = __toESM(require("path"));
17107
17257
 
17108
17258
  // src/beads/install-bd.ts
17109
- var import_child_process16 = require("child_process");
17259
+ var import_child_process17 = require("child_process");
17110
17260
  var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
17111
17261
  var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
17112
17262
  function resolveInstallStrategy(platform3) {
@@ -17137,7 +17287,7 @@ function _defaultInstallSpawn(strategy) {
17137
17287
  return new Promise((resolve7) => {
17138
17288
  let proc;
17139
17289
  try {
17140
- proc = (0, import_child_process16.spawn)(strategy.command, strategy.args, { env: process.env });
17290
+ proc = (0, import_child_process17.spawn)(strategy.command, strategy.args, { env: process.env });
17141
17291
  } catch (err) {
17142
17292
  resolve7({ ok: false, code: -1, stderr: err.message });
17143
17293
  return;
@@ -17167,10 +17317,10 @@ async function installBd(platform3 = process.platform) {
17167
17317
  }
17168
17318
 
17169
17319
  // src/beads/install-dolt.ts
17170
- var import_child_process17 = require("child_process");
17171
- var fs38 = __toESM(require("fs"));
17172
- var os32 = __toESM(require("os"));
17173
- var path42 = __toESM(require("path"));
17320
+ var import_child_process18 = require("child_process");
17321
+ var fs39 = __toESM(require("fs"));
17322
+ var os33 = __toESM(require("os"));
17323
+ var path43 = __toESM(require("path"));
17174
17324
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
17175
17325
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
17176
17326
  function resolveDoltInstallStrategy(platform3) {
@@ -17210,11 +17360,11 @@ function resolveDoltInstallStrategy(platform3) {
17210
17360
  }
17211
17361
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
17212
17362
  function doltPlatformTuple(platform3, arch2) {
17213
- const os42 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17363
+ const os43 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17214
17364
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
17215
17365
  if (!a) return null;
17216
- if (os42 === "windows" && a !== "amd64") return null;
17217
- return `${os42}-${a}`;
17366
+ if (os43 === "windows" && a !== "amd64") return null;
17367
+ return `${os43}-${a}`;
17218
17368
  }
17219
17369
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
17220
17370
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -17259,14 +17409,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
17259
17409
  return result;
17260
17410
  }
17261
17411
  var _doltPathSeam = {
17262
- homedir: () => os32.homedir(),
17412
+ homedir: () => os33.homedir(),
17263
17413
  getPath: () => process.env.PATH ?? "",
17264
17414
  setPath: (p2) => {
17265
17415
  process.env.PATH = p2;
17266
17416
  },
17267
17417
  exists: (p2) => {
17268
17418
  try {
17269
- fs38.accessSync(p2, fs38.constants.F_OK);
17419
+ fs39.accessSync(p2, fs39.constants.F_OK);
17270
17420
  return true;
17271
17421
  } catch {
17272
17422
  return false;
@@ -17277,7 +17427,7 @@ function doltBinaryNames(platform3) {
17277
17427
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
17278
17428
  }
17279
17429
  function knownDoltDirs(platform3) {
17280
- const P3 = platform3 === "win32" ? path42.win32 : path42.posix;
17430
+ const P3 = platform3 === "win32" ? path43.win32 : path43.posix;
17281
17431
  const home = _doltPathSeam.homedir();
17282
17432
  if (platform3 === "win32") {
17283
17433
  return [
@@ -17293,7 +17443,7 @@ function knownDoltDirs(platform3) {
17293
17443
  ].filter(Boolean);
17294
17444
  }
17295
17445
  function ensureDoltResolvable(platform3 = process.platform) {
17296
- const P3 = platform3 === "win32" ? path42.win32 : path42.posix;
17446
+ const P3 = platform3 === "win32" ? path43.win32 : path43.posix;
17297
17447
  const delim = platform3 === "win32" ? ";" : ":";
17298
17448
  const names = doltBinaryNames(platform3);
17299
17449
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -17329,7 +17479,7 @@ function _defaultDoltInstallSpawn(strategy) {
17329
17479
  };
17330
17480
  let proc;
17331
17481
  try {
17332
- proc = (0, import_child_process17.spawn)(strategy.command, strategy.args, {
17482
+ proc = (0, import_child_process18.spawn)(strategy.command, strategy.args, {
17333
17483
  env: process.env,
17334
17484
  stdio: ["ignore", "pipe", "pipe"]
17335
17485
  });
@@ -17427,10 +17577,10 @@ async function ensureSharedServer(adapter, options = {}) {
17427
17577
  }
17428
17578
 
17429
17579
  // src/beads/project-key.ts
17430
- var import_child_process18 = require("child_process");
17580
+ var import_child_process19 = require("child_process");
17431
17581
  var crypto2 = __toESM(require("crypto"));
17432
- var fs39 = __toESM(require("fs"));
17433
- var path43 = __toESM(require("path"));
17582
+ var fs40 = __toESM(require("fs"));
17583
+ var path44 = __toESM(require("path"));
17434
17584
  function normalizeOrigin(raw) {
17435
17585
  const trimmed = raw.trim();
17436
17586
  if (!trimmed) return null;
@@ -17456,17 +17606,17 @@ function normalizeOrigin(raw) {
17456
17606
  return `${host2}/${pathPart}`;
17457
17607
  }
17458
17608
  function findRepoRoot(cwd) {
17459
- let dir = path43.resolve(cwd);
17609
+ let dir = path44.resolve(cwd);
17460
17610
  const seen = /* @__PURE__ */ new Set();
17461
17611
  for (let i = 0; i < 256; i++) {
17462
17612
  if (seen.has(dir)) return null;
17463
17613
  seen.add(dir);
17464
17614
  try {
17465
- const stat3 = fs39.statSync(path43.join(dir, ".git"), { throwIfNoEntry: false });
17615
+ const stat3 = fs40.statSync(path44.join(dir, ".git"), { throwIfNoEntry: false });
17466
17616
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
17467
17617
  } catch {
17468
17618
  }
17469
- const parent = path43.dirname(dir);
17619
+ const parent = path44.dirname(dir);
17470
17620
  if (parent === dir) return null;
17471
17621
  dir = parent;
17472
17622
  }
@@ -17474,10 +17624,10 @@ function findRepoRoot(cwd) {
17474
17624
  }
17475
17625
  var _execSeam2 = {
17476
17626
  exec: (file, args2, opts) => {
17477
- const out2 = (0, import_child_process18.execFileSync)(file, args2, opts);
17627
+ const out2 = (0, import_child_process19.execFileSync)(file, args2, opts);
17478
17628
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
17479
17629
  },
17480
- realpath: (p2) => fs39.realpathSync(p2)
17630
+ realpath: (p2) => fs40.realpathSync(p2)
17481
17631
  };
17482
17632
  function readOrigin(cwd) {
17483
17633
  try {
@@ -17506,7 +17656,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
17506
17656
  } catch {
17507
17657
  }
17508
17658
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
17509
- return { projectKey: `path:${hash}`, projectLabel: path43.basename(real) || "project" };
17659
+ return { projectKey: `path:${hash}`, projectLabel: path44.basename(real) || "project" };
17510
17660
  }
17511
17661
 
17512
17662
  // src/beads/project-prefix.ts
@@ -17548,17 +17698,17 @@ var _provisionSeam = {
17548
17698
  };
17549
17699
  var _linkSeam = {
17550
17700
  platform: () => process.platform,
17551
- homedir: () => os33.homedir(),
17701
+ homedir: () => os34.homedir(),
17552
17702
  isWritableDir: (dir) => {
17553
17703
  try {
17554
- fs40.accessSync(dir, fs40.constants.W_OK);
17704
+ fs41.accessSync(dir, fs41.constants.W_OK);
17555
17705
  return true;
17556
17706
  } catch {
17557
17707
  return false;
17558
17708
  }
17559
17709
  },
17560
17710
  ensureDir: (dir) => {
17561
- fs40.mkdirSync(dir, { recursive: true });
17711
+ fs41.mkdirSync(dir, { recursive: true });
17562
17712
  },
17563
17713
  /**
17564
17714
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -17579,9 +17729,9 @@ var _linkSeam = {
17579
17729
  * which `linkBdOntoPath` creates if missing.
17580
17730
  */
17581
17731
  cliBinDir: () => {
17582
- const pathDirs = (process.env.PATH ?? "").split(path44.delimiter).filter(Boolean);
17732
+ const pathDirs = (process.env.PATH ?? "").split(path45.delimiter).filter(Boolean);
17583
17733
  const home = _linkSeam.homedir();
17584
- const localBin = home ? path44.join(home, ".local", "bin") : null;
17734
+ const localBin = home ? path45.join(home, ".local", "bin") : null;
17585
17735
  if (localBin) {
17586
17736
  try {
17587
17737
  _linkSeam.ensureDir(localBin);
@@ -17591,16 +17741,16 @@ var _linkSeam = {
17591
17741
  const candidates = [];
17592
17742
  if (localBin) candidates.push(localBin);
17593
17743
  try {
17594
- candidates.push(path44.dirname(process.execPath));
17744
+ candidates.push(path45.dirname(process.execPath));
17595
17745
  } catch {
17596
17746
  }
17597
17747
  candidates.push("/usr/local/bin");
17598
17748
  const entry = process.argv[1];
17599
17749
  if (entry) {
17600
17750
  try {
17601
- candidates.push(path44.dirname(fs40.realpathSync(entry)));
17751
+ candidates.push(path45.dirname(fs41.realpathSync(entry)));
17602
17752
  } catch {
17603
- candidates.push(path44.dirname(entry));
17753
+ candidates.push(path45.dirname(entry));
17604
17754
  }
17605
17755
  }
17606
17756
  const onPathWritable = candidates.find(
@@ -17612,20 +17762,20 @@ var _linkSeam = {
17612
17762
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
17613
17763
  readlink: (linkPath) => {
17614
17764
  try {
17615
- return fs40.readlinkSync(linkPath);
17765
+ return fs41.readlinkSync(linkPath);
17616
17766
  } catch {
17617
17767
  return null;
17618
17768
  }
17619
17769
  },
17620
- unlink: (linkPath) => fs40.unlinkSync(linkPath),
17621
- symlink: (target, linkPath) => fs40.symlinkSync(target, linkPath)
17770
+ unlink: (linkPath) => fs41.unlinkSync(linkPath),
17771
+ symlink: (target, linkPath) => fs41.symlinkSync(target, linkPath)
17622
17772
  };
17623
17773
  function linkBdOntoPath(binaryPath) {
17624
17774
  if (_linkSeam.platform() === "win32") return;
17625
17775
  const binDir = _linkSeam.cliBinDir();
17626
17776
  if (!binDir) return;
17627
17777
  _linkSeam.ensureDir(binDir);
17628
- const linkPath = path44.join(binDir, "bd");
17778
+ const linkPath = path45.join(binDir, "bd");
17629
17779
  if (linkPath === binaryPath) return;
17630
17780
  const current = _linkSeam.readlink(linkPath);
17631
17781
  if (current === binaryPath) return;
@@ -17634,7 +17784,7 @@ function linkBdOntoPath(binaryPath) {
17634
17784
  log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
17635
17785
  }
17636
17786
  function setGitBeadsRole() {
17637
- (0, import_child_process19.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
17787
+ (0, import_child_process20.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
17638
17788
  stdio: "ignore"
17639
17789
  });
17640
17790
  }
@@ -17820,7 +17970,7 @@ function dedupeRecipes(agents) {
17820
17970
 
17821
17971
  // src/beads/watcher.ts
17822
17972
  var crypto4 = __toESM(require("crypto"));
17823
- var path45 = __toESM(require("path"));
17973
+ var path46 = __toESM(require("path"));
17824
17974
  var API_BASE6 = resolveApiBaseUrl();
17825
17975
  var DEBOUNCE_MS2 = 400;
17826
17976
  var ZERO_SUMMARY = {
@@ -17844,7 +17994,7 @@ var BeadsWatcher = class {
17844
17994
  constructor(opts) {
17845
17995
  this.opts = opts;
17846
17996
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
17847
- this.feedPath = opts.feedPath ?? path45.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
17997
+ this.feedPath = opts.feedPath ?? path46.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
17848
17998
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
17849
17999
  }
17850
18000
  opts;
@@ -18254,7 +18404,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18254
18404
  function cleanupAttachmentTempFiles() {
18255
18405
  for (const p2 of pendingAttachmentFiles) {
18256
18406
  try {
18257
- fs42.unlinkSync(p2);
18407
+ fs43.unlinkSync(p2);
18258
18408
  } catch {
18259
18409
  }
18260
18410
  }
@@ -18263,8 +18413,8 @@ function cleanupAttachmentTempFiles() {
18263
18413
  function saveFilesTemp(files) {
18264
18414
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18265
18415
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18266
- const tmpPath = path47.join(os35.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18267
- fs42.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18416
+ const tmpPath = path48.join(os36.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18417
+ fs43.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18268
18418
  pendingAttachmentFiles.add(tmpPath);
18269
18419
  return tmpPath;
18270
18420
  });
@@ -18284,7 +18434,7 @@ var startTask = (ctx, _cmd, parsed) => {
18284
18434
  setTimeout(() => {
18285
18435
  for (const p2 of paths) {
18286
18436
  try {
18287
- fs42.unlinkSync(p2);
18437
+ fs43.unlinkSync(p2);
18288
18438
  } catch {
18289
18439
  }
18290
18440
  pendingAttachmentFiles.delete(p2);
@@ -18409,7 +18559,7 @@ var sessionTerminated = async (ctx, cmd) => {
18409
18559
  } catch {
18410
18560
  }
18411
18561
  try {
18412
- const proc = (0, import_child_process20.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18562
+ const proc = (0, import_child_process21.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18413
18563
  detached: true,
18414
18564
  stdio: "ignore"
18415
18565
  });
@@ -18431,7 +18581,7 @@ var shutdownSession = async (ctx, cmd) => {
18431
18581
  }
18432
18582
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
18433
18583
  try {
18434
- const stopProc = (0, import_child_process20.spawn)(
18584
+ const stopProc = (0, import_child_process21.spawn)(
18435
18585
  "bash",
18436
18586
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
18437
18587
  { detached: true, stdio: "ignore" }
@@ -18441,7 +18591,7 @@ var shutdownSession = async (ctx, cmd) => {
18441
18591
  }
18442
18592
  }
18443
18593
  try {
18444
- const proc = (0, import_child_process20.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18594
+ const proc = (0, import_child_process21.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
18445
18595
  detached: true,
18446
18596
  stdio: "ignore"
18447
18597
  });
@@ -18485,9 +18635,9 @@ var listFiles = async (ctx, cmd, parsed) => {
18485
18635
  await ctx.relay.sendResult(cmd.id, "completed", result);
18486
18636
  };
18487
18637
  var envReadH = async (ctx, cmd) => {
18488
- const envPath = path47.join(process.cwd(), ".env");
18638
+ const envPath = path48.join(process.cwd(), ".env");
18489
18639
  try {
18490
- const raw = await fs42.promises.readFile(envPath, "utf8");
18640
+ const raw = await fs43.promises.readFile(envPath, "utf8");
18491
18641
  await ctx.relay.sendResult(cmd.id, "completed", {
18492
18642
  exists: true,
18493
18643
  vars: parseDotenv(raw)
@@ -18518,14 +18668,14 @@ var envWriteH = async (ctx, cmd, parsed) => {
18518
18668
  }
18519
18669
  seen.add(v.key);
18520
18670
  }
18521
- const envPath = path47.join(process.cwd(), ".env");
18522
- const tmpPath = path47.join(process.cwd(), ".env.codeam.tmp");
18671
+ const envPath = path48.join(process.cwd(), ".env");
18672
+ const tmpPath = path48.join(process.cwd(), ".env.codeam.tmp");
18523
18673
  try {
18524
- await fs42.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18525
- await fs42.promises.rename(tmpPath, envPath);
18674
+ await fs43.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18675
+ await fs43.promises.rename(tmpPath, envPath);
18526
18676
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
18527
18677
  } catch (err) {
18528
- await fs42.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18678
+ await fs43.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18529
18679
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
18530
18680
  }
18531
18681
  };
@@ -18543,7 +18693,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18543
18693
  let configuredAgent = rawAgentId;
18544
18694
  if (!configuredAgent) {
18545
18695
  try {
18546
- const raw = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18696
+ const raw = JSON.parse(fs43.readFileSync(headroomConfigPath(), "utf8"));
18547
18697
  configuredAgent = raw.agent ?? "";
18548
18698
  } catch {
18549
18699
  }
@@ -18577,7 +18727,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18577
18727
  persist: persistHeadroomConfig,
18578
18728
  readEnabled: () => {
18579
18729
  try {
18580
- const raw = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18730
+ const raw = JSON.parse(fs43.readFileSync(headroomConfigPath(), "utf8"));
18581
18731
  return raw.enabled === true;
18582
18732
  } catch {
18583
18733
  return false;
@@ -18629,7 +18779,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18629
18779
  restoreAgentHeadroomConfig: (kind) => restoreAgentHeadroomConfig(kind),
18630
18780
  stopProxy: () => {
18631
18781
  try {
18632
- const p2 = (0, import_child_process20.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
18782
+ const p2 = (0, import_child_process21.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
18633
18783
  detached: true,
18634
18784
  stdio: "ignore"
18635
18785
  });
@@ -18671,7 +18821,7 @@ var headroomBudgetH = async (ctx, cmd) => {
18671
18821
  }
18672
18822
  let headroomActive = false;
18673
18823
  try {
18674
- const raw = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18824
+ const raw = JSON.parse(fs43.readFileSync(headroomConfigPath(), "utf8"));
18675
18825
  headroomActive = raw.enabled === true;
18676
18826
  } catch {
18677
18827
  }
@@ -18681,7 +18831,7 @@ var headroomBudgetH = async (ctx, cmd) => {
18681
18831
  }
18682
18832
  let existingConfig = { enabled: true };
18683
18833
  try {
18684
- existingConfig = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18834
+ existingConfig = JSON.parse(fs43.readFileSync(headroomConfigPath(), "utf8"));
18685
18835
  } catch {
18686
18836
  }
18687
18837
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -18705,37 +18855,11 @@ var headroomBudgetH = async (ctx, cmd) => {
18705
18855
  delete process.env["HEADROOM_BUDGET"];
18706
18856
  delete process.env["HEADROOM_BUDGET_PERIOD"];
18707
18857
  }
18708
- try {
18709
- const killer = (0, import_child_process20.spawn)("pkill", ["-TERM", "-f", "headroom.*proxy"], {
18710
- detached: true,
18711
- stdio: "ignore"
18712
- });
18713
- killer.once("error", () => {
18714
- });
18715
- killer.unref();
18716
- } catch {
18717
- }
18718
- try {
18719
- const proxyEnv = { ...process.env, HEADROOM_KOMPRESS_BACKEND: "onnx_cpu" };
18720
- const proxy = (0, import_child_process20.spawn)(
18721
- "headroom",
18722
- ["proxy", "--port", "8787", ...buildBudgetProxyArgs(proxyEnv)],
18723
- {
18724
- stdio: "ignore",
18725
- detached: true,
18726
- env: proxyEnv
18727
- }
18728
- );
18729
- proxy.once("error", (e) => {
18730
- log.warn("headroom-budget", `proxy relaunch error (best-effort): ${e.message}`);
18731
- });
18732
- proxy.unref();
18733
- } catch (e) {
18734
- log.warn(
18735
- "headroom-budget",
18736
- `proxy relaunch failed (best-effort): ${e instanceof Error ? e.message : String(e)}`
18737
- );
18738
- }
18858
+ const budgetSpec = payload.budgetEnabled && payload.budgetUsd != null ? {
18859
+ budgetUsd: payload.budgetUsd,
18860
+ budgetPeriod: payload.budgetPeriod ?? "daily"
18861
+ } : null;
18862
+ await applyBudgetToHeadroom(budgetSpec, makeRealApplyBudgetDeps());
18739
18863
  await ctx.relay.sendResult(cmd.id, "completed", { applied: true });
18740
18864
  };
18741
18865
  var _beadsEmitChain = Promise.resolve();
@@ -19233,8 +19357,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
19233
19357
  if (args2.length === 0) return detection;
19234
19358
  const binName = args2[0];
19235
19359
  if (binName.startsWith("-")) return detection;
19236
- const binPath = path47.join(cwd, "node_modules", ".bin", binName);
19237
- if (!fs42.existsSync(binPath)) return detection;
19360
+ const binPath = path48.join(cwd, "node_modules", ".bin", binName);
19361
+ if (!fs43.existsSync(binPath)) return detection;
19238
19362
  return {
19239
19363
  ...detection,
19240
19364
  command: binPath,
@@ -19469,7 +19593,7 @@ function startPreviewFromDetection(ctx, detection, pluginAuthToken) {
19469
19593
  "BOOT_SEQUENCE",
19470
19594
  `${spawnable.command} ${spawnable.args.join(" ")}`
19471
19595
  );
19472
- const devServer = (0, import_child_process20.spawn)(spawnable.command, spawnable.args, {
19596
+ const devServer = (0, import_child_process21.spawn)(spawnable.command, spawnable.args, {
19473
19597
  cwd: process.cwd(),
19474
19598
  env: { ...process.env, ...spawnable.env ?? {} },
19475
19599
  stdio: ["ignore", "pipe", "pipe"],
@@ -19619,7 +19743,7 @@ function startPreviewFromDetection(ctx, detection, pluginAuthToken) {
19619
19743
  `cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
19620
19744
  );
19621
19745
  }
19622
- const candidate = (0, import_child_process20.spawn)(
19746
+ const candidate = (0, import_child_process21.spawn)(
19623
19747
  bin,
19624
19748
  ["tunnel", "--url", `http://localhost:${detection.port}`],
19625
19749
  { stdio: ["ignore", "pipe", "pipe"] }
@@ -19815,13 +19939,13 @@ async function dispatchCommand(ctx, cmd) {
19815
19939
  }
19816
19940
 
19817
19941
  // src/commands/start/keep-alive.ts
19818
- var import_child_process21 = require("child_process");
19942
+ var import_child_process22 = require("child_process");
19819
19943
  function buildKeepAlive(ctx) {
19820
19944
  let timer = null;
19821
19945
  async function setIdleTimeout(minutes) {
19822
19946
  if (!ctx.inCodespace || !ctx.codespaceName) return;
19823
19947
  await new Promise((resolve7) => {
19824
- const proc = (0, import_child_process21.spawn)(
19948
+ const proc = (0, import_child_process22.spawn)(
19825
19949
  "gh",
19826
19950
  [
19827
19951
  "api",
@@ -20052,12 +20176,12 @@ function readTokenFromArgs(args2) {
20052
20176
  }
20053
20177
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
20054
20178
  if (fileFlag) {
20055
- const path61 = fileFlag.slice("--token-file=".length);
20179
+ const path62 = fileFlag.slice("--token-file=".length);
20056
20180
  try {
20057
- const content = fs43.readFileSync(path61, "utf8").trim();
20058
- if (content.length === 0) fail(`--token-file ${path61} is empty`);
20181
+ const content = fs44.readFileSync(path62, "utf8").trim();
20182
+ if (content.length === 0) fail(`--token-file ${path62} is empty`);
20059
20183
  try {
20060
- fs43.unlinkSync(path61);
20184
+ fs44.unlinkSync(path62);
20061
20185
  } catch {
20062
20186
  }
20063
20187
  return content;
@@ -20083,7 +20207,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
20083
20207
  pluginId,
20084
20208
  ideName: "codeam-cli (codespace)",
20085
20209
  ideVersion: process.env.npm_package_version ?? "unknown",
20086
- hostname: os36.hostname(),
20210
+ hostname: os37.hostname(),
20087
20211
  codespaceName: process.env.CODESPACE_NAME ?? "",
20088
20212
  // Current git branch of the codespace's working directory, so the
20089
20213
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -20144,7 +20268,7 @@ async function claim(token, pluginId, pluginSecretHash) {
20144
20268
  }
20145
20269
  }
20146
20270
  function pairAutoLockPath() {
20147
- return path48.join(os36.homedir(), ".codeam", "pair-auto.lock");
20271
+ return path49.join(os37.homedir(), ".codeam", "pair-auto.lock");
20148
20272
  }
20149
20273
  function isLivePairAuto(pid) {
20150
20274
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -20154,7 +20278,7 @@ function isLivePairAuto(pid) {
20154
20278
  if (e.code !== "EPERM") return false;
20155
20279
  }
20156
20280
  try {
20157
- return fs43.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20281
+ return fs44.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20158
20282
  } catch {
20159
20283
  return true;
20160
20284
  }
@@ -20164,24 +20288,24 @@ function isLiveCodeam(pid) {
20164
20288
  }
20165
20289
  function daemonLockPath(sessionId) {
20166
20290
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
20167
- return path48.join(os36.homedir(), ".codeam", `daemon-${safe}.lock`);
20291
+ return path49.join(os37.homedir(), ".codeam", `daemon-${safe}.lock`);
20168
20292
  }
20169
20293
  function acquireDaemonLock(sessionId) {
20170
20294
  const lockPath = daemonLockPath(sessionId);
20171
20295
  try {
20172
- fs43.mkdirSync(path48.dirname(lockPath), { recursive: true });
20296
+ fs44.mkdirSync(path49.dirname(lockPath), { recursive: true });
20173
20297
  try {
20174
- fs43.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20298
+ fs44.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20175
20299
  } catch (e) {
20176
20300
  if (e.code !== "EEXIST") throw e;
20177
- const holder = Number(fs43.readFileSync(lockPath, "utf8").trim());
20301
+ const holder = Number(fs44.readFileSync(lockPath, "utf8").trim());
20178
20302
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
20179
- fs43.writeFileSync(lockPath, String(process.pid));
20303
+ fs44.writeFileSync(lockPath, String(process.pid));
20180
20304
  }
20181
20305
  const release3 = () => {
20182
20306
  try {
20183
- if (fs43.existsSync(lockPath) && Number(fs43.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20184
- fs43.unlinkSync(lockPath);
20307
+ if (fs44.existsSync(lockPath) && Number(fs44.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20308
+ fs44.unlinkSync(lockPath);
20185
20309
  }
20186
20310
  } catch {
20187
20311
  }
@@ -20203,19 +20327,19 @@ function acquireDaemonLock(sessionId) {
20203
20327
  function acquireSingletonLock() {
20204
20328
  const lockPath = pairAutoLockPath();
20205
20329
  try {
20206
- fs43.mkdirSync(path48.dirname(lockPath), { recursive: true });
20330
+ fs44.mkdirSync(path49.dirname(lockPath), { recursive: true });
20207
20331
  try {
20208
- fs43.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20332
+ fs44.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20209
20333
  } catch (e) {
20210
20334
  if (e.code !== "EEXIST") throw e;
20211
- const holder = Number(fs43.readFileSync(lockPath, "utf8").trim());
20335
+ const holder = Number(fs44.readFileSync(lockPath, "utf8").trim());
20212
20336
  if (isLivePairAuto(holder)) return false;
20213
- fs43.writeFileSync(lockPath, String(process.pid));
20337
+ fs44.writeFileSync(lockPath, String(process.pid));
20214
20338
  }
20215
20339
  process.once("exit", () => {
20216
20340
  try {
20217
- if (fs43.existsSync(lockPath) && Number(fs43.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20218
- fs43.unlinkSync(lockPath);
20341
+ if (fs44.existsSync(lockPath) && Number(fs44.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20342
+ fs44.unlinkSync(lockPath);
20219
20343
  }
20220
20344
  } catch {
20221
20345
  }
@@ -20660,19 +20784,19 @@ var AgentService = class _AgentService {
20660
20784
  };
20661
20785
 
20662
20786
  // src/agents/acp/adapters.ts
20663
- var path49 = __toESM(require("path"));
20787
+ var path50 = __toESM(require("path"));
20664
20788
  var require_ = require;
20665
20789
  function resolveBin(pkgName, binName) {
20666
20790
  try {
20667
20791
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
20668
20792
  const manifest = require_(`${pkgName}/package.json`);
20669
- const pkgDir = path49.dirname(manifestPath);
20793
+ const pkgDir = path50.dirname(manifestPath);
20670
20794
  const bin = manifest.bin;
20671
20795
  if (!bin) return null;
20672
- if (typeof bin === "string") return path49.resolve(pkgDir, bin);
20796
+ if (typeof bin === "string") return path50.resolve(pkgDir, bin);
20673
20797
  const target = binName ?? Object.keys(bin)[0];
20674
20798
  if (!target || !bin[target]) return null;
20675
- return path49.resolve(pkgDir, bin[target]);
20799
+ return path50.resolve(pkgDir, bin[target]);
20676
20800
  } catch {
20677
20801
  return null;
20678
20802
  }
@@ -20742,9 +20866,9 @@ function requiresAcp(agent) {
20742
20866
  var import_node_crypto7 = require("crypto");
20743
20867
 
20744
20868
  // src/services/history.service.ts
20745
- var fs44 = __toESM(require("fs"));
20746
- var path50 = __toESM(require("path"));
20747
- var os37 = __toESM(require("os"));
20869
+ var fs45 = __toESM(require("fs"));
20870
+ var path51 = __toESM(require("path"));
20871
+ var os38 = __toESM(require("os"));
20748
20872
  var https7 = __toESM(require("https"));
20749
20873
  var http6 = __toESM(require("http"));
20750
20874
  var import_zod2 = require("zod");
@@ -20771,7 +20895,7 @@ function parseJsonl(filePath) {
20771
20895
  const messages = [];
20772
20896
  let raw;
20773
20897
  try {
20774
- raw = fs44.readFileSync(filePath, "utf8");
20898
+ raw = fs45.readFileSync(filePath, "utf8");
20775
20899
  } catch (err) {
20776
20900
  if (err.code !== "ENOENT") {
20777
20901
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -20912,7 +21036,7 @@ var HistoryService = class _HistoryService {
20912
21036
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
20913
21037
  }
20914
21038
  get projectDir() {
20915
- return this.runtime.resolveHistoryDir(this.cwd) ?? path50.join(os37.homedir(), ".claude", "projects", encodeCwd(this.cwd));
21039
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path51.join(os38.homedir(), ".claude", "projects", encodeCwd(this.cwd));
20916
21040
  }
20917
21041
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
20918
21042
  setCurrentConversationId(id) {
@@ -20924,7 +21048,7 @@ var HistoryService = class _HistoryService {
20924
21048
  /** Return the current message count in the active conversation. */
20925
21049
  getCurrentMessageCount() {
20926
21050
  if (!this.currentConversationId) return 0;
20927
- const filePath = path50.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21051
+ const filePath = path51.join(this.projectDir, `${this.currentConversationId}.jsonl`);
20928
21052
  return parseJsonl(filePath).length;
20929
21053
  }
20930
21054
  /**
@@ -20935,7 +21059,7 @@ var HistoryService = class _HistoryService {
20935
21059
  const deadline = Date.now() + timeoutMs;
20936
21060
  while (Date.now() < deadline) {
20937
21061
  if (!this.currentConversationId) return null;
20938
- const filePath = path50.join(this.projectDir, `${this.currentConversationId}.jsonl`);
21062
+ const filePath = path51.join(this.projectDir, `${this.currentConversationId}.jsonl`);
20939
21063
  const messages = parseJsonl(filePath);
20940
21064
  if (messages.length > previousCount) {
20941
21065
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -20961,16 +21085,16 @@ var HistoryService = class _HistoryService {
20961
21085
  const dir = this.projectDir;
20962
21086
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
20963
21087
  try {
20964
- const files = fs44.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21088
+ const files = fs45.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
20965
21089
  try {
20966
- const stat3 = fs44.statSync(path50.join(dir, e.name));
21090
+ const stat3 = fs45.statSync(path51.join(dir, e.name));
20967
21091
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
20968
21092
  } catch {
20969
21093
  return { name: e.name, mtime: 0, birthtime: 0 };
20970
21094
  }
20971
21095
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
20972
21096
  if (files.length > 0) {
20973
- this.currentConversationId = path50.basename(files[0].name, ".jsonl");
21097
+ this.currentConversationId = path51.basename(files[0].name, ".jsonl");
20974
21098
  }
20975
21099
  } catch {
20976
21100
  }
@@ -21004,13 +21128,13 @@ var HistoryService = class _HistoryService {
21004
21128
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
21005
21129
  let entries;
21006
21130
  try {
21007
- entries = fs44.readdirSync(dir, { withFileTypes: true });
21131
+ entries = fs45.readdirSync(dir, { withFileTypes: true });
21008
21132
  } catch {
21009
21133
  return null;
21010
21134
  }
21011
21135
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
21012
21136
  try {
21013
- const stat3 = fs44.statSync(path50.join(dir, e.name));
21137
+ const stat3 = fs45.statSync(path51.join(dir, e.name));
21014
21138
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
21015
21139
  } catch {
21016
21140
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -21019,12 +21143,12 @@ var HistoryService = class _HistoryService {
21019
21143
  if (files.length === 0) return null;
21020
21144
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
21021
21145
  if (!files.some((f) => f.name === targetFile)) return null;
21022
- return this.extractUsageFromFile(path50.join(dir, targetFile));
21146
+ return this.extractUsageFromFile(path51.join(dir, targetFile));
21023
21147
  }
21024
21148
  extractUsageFromFile(filePath) {
21025
21149
  let raw;
21026
21150
  try {
21027
- raw = fs44.readFileSync(filePath, "utf8");
21151
+ raw = fs45.readFileSync(filePath, "utf8");
21028
21152
  } catch {
21029
21153
  return null;
21030
21154
  }
@@ -21069,9 +21193,9 @@ var HistoryService = class _HistoryService {
21069
21193
  let totalCost = 0;
21070
21194
  let files;
21071
21195
  try {
21072
- files = fs44.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21196
+ files = fs45.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21073
21197
  try {
21074
- return fs44.statSync(path50.join(projectDir, f)).mtimeMs >= monthStartMs;
21198
+ return fs45.statSync(path51.join(projectDir, f)).mtimeMs >= monthStartMs;
21075
21199
  } catch {
21076
21200
  return false;
21077
21201
  }
@@ -21082,7 +21206,7 @@ var HistoryService = class _HistoryService {
21082
21206
  for (const file of files) {
21083
21207
  let raw;
21084
21208
  try {
21085
- raw = fs44.readFileSync(path50.join(projectDir, file), "utf8");
21209
+ raw = fs45.readFileSync(path51.join(projectDir, file), "utf8");
21086
21210
  } catch {
21087
21211
  continue;
21088
21212
  }
@@ -21161,7 +21285,7 @@ var HistoryService = class _HistoryService {
21161
21285
  if (this.runtime.resolveHistoryFile) {
21162
21286
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
21163
21287
  }
21164
- return path50.join(this.projectDir, `${sessionId}.jsonl`);
21288
+ return path51.join(this.projectDir, `${sessionId}.jsonl`);
21165
21289
  }
21166
21290
  /**
21167
21291
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -21195,7 +21319,7 @@ var HistoryService = class _HistoryService {
21195
21319
  };
21196
21320
  });
21197
21321
  }
21198
- return parseJsonl(path50.join(this.projectDir, `${sessionId}.jsonl`));
21322
+ return parseJsonl(path51.join(this.projectDir, `${sessionId}.jsonl`));
21199
21323
  }
21200
21324
  async loadConversation(sessionId) {
21201
21325
  const messages = this.readConversation(sessionId);
@@ -21251,7 +21375,7 @@ var HistoryService = class _HistoryService {
21251
21375
  if (!filePath) return false;
21252
21376
  let mtimeMs;
21253
21377
  try {
21254
- mtimeMs = fs44.statSync(filePath).mtimeMs;
21378
+ mtimeMs = fs45.statSync(filePath).mtimeMs;
21255
21379
  } catch {
21256
21380
  return false;
21257
21381
  }
@@ -21320,10 +21444,10 @@ var HistoryService = class _HistoryService {
21320
21444
 
21321
21445
  // src/agents/acp/client.ts
21322
21446
  var import_node_child_process17 = require("child_process");
21323
- var fs45 = __toESM(require("fs/promises"));
21447
+ var fs46 = __toESM(require("fs/promises"));
21324
21448
  var fsSync = __toESM(require("fs"));
21325
- var os38 = __toESM(require("os"));
21326
- var path51 = __toESM(require("path"));
21449
+ var os39 = __toESM(require("os"));
21450
+ var path52 = __toESM(require("path"));
21327
21451
  var import_node_stream = require("stream");
21328
21452
 
21329
21453
  // ../../node_modules/@agentclientprotocol/sdk/dist/acp.js
@@ -24156,7 +24280,7 @@ var AcpClient = class {
24156
24280
  },
24157
24281
  readTextFile: async (params) => {
24158
24282
  try {
24159
- const content = await fs45.readFile(params.path, "utf8");
24283
+ const content = await fs46.readFile(params.path, "utf8");
24160
24284
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
24161
24285
  } catch (err) {
24162
24286
  const code = err.code;
@@ -24176,7 +24300,7 @@ var AcpClient = class {
24176
24300
  },
24177
24301
  writeTextFile: async (params) => {
24178
24302
  try {
24179
- await fs45.writeFile(params.path, params.content, "utf8");
24303
+ await fs46.writeFile(params.path, params.content, "utf8");
24180
24304
  return {};
24181
24305
  } catch (err) {
24182
24306
  const code = err.code;
@@ -24225,25 +24349,25 @@ function applyLineRange(content, line, limit) {
24225
24349
  return { content: lines.slice(start2, end).join("\n") };
24226
24350
  }
24227
24351
  function knownAgentBinaryDirs() {
24228
- const home = os38.homedir();
24352
+ const home = os39.homedir();
24229
24353
  const out2 = [];
24230
24354
  out2.push("/tmp/codeam-node20/bin");
24231
24355
  for (const root of [
24232
24356
  "/usr/local/share/nvm/versions/node",
24233
- path51.join(home, ".nvm/versions/node")
24357
+ path52.join(home, ".nvm/versions/node")
24234
24358
  ]) {
24235
24359
  try {
24236
24360
  for (const child of fsSync.readdirSync(root)) {
24237
- out2.push(path51.join(root, child, "bin"));
24361
+ out2.push(path52.join(root, child, "bin"));
24238
24362
  }
24239
24363
  } catch {
24240
24364
  }
24241
24365
  }
24242
- out2.push(path51.join(home, ".volta/bin"));
24366
+ out2.push(path52.join(home, ".volta/bin"));
24243
24367
  out2.push("/usr/local/bin");
24244
24368
  out2.push("/usr/bin");
24245
- out2.push(path51.join(home, ".local/bin"));
24246
- out2.push(path51.join(home, "bin"));
24369
+ out2.push(path52.join(home, ".local/bin"));
24370
+ out2.push(path52.join(home, "bin"));
24247
24371
  return out2.filter((p2) => {
24248
24372
  try {
24249
24373
  return fsSync.statSync(p2).isDirectory();
@@ -24254,7 +24378,7 @@ function knownAgentBinaryDirs() {
24254
24378
  }
24255
24379
  function expandPathForAgentBinaries(existingPath) {
24256
24380
  const existing = new Set(
24257
- existingPath.split(path51.delimiter).filter((p2) => p2.length > 0)
24381
+ existingPath.split(path52.delimiter).filter((p2) => p2.length > 0)
24258
24382
  );
24259
24383
  const additions = [];
24260
24384
  for (const dir of knownAgentBinaryDirs()) {
@@ -24264,7 +24388,7 @@ function expandPathForAgentBinaries(existingPath) {
24264
24388
  }
24265
24389
  }
24266
24390
  if (additions.length === 0) return existingPath;
24267
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path51.delimiter);
24391
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path52.delimiter);
24268
24392
  }
24269
24393
 
24270
24394
  // src/services/streaming/transport.ts
@@ -24748,16 +24872,16 @@ function commonPrefixLength(a, b) {
24748
24872
  }
24749
24873
 
24750
24874
  // src/agents/acp/onboarding.ts
24751
- var import_child_process22 = require("child_process");
24752
- var fs46 = __toESM(require("fs"));
24753
- var os39 = __toESM(require("os"));
24754
- var path52 = __toESM(require("path"));
24875
+ var import_child_process23 = require("child_process");
24876
+ var fs47 = __toESM(require("fs"));
24877
+ var os40 = __toESM(require("os"));
24878
+ var path53 = __toESM(require("path"));
24755
24879
  var _onboardingSeam = {
24756
- markerPath: (sessionId) => path52.join(os39.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
24757
- exists: (p2) => fs46.existsSync(p2),
24880
+ markerPath: (sessionId) => path53.join(os40.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
24881
+ exists: (p2) => fs47.existsSync(p2),
24758
24882
  write: (p2) => {
24759
- fs46.mkdirSync(path52.dirname(p2), { recursive: true });
24760
- fs46.writeFileSync(p2, "");
24883
+ fs47.mkdirSync(path53.dirname(p2), { recursive: true });
24884
+ fs47.writeFileSync(p2, "");
24761
24885
  },
24762
24886
  disabled: () => {
24763
24887
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -24769,7 +24893,7 @@ var _onboardingSeam = {
24769
24893
  */
24770
24894
  gitRemoteUrl: (cwd) => {
24771
24895
  try {
24772
- return (0, import_child_process22.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
24896
+ return (0, import_child_process23.execFileSync)("git", ["-C", cwd, "remote", "get-url", "origin"], {
24773
24897
  encoding: "utf8",
24774
24898
  stdio: ["ignore", "pipe", "ignore"],
24775
24899
  timeout: 2e3
@@ -24794,7 +24918,7 @@ function resolveRepoName(cwd) {
24794
24918
  if (name) return name;
24795
24919
  }
24796
24920
  }
24797
- const base = path52.basename(cwd || "");
24921
+ const base = path53.basename(cwd || "");
24798
24922
  if (base && !isUuid(base)) return base;
24799
24923
  return "this project";
24800
24924
  }
@@ -25086,9 +25210,9 @@ function deriveInputSuggestion(finalText) {
25086
25210
  var import_crypto5 = require("crypto");
25087
25211
 
25088
25212
  // src/services/turn-files/git-changeset.ts
25089
- var import_child_process23 = require("child_process");
25090
- var fs47 = __toESM(require("fs/promises"));
25091
- var path53 = __toESM(require("path"));
25213
+ var import_child_process24 = require("child_process");
25214
+ var fs48 = __toESM(require("fs/promises"));
25215
+ var path54 = __toESM(require("path"));
25092
25216
  async function collectRepoChangeset(opts) {
25093
25217
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
25094
25218
  if (status2 === null) return null;
@@ -25106,7 +25230,7 @@ async function collectRepoChangeset(opts) {
25106
25230
  let stats;
25107
25231
  if (row.fileStatus === "added" && numstatEntry === void 0) {
25108
25232
  const lineCount = await readUntrackedLineCount(
25109
- path53.join(opts.repoRoot, row.filePath)
25233
+ path54.join(opts.repoRoot, row.filePath)
25110
25234
  );
25111
25235
  stats = { added: lineCount, removed: 0 };
25112
25236
  } else {
@@ -25137,7 +25261,7 @@ function readUntrackedLineCount(absPath) {
25137
25261
  }
25138
25262
  async function defaultReadUntrackedLineCount(absPath) {
25139
25263
  try {
25140
- const content = await fs47.readFile(absPath, "utf8");
25264
+ const content = await fs48.readFile(absPath, "utf8");
25141
25265
  let count = 0;
25142
25266
  let pos = -1;
25143
25267
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -25201,7 +25325,7 @@ function defaultRunGit(cwd, args2) {
25201
25325
  return new Promise((resolve7) => {
25202
25326
  let proc;
25203
25327
  try {
25204
- proc = (0, import_child_process23.spawn)("git", args2, { cwd, env: process.env });
25328
+ proc = (0, import_child_process24.spawn)("git", args2, { cwd, env: process.env });
25205
25329
  } catch {
25206
25330
  resolve7(null);
25207
25331
  return;
@@ -25229,7 +25353,7 @@ function defaultRunGit(cwd, args2) {
25229
25353
  });
25230
25354
  }
25231
25355
  async function discoverRepos(workingDir, maxDepth = 4) {
25232
- const fs51 = await import("fs/promises");
25356
+ const fs52 = await import("fs/promises");
25233
25357
  const out2 = [];
25234
25358
  await walk(workingDir, 0);
25235
25359
  return out2;
@@ -25237,7 +25361,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25237
25361
  if (depth > maxDepth) return;
25238
25362
  let entries = [];
25239
25363
  try {
25240
- const dirents = await fs51.readdir(dir, { withFileTypes: true });
25364
+ const dirents = await fs52.readdir(dir, { withFileTypes: true });
25241
25365
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
25242
25366
  } catch {
25243
25367
  return;
@@ -25248,8 +25372,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25248
25372
  if (hasGit) {
25249
25373
  out2.push({
25250
25374
  repoRoot: dir,
25251
- repoPath: path53.relative(workingDir, dir),
25252
- repoName: path53.basename(dir)
25375
+ repoPath: path54.relative(workingDir, dir),
25376
+ repoName: path54.basename(dir)
25253
25377
  });
25254
25378
  return;
25255
25379
  }
@@ -25257,14 +25381,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25257
25381
  if (!entry.isDirectory) continue;
25258
25382
  if (entry.name === "node_modules") continue;
25259
25383
  if (entry.name === "dist" || entry.name === "build") continue;
25260
- await walk(path53.join(dir, entry.name), depth + 1);
25384
+ await walk(path54.join(dir, entry.name), depth + 1);
25261
25385
  }
25262
25386
  }
25263
25387
  }
25264
25388
 
25265
25389
  // src/services/turn-files/files-outbox.ts
25266
- var fs48 = __toESM(require("fs/promises"));
25267
- var path54 = __toESM(require("path"));
25390
+ var fs49 = __toESM(require("fs/promises"));
25391
+ var path55 = __toESM(require("path"));
25268
25392
  var import_os7 = require("os");
25269
25393
  var HOME_OUTBOX_DIR = ".codeam/outbox";
25270
25394
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -25297,16 +25421,16 @@ var FilesOutbox = class {
25297
25421
  backoffIndex = 0;
25298
25422
  stopped = false;
25299
25423
  constructor(opts) {
25300
- const base = opts.baseDir ?? path54.join(homeDir(), HOME_OUTBOX_DIR);
25301
- this.filePath = path54.join(base, `${opts.sessionId}.jsonl`);
25424
+ const base = opts.baseDir ?? path55.join(homeDir(), HOME_OUTBOX_DIR);
25425
+ this.filePath = path55.join(base, `${opts.sessionId}.jsonl`);
25302
25426
  this.post = opts.post;
25303
25427
  this.autoSchedule = opts.autoSchedule !== false;
25304
25428
  }
25305
25429
  /** Persist the entry to disk and trigger a flush. Returns once the
25306
25430
  * line is durable on disk (not once the POST succeeds). */
25307
25431
  async enqueue(entry) {
25308
- await fs48.mkdir(path54.dirname(this.filePath), { recursive: true });
25309
- await fs48.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25432
+ await fs49.mkdir(path55.dirname(this.filePath), { recursive: true });
25433
+ await fs49.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25310
25434
  this.backoffIndex = 0;
25311
25435
  if (this.autoSchedule) this.scheduleFlush(0);
25312
25436
  }
@@ -25395,7 +25519,7 @@ var FilesOutbox = class {
25395
25519
  async readAll() {
25396
25520
  let raw = "";
25397
25521
  try {
25398
- raw = await fs48.readFile(this.filePath, "utf8");
25522
+ raw = await fs49.readFile(this.filePath, "utf8");
25399
25523
  } catch {
25400
25524
  return [];
25401
25525
  }
@@ -25419,12 +25543,12 @@ var FilesOutbox = class {
25419
25543
  async rewrite(entries) {
25420
25544
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
25421
25545
  if (entries.length === 0) {
25422
- await fs48.unlink(this.filePath).catch(() => void 0);
25546
+ await fs49.unlink(this.filePath).catch(() => void 0);
25423
25547
  return;
25424
25548
  }
25425
25549
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
25426
- await fs48.writeFile(tmpPath, payload, "utf8");
25427
- await fs48.rename(tmpPath, this.filePath);
25550
+ await fs49.writeFile(tmpPath, payload, "utf8");
25551
+ await fs49.rename(tmpPath, this.filePath);
25428
25552
  }
25429
25553
  };
25430
25554
  function applyJitter(ms) {
@@ -26401,9 +26525,9 @@ async function runAcpSession(opts) {
26401
26525
  });
26402
26526
  let _budgetReachedPosted = false;
26403
26527
  const relaunchProxyWithoutBudget = async () => {
26404
- const { spawn: spawn32 } = await import("child_process");
26528
+ const { spawn: spawn33 } = await import("child_process");
26405
26529
  try {
26406
- const killer = spawn32("pkill", ["-TERM", "-f", "headroom.*proxy"], {
26530
+ const killer = spawn33("pkill", ["-TERM", "-f", "headroom.*proxy"], {
26407
26531
  detached: true,
26408
26532
  stdio: "ignore"
26409
26533
  });
@@ -26415,7 +26539,7 @@ async function runAcpSession(opts) {
26415
26539
  await new Promise((r) => setTimeout(r, 500));
26416
26540
  const proxyEnv = buildRelaunchProxyEnv(process.env);
26417
26541
  try {
26418
- const proxy = spawn32(
26542
+ const proxy = spawn33(
26419
26543
  "headroom",
26420
26544
  ["proxy", "--port", "8787"],
26421
26545
  { stdio: "ignore", detached: true, env: proxyEnv }
@@ -28053,15 +28177,15 @@ function fetchQuotaUsage(runtime, historySvc) {
28053
28177
  }
28054
28178
 
28055
28179
  // src/agents/claude/onboarding.ts
28056
- var fs49 = __toESM(require("fs"));
28057
- var os40 = __toESM(require("os"));
28058
- var path55 = __toESM(require("path"));
28180
+ var fs50 = __toESM(require("fs"));
28181
+ var os41 = __toESM(require("os"));
28182
+ var path56 = __toESM(require("path"));
28059
28183
  function ensureClaudeOnboarded() {
28060
28184
  try {
28061
- const file = path55.join(os40.homedir(), ".claude.json");
28185
+ const file = path56.join(os41.homedir(), ".claude.json");
28062
28186
  let config = {};
28063
28187
  try {
28064
- config = JSON.parse(fs49.readFileSync(file, "utf8"));
28188
+ config = JSON.parse(fs50.readFileSync(file, "utf8"));
28065
28189
  } catch {
28066
28190
  }
28067
28191
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -28072,8 +28196,8 @@ function ensureClaudeOnboarded() {
28072
28196
  if (typeof config.lastOnboardingVersion !== "string") {
28073
28197
  config.lastOnboardingVersion = "2.1.177";
28074
28198
  }
28075
- fs49.mkdirSync(path55.dirname(file), { recursive: true });
28076
- fs49.writeFileSync(file, JSON.stringify(config, null, 2));
28199
+ fs50.mkdirSync(path56.dirname(file), { recursive: true });
28200
+ fs50.writeFileSync(file, JSON.stringify(config, null, 2));
28077
28201
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
28078
28202
  } catch (err) {
28079
28203
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -28720,11 +28844,11 @@ async function logout() {
28720
28844
  var import_picocolors11 = __toESM(require("picocolors"));
28721
28845
 
28722
28846
  // src/services/providers/github-codespaces.ts
28723
- var import_child_process24 = require("child_process");
28847
+ var import_child_process25 = require("child_process");
28724
28848
  var import_util4 = require("util");
28725
28849
  var import_picocolors9 = __toESM(require("picocolors"));
28726
- var path56 = __toESM(require("path"));
28727
- var execFileP6 = (0, import_util4.promisify)(import_child_process24.execFile);
28850
+ var path57 = __toESM(require("path"));
28851
+ var execFileP6 = (0, import_util4.promisify)(import_child_process25.execFile);
28728
28852
  var MAX_BUFFER = 8 * 1024 * 1024;
28729
28853
  function resetStdinForChild() {
28730
28854
  if (process.stdin.isTTY) {
@@ -28768,7 +28892,7 @@ var GitHubCodespacesProvider = class {
28768
28892
  if (!isAuthed) {
28769
28893
  resetStdinForChild();
28770
28894
  await new Promise((resolve7, reject) => {
28771
- const proc = (0, import_child_process24.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
28895
+ const proc = (0, import_child_process25.spawn)("gh", ["auth", "login", "-s", "codespace,repo,read:user"], {
28772
28896
  stdio: "inherit"
28773
28897
  });
28774
28898
  proc.on("exit", (code) => {
@@ -28802,7 +28926,7 @@ var GitHubCodespacesProvider = class {
28802
28926
  wt(noteLines.join("\n"), "One more permission needed");
28803
28927
  resetStdinForChild();
28804
28928
  const refreshCode = await new Promise((resolve7, reject) => {
28805
- const proc = (0, import_child_process24.spawn)(
28929
+ const proc = (0, import_child_process25.spawn)(
28806
28930
  "gh",
28807
28931
  ["auth", "refresh", "-h", "github.com", "-s", "codespace"],
28808
28932
  { stdio: "inherit" }
@@ -28952,7 +29076,7 @@ var GitHubCodespacesProvider = class {
28952
29076
  O2.step(`Installing gh via ${installCmd.describe}\u2026`);
28953
29077
  resetStdinForChild();
28954
29078
  const ok = await new Promise((resolve7) => {
28955
- const proc = (0, import_child_process24.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
29079
+ const proc = (0, import_child_process25.spawn)(installCmd.exe, installCmd.args, { stdio: "inherit" });
28956
29080
  proc.on("exit", (code) => resolve7(code === 0));
28957
29081
  proc.on("error", () => resolve7(false));
28958
29082
  });
@@ -28979,7 +29103,7 @@ var GitHubCodespacesProvider = class {
28979
29103
  );
28980
29104
  resetStdinForChild();
28981
29105
  await new Promise((resolve7, reject) => {
28982
- const proc = (0, import_child_process24.spawn)(
29106
+ const proc = (0, import_child_process25.spawn)(
28983
29107
  "gh",
28984
29108
  ["auth", "refresh", "-h", "github.com", "-s", "repo,read:org"],
28985
29109
  { stdio: "inherit" }
@@ -29157,7 +29281,7 @@ var GitHubCodespacesProvider = class {
29157
29281
  async streamCommand(workspaceId, command2) {
29158
29282
  resetStdinForChild();
29159
29283
  return new Promise((resolve7, reject) => {
29160
- const proc = (0, import_child_process24.spawn)(
29284
+ const proc = (0, import_child_process25.spawn)(
29161
29285
  "gh",
29162
29286
  ["codespace", "ssh", "-c", workspaceId, "--", "-tt", command2],
29163
29287
  { stdio: "inherit" }
@@ -29184,11 +29308,11 @@ var GitHubCodespacesProvider = class {
29184
29308
  `mkdir -p ${shellQuote(remoteDir)} && tar -xzf - -C ${shellQuote(remoteDir)}`
29185
29309
  ];
29186
29310
  await new Promise((resolve7, reject) => {
29187
- const tar = (0, import_child_process24.spawn)("tar", tarArgs, {
29311
+ const tar = (0, import_child_process25.spawn)("tar", tarArgs, {
29188
29312
  stdio: ["ignore", "pipe", "pipe"],
29189
29313
  env: tarEnv
29190
29314
  });
29191
- const ssh = (0, import_child_process24.spawn)("gh", sshArgs, {
29315
+ const ssh = (0, import_child_process25.spawn)("gh", sshArgs, {
29192
29316
  stdio: [tar.stdout, "pipe", "pipe"]
29193
29317
  });
29194
29318
  let tarErr = "";
@@ -29212,7 +29336,7 @@ var GitHubCodespacesProvider = class {
29212
29336
  });
29213
29337
  }
29214
29338
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29215
- const remoteDir = path56.posix.dirname(remotePath);
29339
+ const remoteDir = path57.posix.dirname(remotePath);
29216
29340
  const parts = [
29217
29341
  `mkdir -p ${shellQuote(remoteDir)}`,
29218
29342
  `cat > ${shellQuote(remotePath)}`
@@ -29222,7 +29346,7 @@ var GitHubCodespacesProvider = class {
29222
29346
  }
29223
29347
  const cmd = parts.join(" && ");
29224
29348
  await new Promise((resolve7, reject) => {
29225
- const proc = (0, import_child_process24.spawn)(
29349
+ const proc = (0, import_child_process25.spawn)(
29226
29350
  "gh",
29227
29351
  ["codespace", "ssh", "-c", workspaceId, "--", cmd],
29228
29352
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -29280,11 +29404,11 @@ function shellQuote(s) {
29280
29404
  }
29281
29405
 
29282
29406
  // src/services/providers/gitpod.ts
29283
- var import_child_process25 = require("child_process");
29407
+ var import_child_process26 = require("child_process");
29284
29408
  var import_util5 = require("util");
29285
- var path57 = __toESM(require("path"));
29409
+ var path58 = __toESM(require("path"));
29286
29410
  var import_picocolors10 = __toESM(require("picocolors"));
29287
- var execFileP7 = (0, import_util5.promisify)(import_child_process25.execFile);
29411
+ var execFileP7 = (0, import_util5.promisify)(import_child_process26.execFile);
29288
29412
  var MAX_BUFFER2 = 8 * 1024 * 1024;
29289
29413
  function resetStdinForChild2() {
29290
29414
  if (process.stdin.isTTY) {
@@ -29324,7 +29448,7 @@ var GitpodProvider = class {
29324
29448
  );
29325
29449
  resetStdinForChild2();
29326
29450
  await new Promise((resolve7, reject) => {
29327
- const proc = (0, import_child_process25.spawn)("gitpod", ["login"], { stdio: "inherit" });
29451
+ const proc = (0, import_child_process26.spawn)("gitpod", ["login"], { stdio: "inherit" });
29328
29452
  proc.on("exit", (code) => {
29329
29453
  if (code === 0) resolve7();
29330
29454
  else reject(new Error("gitpod login failed."));
@@ -29476,7 +29600,7 @@ var GitpodProvider = class {
29476
29600
  async streamCommand(workspaceId, command2) {
29477
29601
  resetStdinForChild2();
29478
29602
  return new Promise((resolve7, reject) => {
29479
- const proc = (0, import_child_process25.spawn)(
29603
+ const proc = (0, import_child_process26.spawn)(
29480
29604
  "gitpod",
29481
29605
  ["workspace", "ssh", workspaceId, "--", "-tt", command2],
29482
29606
  { stdio: "inherit" }
@@ -29496,11 +29620,11 @@ var GitpodProvider = class {
29496
29620
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
29497
29621
  const remoteCmd = `mkdir -p ${shellQuote2(remoteDir)} && tar -xzf - -C ${shellQuote2(remoteDir)}`;
29498
29622
  await new Promise((resolve7, reject) => {
29499
- const tar = (0, import_child_process25.spawn)("tar", tarArgs, {
29623
+ const tar = (0, import_child_process26.spawn)("tar", tarArgs, {
29500
29624
  stdio: ["ignore", "pipe", "pipe"],
29501
29625
  env: tarEnv
29502
29626
  });
29503
- const ssh = (0, import_child_process25.spawn)(
29627
+ const ssh = (0, import_child_process26.spawn)(
29504
29628
  "gitpod",
29505
29629
  ["workspace", "ssh", workspaceId, "--", remoteCmd],
29506
29630
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -29522,7 +29646,7 @@ var GitpodProvider = class {
29522
29646
  });
29523
29647
  }
29524
29648
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29525
- const remoteDir = path57.posix.dirname(remotePath);
29649
+ const remoteDir = path58.posix.dirname(remotePath);
29526
29650
  const parts = [
29527
29651
  `mkdir -p ${shellQuote2(remoteDir)}`,
29528
29652
  `cat > ${shellQuote2(remotePath)}`
@@ -29532,7 +29656,7 @@ var GitpodProvider = class {
29532
29656
  }
29533
29657
  const cmd = parts.join(" && ");
29534
29658
  await new Promise((resolve7, reject) => {
29535
- const proc = (0, import_child_process25.spawn)(
29659
+ const proc = (0, import_child_process26.spawn)(
29536
29660
  "gitpod",
29537
29661
  ["workspace", "ssh", workspaceId, "--", cmd],
29538
29662
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -29556,10 +29680,10 @@ function shellQuote2(s) {
29556
29680
  }
29557
29681
 
29558
29682
  // src/services/providers/gitlab-workspaces.ts
29559
- var import_child_process26 = require("child_process");
29683
+ var import_child_process27 = require("child_process");
29560
29684
  var import_util6 = require("util");
29561
- var path58 = __toESM(require("path"));
29562
- var execFileP8 = (0, import_util6.promisify)(import_child_process26.execFile);
29685
+ var path59 = __toESM(require("path"));
29686
+ var execFileP8 = (0, import_util6.promisify)(import_child_process27.execFile);
29563
29687
  var MAX_BUFFER3 = 8 * 1024 * 1024;
29564
29688
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
29565
29689
  function resetStdinForChild3() {
@@ -29601,7 +29725,7 @@ var GitLabWorkspacesProvider = class {
29601
29725
  );
29602
29726
  resetStdinForChild3();
29603
29727
  await new Promise((resolve7, reject) => {
29604
- const proc = (0, import_child_process26.spawn)(
29728
+ const proc = (0, import_child_process27.spawn)(
29605
29729
  "glab",
29606
29730
  ["auth", "login", "--scopes", "api,read_user,read_repository"],
29607
29731
  { stdio: "inherit" }
@@ -29773,7 +29897,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
29773
29897
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
29774
29898
  resetStdinForChild3();
29775
29899
  return new Promise((resolve7, reject) => {
29776
- const proc = (0, import_child_process26.spawn)(
29900
+ const proc = (0, import_child_process27.spawn)(
29777
29901
  "ssh",
29778
29902
  ["-tt", "-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, command2],
29779
29903
  { stdio: "inherit" }
@@ -29794,8 +29918,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
29794
29918
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
29795
29919
  const remoteCmd = `mkdir -p ${shellQuote3(remoteDir)} && tar -xzf - -C ${shellQuote3(remoteDir)}`;
29796
29920
  await new Promise((resolve7, reject) => {
29797
- const tar = (0, import_child_process26.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
29798
- const ssh = (0, import_child_process26.spawn)(
29921
+ const tar = (0, import_child_process27.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
29922
+ const ssh = (0, import_child_process27.spawn)(
29799
29923
  "ssh",
29800
29924
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, remoteCmd],
29801
29925
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -29818,14 +29942,14 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
29818
29942
  }
29819
29943
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
29820
29944
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
29821
- const remoteDir = path58.posix.dirname(remotePath);
29945
+ const remoteDir = path59.posix.dirname(remotePath);
29822
29946
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
29823
29947
  if (options.mode != null) {
29824
29948
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
29825
29949
  }
29826
29950
  const cmd = parts.join(" && ");
29827
29951
  await new Promise((resolve7, reject) => {
29828
- const proc = (0, import_child_process26.spawn)(
29952
+ const proc = (0, import_child_process27.spawn)(
29829
29953
  "ssh",
29830
29954
  ["-o", "StrictHostKeyChecking=accept-new", `${workspaceId}@${sshHost}`, cmd],
29831
29955
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -29884,10 +30008,10 @@ function shellQuote3(s) {
29884
30008
  }
29885
30009
 
29886
30010
  // src/services/providers/railway.ts
29887
- var import_child_process27 = require("child_process");
30011
+ var import_child_process28 = require("child_process");
29888
30012
  var import_util7 = require("util");
29889
- var path59 = __toESM(require("path"));
29890
- var execFileP9 = (0, import_util7.promisify)(import_child_process27.execFile);
30013
+ var path60 = __toESM(require("path"));
30014
+ var execFileP9 = (0, import_util7.promisify)(import_child_process28.execFile);
29891
30015
  var MAX_BUFFER4 = 8 * 1024 * 1024;
29892
30016
  function resetStdinForChild4() {
29893
30017
  if (process.stdin.isTTY) {
@@ -29928,7 +30052,7 @@ var RailwayProvider = class {
29928
30052
  );
29929
30053
  resetStdinForChild4();
29930
30054
  await new Promise((resolve7, reject) => {
29931
- const proc = (0, import_child_process27.spawn)("railway", ["login"], { stdio: "inherit" });
30055
+ const proc = (0, import_child_process28.spawn)("railway", ["login"], { stdio: "inherit" });
29932
30056
  proc.on("exit", (code) => {
29933
30057
  if (code === 0) resolve7();
29934
30058
  else reject(new Error("railway login failed."));
@@ -30071,7 +30195,7 @@ var RailwayProvider = class {
30071
30195
  }
30072
30196
  resetStdinForChild4();
30073
30197
  return new Promise((resolve7, reject) => {
30074
- const proc = (0, import_child_process27.spawn)(
30198
+ const proc = (0, import_child_process28.spawn)(
30075
30199
  "railway",
30076
30200
  ["shell", "--project", projectId, "--service", serviceId, "--command", command2],
30077
30201
  { stdio: "inherit" }
@@ -30095,8 +30219,8 @@ var RailwayProvider = class {
30095
30219
  const tarEnv = { ...process.env, COPYFILE_DISABLE: "1" };
30096
30220
  const remoteCmd = `mkdir -p ${shellQuote4(remoteDir)} && tar -xzf - -C ${shellQuote4(remoteDir)}`;
30097
30221
  await new Promise((resolve7, reject) => {
30098
- const tar = (0, import_child_process27.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
30099
- const sh = (0, import_child_process27.spawn)(
30222
+ const tar = (0, import_child_process28.spawn)("tar", tarArgs, { stdio: ["ignore", "pipe", "pipe"], env: tarEnv });
30223
+ const sh = (0, import_child_process28.spawn)(
30100
30224
  "railway",
30101
30225
  ["shell", "--project", projectId, "--service", serviceId, "--command", remoteCmd],
30102
30226
  { stdio: [tar.stdout, "pipe", "pipe"] }
@@ -30122,14 +30246,14 @@ var RailwayProvider = class {
30122
30246
  if (!projectId || !serviceId) {
30123
30247
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
30124
30248
  }
30125
- const remoteDir = path59.posix.dirname(remotePath);
30249
+ const remoteDir = path60.posix.dirname(remotePath);
30126
30250
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
30127
30251
  if (options.mode != null) {
30128
30252
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
30129
30253
  }
30130
30254
  const cmd = parts.join(" && ");
30131
30255
  await new Promise((resolve7, reject) => {
30132
- const proc = (0, import_child_process27.spawn)(
30256
+ const proc = (0, import_child_process28.spawn)(
30133
30257
  "railway",
30134
30258
  ["shell", "--project", projectId, "--service", serviceId, "--command", cmd],
30135
30259
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -30768,8 +30892,8 @@ async function invite() {
30768
30892
  var import_node_dns = require("dns");
30769
30893
  var import_node_util5 = require("util");
30770
30894
  var import_node_crypto8 = require("crypto");
30771
- var fs50 = __toESM(require("fs"));
30772
- var path60 = __toESM(require("path"));
30895
+ var fs51 = __toESM(require("fs"));
30896
+ var path61 = __toESM(require("path"));
30773
30897
  var import_picocolors14 = __toESM(require("picocolors"));
30774
30898
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
30775
30899
  async function checkDns(apiBase2) {
@@ -30825,13 +30949,13 @@ async function checkHealth(apiBase2) {
30825
30949
  }
30826
30950
  }
30827
30951
  function checkConfigDir() {
30828
- const dir = path60.join(require("os").homedir(), ".codeam");
30952
+ const dir = path61.join(require("os").homedir(), ".codeam");
30829
30953
  try {
30830
- fs50.mkdirSync(dir, { recursive: true, mode: 448 });
30831
- const probe = path60.join(dir, ".doctor-probe");
30832
- fs50.writeFileSync(probe, "ok", { mode: 384 });
30833
- const read2 = fs50.readFileSync(probe, "utf8");
30834
- fs50.unlinkSync(probe);
30954
+ fs51.mkdirSync(dir, { recursive: true, mode: 448 });
30955
+ const probe = path61.join(dir, ".doctor-probe");
30956
+ fs51.writeFileSync(probe, "ok", { mode: 384 });
30957
+ const read2 = fs51.readFileSync(probe, "utf8");
30958
+ fs51.unlinkSync(probe);
30835
30959
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
30836
30960
  return {
30837
30961
  id: "config-dir",
@@ -30871,9 +30995,9 @@ function checkSessions() {
30871
30995
  }
30872
30996
  }
30873
30997
  function checkAgentBinaries() {
30874
- const os42 = createOsStrategy();
30998
+ const os43 = createOsStrategy();
30875
30999
  return getEnabledAgents().map((meta) => {
30876
- const found = os42.findInPath(meta.binaryName);
31000
+ const found = os43.findInPath(meta.binaryName);
30877
31001
  return {
30878
31002
  id: `agent-${meta.id}`,
30879
31003
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -30895,7 +31019,7 @@ function checkNodePty() {
30895
31019
  detail: "not required on this platform"
30896
31020
  };
30897
31021
  }
30898
- const vendoredPath = path60.join(__dirname, "vendor", "node-pty");
31022
+ const vendoredPath = path61.join(__dirname, "vendor", "node-pty");
30899
31023
  for (const target of [vendoredPath, "node-pty"]) {
30900
31024
  try {
30901
31025
  require(target);
@@ -30937,7 +31061,7 @@ function checkChokidar() {
30937
31061
  }
30938
31062
  async function doctor(args2 = []) {
30939
31063
  const json = args2.includes("--json");
30940
- const cliVersion = true ? "2.51.1" : "0.0.0-dev";
31064
+ const cliVersion = true ? "2.51.2" : "0.0.0-dev";
30941
31065
  const apiBase2 = resolveApiBaseUrl();
30942
31066
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
30943
31067
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -31136,7 +31260,7 @@ async function completion(args2) {
31136
31260
  // src/commands/version.ts
31137
31261
  var import_picocolors15 = __toESM(require("picocolors"));
31138
31262
  function version2() {
31139
- const v = true ? "2.51.1" : "unknown";
31263
+ const v = true ? "2.51.2" : "unknown";
31140
31264
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
31141
31265
  }
31142
31266
 
@@ -31285,10 +31409,10 @@ var EXIT_CODE_NAMES = {
31285
31409
  };
31286
31410
 
31287
31411
  // src/index.ts
31288
- var os41 = __toESM(require("os"));
31412
+ var os42 = __toESM(require("os"));
31289
31413
  if (!process.env.HOME) {
31290
31414
  try {
31291
- const home = os41.homedir();
31415
+ const home = os42.homedir();
31292
31416
  if (home) process.env.HOME = home;
31293
31417
  } catch {
31294
31418
  }