codeam-cli 2.65.0 → 2.65.1

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 +17 -0
  2. package/dist/index.js +724 -631
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3321,9 +3321,9 @@ var _default = makeConfig();
3321
3321
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, setSessionAgent, setSquadAuto, getSquadAuto, clearAll, saveCliConfig, loadCliConfig } = _default;
3322
3322
 
3323
3323
  // src/commands/pair-auto.ts
3324
- var fs63 = __toESM(require("fs"));
3325
- var os53 = __toESM(require("os"));
3326
- var path68 = __toESM(require("path"));
3324
+ var fs64 = __toESM(require("fs"));
3325
+ var os54 = __toESM(require("os"));
3326
+ var path69 = __toESM(require("path"));
3327
3327
  var import_crypto4 = require("crypto");
3328
3328
 
3329
3329
  // src/services/telemetry.service.ts
@@ -8073,7 +8073,7 @@ function readAnonId() {
8073
8073
  }
8074
8074
  function superProperties() {
8075
8075
  return {
8076
- cliVersion: true ? "2.65.0" : "0.0.0-dev",
8076
+ cliVersion: true ? "2.65.1" : "0.0.0-dev",
8077
8077
  nodeVersion: process.version,
8078
8078
  platform: process.platform,
8079
8079
  arch: process.arch,
@@ -8254,7 +8254,7 @@ var os4 = __toESM(require("os"));
8254
8254
  // package.json
8255
8255
  var package_default = {
8256
8256
  name: "codeam-cli",
8257
- version: "2.65.0",
8257
+ version: "2.65.1",
8258
8258
  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.",
8259
8259
  type: "commonjs",
8260
8260
  main: "dist/index.js",
@@ -9706,7 +9706,7 @@ var CommandRelayService = class _CommandRelayService {
9706
9706
  // fresh + clear the "CLI update available" banner after a self-update
9707
9707
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9708
9708
  // pair/reconnect). Older backends ignore the extra field.
9709
- ..."2.65.0" ? { ideVersion: "2.65.0" } : {}
9709
+ ..."2.65.1" ? { ideVersion: "2.65.1" } : {}
9710
9710
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9711
9711
  }
9712
9712
  /**
@@ -11098,11 +11098,11 @@ function closeAllTerminals() {
11098
11098
  }
11099
11099
 
11100
11100
  // src/commands/start/handlers.ts
11101
- var fs62 = __toESM(require("fs"));
11102
- var os52 = __toESM(require("os"));
11103
- var path67 = __toESM(require("path"));
11101
+ var fs63 = __toESM(require("fs"));
11102
+ var os53 = __toESM(require("os"));
11103
+ var path68 = __toESM(require("path"));
11104
11104
  var import_crypto3 = require("crypto");
11105
- var import_child_process25 = require("child_process");
11105
+ var import_child_process26 = require("child_process");
11106
11106
 
11107
11107
  // src/lib/payload.ts
11108
11108
  var import_zod = require("zod");
@@ -11932,8 +11932,8 @@ function findGitRoot2(startDir) {
11932
11932
 
11933
11933
  // src/commands/link.ts
11934
11934
  var import_node_crypto8 = require("crypto");
11935
- var fs31 = __toESM(require("fs"));
11936
- var path36 = __toESM(require("path"));
11935
+ var fs32 = __toESM(require("fs"));
11936
+ var path37 = __toESM(require("path"));
11937
11937
  var import_chokidar = __toESM(require("chokidar"));
11938
11938
  var import_picocolors2 = __toESM(require("picocolors"));
11939
11939
 
@@ -16543,6 +16543,18 @@ var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
16543
16543
  var INSTALL_TIMEOUT_MS = 15e4;
16544
16544
  var PREREQ_INSTALL_TIMEOUT_MS = 12e4;
16545
16545
  var REQUIRED_TOOLS = ["unzip", "git"];
16546
+ function defaultRunVersionProbe(binary, env) {
16547
+ const r = (0, import_node_child_process7.spawnSync)(binary, ["--version"], { stdio: "ignore", timeout: 15e3, env });
16548
+ return !r.error && r.status === 0;
16549
+ }
16550
+ function probeRuns(binary, env, deps) {
16551
+ const probe = deps.runVersionProbe ?? defaultRunVersionProbe;
16552
+ try {
16553
+ return probe(binary, env);
16554
+ } catch {
16555
+ return false;
16556
+ }
16557
+ }
16546
16558
  function manualInstallHint(runner, tools) {
16547
16559
  const pkgs = tools.join(" ");
16548
16560
  const argv = osPackageInstallArgv(detectPackageManager(runner), [...tools]);
@@ -16677,22 +16689,27 @@ async function ensureCoderabbitInstalled(os66, deps = {}) {
16677
16689
  log.info("coderabbit", "CodeRabbit CLI not found \u2014 installing via the official script");
16678
16690
  const run = deps.runInstallScript ?? defaultRunInstallScript;
16679
16691
  const { code, output } = await run(env);
16680
- if (code !== 0) {
16681
- const detail = summarizeInstallFailure(output);
16692
+ os66.augmentPath([`${os66.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
16693
+ const binary = os66.findInPath("coderabbit");
16694
+ const detail = summarizeInstallFailure(output);
16695
+ if (binary !== null) {
16696
+ if (code === 0) return { ok: true };
16697
+ if (probeRuns(binary, env, deps)) return { ok: true };
16682
16698
  return {
16683
16699
  ok: false,
16684
- error: detail ? `CodeRabbit CLI install failed: ${detail}` : "CodeRabbit CLI install failed \u2014 check this machine's network egress and try again."
16700
+ error: detail ? `CodeRabbit CLI install failed and the installed binary does not run: ${detail}` : "CodeRabbit CLI install failed \u2014 the installed `coderabbit` binary does not run. Re-run the install and check this machine's network egress."
16685
16701
  };
16686
16702
  }
16687
- os66.augmentPath([`${os66.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
16688
- if (os66.findInPath("coderabbit") === null) {
16689
- const detail = summarizeInstallFailure(output);
16703
+ if (code !== 0) {
16690
16704
  return {
16691
16705
  ok: false,
16692
- error: detail ? `CodeRabbit CLI install did not produce a binary: ${detail}` : "CodeRabbit CLI install reported success but no `coderabbit` binary was found on PATH."
16706
+ error: detail ? `CodeRabbit CLI install failed: ${detail}` : "CodeRabbit CLI install failed \u2014 check this machine's network egress and try again."
16693
16707
  };
16694
16708
  }
16695
- return { ok: true };
16709
+ return {
16710
+ ok: false,
16711
+ error: detail ? `CodeRabbit CLI install did not produce a binary: ${detail}` : "CodeRabbit CLI install reported success but no `coderabbit` binary was found on PATH."
16712
+ };
16696
16713
  }
16697
16714
 
16698
16715
  // src/agents/coderabbit/link.ts
@@ -17581,6 +17598,198 @@ function detectAiderSelector(_lines) {
17581
17598
  return null;
17582
17599
  }
17583
17600
 
17601
+ // src/agents/acp/agent-binary.ts
17602
+ var import_fs = __toESM(require("fs"));
17603
+ var import_os4 = __toESM(require("os"));
17604
+ var import_path4 = __toESM(require("path"));
17605
+ var import_child_process13 = require("child_process");
17606
+ function currentPlatformKey() {
17607
+ return `${process.platform}-${process.arch}`;
17608
+ }
17609
+ var SDK_PKG = "@anthropic-ai/claude-agent-sdk";
17610
+ function resolveSdkDirViaRequire(req = require) {
17611
+ try {
17612
+ return import_path4.default.dirname(req.resolve(`${SDK_PKG}/package.json`));
17613
+ } catch {
17614
+ }
17615
+ try {
17616
+ let dir = import_path4.default.dirname(req.resolve(SDK_PKG));
17617
+ for (let i = 0; i < 5; i++) {
17618
+ if (import_path4.default.basename(dir) === "claude-agent-sdk") return dir;
17619
+ const parent = import_path4.default.dirname(dir);
17620
+ if (parent === dir) break;
17621
+ dir = parent;
17622
+ }
17623
+ return null;
17624
+ } catch {
17625
+ return null;
17626
+ }
17627
+ }
17628
+ function defaultSdkDir() {
17629
+ return resolveSdkDirViaRequire();
17630
+ }
17631
+ function resolveClaudeNativeBinary(deps = {}) {
17632
+ const existsSync29 = deps.existsSync ?? import_fs.default.existsSync;
17633
+ const platformKey = deps.platformKey ?? currentPlatformKey();
17634
+ const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
17635
+ if (!sdkDir) return null;
17636
+ const scopeDir = import_path4.default.dirname(sdkDir);
17637
+ const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
17638
+ const candidate = import_path4.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
17639
+ return existsSync29(candidate) ? candidate : null;
17640
+ }
17641
+ var realSleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
17642
+ async function waitForClaudeNativeBinary(opts = {}) {
17643
+ const timeoutMs = opts.timeoutMs ?? 18e4;
17644
+ const pollMs = opts.pollMs ?? 500;
17645
+ const now = opts.now ?? Date.now;
17646
+ const sleep5 = opts.sleep ?? realSleep;
17647
+ const deps = {
17648
+ sdkDir: opts.sdkDir,
17649
+ platformKey: opts.platformKey,
17650
+ existsSync: opts.existsSync
17651
+ };
17652
+ const deadline = now() + timeoutMs;
17653
+ let found = resolveClaudeNativeBinary(deps);
17654
+ if (found) return found;
17655
+ while (now() < deadline) {
17656
+ await sleep5(pollMs);
17657
+ found = resolveClaudeNativeBinary(deps);
17658
+ if (found) return found;
17659
+ }
17660
+ return resolveClaudeNativeBinary(deps);
17661
+ }
17662
+ function isCommandOnPath(cmd, probe = defaultWhich) {
17663
+ return probe(cmd);
17664
+ }
17665
+ function defaultWhich(cmd) {
17666
+ const finder = process.platform === "win32" ? "where" : "which";
17667
+ try {
17668
+ const res = (0, import_child_process13.spawnSync)(finder, [cmd], { stdio: "ignore" });
17669
+ return res.status === 0;
17670
+ } catch {
17671
+ return false;
17672
+ }
17673
+ }
17674
+ async function waitForCommandOnPath(cmd, opts = {}) {
17675
+ const timeoutMs = opts.timeoutMs ?? 18e4;
17676
+ const pollMs = opts.pollMs ?? 500;
17677
+ const now = opts.now ?? Date.now;
17678
+ const sleep5 = opts.sleep ?? realSleep;
17679
+ const probe = opts.probe;
17680
+ const check = () => isCommandOnPath(cmd, probe);
17681
+ const deadline = now() + timeoutMs;
17682
+ if (check()) return true;
17683
+ while (now() < deadline) {
17684
+ await sleep5(pollMs);
17685
+ if (check()) return true;
17686
+ }
17687
+ return check();
17688
+ }
17689
+ function augmentUserLocalBinPaths() {
17690
+ const home = import_os4.default.homedir();
17691
+ const candidates = [
17692
+ // XDG-style per-user bin — npm's default global-prefix bin dir on most
17693
+ // Linux setups (`npm config set prefix ~/.local` or an nvm-less
17694
+ // per-user npm), and where curl-based agent installers commonly land.
17695
+ import_path4.default.join(home, ".local", "bin"),
17696
+ // Common explicit npm global-prefix conventions seen in the wild
17697
+ // (`npm config set prefix ~/.npm-global`, and Debian/Fedora's
17698
+ // `~/.local/share/npm` layout for `npm config set prefix
17699
+ // ~/.local/share/npm`).
17700
+ import_path4.default.join(home, ".npm-global", "bin"),
17701
+ import_path4.default.join(home, ".local", "share", "npm", "bin")
17702
+ ];
17703
+ const parts = (process.env.PATH ?? "").split(import_path4.default.delimiter).filter((p2) => p2.length > 0);
17704
+ const existing = new Set(parts);
17705
+ const additions = candidates.filter((dir) => !existing.has(dir));
17706
+ if (additions.length === 0) return;
17707
+ process.env.PATH = [...additions, ...parts].join(import_path4.default.delimiter);
17708
+ }
17709
+ function resolveCursorAgentBinary(deps = {}) {
17710
+ const existsSync29 = deps.existsSync ?? import_fs.default.existsSync;
17711
+ const platform3 = deps.platform ?? process.platform;
17712
+ const env = deps.env ?? process.env;
17713
+ if (platform3 === "win32") {
17714
+ const localAppData = env.LOCALAPPDATA;
17715
+ if (!localAppData) return null;
17716
+ const exe = import_path4.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
17717
+ return existsSync29(exe) ? exe : null;
17718
+ }
17719
+ const home = deps.homedir ?? import_os4.default.homedir();
17720
+ const unix = import_path4.default.posix.join(home, ".local", "bin", "cursor-agent");
17721
+ return existsSync29(unix) ? unix : null;
17722
+ }
17723
+ async function waitForCursorAgent(opts = {}) {
17724
+ const timeoutMs = opts.timeoutMs ?? 18e4;
17725
+ const pollMs = opts.pollMs ?? 500;
17726
+ const now = opts.now ?? Date.now;
17727
+ const sleep5 = opts.sleep ?? realSleep;
17728
+ const check = () => resolveCursorAgentBinary(opts) !== null || isCommandOnPath("cursor-agent", opts.probe);
17729
+ const deadline = now() + timeoutMs;
17730
+ if (check()) return true;
17731
+ while (now() < deadline) {
17732
+ await sleep5(pollMs);
17733
+ if (check()) return true;
17734
+ }
17735
+ return check();
17736
+ }
17737
+ var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_REQUIRE_ESM|ERR_UNKNOWN_BUILTIN_MODULE|ERR_UNSUPPORTED_DIR_IMPORT|ERR_PACKAGE_PATH_NOT_EXPORTED|ERR_INVALID_PACKAGE_CONFIG|ERR_INVALID_PACKAGE_TARGET|ERR_INVALID_MODULE_SPECIFIER|node:internal\/modules\/|Directory import|SyntaxError|Unexpected (token|end|identifier)|missing \) after argument list/i;
17738
+ var PERMANENT_ADAPTER_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
17739
+ function probeAdapterModuleGraph(command2, args2, opts = {}) {
17740
+ const livenessMs = opts.livenessMs ?? 400;
17741
+ const spawnFn = opts.spawnFn ?? import_child_process13.spawn;
17742
+ return new Promise((resolve9) => {
17743
+ let settled = false;
17744
+ let stderr = "";
17745
+ let timer;
17746
+ let child;
17747
+ const finish = (r) => {
17748
+ if (settled) return;
17749
+ settled = true;
17750
+ if (timer) clearTimeout(timer);
17751
+ try {
17752
+ child?.kill("SIGKILL");
17753
+ } catch {
17754
+ }
17755
+ resolve9(r);
17756
+ };
17757
+ try {
17758
+ child = spawnFn(command2, [...args2], { stdio: ["pipe", "ignore", "pipe"] });
17759
+ } catch {
17760
+ resolve9("ok");
17761
+ return;
17762
+ }
17763
+ child.stderr?.on("data", (d3) => {
17764
+ stderr += d3.toString();
17765
+ if (stderr.length > 8192) stderr = stderr.slice(-8192);
17766
+ });
17767
+ child.on("error", () => finish("ok"));
17768
+ child.on("exit", (code) => {
17769
+ if (code !== 0 && code !== null && !PERMANENT_ADAPTER_STARTUP_RE.test(stderr)) {
17770
+ finish("transient");
17771
+ } else {
17772
+ finish("ok");
17773
+ }
17774
+ });
17775
+ timer = setTimeout(() => finish("ok"), livenessMs);
17776
+ });
17777
+ }
17778
+ async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
17779
+ const timeoutMs = opts.timeoutMs ?? 18e4;
17780
+ const pollMs = opts.pollMs ?? 500;
17781
+ const now = opts.now ?? Date.now;
17782
+ const sleep5 = opts.sleep ?? realSleep;
17783
+ const probeOpts = { livenessMs: opts.livenessMs, spawnFn: opts.spawnFn };
17784
+ const deadline = now() + timeoutMs;
17785
+ if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
17786
+ while (now() < deadline) {
17787
+ await sleep5(pollMs);
17788
+ if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
17789
+ }
17790
+ return false;
17791
+ }
17792
+
17584
17793
  // src/agents/aider/runtime.ts
17585
17794
  var AIDER_CONTEXT_WINDOW = 2e5;
17586
17795
  var AIDER_MODELS = [
@@ -17599,6 +17808,7 @@ var AiderRuntimeStrategy = class {
17599
17808
  this.os = os66;
17600
17809
  }
17601
17810
  async prepareLaunch() {
17811
+ augmentUserLocalBinPaths();
17602
17812
  const binary = this.os.findInPath("aider");
17603
17813
  if (!binary) {
17604
17814
  throw new Error(
@@ -17670,19 +17880,19 @@ var import_node_crypto6 = require("crypto");
17670
17880
  var import_node_child_process13 = require("child_process");
17671
17881
 
17672
17882
  // src/agents/gemini/local-token.ts
17673
- var fs28 = __toESM(require("fs"));
17674
- var os25 = __toESM(require("os"));
17675
- var path33 = __toESM(require("path"));
17883
+ var fs29 = __toESM(require("fs"));
17884
+ var os26 = __toESM(require("os"));
17885
+ var path34 = __toESM(require("path"));
17676
17886
  function geminiCredentialsPath() {
17677
- return path33.join(os25.homedir(), ".gemini", "oauth_creds.json");
17887
+ return path34.join(os26.homedir(), ".gemini", "oauth_creds.json");
17678
17888
  }
17679
17889
  function geminiCredentialsPaths() {
17680
17890
  return [geminiCredentialsPath()];
17681
17891
  }
17682
17892
  async function extractLocalGeminiToken() {
17683
17893
  const file = geminiCredentialsPath();
17684
- if (!fs28.existsSync(file)) return null;
17685
- const credential = fs28.readFileSync(file, "utf8").trim();
17894
+ if (!fs29.existsSync(file)) return null;
17895
+ const credential = fs29.readFileSync(file, "utf8").trim();
17686
17896
  if (credential.length === 0) return null;
17687
17897
  return { method: "oauth", credential, source: "flat-file" };
17688
17898
  }
@@ -17738,20 +17948,20 @@ function geminiLoginLauncher() {
17738
17948
  }
17739
17949
 
17740
17950
  // src/agents/gemini/history.ts
17741
- var fs29 = __toESM(require("fs"));
17742
- var os26 = __toESM(require("os"));
17743
- var path34 = __toESM(require("path"));
17744
- var GEMINI_ROOT = path34.join(os26.homedir(), ".gemini");
17951
+ var fs30 = __toESM(require("fs"));
17952
+ var os27 = __toESM(require("os"));
17953
+ var path35 = __toESM(require("path"));
17954
+ var GEMINI_ROOT = path35.join(os27.homedir(), ".gemini");
17745
17955
  function projectNameForCwd(cwd, root) {
17746
17956
  try {
17747
17957
  const parsed = JSON.parse(
17748
- fs29.readFileSync(path34.join(root, "projects.json"), "utf8")
17958
+ fs30.readFileSync(path35.join(root, "projects.json"), "utf8")
17749
17959
  );
17750
17960
  const map = parsed.projects;
17751
17961
  if (map && typeof map === "object") {
17752
17962
  if (typeof map[cwd] === "string") return map[cwd];
17753
17963
  try {
17754
- const rp = fs29.realpathSync(cwd);
17964
+ const rp = fs30.realpathSync(cwd);
17755
17965
  if (typeof map[rp] === "string") return map[rp];
17756
17966
  } catch {
17757
17967
  }
@@ -17760,7 +17970,7 @@ function projectNameForCwd(cwd, root) {
17760
17970
  } catch (err) {
17761
17971
  log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
17762
17972
  }
17763
- return path34.basename(cwd) || null;
17973
+ return path35.basename(cwd) || null;
17764
17974
  }
17765
17975
  function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17766
17976
  const name = projectNameForCwd(cwd, root);
@@ -17768,8 +17978,8 @@ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17768
17978
  log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
17769
17979
  return null;
17770
17980
  }
17771
- const dir = path34.join(root, "tmp", name, "chats");
17772
- if (!fs29.existsSync(dir)) {
17981
+ const dir = path35.join(root, "tmp", name, "chats");
17982
+ if (!fs30.existsSync(dir)) {
17773
17983
  log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
17774
17984
  return null;
17775
17985
  }
@@ -17781,7 +17991,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17781
17991
  if (!dir) return null;
17782
17992
  let files;
17783
17993
  try {
17784
- files = fs29.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
17994
+ files = fs30.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
17785
17995
  } catch (err) {
17786
17996
  log.warn("gemini", `resolveHistoryFile \u2014 cannot read chats dir ${dir} (id8=${id8})`, err);
17787
17997
  return null;
@@ -17793,12 +18003,12 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17793
18003
  const byName = files.find((f) => id8.length > 0 && f.includes(id8));
17794
18004
  if (byName) {
17795
18005
  log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
17796
- return path34.join(dir, byName);
18006
+ return path35.join(dir, byName);
17797
18007
  }
17798
18008
  for (const f of files) {
17799
- const full = path34.join(dir, f);
18009
+ const full = path35.join(dir, f);
17800
18010
  try {
17801
- const firstLine = fs29.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
18011
+ const firstLine = fs30.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
17802
18012
  const hdr = JSON.parse(firstLine);
17803
18013
  if (hdr.sessionId === sessionId) {
17804
18014
  log.info("gemini", `resolveHistoryFile \u2014 matched by header sessionId: ${f}`);
@@ -17811,7 +18021,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17811
18021
  let newest = null;
17812
18022
  for (const f of files) {
17813
18023
  try {
17814
- const mtime = fs29.statSync(path34.join(dir, f)).mtimeMs;
18024
+ const mtime = fs30.statSync(path35.join(dir, f)).mtimeMs;
17815
18025
  if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
17816
18026
  } catch {
17817
18027
  }
@@ -17820,7 +18030,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17820
18030
  "gemini",
17821
18031
  `resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
17822
18032
  );
17823
- return newest ? path34.join(dir, newest.file) : null;
18033
+ return newest ? path35.join(dir, newest.file) : null;
17824
18034
  }
17825
18035
  function extractGeminiText(content) {
17826
18036
  const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
@@ -17848,7 +18058,7 @@ function isSyntheticGeminiTurn(text) {
17848
18058
  function parseHistoryFile5(filePath) {
17849
18059
  let raw;
17850
18060
  try {
17851
- raw = fs29.readFileSync(filePath, "utf8");
18061
+ raw = fs30.readFileSync(filePath, "utf8");
17852
18062
  } catch (err) {
17853
18063
  log.warn("gemini", `parseHistoryFile \u2014 cannot read ${filePath}`, err);
17854
18064
  return [];
@@ -17889,7 +18099,7 @@ function parseHistoryFile5(filePath) {
17889
18099
  }
17890
18100
  log.trace(
17891
18101
  "gemini",
17892
- `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path34.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
18102
+ `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path35.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
17893
18103
  );
17894
18104
  return out2;
17895
18105
  }
@@ -18033,42 +18243,42 @@ var import_node_os3 = require("os");
18033
18243
  var import_node_path4 = require("path");
18034
18244
 
18035
18245
  // src/agents/kimi/history.ts
18036
- var fs30 = __toESM(require("fs"));
18037
- var os27 = __toESM(require("os"));
18038
- var path35 = __toESM(require("path"));
18246
+ var fs31 = __toESM(require("fs"));
18247
+ var os28 = __toESM(require("os"));
18248
+ var path36 = __toESM(require("path"));
18039
18249
  var import_node_crypto7 = require("crypto");
18040
18250
  function kimiHome() {
18041
- return process.env.KIMI_CODE_HOME || path35.join(os27.homedir(), ".kimi-code");
18251
+ return process.env.KIMI_CODE_HOME || path36.join(os28.homedir(), ".kimi-code");
18042
18252
  }
18043
18253
  function workDirKey(cwd) {
18044
18254
  const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
18045
- return `wd_${path35.basename(cwd)}_${hash}`;
18255
+ return `wd_${path36.basename(cwd)}_${hash}`;
18046
18256
  }
18047
18257
  function resolveHistoryDir6(cwd) {
18048
- const dir = path35.join(kimiHome(), "sessions", workDirKey(cwd));
18049
- if (!fs30.existsSync(dir)) {
18258
+ const dir = path36.join(kimiHome(), "sessions", workDirKey(cwd));
18259
+ if (!fs31.existsSync(dir)) {
18050
18260
  log.debug("kimi", `resolveHistoryDir \u2014 session bucket not present yet: ${dir}`);
18051
18261
  return null;
18052
18262
  }
18053
18263
  return dir;
18054
18264
  }
18055
- var WIRE_REL = path35.join("agents", "main", "wire.jsonl");
18265
+ var WIRE_REL = path36.join("agents", "main", "wire.jsonl");
18056
18266
  function resolveHistoryFile5(cwd, sessionId) {
18057
18267
  const fromIndex = sessionDirFromIndex(sessionId);
18058
18268
  if (fromIndex) {
18059
- const p2 = path35.join(fromIndex, WIRE_REL);
18060
- if (fs30.existsSync(p2)) return p2;
18269
+ const p2 = path36.join(fromIndex, WIRE_REL);
18270
+ if (fs31.existsSync(p2)) return p2;
18061
18271
  }
18062
- const bucket2 = path35.join(kimiHome(), "sessions", workDirKey(cwd));
18063
- const computed = path35.join(bucket2, sessionId, WIRE_REL);
18064
- if (fs30.existsSync(computed)) return computed;
18272
+ const bucket2 = path36.join(kimiHome(), "sessions", workDirKey(cwd));
18273
+ const computed = path36.join(bucket2, sessionId, WIRE_REL);
18274
+ if (fs31.existsSync(computed)) return computed;
18065
18275
  const scanned = scanBucketsForSession(sessionId);
18066
18276
  if (scanned) return scanned;
18067
18277
  return null;
18068
18278
  }
18069
18279
  function sessionDirFromIndex(sessionId) {
18070
18280
  try {
18071
- const raw = fs30.readFileSync(path35.join(kimiHome(), "session_index.jsonl"), "utf8");
18281
+ const raw = fs31.readFileSync(path36.join(kimiHome(), "session_index.jsonl"), "utf8");
18072
18282
  for (const line of raw.split("\n")) {
18073
18283
  if (!line.includes(sessionId)) continue;
18074
18284
  try {
@@ -18084,22 +18294,22 @@ function sessionDirFromIndex(sessionId) {
18084
18294
  return null;
18085
18295
  }
18086
18296
  function scanBucketsForSession(sessionId) {
18087
- const sessionsRoot = path35.join(kimiHome(), "sessions");
18297
+ const sessionsRoot = path36.join(kimiHome(), "sessions");
18088
18298
  let buckets;
18089
18299
  try {
18090
- buckets = fs30.readdirSync(sessionsRoot, { withFileTypes: true });
18300
+ buckets = fs31.readdirSync(sessionsRoot, { withFileTypes: true });
18091
18301
  } catch {
18092
18302
  return null;
18093
18303
  }
18094
18304
  for (const b of buckets) {
18095
18305
  if (!b.isDirectory()) continue;
18096
- const candidate = path35.join(sessionsRoot, b.name, sessionId, WIRE_REL);
18097
- if (fs30.existsSync(candidate)) return candidate;
18306
+ const candidate = path36.join(sessionsRoot, b.name, sessionId, WIRE_REL);
18307
+ if (fs31.existsSync(candidate)) return candidate;
18098
18308
  }
18099
18309
  return null;
18100
18310
  }
18101
18311
  async function discoverSessionId2(cwd, opts) {
18102
- const bucket2 = path35.join(kimiHome(), "sessions", workDirKey(cwd));
18312
+ const bucket2 = path36.join(kimiHome(), "sessions", workDirKey(cwd));
18103
18313
  const floor = opts.sinceMs - 2e3;
18104
18314
  const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
18105
18315
  for (; ; ) {
@@ -18112,7 +18322,7 @@ async function discoverSessionId2(cwd, opts) {
18112
18322
  function newestSessionSince(bucket2, floorMs) {
18113
18323
  let entries;
18114
18324
  try {
18115
- entries = fs30.readdirSync(bucket2, { withFileTypes: true });
18325
+ entries = fs31.readdirSync(bucket2, { withFileTypes: true });
18116
18326
  } catch {
18117
18327
  return null;
18118
18328
  }
@@ -18122,7 +18332,7 @@ function newestSessionSince(bucket2, floorMs) {
18122
18332
  if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
18123
18333
  let mtime;
18124
18334
  try {
18125
- mtime = fs30.statSync(path35.join(bucket2, e.name)).mtimeMs;
18335
+ mtime = fs31.statSync(path36.join(bucket2, e.name)).mtimeMs;
18126
18336
  } catch {
18127
18337
  continue;
18128
18338
  }
@@ -18143,7 +18353,7 @@ function joinTextParts(parts) {
18143
18353
  function parseHistoryFile6(filePath) {
18144
18354
  let raw;
18145
18355
  try {
18146
- raw = fs30.readFileSync(filePath, "utf8");
18356
+ raw = fs31.readFileSync(filePath, "utf8");
18147
18357
  } catch {
18148
18358
  return [];
18149
18359
  }
@@ -18521,7 +18731,7 @@ function parseLinkArgs(args2) {
18521
18731
  if (apiKeyFileArg) {
18522
18732
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
18523
18733
  try {
18524
- apiKey = fs31.readFileSync(path36.resolve(filePath), "utf8").trim();
18734
+ apiKey = fs32.readFileSync(path37.resolve(filePath), "utf8").trim();
18525
18735
  } catch (err) {
18526
18736
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
18527
18737
  }
@@ -18648,7 +18858,7 @@ async function link(args2 = []) {
18648
18858
  return;
18649
18859
  }
18650
18860
  if (parsed.tokenFile) {
18651
- const credential = fs31.readFileSync(path36.resolve(parsed.tokenFile), "utf8").trim();
18861
+ const credential = fs32.readFileSync(path37.resolve(parsed.tokenFile), "utf8").trim();
18652
18862
  if (!credential) {
18653
18863
  showError(`--token-file ${parsed.tokenFile} is empty.`);
18654
18864
  process.exit(1);
@@ -18867,13 +19077,13 @@ async function linkDryRunPreflight(ctx) {
18867
19077
  // src/agents/coderabbit/configure.ts
18868
19078
  var import_node_child_process17 = require("child_process");
18869
19079
  var import_node_fs6 = require("fs");
18870
- var path38 = __toESM(require("path"));
19080
+ var path39 = __toESM(require("path"));
18871
19081
 
18872
19082
  // src/agents/coderabbit/oauth.ts
18873
19083
  var import_node_child_process16 = require("child_process");
18874
- var fs32 = __toESM(require("fs"));
18875
- var os28 = __toESM(require("os"));
18876
- var path37 = __toESM(require("path"));
19084
+ var fs33 = __toESM(require("fs"));
19085
+ var os29 = __toESM(require("os"));
19086
+ var path38 = __toESM(require("path"));
18877
19087
  function parseCoderabbitAuthEvent(line) {
18878
19088
  const l = line.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "").trim();
18879
19089
  if (!l || l[0] !== "{") return null;
@@ -18922,8 +19132,8 @@ function resolvePython() {
18922
19132
  function spawnCoderabbitLoginProc(cmd, args2) {
18923
19133
  const python = resolvePython();
18924
19134
  if (python) {
18925
- const helper = path37.join(os28.tmpdir(), "codeam-cr-pty.py");
18926
- fs32.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
19135
+ const helper = path38.join(os29.tmpdir(), "codeam-cr-pty.py");
19136
+ fs33.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
18927
19137
  return (0, import_node_child_process16.spawn)(python, [helper, cmd, ...args2], {
18928
19138
  stdio: ["pipe", "pipe", "pipe"],
18929
19139
  env: { ...process.env, TERM: "xterm-256color", COLUMNS: "220", LINES: "50" },
@@ -19034,7 +19244,7 @@ function runCoderabbitOAuthLogin(deps) {
19034
19244
  });
19035
19245
  }
19036
19246
  function coderabbitDir(home) {
19037
- return path37.join(home ?? os28.homedir(), ".coderabbit");
19247
+ return path38.join(home ?? os29.homedir(), ".coderabbit");
19038
19248
  }
19039
19249
  var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
19040
19250
  function snapshotCredentialDir(home) {
@@ -19042,14 +19252,14 @@ function snapshotCredentialDir(home) {
19042
19252
  const snap = {};
19043
19253
  let entries;
19044
19254
  try {
19045
- entries = fs32.readdirSync(dir, { withFileTypes: true });
19255
+ entries = fs33.readdirSync(dir, { withFileTypes: true });
19046
19256
  } catch {
19047
19257
  return snap;
19048
19258
  }
19049
19259
  for (const e of entries) {
19050
19260
  if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
19051
19261
  try {
19052
- const st3 = fs32.statSync(path37.join(dir, e.name));
19262
+ const st3 = fs33.statSync(path38.join(dir, e.name));
19053
19263
  snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
19054
19264
  } catch {
19055
19265
  }
@@ -19067,7 +19277,7 @@ function diffCapturedCredential(before, home) {
19067
19277
  }
19068
19278
  if (!best) return null;
19069
19279
  try {
19070
- return { file: best.file, contents: fs32.readFileSync(path37.join(dir, best.file), "utf8") };
19280
+ return { file: best.file, contents: fs33.readFileSync(path38.join(dir, best.file), "utf8") };
19071
19281
  } catch {
19072
19282
  return null;
19073
19283
  }
@@ -19144,7 +19354,7 @@ function collectChangedFiles(cwd) {
19144
19354
  return [...byPath.values()];
19145
19355
  }
19146
19356
  function restoreCoderabbitOauthBlob(os66, value) {
19147
- const dir = path38.join(os66.homeDir(), ".coderabbit");
19357
+ const dir = path39.join(os66.homeDir(), ".coderabbit");
19148
19358
  (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
19149
19359
  let file = "auth.json";
19150
19360
  let contents = value.trim();
@@ -19152,13 +19362,13 @@ function restoreCoderabbitOauthBlob(os66, value) {
19152
19362
  try {
19153
19363
  const parsed = JSON.parse(contents);
19154
19364
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
19155
- file = path38.basename(parsed.file);
19365
+ file = path39.basename(parsed.file);
19156
19366
  contents = parsed.contents;
19157
19367
  }
19158
19368
  } catch {
19159
19369
  }
19160
19370
  }
19161
- (0, import_node_fs6.writeFileSync)(path38.join(dir, file), contents, { mode: 384 });
19371
+ (0, import_node_fs6.writeFileSync)(path39.join(dir, file), contents, { mode: 384 });
19162
19372
  }
19163
19373
  function installFailureMessage(result) {
19164
19374
  return result.error ?? "CodeRabbit CLI could not be installed";
@@ -19174,10 +19384,10 @@ async function configureCoderabbit(input, deps = {}) {
19174
19384
  const home = os66.homeDir();
19175
19385
  os66.augmentPath(
19176
19386
  os66.id === "win32" ? [
19177
- path38.join(home, ".local", "bin"),
19178
- path38.join(process.env.APPDATA ?? path38.join(home, "AppData", "Roaming"), "npm"),
19179
- path38.join(home, "scoop", "shims")
19180
- ] : [path38.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
19387
+ path39.join(home, ".local", "bin"),
19388
+ path39.join(process.env.APPDATA ?? path39.join(home, "AppData", "Roaming"), "npm"),
19389
+ path39.join(home, "scoop", "shims")
19390
+ ] : [path39.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
19181
19391
  );
19182
19392
  const installed2 = os66.findInPath("coderabbit") !== null;
19183
19393
  const base = () => ({
@@ -19486,9 +19696,9 @@ function defaultRunGh(args2) {
19486
19696
 
19487
19697
  // src/commands/host-agent.ts
19488
19698
  var import_node_child_process25 = require("child_process");
19489
- var os41 = __toESM(require("os"));
19490
- var fs45 = __toESM(require("fs"));
19491
- var path49 = __toESM(require("path"));
19699
+ var os42 = __toESM(require("os"));
19700
+ var fs46 = __toESM(require("fs"));
19701
+ var path50 = __toESM(require("path"));
19492
19702
 
19493
19703
  // src/integrations/manifest.ts
19494
19704
  var import_node_fs8 = __toESM(require("fs"));
@@ -19611,14 +19821,14 @@ function persistOrClearSkillsFromPayload(skills) {
19611
19821
  }
19612
19822
 
19613
19823
  // src/commands/host/agent-install.ts
19614
- var import_child_process13 = require("child_process");
19615
- var os32 = __toESM(require("os"));
19824
+ var import_child_process14 = require("child_process");
19825
+ var os33 = __toESM(require("os"));
19616
19826
  function runAgentInstallScript(script, opts = {}) {
19617
19827
  const timeoutMs = opts.timeoutMs ?? 18e4;
19618
19828
  const scope = opts.logScope ?? "agent-install";
19619
19829
  return new Promise((resolve9) => {
19620
- const home = process.env.HOME || os32.homedir();
19621
- const child = (0, import_child_process13.spawn)("sh", ["-c", script], {
19830
+ const home = process.env.HOME || os33.homedir();
19831
+ const child = (0, import_child_process14.spawn)("sh", ["-c", script], {
19622
19832
  env: { ...process.env, HOME: home },
19623
19833
  stdio: ["ignore", "pipe", "pipe"]
19624
19834
  });
@@ -19683,14 +19893,14 @@ function describeReason(reason) {
19683
19893
  }
19684
19894
 
19685
19895
  // src/commands/host/host-client.ts
19686
- var fs36 = __toESM(require("fs"));
19687
- var os33 = __toESM(require("os"));
19688
- var path41 = __toESM(require("path"));
19896
+ var fs37 = __toESM(require("fs"));
19897
+ var os34 = __toESM(require("os"));
19898
+ var path42 = __toESM(require("path"));
19689
19899
  var import_node_crypto9 = require("crypto");
19690
19900
  function sampleCpuTimes() {
19691
19901
  let idle = 0;
19692
19902
  let total = 0;
19693
- for (const cpu of os33.cpus()) {
19903
+ for (const cpu of os34.cpus()) {
19694
19904
  const t2 = cpu.times;
19695
19905
  idle += t2.idle;
19696
19906
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -19709,8 +19919,8 @@ var MetricsCollector = class {
19709
19919
  const prev = this.prevCpu;
19710
19920
  this.prevCpu = current2;
19711
19921
  if (!prev) {
19712
- const cores = os33.cpus().length || 1;
19713
- const proxy = os33.loadavg()[0] / cores * 100;
19922
+ const cores = os34.cpus().length || 1;
19923
+ const proxy = os34.loadavg()[0] / cores * 100;
19714
19924
  return Math.min(100, Math.max(0, Math.round(proxy)));
19715
19925
  }
19716
19926
  const idleDelta = current2.idle - prev.idle;
@@ -19723,8 +19933,8 @@ var MetricsCollector = class {
19723
19933
  collect() {
19724
19934
  return {
19725
19935
  cpuPct: this.cpuPct(),
19726
- ramUsedMb: Math.round((os33.totalmem() - os33.freemem()) / 1048576),
19727
- ramTotalMb: Math.round(os33.totalmem() / 1048576),
19936
+ ramUsedMb: Math.round((os34.totalmem() - os34.freemem()) / 1048576),
19937
+ ramTotalMb: Math.round(os34.totalmem() / 1048576),
19728
19938
  latencyMs: this.lastLatencyMs
19729
19939
  };
19730
19940
  }
@@ -19733,19 +19943,19 @@ function apiBase() {
19733
19943
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
19734
19944
  }
19735
19945
  function hostIdentityPath() {
19736
- return path41.join(os33.homedir(), ".codeam", "host-agent.json");
19946
+ return path42.join(os34.homedir(), ".codeam", "host-agent.json");
19737
19947
  }
19738
19948
  function collectOsInfo() {
19739
19949
  return {
19740
- distro: os33.platform(),
19741
- arch: os33.arch(),
19742
- kernel: os33.release(),
19950
+ distro: os34.platform(),
19951
+ arch: os34.arch(),
19952
+ kernel: os34.release(),
19743
19953
  nodeVersion: process.versions.node
19744
19954
  };
19745
19955
  }
19746
19956
  function loadHostIdentity() {
19747
19957
  try {
19748
- const raw = fs36.readFileSync(hostIdentityPath(), "utf8");
19958
+ const raw = fs37.readFileSync(hostIdentityPath(), "utf8");
19749
19959
  const parsed = JSON.parse(raw);
19750
19960
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
19751
19961
  const p2 = parsed;
@@ -19764,8 +19974,8 @@ function loadHostIdentity() {
19764
19974
  }
19765
19975
  function saveHostIdentity(identity) {
19766
19976
  const file = hostIdentityPath();
19767
- fs36.mkdirSync(path41.dirname(file), { recursive: true, mode: 448 });
19768
- fs36.writeFileSync(file, JSON.stringify(identity, null, 2), {
19977
+ fs37.mkdirSync(path42.dirname(file), { recursive: true, mode: 448 });
19978
+ fs37.writeFileSync(file, JSON.stringify(identity, null, 2), {
19769
19979
  encoding: "utf8",
19770
19980
  mode: 384
19771
19981
  });
@@ -19810,7 +20020,7 @@ function isTerminalEnrollError(err) {
19810
20020
  }
19811
20021
  function deleteHostIdentity() {
19812
20022
  try {
19813
- fs36.rmSync(hostIdentityPath(), { force: true });
20023
+ fs37.rmSync(hostIdentityPath(), { force: true });
19814
20024
  } catch {
19815
20025
  }
19816
20026
  }
@@ -19834,7 +20044,7 @@ async function postJson(pathname, body) {
19834
20044
  function resolveHostLabel(label) {
19835
20045
  const explicit = label?.trim();
19836
20046
  const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
19837
- const resolved = explicit || envLabel || os33.hostname();
20047
+ const resolved = explicit || envLabel || os34.hostname();
19838
20048
  return resolved.slice(0, 80);
19839
20049
  }
19840
20050
  async function redeemEnrollToken(token, label) {
@@ -19945,17 +20155,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
19945
20155
  }
19946
20156
 
19947
20157
  // src/commands/host/workspace.ts
19948
- var fs37 = __toESM(require("fs"));
19949
- var os34 = __toESM(require("os"));
19950
- var path42 = __toESM(require("path"));
20158
+ var fs38 = __toESM(require("fs"));
20159
+ var os35 = __toESM(require("os"));
20160
+ var path43 = __toESM(require("path"));
19951
20161
  var import_node_child_process20 = require("child_process");
19952
20162
  var import_node_util4 = require("util");
19953
20163
  var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process20.execFile);
19954
20164
  function isAbsolutePathTarget(target) {
19955
- return path42.isAbsolute(target);
20165
+ return path43.isAbsolute(target);
19956
20166
  }
19957
20167
  function selfHostedWorkspaceRoot() {
19958
- return path42.join(os34.homedir(), ".codeam", "self-hosted");
20168
+ return path43.join(os35.homedir(), ".codeam", "self-hosted");
19959
20169
  }
19960
20170
  function nonInteractiveGitEnv() {
19961
20171
  return {
@@ -20025,15 +20235,15 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
20025
20235
  const isGitlab = provider === "gitlab";
20026
20236
  if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
20027
20237
  if (!cloneToken) return;
20028
- const credFile = path42.join(dest, ".git", "codeam-credentials");
20238
+ const credFile = path43.join(dest, ".git", "codeam-credentials");
20029
20239
  const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
20030
20240
  ` : `https://x-access-token:${cloneToken}@github.com
20031
20241
  `;
20032
- fs37.writeFileSync(credFile, credLine, { mode: 384 });
20242
+ fs38.writeFileSync(credFile, credLine, { mode: 384 });
20033
20243
  restrictToOwner(credFile);
20034
20244
  const env = nonInteractiveGitEnv();
20035
20245
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
20036
- const credFilePosix = credFile.split(path42.sep).join("/");
20246
+ const credFilePosix = credFile.split(path43.sep).join("/");
20037
20247
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
20038
20248
  });
20039
20249
  await git2([
@@ -20066,17 +20276,17 @@ function maskToken(text, cloneToken) {
20066
20276
  }
20067
20277
  async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
20068
20278
  if (isAbsolutePathTarget(repoOrPath)) {
20069
- if (!fs37.existsSync(repoOrPath)) {
20279
+ if (!fs38.existsSync(repoOrPath)) {
20070
20280
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
20071
20281
  }
20072
20282
  return repoOrPath;
20073
20283
  }
20074
- const dest = path42.join(selfHostedWorkspaceRoot(), deployId);
20075
- if (fs37.existsSync(path42.join(dest, ".git"))) {
20284
+ const dest = path43.join(selfHostedWorkspaceRoot(), deployId);
20285
+ if (fs38.existsSync(path43.join(dest, ".git"))) {
20076
20286
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
20077
20287
  return dest;
20078
20288
  }
20079
- fs37.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
20289
+ fs38.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
20080
20290
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
20081
20291
  const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
20082
20292
  try {
@@ -20094,9 +20304,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
20094
20304
  }
20095
20305
 
20096
20306
  // src/commands/host/agent-provisioning.ts
20097
- var fs38 = __toESM(require("fs"));
20098
- var os35 = __toESM(require("os"));
20099
- var path43 = __toESM(require("path"));
20307
+ var fs39 = __toESM(require("fs"));
20308
+ var os36 = __toESM(require("os"));
20309
+ var path44 = __toESM(require("path"));
20100
20310
  var PUBLIC_TO_INTERNAL_AGENT = {
20101
20311
  claude_code: "claude",
20102
20312
  claude: "claude",
@@ -20113,22 +20323,22 @@ function toInternalAgentId(publicAgentId) {
20113
20323
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
20114
20324
  }
20115
20325
  function ensureDir(dir) {
20116
- fs38.mkdirSync(dir, { recursive: true, mode: 448 });
20326
+ fs39.mkdirSync(dir, { recursive: true, mode: 448 });
20117
20327
  }
20118
20328
  function writeFile0600(filePath, contents) {
20119
- ensureDir(path43.dirname(filePath));
20120
- fs38.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
20329
+ ensureDir(path44.dirname(filePath));
20330
+ fs39.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
20121
20331
  restrictToOwner(filePath);
20122
20332
  }
20123
20333
  function rmIfExists(filePath) {
20124
20334
  try {
20125
- fs38.rmSync(filePath, { force: true });
20335
+ fs39.rmSync(filePath, { force: true });
20126
20336
  } catch {
20127
20337
  }
20128
20338
  }
20129
20339
  var claudeProvisioner = {
20130
20340
  write(auth, home) {
20131
- const credentialsJson = path43.join(home, ".claude", ".credentials.json");
20341
+ const credentialsJson = path44.join(home, ".claude", ".credentials.json");
20132
20342
  if (auth.kind === "api_key") {
20133
20343
  rmIfExists(credentialsJson);
20134
20344
  return { ANTHROPIC_API_KEY: auth.value };
@@ -20140,8 +20350,8 @@ var claudeProvisioner = {
20140
20350
  } else {
20141
20351
  rmIfExists(credentialsJson);
20142
20352
  }
20143
- const claudeJson = path43.join(home, ".claude.json");
20144
- if (!fs38.existsSync(claudeJson)) {
20353
+ const claudeJson = path44.join(home, ".claude.json");
20354
+ if (!fs39.existsSync(claudeJson)) {
20145
20355
  writeFile0600(
20146
20356
  claudeJson,
20147
20357
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -20152,7 +20362,7 @@ var claudeProvisioner = {
20152
20362
  };
20153
20363
  var codexProvisioner = {
20154
20364
  write(auth, home) {
20155
- const authJson = path43.join(home, ".codex", "auth.json");
20365
+ const authJson = path44.join(home, ".codex", "auth.json");
20156
20366
  if (auth.kind === "api_key") {
20157
20367
  rmIfExists(authJson);
20158
20368
  return { OPENAI_API_KEY: auth.value };
@@ -20163,8 +20373,8 @@ var codexProvisioner = {
20163
20373
  };
20164
20374
  var geminiProvisioner = {
20165
20375
  write(auth, home) {
20166
- const settingsJson = path43.join(home, ".gemini", "settings.json");
20167
- const oauthCreds = path43.join(home, ".gemini", "oauth_creds.json");
20376
+ const settingsJson = path44.join(home, ".gemini", "settings.json");
20377
+ const oauthCreds = path44.join(home, ".gemini", "oauth_creds.json");
20168
20378
  if (auth.kind === "api_key") {
20169
20379
  rmIfExists(oauthCreds);
20170
20380
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -20177,7 +20387,7 @@ var geminiProvisioner = {
20177
20387
  };
20178
20388
  var cursorProvisioner = {
20179
20389
  write(auth, home) {
20180
- const authJson = path43.join(home, ".config", "cursor", "auth.json");
20390
+ const authJson = path44.join(home, ".config", "cursor", "auth.json");
20181
20391
  if (auth.kind === "api_key") {
20182
20392
  rmIfExists(authJson);
20183
20393
  return { CURSOR_API_KEY: auth.value };
@@ -20219,22 +20429,22 @@ max_context_size = 262144
20219
20429
  var kimiProvisioner = {
20220
20430
  write(auth, home) {
20221
20431
  const credentialsFiles = [
20222
- path43.join(home, ".kimi", "credentials", "kimi-code.json"),
20223
- path43.join(home, ".kimi-code", "credentials", "kimi-code.json")
20432
+ path44.join(home, ".kimi", "credentials", "kimi-code.json"),
20433
+ path44.join(home, ".kimi-code", "credentials", "kimi-code.json")
20224
20434
  ];
20225
20435
  if (auth.kind === "api_key") {
20226
20436
  credentialsFiles.forEach(rmIfExists);
20227
20437
  return { KIMI_API_KEY: auth.value };
20228
20438
  }
20229
20439
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
20230
- writeFile0600(path43.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
20440
+ writeFile0600(path44.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
20231
20441
  return {};
20232
20442
  }
20233
20443
  };
20234
20444
  var coderabbitProvisioner = {
20235
20445
  write(auth, home) {
20236
- const dir = path43.join(home, ".coderabbit");
20237
- const authJson = path43.join(dir, "auth.json");
20446
+ const dir = path44.join(home, ".coderabbit");
20447
+ const authJson = path44.join(dir, "auth.json");
20238
20448
  if (auth.kind === "api_key") {
20239
20449
  rmIfExists(authJson);
20240
20450
  return { CODERABBIT_API_KEY: auth.value };
@@ -20246,13 +20456,13 @@ var coderabbitProvisioner = {
20246
20456
  try {
20247
20457
  const parsed = JSON.parse(value);
20248
20458
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
20249
- file = path43.basename(parsed.file);
20459
+ file = path44.basename(parsed.file);
20250
20460
  contents = parsed.contents;
20251
20461
  }
20252
20462
  } catch {
20253
20463
  }
20254
20464
  }
20255
- writeFile0600(path43.join(dir, file), contents);
20465
+ writeFile0600(path44.join(dir, file), contents);
20256
20466
  return {};
20257
20467
  }
20258
20468
  };
@@ -20280,7 +20490,7 @@ var UnsupportedAgentError = class extends Error {
20280
20490
  this.agentId = agentId;
20281
20491
  }
20282
20492
  };
20283
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os35.homedir()) {
20493
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os36.homedir()) {
20284
20494
  const internal = toInternalAgentId(publicAgentId);
20285
20495
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
20286
20496
  const provisioner = PROVISIONERS[internal];
@@ -20290,11 +20500,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os35.homedir(
20290
20500
 
20291
20501
  // src/commands/host/git-tooling.ts
20292
20502
  var import_node_child_process21 = require("child_process");
20293
- var fs39 = __toESM(require("fs"));
20294
- var os36 = __toESM(require("os"));
20295
- var path44 = __toESM(require("path"));
20503
+ var fs40 = __toESM(require("fs"));
20504
+ var os37 = __toESM(require("os"));
20505
+ var path45 = __toESM(require("path"));
20296
20506
  function codeamBinDir() {
20297
- return process.env.CODEAM_BIN_DIR ?? path44.join(os36.homedir(), ".codeam", "bin");
20507
+ return process.env.CODEAM_BIN_DIR ?? path45.join(os37.homedir(), ".codeam", "bin");
20298
20508
  }
20299
20509
  var FALLBACK_GH_VERSION = "2.62.0";
20300
20510
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -20326,7 +20536,7 @@ async function download(url2, dest) {
20326
20536
  const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
20327
20537
  if (!res.ok || !res.body) return false;
20328
20538
  const buf = Buffer.from(await res.arrayBuffer());
20329
- fs39.writeFileSync(dest, buf);
20539
+ fs40.writeFileSync(dest, buf);
20330
20540
  return true;
20331
20541
  } catch {
20332
20542
  return false;
@@ -20349,8 +20559,8 @@ async function ensureGhCli(runner, token, deps = {}) {
20349
20559
  const version3 = await resolveVersionFn(token);
20350
20560
  const asset = `gh_${version3}_${osToken}_${arch2}`;
20351
20561
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
20352
- const tmpRoot = fs39.mkdtempSync(path44.join(os36.tmpdir(), "codeam-gh-"));
20353
- const archive = path44.join(tmpRoot, `${asset}.${ext}`);
20562
+ const tmpRoot = fs40.mkdtempSync(path45.join(os37.tmpdir(), "codeam-gh-"));
20563
+ const archive = path45.join(tmpRoot, `${asset}.${ext}`);
20354
20564
  if (!await downloadFn(url2, archive)) {
20355
20565
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
20356
20566
  return null;
@@ -20360,16 +20570,16 @@ async function ensureGhCli(runner, token, deps = {}) {
20360
20570
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
20361
20571
  return null;
20362
20572
  }
20363
- const extractedBin = path44.join(tmpRoot, asset, "bin", binaryName);
20364
- if (!fs39.existsSync(extractedBin)) {
20573
+ const extractedBin = path45.join(tmpRoot, asset, "bin", binaryName);
20574
+ if (!fs40.existsSync(extractedBin)) {
20365
20575
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
20366
20576
  return null;
20367
20577
  }
20368
20578
  const binDir = codeamBinDir();
20369
- fs39.mkdirSync(binDir, { recursive: true });
20370
- const target = path44.join(binDir, binaryName);
20371
- fs39.copyFileSync(extractedBin, target);
20372
- fs39.chmodSync(target, 493);
20579
+ fs40.mkdirSync(binDir, { recursive: true });
20580
+ const target = path45.join(binDir, binaryName);
20581
+ fs40.copyFileSync(extractedBin, target);
20582
+ fs40.chmodSync(target, 493);
20373
20583
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
20374
20584
  return target;
20375
20585
  } catch (e) {
@@ -20429,8 +20639,8 @@ async function ensureGlabCli(runner, deps = {}) {
20429
20639
  const version3 = await resolveLatestGlabVersion();
20430
20640
  const asset = `glab_${version3}_${osToken}_${arch2}`;
20431
20641
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
20432
- const tmpRoot = fs39.mkdtempSync(path44.join(os36.tmpdir(), "codeam-glab-"));
20433
- const archive = path44.join(tmpRoot, `${asset}.${ext}`);
20642
+ const tmpRoot = fs40.mkdtempSync(path45.join(os37.tmpdir(), "codeam-glab-"));
20643
+ const archive = path45.join(tmpRoot, `${asset}.${ext}`);
20434
20644
  if (!await downloadFn(url2, archive)) {
20435
20645
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
20436
20646
  return null;
@@ -20441,20 +20651,20 @@ async function ensureGlabCli(runner, deps = {}) {
20441
20651
  return null;
20442
20652
  }
20443
20653
  const candidates = [
20444
- path44.join(tmpRoot, "bin", binaryName),
20445
- path44.join(tmpRoot, asset, "bin", binaryName),
20446
- path44.join(tmpRoot, binaryName)
20654
+ path45.join(tmpRoot, "bin", binaryName),
20655
+ path45.join(tmpRoot, asset, "bin", binaryName),
20656
+ path45.join(tmpRoot, binaryName)
20447
20657
  ];
20448
- const extractedBin = candidates.find((c2) => fs39.existsSync(c2));
20658
+ const extractedBin = candidates.find((c2) => fs40.existsSync(c2));
20449
20659
  if (!extractedBin) {
20450
20660
  log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
20451
20661
  return null;
20452
20662
  }
20453
20663
  const binDir = codeamBinDir();
20454
- fs39.mkdirSync(binDir, { recursive: true });
20455
- const target = path44.join(binDir, binaryName);
20456
- fs39.copyFileSync(extractedBin, target);
20457
- fs39.chmodSync(target, 493);
20664
+ fs40.mkdirSync(binDir, { recursive: true });
20665
+ const target = path45.join(binDir, binaryName);
20666
+ fs40.copyFileSync(extractedBin, target);
20667
+ fs40.chmodSync(target, 493);
20458
20668
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
20459
20669
  return target;
20460
20670
  } catch (e) {
@@ -20651,24 +20861,24 @@ var HeadroomStatsReporter = class {
20651
20861
  };
20652
20862
 
20653
20863
  // src/commands/host/headroom-bootstrap.ts
20654
- var fs41 = __toESM(require("fs"));
20655
- var path46 = __toESM(require("path"));
20656
- var os38 = __toESM(require("os"));
20864
+ var fs42 = __toESM(require("fs"));
20865
+ var path47 = __toESM(require("path"));
20866
+ var os39 = __toESM(require("os"));
20657
20867
 
20658
20868
  // src/commands/host/headroom-config.ts
20659
- var fs40 = __toESM(require("fs"));
20660
- var os37 = __toESM(require("os"));
20661
- var path45 = __toESM(require("path"));
20869
+ var fs41 = __toESM(require("fs"));
20870
+ var os38 = __toESM(require("os"));
20871
+ var path46 = __toESM(require("path"));
20662
20872
  function headroomConfigPath() {
20663
- return path45.join(os37.homedir(), ".codeam", "headroom-config.json");
20873
+ return path46.join(os38.homedir(), ".codeam", "headroom-config.json");
20664
20874
  }
20665
20875
  function persistHeadroomConfig(config) {
20666
20876
  try {
20667
20877
  const file = headroomConfigPath();
20668
- fs40.mkdirSync(path45.dirname(file), { recursive: true, mode: 448 });
20878
+ fs41.mkdirSync(path46.dirname(file), { recursive: true, mode: 448 });
20669
20879
  const tmp = `${file}.tmp-${process.pid}`;
20670
- fs40.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20671
- fs40.renameSync(tmp, file);
20880
+ fs41.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20881
+ fs41.renameSync(tmp, file);
20672
20882
  restrictToOwner(file);
20673
20883
  } catch (err) {
20674
20884
  log.warn(
@@ -20678,21 +20888,21 @@ function persistHeadroomConfig(config) {
20678
20888
  }
20679
20889
  }
20680
20890
  function agentSettingsPath(kind) {
20681
- const home = os37.homedir();
20682
- if (kind === "claude") return path45.join(home, ".claude", "settings.json");
20683
- if (kind === "codex") return path45.join(home, ".codex", "auth.json");
20684
- if (kind === "copilot") return path45.join(home, ".config", "github-copilot", "hosts.json");
20891
+ const home = os38.homedir();
20892
+ if (kind === "claude") return path46.join(home, ".claude", "settings.json");
20893
+ if (kind === "codex") return path46.join(home, ".codex", "auth.json");
20894
+ if (kind === "copilot") return path46.join(home, ".config", "github-copilot", "hosts.json");
20685
20895
  return null;
20686
20896
  }
20687
20897
  function backupAgentHeadroomConfig(kind) {
20688
20898
  const src = agentSettingsPath(kind);
20689
20899
  if (!src) return;
20690
20900
  try {
20691
- if (!fs40.existsSync(src)) return;
20692
- const dest = path45.join(os37.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20693
- fs40.mkdirSync(path45.dirname(dest), { recursive: true, mode: 448 });
20694
- fs40.copyFileSync(src, dest);
20695
- fs40.chmodSync(dest, 384);
20901
+ if (!fs41.existsSync(src)) return;
20902
+ const dest = path46.join(os38.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20903
+ fs41.mkdirSync(path46.dirname(dest), { recursive: true, mode: 448 });
20904
+ fs41.copyFileSync(src, dest);
20905
+ fs41.chmodSync(dest, 384);
20696
20906
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
20697
20907
  } catch (err) {
20698
20908
  log.warn(
@@ -20704,12 +20914,12 @@ function backupAgentHeadroomConfig(kind) {
20704
20914
  function restoreAgentHeadroomConfig(kind) {
20705
20915
  const dest = agentSettingsPath(kind);
20706
20916
  if (!dest) return false;
20707
- const src = path45.join(os37.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20708
- if (!fs40.existsSync(src)) return false;
20917
+ const src = path46.join(os38.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20918
+ if (!fs41.existsSync(src)) return false;
20709
20919
  try {
20710
- fs40.mkdirSync(path45.dirname(dest), { recursive: true, mode: 448 });
20711
- fs40.copyFileSync(src, dest);
20712
- fs40.chmodSync(dest, 384);
20920
+ fs41.mkdirSync(path46.dirname(dest), { recursive: true, mode: 448 });
20921
+ fs41.copyFileSync(src, dest);
20922
+ fs41.chmodSync(dest, 384);
20713
20923
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
20714
20924
  return true;
20715
20925
  } catch (err) {
@@ -20722,7 +20932,7 @@ function restoreAgentHeadroomConfig(kind) {
20722
20932
  }
20723
20933
  function readHeadroomChildEnv() {
20724
20934
  try {
20725
- const raw = fs40.readFileSync(headroomConfigPath(), "utf8");
20935
+ const raw = fs41.readFileSync(headroomConfigPath(), "utf8");
20726
20936
  const parsed = JSON.parse(raw);
20727
20937
  if (typeof parsed !== "object" || parsed === null) return {};
20728
20938
  const o = parsed;
@@ -20758,49 +20968,49 @@ function bundledClaudeBinDir() {
20758
20968
  const roots = /* @__PURE__ */ new Set();
20759
20969
  let dir = __dirname;
20760
20970
  for (let i = 0; i < 6; i++) {
20761
- roots.add(path46.join(dir, "node_modules"));
20762
- const parent = path46.dirname(dir);
20971
+ roots.add(path47.join(dir, "node_modules"));
20972
+ const parent = path47.dirname(dir);
20763
20973
  if (parent === dir) break;
20764
20974
  dir = parent;
20765
20975
  }
20766
20976
  try {
20767
20977
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
20768
- const marker = `${path46.sep}@anthropic-ai${path46.sep}`;
20978
+ const marker = `${path47.sep}@anthropic-ai${path47.sep}`;
20769
20979
  const idx = main2.lastIndexOf(marker);
20770
20980
  if (idx !== -1) roots.add(main2.slice(0, idx));
20771
20981
  } catch {
20772
20982
  }
20773
20983
  for (const nm of roots) {
20774
- const atAnthropic = path46.join(nm, "@anthropic-ai");
20984
+ const atAnthropic = path47.join(nm, "@anthropic-ai");
20775
20985
  let entries;
20776
20986
  try {
20777
- entries = fs41.readdirSync(atAnthropic);
20987
+ entries = fs42.readdirSync(atAnthropic);
20778
20988
  } catch {
20779
20989
  continue;
20780
20990
  }
20781
20991
  for (const entry of entries) {
20782
20992
  if (!entry.startsWith("claude-agent-sdk-")) continue;
20783
- const bin = path46.join(atAnthropic, entry, "claude");
20784
- if (fs41.existsSync(bin)) return path46.dirname(bin);
20993
+ const bin = path47.join(atAnthropic, entry, "claude");
20994
+ if (fs42.existsSync(bin)) return path47.dirname(bin);
20785
20995
  }
20786
20996
  }
20787
20997
  return null;
20788
20998
  }
20789
20999
  async function getFreeDiskBytes(dir) {
20790
21000
  try {
20791
- const s = await fs41.promises.statfs(dir);
21001
+ const s = await fs42.promises.statfs(dir);
20792
21002
  return s.bsize * s.bavail;
20793
21003
  } catch {
20794
21004
  return null;
20795
21005
  }
20796
21006
  }
20797
21007
  function headroomModelsCached() {
20798
- const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path46.join(
20799
- process.env.HF_HOME || path46.join(os38.homedir(), ".cache", "huggingface"),
21008
+ const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path47.join(
21009
+ process.env.HF_HOME || path47.join(os39.homedir(), ".cache", "huggingface"),
20800
21010
  "hub"
20801
21011
  );
20802
21012
  return HEADROOM_MODELS.every(
20803
- (m) => fs41.existsSync(path46.join(hubDir, `models--${m.repo.replace("/", "--")}`))
21013
+ (m) => fs42.existsSync(path47.join(hubDir, `models--${m.repo.replace("/", "--")}`))
20804
21014
  );
20805
21015
  }
20806
21016
  async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner, opts = {}) {
@@ -20869,7 +21079,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
20869
21079
  if (initKind === "claude") {
20870
21080
  const claudeDir = bundledClaudeBinDir();
20871
21081
  if (claudeDir) {
20872
- initEnv.PATH = `${claudeDir}${path46.delimiter}${process.env["PATH"] ?? ""}`;
21082
+ initEnv.PATH = `${claudeDir}${path47.delimiter}${process.env["PATH"] ?? ""}`;
20873
21083
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
20874
21084
  } else {
20875
21085
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -20906,19 +21116,19 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
20906
21116
  }
20907
21117
 
20908
21118
  // src/commands/host/house-proxy-config.ts
20909
- var fs42 = __toESM(require("fs"));
20910
- var os39 = __toESM(require("os"));
20911
- var path47 = __toESM(require("path"));
21119
+ var fs43 = __toESM(require("fs"));
21120
+ var os40 = __toESM(require("os"));
21121
+ var path48 = __toESM(require("path"));
20912
21122
  function houseProxyConfigPath() {
20913
- return path47.join(os39.homedir(), ".codeam", "house-proxy.json");
21123
+ return path48.join(os40.homedir(), ".codeam", "house-proxy.json");
20914
21124
  }
20915
21125
  function persistHouseProxyConfig(config) {
20916
21126
  try {
20917
21127
  const file = houseProxyConfigPath();
20918
- fs42.mkdirSync(path47.dirname(file), { recursive: true, mode: 448 });
21128
+ fs43.mkdirSync(path48.dirname(file), { recursive: true, mode: 448 });
20919
21129
  const tmp = `${file}.tmp-${process.pid}`;
20920
- fs42.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20921
- fs42.renameSync(tmp, file);
21130
+ fs43.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
21131
+ fs43.renameSync(tmp, file);
20922
21132
  restrictToOwner(file);
20923
21133
  } catch (err) {
20924
21134
  log.warn(
@@ -20929,13 +21139,13 @@ function persistHouseProxyConfig(config) {
20929
21139
  }
20930
21140
  function clearHouseProxyConfig() {
20931
21141
  try {
20932
- fs42.rmSync(houseProxyConfigPath(), { force: true });
21142
+ fs43.rmSync(houseProxyConfigPath(), { force: true });
20933
21143
  } catch {
20934
21144
  }
20935
21145
  }
20936
21146
  function readHouseProxyChildEnv() {
20937
21147
  try {
20938
- const raw = fs42.readFileSync(houseProxyConfigPath(), "utf8");
21148
+ const raw = fs43.readFileSync(houseProxyConfigPath(), "utf8");
20939
21149
  const parsed = JSON.parse(raw);
20940
21150
  if (typeof parsed !== "object" || parsed === null) return {};
20941
21151
  const o = parsed;
@@ -20968,9 +21178,9 @@ function readHouseProxyChildEnv() {
20968
21178
  var import_node_child_process23 = require("child_process");
20969
21179
 
20970
21180
  // src/lib/updateNotifier.ts
20971
- var fs43 = __toESM(require("fs"));
20972
- var os40 = __toESM(require("os"));
20973
- var path48 = __toESM(require("path"));
21181
+ var fs44 = __toESM(require("fs"));
21182
+ var os41 = __toESM(require("os"));
21183
+ var path49 = __toESM(require("path"));
20974
21184
  var https6 = __toESM(require("https"));
20975
21185
  var import_node_child_process22 = require("child_process");
20976
21186
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -20979,12 +21189,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
20979
21189
  var TTL_MS = 24 * 60 * 60 * 1e3;
20980
21190
  var REQUEST_TIMEOUT_MS = 1500;
20981
21191
  function cachePath() {
20982
- const dir = path48.join(os40.homedir(), ".codeam");
20983
- return path48.join(dir, "update-check.json");
21192
+ const dir = path49.join(os41.homedir(), ".codeam");
21193
+ return path49.join(dir, "update-check.json");
20984
21194
  }
20985
21195
  function readCache() {
20986
21196
  try {
20987
- const raw = fs43.readFileSync(cachePath(), "utf8");
21197
+ const raw = fs44.readFileSync(cachePath(), "utf8");
20988
21198
  const parsed = JSON.parse(raw);
20989
21199
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
20990
21200
  return parsed;
@@ -20995,10 +21205,10 @@ function readCache() {
20995
21205
  function writeCache(cache) {
20996
21206
  try {
20997
21207
  const file = cachePath();
20998
- fs43.mkdirSync(path48.dirname(file), { recursive: true });
21208
+ fs44.mkdirSync(path49.dirname(file), { recursive: true });
20999
21209
  const tmp = `${file}.${process.pid}.tmp`;
21000
- fs43.writeFileSync(tmp, JSON.stringify(cache));
21001
- fs43.renameSync(tmp, file);
21210
+ fs44.writeFileSync(tmp, JSON.stringify(cache));
21211
+ fs44.renameSync(tmp, file);
21002
21212
  } catch {
21003
21213
  }
21004
21214
  }
@@ -21072,8 +21282,8 @@ function isLinkedInstall() {
21072
21282
  timeout: 2e3
21073
21283
  }).trim();
21074
21284
  if (!root) return false;
21075
- const pkgPath = path48.join(root, PKG_NAME);
21076
- return fs43.lstatSync(pkgPath).isSymbolicLink();
21285
+ const pkgPath = path49.join(root, PKG_NAME);
21286
+ return fs44.lstatSync(pkgPath).isSymbolicLink();
21077
21287
  } catch {
21078
21288
  return false;
21079
21289
  }
@@ -21109,7 +21319,7 @@ function maybeAutoUpdate(currentVersion, latest) {
21109
21319
  return;
21110
21320
  }
21111
21321
  try {
21112
- fs43.unlinkSync(cachePath());
21322
+ fs44.unlinkSync(cachePath());
21113
21323
  } catch {
21114
21324
  }
21115
21325
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
@@ -21125,7 +21335,7 @@ async function autoUpgradeBeforeCriticalCommand() {
21125
21335
  if (process.env.NODE_ENV === "test") return;
21126
21336
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
21127
21337
  if (process.env.CI) return;
21128
- const current2 = true ? "2.65.0" : null;
21338
+ const current2 = true ? "2.65.1" : null;
21129
21339
  if (!current2) return;
21130
21340
  const cache = readCache();
21131
21341
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -21142,7 +21352,7 @@ function checkForUpdates() {
21142
21352
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
21143
21353
  if (process.env.CI) return;
21144
21354
  if (!process.stdout.isTTY) return;
21145
- const current2 = true ? "2.65.0" : null;
21355
+ const current2 = true ? "2.65.1" : null;
21146
21356
  if (!current2) return;
21147
21357
  const cache = readCache();
21148
21358
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -21162,7 +21372,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
21162
21372
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
21163
21373
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
21164
21374
  function currentCliVersion() {
21165
- return true ? "2.65.0" : null;
21375
+ return true ? "2.65.1" : null;
21166
21376
  }
21167
21377
  function runCmd(cmd, args2, timeoutMs) {
21168
21378
  return new Promise((resolve9) => {
@@ -21229,7 +21439,7 @@ async function runSelfUpdate() {
21229
21439
 
21230
21440
  // src/commands/host/teardown.ts
21231
21441
  var import_node_child_process24 = require("child_process");
21232
- var fs44 = __toESM(require("fs"));
21442
+ var fs45 = __toESM(require("fs"));
21233
21443
  var defaultDisableService = () => {
21234
21444
  try {
21235
21445
  (0, import_node_child_process24.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
@@ -21238,7 +21448,7 @@ var defaultDisableService = () => {
21238
21448
  };
21239
21449
  var defaultTeardownHeadroom = () => {
21240
21450
  try {
21241
- const kind = JSON.parse(fs44.readFileSync(headroomConfigPath(), "utf8")).agent;
21451
+ const kind = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8")).agent;
21242
21452
  if (kind) {
21243
21453
  (0, import_node_child_process24.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
21244
21454
  }
@@ -21306,8 +21516,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
21306
21516
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
21307
21517
  try {
21308
21518
  const file = headroomConfigPath();
21309
- if (!fs45.existsSync(file)) return null;
21310
- const cfg = JSON.parse(fs45.readFileSync(file, "utf8"));
21519
+ if (!fs46.existsSync(file)) return null;
21520
+ const cfg = JSON.parse(fs46.readFileSync(file, "utf8"));
21311
21521
  if (!cfg?.enabled) return null;
21312
21522
  const agent = cfg.agent ?? "claude";
21313
21523
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -21894,13 +22104,13 @@ var HostAgentSupervisor = class {
21894
22104
  const relay = this.relay;
21895
22105
  if (!relay) return;
21896
22106
  const raw = cmd.payload?.path;
21897
- const target = typeof raw === "string" && raw.trim() ? path49.resolve(raw.trim()) : os41.homedir();
22107
+ const target = typeof raw === "string" && raw.trim() ? path50.resolve(raw.trim()) : os42.homedir();
21898
22108
  try {
21899
- const dirents = await fs45.promises.readdir(target, { withFileTypes: true });
22109
+ const dirents = await fs46.promises.readdir(target, { withFileTypes: true });
21900
22110
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
21901
22111
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
21902
22112
  );
21903
- const parent = path49.dirname(target);
22113
+ const parent = path50.dirname(target);
21904
22114
  await relay.sendResult(cmd.id, "completed", {
21905
22115
  path: target,
21906
22116
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -22133,14 +22343,14 @@ var HostAgentSupervisor = class {
22133
22343
  API_TIMEOUT_MS: "3000000",
22134
22344
  CODEAM_AUTO_TOKEN: payload.autoPairToken
22135
22345
  };
22136
- const houseConfigDir = path49.join(
22137
- os41.homedir(),
22346
+ const houseConfigDir = path50.join(
22347
+ os42.homedir(),
22138
22348
  ".codeam",
22139
22349
  "house-claude",
22140
22350
  payload.deployId
22141
22351
  );
22142
22352
  try {
22143
- fs45.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
22353
+ fs46.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
22144
22354
  } catch {
22145
22355
  }
22146
22356
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -22166,7 +22376,7 @@ var HostAgentSupervisor = class {
22166
22376
  report("installing", "installing agent CLI");
22167
22377
  await this.runAgentInstall(payload.agentInstallScript);
22168
22378
  }
22169
- const home = process.env.HOME || os41.homedir();
22379
+ const home = process.env.HOME || os42.homedir();
22170
22380
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
22171
22381
  if (payload.cloneToken) {
22172
22382
  try {
@@ -22174,13 +22384,13 @@ var HostAgentSupervisor = class {
22174
22384
  if ((payload.repoProvider ?? "github") === "gitlab") {
22175
22385
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
22176
22386
  if (glabCmd) {
22177
- childEnv.PATH = `${codeamBinDir()}${path49.delimiter}${childEnv.PATH}`;
22387
+ childEnv.PATH = `${codeamBinDir()}${path50.delimiter}${childEnv.PATH}`;
22178
22388
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
22179
22389
  }
22180
22390
  } else {
22181
22391
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
22182
22392
  if (ghCmd) {
22183
- childEnv.PATH = `${codeamBinDir()}${path49.delimiter}${childEnv.PATH}`;
22393
+ childEnv.PATH = `${codeamBinDir()}${path50.delimiter}${childEnv.PATH}`;
22184
22394
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
22185
22395
  }
22186
22396
  }
@@ -22200,7 +22410,7 @@ var HostAgentSupervisor = class {
22200
22410
  }
22201
22411
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
22202
22412
  report("headroom", "setting up Headroom proxy");
22203
- const freeBytes = await this.getFreeDisk(os41.homedir());
22413
+ const freeBytes = await this.getFreeDisk(os42.homedir());
22204
22414
  const alreadyInstalled = this.isHeadroomInstalled();
22205
22415
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
22206
22416
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -22259,9 +22469,9 @@ var HostAgentSupervisor = class {
22259
22469
  );
22260
22470
  if (!payload.suppressOnboardingWelcome) {
22261
22471
  try {
22262
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path49.join(os41.homedir(), ".claude");
22263
- const projectDir = path49.join(cfgDir, "projects", encodeCwd(cwd));
22264
- const hasPriorConversation = fs45.existsSync(projectDir) && fs45.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
22472
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path50.join(os42.homedir(), ".claude");
22473
+ const projectDir = path50.join(cfgDir, "projects", encodeCwd(cwd));
22474
+ const hasPriorConversation = fs46.existsSync(projectDir) && fs46.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
22265
22475
  if (hasPriorConversation) {
22266
22476
  childEnv.CODEAM_RESUME_LATEST = "1";
22267
22477
  log.info(
@@ -22360,7 +22570,7 @@ var HostAgentSupervisor = class {
22360
22570
  if (this.children.size > 0) return;
22361
22571
  const session = getActiveSession();
22362
22572
  if (!session || !session.pluginId || !session.pollSecret || !session.agent) return;
22363
- const cwd = session.cwd && fs45.existsSync(session.cwd) ? session.cwd : process.cwd();
22573
+ const cwd = session.cwd && fs46.existsSync(session.cwd) ? session.cwd : process.cwd();
22364
22574
  const proc = this.resumeSpawner(
22365
22575
  { ...readHeadroomChildEnv(), ...readHouseProxyChildEnv() },
22366
22576
  cwd
@@ -22457,12 +22667,12 @@ var HostAgentSupervisor = class {
22457
22667
  this.children.delete(deployId);
22458
22668
  }
22459
22669
  const dirs = [
22460
- path49.join(selfHostedWorkspaceRoot(), deployId),
22461
- path49.join(os41.homedir(), ".codeam", "house-claude", deployId)
22670
+ path50.join(selfHostedWorkspaceRoot(), deployId),
22671
+ path50.join(os42.homedir(), ".codeam", "house-claude", deployId)
22462
22672
  ];
22463
22673
  for (const dir of dirs) {
22464
22674
  try {
22465
- fs45.rmSync(dir, { recursive: true, force: true });
22675
+ fs46.rmSync(dir, { recursive: true, force: true });
22466
22676
  } catch (err) {
22467
22677
  log.warn(
22468
22678
  "host-agent",
@@ -22599,10 +22809,10 @@ async function configureHeadroom(action, ctx, deps) {
22599
22809
  }
22600
22810
 
22601
22811
  // src/services/headroom/budget-relaunch.ts
22602
- var fs46 = __toESM(require("fs"));
22603
- var os42 = __toESM(require("os"));
22604
- var path50 = __toESM(require("path"));
22605
- var import_child_process14 = require("child_process");
22812
+ var fs47 = __toESM(require("fs"));
22813
+ var os43 = __toESM(require("os"));
22814
+ var path51 = __toESM(require("path"));
22815
+ var import_child_process15 = require("child_process");
22606
22816
  function amendDeploymentManifestBudget(manifest, budget) {
22607
22817
  const rawArgs = manifest.proxy_args ?? [];
22608
22818
  const strippedArgs = [];
@@ -22635,7 +22845,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
22635
22845
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
22636
22846
  }
22637
22847
  function findHeadroomDeployments(homeDir2, deps) {
22638
- const deployDir = path50.join(homeDir2, ".headroom", "deploy");
22848
+ const deployDir = path51.join(homeDir2, ".headroom", "deploy");
22639
22849
  let profiles;
22640
22850
  try {
22641
22851
  profiles = deps.readDir(deployDir);
@@ -22644,7 +22854,7 @@ function findHeadroomDeployments(homeDir2, deps) {
22644
22854
  }
22645
22855
  const results = [];
22646
22856
  for (const profile of profiles) {
22647
- const manifestPath = path50.join(deployDir, profile, "manifest.json");
22857
+ const manifestPath = path51.join(deployDir, profile, "manifest.json");
22648
22858
  let raw;
22649
22859
  try {
22650
22860
  raw = deps.readJson(manifestPath);
@@ -22676,12 +22886,12 @@ async function applyBudgetToHeadroom(budget, deps) {
22676
22886
  }
22677
22887
  function writeManifestReal(manifestPath, manifest) {
22678
22888
  const tmp = manifestPath + ".codeam.tmp";
22679
- fs46.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
22680
- fs46.renameSync(tmp, manifestPath);
22889
+ fs47.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
22890
+ fs47.renameSync(tmp, manifestPath);
22681
22891
  }
22682
22892
  function restartDeploymentReal(profile) {
22683
22893
  try {
22684
- const proc = (0, import_child_process14.spawn)("headroom", ["install", "restart", "--profile", profile], {
22894
+ const proc = (0, import_child_process15.spawn)("headroom", ["install", "restart", "--profile", profile], {
22685
22895
  detached: true,
22686
22896
  stdio: "ignore"
22687
22897
  });
@@ -22712,11 +22922,11 @@ function spawnProxyReal2(_budget) {
22712
22922
  );
22713
22923
  }
22714
22924
  function makeRealApplyBudgetDeps() {
22715
- const homeDir2 = os42.homedir();
22925
+ const homeDir2 = os43.homedir();
22716
22926
  return {
22717
22927
  findDeployments: () => findHeadroomDeployments(homeDir2, {
22718
- readDir: (dir) => fs46.readdirSync(dir),
22719
- readJson: (filePath) => JSON.parse(fs46.readFileSync(filePath, "utf8"))
22928
+ readDir: (dir) => fs47.readdirSync(dir),
22929
+ readJson: (filePath) => JSON.parse(fs47.readFileSync(filePath, "utf8"))
22720
22930
  }),
22721
22931
  writeManifest: writeManifestReal,
22722
22932
  restartDeployment: restartDeploymentReal,
@@ -22849,47 +23059,47 @@ async function readUsageReport(deps = {}) {
22849
23059
  }
22850
23060
 
22851
23061
  // src/agents/acp/guardrail-config.ts
22852
- var fs47 = __toESM(require("fs"));
22853
- var path51 = __toESM(require("path"));
22854
- var os43 = __toESM(require("os"));
23062
+ var fs48 = __toESM(require("fs"));
23063
+ var path52 = __toESM(require("path"));
23064
+ var os44 = __toESM(require("os"));
22855
23065
  var current = null;
22856
- function guardrailConfigPath(homeDir2 = os43.homedir()) {
22857
- return path51.join(homeDir2, ".codeam", "guardrails.json");
23066
+ function guardrailConfigPath(homeDir2 = os44.homedir()) {
23067
+ return path52.join(homeDir2, ".codeam", "guardrails.json");
22858
23068
  }
22859
- function loadGuardrailPolicy(homeDir2 = os43.homedir()) {
23069
+ function loadGuardrailPolicy(homeDir2 = os44.homedir()) {
22860
23070
  try {
22861
- current = normalizeGuardrailPolicy(JSON.parse(fs47.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
23071
+ current = normalizeGuardrailPolicy(JSON.parse(fs48.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
22862
23072
  } catch {
22863
23073
  current = { ...DEFAULT_GUARDRAIL_POLICY };
22864
23074
  }
22865
23075
  return current;
22866
23076
  }
22867
- function getGuardrailPolicy(homeDir2 = os43.homedir()) {
23077
+ function getGuardrailPolicy(homeDir2 = os44.homedir()) {
22868
23078
  return current ?? loadGuardrailPolicy(homeDir2);
22869
23079
  }
22870
- function setGuardrailPolicy(raw, homeDir2 = os43.homedir()) {
23080
+ function setGuardrailPolicy(raw, homeDir2 = os44.homedir()) {
22871
23081
  const next = normalizeGuardrailPolicy(raw);
22872
23082
  current = next;
22873
23083
  try {
22874
23084
  const p2 = guardrailConfigPath(homeDir2);
22875
- fs47.mkdirSync(path51.dirname(p2), { recursive: true });
22876
- fs47.writeFileSync(p2, JSON.stringify(next, null, 2));
23085
+ fs48.mkdirSync(path52.dirname(p2), { recursive: true });
23086
+ fs48.writeFileSync(p2, JSON.stringify(next, null, 2));
22877
23087
  } catch {
22878
23088
  }
22879
23089
  return next;
22880
23090
  }
22881
23091
 
22882
23092
  // src/services/preview/port-registry.ts
22883
- var fs48 = __toESM(require("fs"));
22884
- var os44 = __toESM(require("os"));
22885
- var path52 = __toESM(require("path"));
22886
- var import_child_process15 = require("child_process");
23093
+ var fs49 = __toESM(require("fs"));
23094
+ var os45 = __toESM(require("os"));
23095
+ var path53 = __toESM(require("path"));
23096
+ var import_child_process16 = require("child_process");
22887
23097
  function registryPath() {
22888
- return path52.join(os44.homedir(), ".codeam", "preview-ports.json");
23098
+ return path53.join(os45.homedir(), ".codeam", "preview-ports.json");
22889
23099
  }
22890
23100
  function readRegistry() {
22891
23101
  try {
22892
- const raw = fs48.readFileSync(registryPath(), "utf8");
23102
+ const raw = fs49.readFileSync(registryPath(), "utf8");
22893
23103
  const parsed = JSON.parse(raw);
22894
23104
  if (parsed && typeof parsed === "object") return parsed;
22895
23105
  } catch {
@@ -22899,10 +23109,10 @@ function readRegistry() {
22899
23109
  function writeRegistry(reg) {
22900
23110
  try {
22901
23111
  const file = registryPath();
22902
- fs48.mkdirSync(path52.dirname(file), { recursive: true });
23112
+ fs49.mkdirSync(path53.dirname(file), { recursive: true });
22903
23113
  const tmp = `${file}.tmp`;
22904
- fs48.writeFileSync(tmp, JSON.stringify(reg), "utf8");
22905
- fs48.renameSync(tmp, file);
23114
+ fs49.writeFileSync(tmp, JSON.stringify(reg), "utf8");
23115
+ fs49.renameSync(tmp, file);
22906
23116
  } catch (err) {
22907
23117
  log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
22908
23118
  }
@@ -22930,7 +23140,7 @@ function groupAlive(pgid) {
22930
23140
  }
22931
23141
  function killGroup(pgid) {
22932
23142
  if (process.platform === "win32") {
22933
- (0, import_child_process15.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pgid)], { stdio: "ignore" });
23143
+ (0, import_child_process16.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pgid)], { stdio: "ignore" });
22934
23144
  return;
22935
23145
  }
22936
23146
  try {
@@ -22967,8 +23177,8 @@ function reclaimOwnOrphanPort(port) {
22967
23177
  }
22968
23178
 
22969
23179
  // src/services/preview/host-allow.ts
22970
- var import_fs = require("fs");
22971
- var path53 = __toESM(require("path"));
23180
+ var import_fs2 = require("fs");
23181
+ var path54 = __toESM(require("path"));
22972
23182
  var NEXT_ALLOWED_ORIGINS = [
22973
23183
  "*.trycloudflare.com",
22974
23184
  "*.preview.codeagent-mobile.com",
@@ -22988,11 +23198,11 @@ var MARKER_DIR = ".codeam";
22988
23198
  var MARKER_FILE = "preview-host-allow.json";
22989
23199
  var ORIG_INFIX = ".codeam-orig";
22990
23200
  function markerPath(cwd) {
22991
- return path53.join(cwd, MARKER_DIR, MARKER_FILE);
23201
+ return path54.join(cwd, MARKER_DIR, MARKER_FILE);
22992
23202
  }
22993
23203
  async function fileExists(p2) {
22994
23204
  try {
22995
- await import_fs.promises.access(p2);
23205
+ await import_fs2.promises.access(p2);
22996
23206
  return true;
22997
23207
  } catch {
22998
23208
  return false;
@@ -23001,13 +23211,13 @@ async function fileExists(p2) {
23001
23211
  async function findConfigFile(cwd, framework) {
23002
23212
  const base = CONFIG_BASENAMES[framework];
23003
23213
  for (const ext of CONFIG_EXTS) {
23004
- if (await fileExists(path53.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
23214
+ if (await fileExists(path54.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
23005
23215
  }
23006
23216
  return null;
23007
23217
  }
23008
23218
  async function dependsOn(cwd, pkgName) {
23009
23219
  try {
23010
- const raw = await import_fs.promises.readFile(path53.join(cwd, "package.json"), "utf8");
23220
+ const raw = await import_fs2.promises.readFile(path54.join(cwd, "package.json"), "utf8");
23011
23221
  const pkg = JSON.parse(raw);
23012
23222
  return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
23013
23223
  } catch {
@@ -23015,11 +23225,11 @@ async function dependsOn(cwd, pkgName) {
23015
23225
  }
23016
23226
  }
23017
23227
  async function isEsmConfig(cwd, configFile) {
23018
- const ext = path53.extname(configFile);
23228
+ const ext = path54.extname(configFile);
23019
23229
  if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
23020
23230
  if (ext === ".cjs") return false;
23021
23231
  try {
23022
- const raw = await import_fs.promises.readFile(path53.join(cwd, "package.json"), "utf8");
23232
+ const raw = await import_fs2.promises.readFile(path54.join(cwd, "package.json"), "utf8");
23023
23233
  return JSON.parse(raw).type === "module";
23024
23234
  } catch {
23025
23235
  return false;
@@ -23102,12 +23312,12 @@ function shimFor(framework, origBasename, esm) {
23102
23312
  return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
23103
23313
  }
23104
23314
  async function writeMarker(cwd, marker) {
23105
- await import_fs.promises.mkdir(path53.join(cwd, MARKER_DIR), { recursive: true });
23106
- await import_fs.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
23315
+ await import_fs2.promises.mkdir(path54.join(cwd, MARKER_DIR), { recursive: true });
23316
+ await import_fs2.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
23107
23317
  }
23108
23318
  async function readMarker(cwd) {
23109
23319
  try {
23110
- const parsed = JSON.parse(await import_fs.promises.readFile(markerPath(cwd), "utf8"));
23320
+ const parsed = JSON.parse(await import_fs2.promises.readFile(markerPath(cwd), "utf8"));
23111
23321
  return parsed && parsed.configFile ? parsed : null;
23112
23322
  } catch {
23113
23323
  return null;
@@ -23117,20 +23327,20 @@ async function restorePreviewHostAllow(cwd) {
23117
23327
  const marker = await readMarker(cwd);
23118
23328
  if (!marker) return;
23119
23329
  try {
23120
- const configAbs = path53.join(cwd, marker.configFile);
23330
+ const configAbs = path54.join(cwd, marker.configFile);
23121
23331
  if (marker.backupFile) {
23122
- const backupAbs = path53.join(cwd, marker.backupFile);
23332
+ const backupAbs = path54.join(cwd, marker.backupFile);
23123
23333
  if (await fileExists(backupAbs)) {
23124
- await import_fs.promises.rm(configAbs, { force: true });
23125
- await import_fs.promises.rename(backupAbs, configAbs);
23334
+ await import_fs2.promises.rm(configAbs, { force: true });
23335
+ await import_fs2.promises.rename(backupAbs, configAbs);
23126
23336
  }
23127
23337
  } else {
23128
- await import_fs.promises.rm(configAbs, { force: true });
23338
+ await import_fs2.promises.rm(configAbs, { force: true });
23129
23339
  }
23130
23340
  } catch (err) {
23131
23341
  log.warn("preview", `host-allow restore failed: ${err instanceof Error ? err.message : err}`);
23132
23342
  } finally {
23133
- await import_fs.promises.rm(markerPath(cwd), { force: true }).catch(() => void 0);
23343
+ await import_fs2.promises.rm(markerPath(cwd), { force: true }).catch(() => void 0);
23134
23344
  }
23135
23345
  }
23136
23346
  async function applyPreviewHostAllow(cwd) {
@@ -23152,16 +23362,16 @@ async function applyPreviewHostAllow(cwd) {
23152
23362
  }
23153
23363
  if (!framework) return;
23154
23364
  if (existing) {
23155
- const ext = path53.extname(existing);
23365
+ const ext = path54.extname(existing);
23156
23366
  const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
23157
23367
  const esm = await isEsmConfig(cwd, existing);
23158
- await import_fs.promises.rename(path53.join(cwd, existing), path53.join(cwd, origBasename));
23159
- await import_fs.promises.writeFile(path53.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
23368
+ await import_fs2.promises.rename(path54.join(cwd, existing), path54.join(cwd, origBasename));
23369
+ await import_fs2.promises.writeFile(path54.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
23160
23370
  await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
23161
23371
  log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
23162
23372
  } else {
23163
23373
  const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
23164
- await import_fs.promises.writeFile(path53.join(cwd, configFile), shimFor(framework, null, true), "utf8");
23374
+ await import_fs2.promises.writeFile(path54.join(cwd, configFile), shimFor(framework, null, true), "utf8");
23165
23375
  await writeMarker(cwd, { framework, configFile, backupFile: null });
23166
23376
  log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
23167
23377
  }
@@ -23171,14 +23381,14 @@ async function applyPreviewHostAllow(cwd) {
23171
23381
  }
23172
23382
 
23173
23383
  // src/services/preview/cloudflared.ts
23174
- var import_child_process16 = require("child_process");
23175
- var import_fs2 = require("fs");
23384
+ var import_child_process17 = require("child_process");
23385
+ var import_fs3 = require("fs");
23176
23386
  var import_promises = __toESM(require("fs/promises"));
23177
- var import_os9 = __toESM(require("os"));
23178
- var import_path4 = __toESM(require("path"));
23387
+ var import_os10 = __toESM(require("os"));
23388
+ var import_path5 = __toESM(require("path"));
23179
23389
  var import_promises2 = require("stream/promises");
23180
23390
  var import_which = __toESM(require("which"));
23181
- var CACHED_BINARY = import_path4.default.join(import_os9.default.homedir(), ".codeam", "bin", "cloudflared");
23391
+ var CACHED_BINARY = import_path5.default.join(import_os10.default.homedir(), ".codeam", "bin", "cloudflared");
23182
23392
  async function resolveCloudflared(opts = {}) {
23183
23393
  try {
23184
23394
  return await (0, import_which.default)("cloudflared");
@@ -23202,7 +23412,7 @@ async function resolveCloudflared(opts = {}) {
23202
23412
  }
23203
23413
  async function downloadCloudflared(target) {
23204
23414
  const url2 = downloadUrlForPlatform();
23205
- await import_promises.default.mkdir(import_path4.default.dirname(target), { recursive: true });
23415
+ await import_promises.default.mkdir(import_path5.default.dirname(target), { recursive: true });
23206
23416
  const response = await fetch(url2);
23207
23417
  if (!response.ok || !response.body) {
23208
23418
  throw new Error(
@@ -23213,10 +23423,10 @@ async function downloadCloudflared(target) {
23213
23423
  const tmp = `${target}.download.tgz`;
23214
23424
  await (0, import_promises2.pipeline)(
23215
23425
  response.body,
23216
- (0, import_fs2.createWriteStream)(tmp)
23426
+ (0, import_fs3.createWriteStream)(tmp)
23217
23427
  );
23218
23428
  try {
23219
- await extractTgz(tmp, import_path4.default.dirname(target));
23429
+ await extractTgz(tmp, import_path5.default.dirname(target));
23220
23430
  await import_promises.default.access(target);
23221
23431
  await import_promises.default.chmod(target, 493);
23222
23432
  } catch (err) {
@@ -23230,7 +23440,7 @@ async function downloadCloudflared(target) {
23230
23440
  }
23231
23441
  await (0, import_promises2.pipeline)(
23232
23442
  response.body,
23233
- (0, import_fs2.createWriteStream)(target, { mode: 493 })
23443
+ (0, import_fs3.createWriteStream)(target, { mode: 493 })
23234
23444
  );
23235
23445
  }
23236
23446
  async function isExecutableBinary(p2) {
@@ -23248,7 +23458,7 @@ async function isExecutableBinary(p2) {
23248
23458
  }
23249
23459
  function extractTgz(tgzPath, destDir) {
23250
23460
  return new Promise((resolve9, reject) => {
23251
- const child = (0, import_child_process16.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
23461
+ const child = (0, import_child_process17.spawn)("tar", ["-xzf", tgzPath, "-C", destDir], { stdio: "ignore" });
23252
23462
  child.on("error", (err) => reject(err));
23253
23463
  child.on(
23254
23464
  "exit",
@@ -23278,11 +23488,11 @@ function decodeTunnelToken(token) {
23278
23488
  }
23279
23489
  async function spawnNamedTunnel(bin, token, port) {
23280
23490
  const creds = decodeTunnelToken(token);
23281
- const credDir = import_path4.default.join(import_os9.default.homedir(), ".codeam");
23491
+ const credDir = import_path5.default.join(import_os10.default.homedir(), ".codeam");
23282
23492
  await import_promises.default.mkdir(credDir, { recursive: true });
23283
- const credFile = import_path4.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
23493
+ const credFile = import_path5.default.join(credDir, `tunnel-${creds.TunnelID}.json`);
23284
23494
  await import_promises.default.writeFile(credFile, JSON.stringify(creds), { mode: 384 });
23285
- return (0, import_child_process16.spawn)(
23495
+ return (0, import_child_process17.spawn)(
23286
23496
  bin,
23287
23497
  [
23288
23498
  "tunnel",
@@ -23298,17 +23508,17 @@ async function spawnNamedTunnel(bin, token, port) {
23298
23508
  }
23299
23509
 
23300
23510
  // src/services/preview/codespace.ts
23301
- var import_child_process17 = require("child_process");
23511
+ var import_child_process18 = require("child_process");
23302
23512
  var import_util3 = require("util");
23303
- var execFileP5 = (0, import_util3.promisify)(import_child_process17.execFile);
23513
+ var execFileP5 = (0, import_util3.promisify)(import_child_process18.execFile);
23304
23514
 
23305
23515
  // src/services/preview/config-file.ts
23306
23516
  var import_promises3 = __toESM(require("fs/promises"));
23307
- var import_path5 = __toESM(require("path"));
23517
+ var import_path6 = __toESM(require("path"));
23308
23518
  var CONFIG_DIR = ".codeam";
23309
23519
  var CONFIG_FILE = "preview.json";
23310
23520
  function configPath(cwd) {
23311
- return import_path5.default.join(cwd, CONFIG_DIR, CONFIG_FILE);
23521
+ return import_path6.default.join(cwd, CONFIG_DIR, CONFIG_FILE);
23312
23522
  }
23313
23523
  var REQUIRED_FIELDS = [
23314
23524
  "framework",
@@ -23339,7 +23549,7 @@ async function readPreviewConfig(cwd) {
23339
23549
  }
23340
23550
  async function writePreviewConfig(cwd, detection) {
23341
23551
  const filePath = configPath(cwd);
23342
- await import_promises3.default.mkdir(import_path5.default.dirname(filePath), { recursive: true });
23552
+ await import_promises3.default.mkdir(import_path6.default.dirname(filePath), { recursive: true });
23343
23553
  await import_promises3.default.writeFile(filePath, JSON.stringify(detection, null, 2) + "\n", "utf-8");
23344
23554
  }
23345
23555
 
@@ -23491,14 +23701,14 @@ async function waitForPortListening(port, opts) {
23491
23701
  }
23492
23702
 
23493
23703
  // src/services/preview/provision-deps.ts
23494
- var import_fs3 = require("fs");
23495
- var import_path6 = __toESM(require("path"));
23704
+ var import_fs4 = require("fs");
23705
+ var import_path7 = __toESM(require("path"));
23496
23706
 
23497
23707
  // src/services/preview/run-setup.ts
23498
- var import_child_process18 = require("child_process");
23708
+ var import_child_process19 = require("child_process");
23499
23709
  function runSetupCommand(cmd, args2, cwd, env, opts) {
23500
23710
  return new Promise((resolve9) => {
23501
- const child = (0, import_child_process18.spawn)(cmd, args2, {
23711
+ const child = (0, import_child_process19.spawn)(cmd, args2, {
23502
23712
  cwd,
23503
23713
  env: { ...process.env, ...env ?? {} },
23504
23714
  stdio: ["ignore", "pipe", "pipe"]
@@ -23639,37 +23849,37 @@ function pickMigrationScript(scripts) {
23639
23849
  }
23640
23850
  async function exists(p2) {
23641
23851
  try {
23642
- await import_fs3.promises.access(p2);
23852
+ await import_fs4.promises.access(p2);
23643
23853
  return true;
23644
23854
  } catch {
23645
23855
  return false;
23646
23856
  }
23647
23857
  }
23648
23858
  async function firstExisting(cwd, names) {
23649
- for (const n of names) if (await exists(import_path6.default.join(cwd, n))) return n;
23859
+ for (const n of names) if (await exists(import_path7.default.join(cwd, n))) return n;
23650
23860
  return null;
23651
23861
  }
23652
23862
  async function ensureEnvFile(cwd, generated) {
23653
- if (await exists(import_path6.default.join(cwd, ".env"))) {
23863
+ if (await exists(import_path7.default.join(cwd, ".env"))) {
23654
23864
  log.info("provision", ".env already present \u2014 leaving it untouched");
23655
23865
  return;
23656
23866
  }
23657
23867
  const sample = await firstExisting(cwd, ENV_SAMPLES);
23658
23868
  if (sample) {
23659
- const body = await import_fs3.promises.readFile(import_path6.default.join(cwd, sample), "utf8");
23660
- await import_fs3.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
23869
+ const body = await import_fs4.promises.readFile(import_path7.default.join(cwd, sample), "utf8");
23870
+ await import_fs4.promises.writeFile(import_path7.default.join(cwd, ".env"), body);
23661
23871
  log.info("provision", `wrote .env from ${sample}`);
23662
23872
  return;
23663
23873
  }
23664
23874
  if (generated.length > 0) {
23665
23875
  const body = "# Generated by codeam \u2014 points at the auto-provisioned local services.\n" + generated.flatMap((s) => s.envLines).join("\n") + "\n";
23666
- await import_fs3.promises.writeFile(import_path6.default.join(cwd, ".env"), body);
23876
+ await import_fs4.promises.writeFile(import_path7.default.join(cwd, ".env"), body);
23667
23877
  log.info("provision", `generated .env for ${generated.map((s) => s.name).join("+")}`);
23668
23878
  }
23669
23879
  }
23670
23880
  async function readPackageJson(cwd) {
23671
23881
  try {
23672
- return JSON.parse(await import_fs3.promises.readFile(import_path6.default.join(cwd, "package.json"), "utf8"));
23882
+ return JSON.parse(await import_fs4.promises.readFile(import_path7.default.join(cwd, "package.json"), "utf8"));
23673
23883
  } catch {
23674
23884
  return null;
23675
23885
  }
@@ -23709,10 +23919,10 @@ async function provisionProjectDependencies(cwd) {
23709
23919
  } else if (pkg) {
23710
23920
  generated = detectServicesFromDeps(pkg);
23711
23921
  if (generated.length > 0) {
23712
- const dir = import_path6.default.join(cwd, ".codeam", "provision");
23713
- await import_fs3.promises.mkdir(dir, { recursive: true });
23714
- const file = import_path6.default.join(dir, "compose.generated.yaml");
23715
- await import_fs3.promises.writeFile(file, renderComposeYaml(generated));
23922
+ const dir = import_path7.default.join(cwd, ".codeam", "provision");
23923
+ await import_fs4.promises.mkdir(dir, { recursive: true });
23924
+ const file = import_path7.default.join(dir, "compose.generated.yaml");
23925
+ await import_fs4.promises.writeFile(file, renderComposeYaml(generated));
23716
23926
  log.info(
23717
23927
  "provision",
23718
23928
  `no compose in repo \u2014 generated ${generated.map((s) => s.name).join("+")}`
@@ -23733,12 +23943,12 @@ async function provisionProjectDependencies(cwd) {
23733
23943
  }
23734
23944
 
23735
23945
  // src/services/preview/setup-deps.ts
23736
- var import_fs4 = __toESM(require("fs"));
23737
- var import_path7 = __toESM(require("path"));
23946
+ var import_fs5 = __toESM(require("fs"));
23947
+ var import_path8 = __toESM(require("path"));
23738
23948
  function detectMissingNodeDeps(cwd) {
23739
- if (!import_fs4.default.existsSync(import_path7.default.join(cwd, "package.json"))) return null;
23740
- if (import_fs4.default.existsSync(import_path7.default.join(cwd, "node_modules"))) return null;
23741
- if (import_fs4.default.existsSync(import_path7.default.join(cwd, "yarn.lock"))) {
23949
+ if (!import_fs5.default.existsSync(import_path8.default.join(cwd, "package.json"))) return null;
23950
+ if (import_fs5.default.existsSync(import_path8.default.join(cwd, "node_modules"))) return null;
23951
+ if (import_fs5.default.existsSync(import_path8.default.join(cwd, "yarn.lock"))) {
23742
23952
  return { cmd: "yarn", args: ["install"] };
23743
23953
  }
23744
23954
  return { cmd: "npm", args: ["install", "--legacy-peer-deps"] };
@@ -23842,20 +24052,20 @@ function activePreviewSessionIds() {
23842
24052
  }
23843
24053
 
23844
24054
  // src/services/preview/start-orchestrator.ts
23845
- var import_child_process20 = require("child_process");
23846
- var fs56 = __toESM(require("fs"));
23847
- var path60 = __toESM(require("path"));
24055
+ var import_child_process21 = require("child_process");
24056
+ var fs57 = __toESM(require("fs"));
24057
+ var path61 = __toESM(require("path"));
23848
24058
  var import_which2 = __toESM(require("which"));
23849
24059
 
23850
24060
  // src/services/project-env/index.ts
23851
- var import_fs5 = require("fs");
23852
- var path59 = __toESM(require("path"));
24061
+ var import_fs6 = require("fs");
24062
+ var path60 = __toESM(require("path"));
23853
24063
 
23854
24064
  // src/beads/project-key.ts
23855
- var import_child_process19 = require("child_process");
24065
+ var import_child_process20 = require("child_process");
23856
24066
  var crypto2 = __toESM(require("crypto"));
23857
- var fs54 = __toESM(require("fs"));
23858
- var path58 = __toESM(require("path"));
24067
+ var fs55 = __toESM(require("fs"));
24068
+ var path59 = __toESM(require("path"));
23859
24069
  function normalizeOrigin(raw) {
23860
24070
  const trimmed = raw.trim();
23861
24071
  if (!trimmed) return null;
@@ -23881,17 +24091,17 @@ function normalizeOrigin(raw) {
23881
24091
  return `${host2}/${pathPart}`;
23882
24092
  }
23883
24093
  function findRepoRoot(cwd) {
23884
- let dir = path58.resolve(cwd);
24094
+ let dir = path59.resolve(cwd);
23885
24095
  const seen = /* @__PURE__ */ new Set();
23886
24096
  for (let i = 0; i < 256; i++) {
23887
24097
  if (seen.has(dir)) return null;
23888
24098
  seen.add(dir);
23889
24099
  try {
23890
- const stat3 = fs54.statSync(path58.join(dir, ".git"), { throwIfNoEntry: false });
24100
+ const stat3 = fs55.statSync(path59.join(dir, ".git"), { throwIfNoEntry: false });
23891
24101
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
23892
24102
  } catch {
23893
24103
  }
23894
- const parent = path58.dirname(dir);
24104
+ const parent = path59.dirname(dir);
23895
24105
  if (parent === dir) return null;
23896
24106
  dir = parent;
23897
24107
  }
@@ -23899,10 +24109,10 @@ function findRepoRoot(cwd) {
23899
24109
  }
23900
24110
  var _execSeam2 = {
23901
24111
  exec: (file, args2, opts) => {
23902
- const out2 = (0, import_child_process19.execFileSync)(file, args2, opts);
24112
+ const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
23903
24113
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
23904
24114
  },
23905
- realpath: (p2) => fs54.realpathSync(p2)
24115
+ realpath: (p2) => fs55.realpathSync(p2)
23906
24116
  };
23907
24117
  function readOrigin(cwd) {
23908
24118
  try {
@@ -23931,20 +24141,20 @@ function deriveProjectIdentity(cwd = process.cwd()) {
23931
24141
  } catch {
23932
24142
  }
23933
24143
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
23934
- return { projectKey: `path:${hash}`, projectLabel: path58.basename(real) || "project" };
24144
+ return { projectKey: `path:${hash}`, projectLabel: path59.basename(real) || "project" };
23935
24145
  }
23936
24146
 
23937
24147
  // src/services/project-env/index.ts
23938
24148
  async function readIfExists(p2) {
23939
24149
  try {
23940
- return await import_fs5.promises.readFile(p2, "utf8");
24150
+ return await import_fs6.promises.readFile(p2, "utf8");
23941
24151
  } catch {
23942
24152
  return null;
23943
24153
  }
23944
24154
  }
23945
24155
  async function syncProjectEnvUp(cwd, ctx) {
23946
24156
  if (!ctx.pluginAuthToken) return;
23947
- const content = await readIfExists(path59.join(cwd, ".env"));
24157
+ const content = await readIfExists(path60.join(cwd, ".env"));
23948
24158
  if (content == null) return;
23949
24159
  try {
23950
24160
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23966,7 +24176,7 @@ async function syncProjectEnvUp(cwd, ctx) {
23966
24176
  }
23967
24177
  async function restoreProjectEnvIfMissing(cwd, ctx) {
23968
24178
  if (!ctx.pluginAuthToken) return false;
23969
- const envPath = path59.join(cwd, ".env");
24179
+ const envPath = path60.join(cwd, ".env");
23970
24180
  if (await readIfExists(envPath) != null) return false;
23971
24181
  try {
23972
24182
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23977,9 +24187,9 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
23977
24187
  projectKey
23978
24188
  });
23979
24189
  if (!stored) return false;
23980
- const tmp = path59.join(cwd, ".env.codeam-restore.tmp");
23981
- await import_fs5.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
23982
- await import_fs5.promises.rename(tmp, envPath);
24190
+ const tmp = path60.join(cwd, ".env.codeam-restore.tmp");
24191
+ await import_fs6.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
24192
+ await import_fs6.promises.rename(tmp, envPath);
23983
24193
  log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
23984
24194
  return true;
23985
24195
  } catch (err) {
@@ -24054,8 +24264,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
24054
24264
  if (args2.length === 0) return detection;
24055
24265
  const binName = args2[0];
24056
24266
  if (binName.startsWith("-")) return detection;
24057
- const binPath = path60.join(cwd, "node_modules", ".bin", binName);
24058
- if (!fs56.existsSync(binPath)) return detection;
24267
+ const binPath = path61.join(cwd, "node_modules", ".bin", binName);
24268
+ if (!fs57.existsSync(binPath)) return detection;
24059
24269
  return {
24060
24270
  ...detection,
24061
24271
  command: binPath,
@@ -24271,7 +24481,7 @@ async function startDevServer(ctx) {
24271
24481
  await applyPreviewHostAllow(cwd);
24272
24482
  const spawnable = normalizeDetectionForSpawn(detection, cwd);
24273
24483
  emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
24274
- const devServer = (0, import_child_process20.spawn)(spawnable.command, spawnable.args, {
24484
+ const devServer = (0, import_child_process21.spawn)(spawnable.command, spawnable.args, {
24275
24485
  cwd,
24276
24486
  env: { ...process.env, ...spawnable.env ?? {} },
24277
24487
  stdio: ["ignore", "pipe", "pipe"],
@@ -24396,7 +24606,7 @@ async function establishTunnel(ctx, dev) {
24396
24606
  `cloudflared quick tunnel (retry ${attempt}/${MAX_TUNNEL_ATTEMPTS})`
24397
24607
  );
24398
24608
  }
24399
- const candidate = (0, import_child_process20.spawn)(
24609
+ const candidate = (0, import_child_process21.spawn)(
24400
24610
  bin,
24401
24611
  ["tunnel", "--url", `http://localhost:${detection.port}`],
24402
24612
  { stdio: ["ignore", "pipe", "pipe"] }
@@ -24427,10 +24637,10 @@ async function establishTunnel(ctx, dev) {
24427
24637
  }
24428
24638
 
24429
24639
  // src/beads/bd-adapter.ts
24430
- var import_child_process21 = require("child_process");
24431
- var fs57 = __toESM(require("fs"));
24432
- var os46 = __toESM(require("os"));
24433
- var path61 = __toESM(require("path"));
24640
+ var import_child_process22 = require("child_process");
24641
+ var fs58 = __toESM(require("fs"));
24642
+ var os47 = __toESM(require("os"));
24643
+ var path62 = __toESM(require("path"));
24434
24644
  var BD_PACKAGE = "@beads/bd";
24435
24645
  function resolveBundledBdBinary() {
24436
24646
  return _resolveSeam.resolveBundled();
@@ -24442,11 +24652,11 @@ function _defaultResolveBundled() {
24442
24652
  } catch {
24443
24653
  return null;
24444
24654
  }
24445
- const binDir = path61.join(path61.dirname(pkgJsonPath), "bin");
24655
+ const binDir = path62.join(path62.dirname(pkgJsonPath), "bin");
24446
24656
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
24447
- const binaryPath = path61.join(binDir, binaryName);
24657
+ const binaryPath = path62.join(binDir, binaryName);
24448
24658
  try {
24449
- fs57.accessSync(binaryPath, fs57.constants.F_OK);
24659
+ fs58.accessSync(binaryPath, fs58.constants.F_OK);
24450
24660
  return binaryPath;
24451
24661
  } catch {
24452
24662
  return null;
@@ -24456,13 +24666,13 @@ function resolveBdOnPath() {
24456
24666
  return _resolveSeam.resolveOnPath();
24457
24667
  }
24458
24668
  function _defaultResolveOnPath() {
24459
- const dirs = (process.env.PATH ?? "").split(path61.delimiter).filter(Boolean);
24669
+ const dirs = (process.env.PATH ?? "").split(path62.delimiter).filter(Boolean);
24460
24670
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
24461
24671
  for (const dir of dirs) {
24462
24672
  for (const candidate of candidates) {
24463
- const full = path61.join(dir, candidate);
24673
+ const full = path62.join(dir, candidate);
24464
24674
  try {
24465
- fs57.accessSync(full, fs57.constants.F_OK);
24675
+ fs58.accessSync(full, fs58.constants.F_OK);
24466
24676
  return full;
24467
24677
  } catch {
24468
24678
  }
@@ -24481,7 +24691,7 @@ function _defaultSpawn(binaryPath, args2, opts) {
24481
24691
  return new Promise((resolve9) => {
24482
24692
  let proc;
24483
24693
  try {
24484
- proc = (0, import_child_process21.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
24694
+ proc = (0, import_child_process22.spawn)(binaryPath, args2, { cwd: opts.cwd, env: opts.env });
24485
24695
  } catch (err) {
24486
24696
  resolve9({ code: -1, stdout: "", stderr: err.message });
24487
24697
  return;
@@ -24547,7 +24757,7 @@ var BdAdapter = class {
24547
24757
  const env = { ...process.env };
24548
24758
  if (!env.HOME) {
24549
24759
  try {
24550
- const home = os46.homedir();
24760
+ const home = os47.homedir();
24551
24761
  if (home) env.HOME = home;
24552
24762
  } catch {
24553
24763
  }
@@ -24638,13 +24848,13 @@ function coerceIssue(row, projectKey) {
24638
24848
  }
24639
24849
 
24640
24850
  // src/beads/provisioner.ts
24641
- var import_child_process24 = require("child_process");
24642
- var fs59 = __toESM(require("fs"));
24643
- var os48 = __toESM(require("os"));
24644
- var path63 = __toESM(require("path"));
24851
+ var import_child_process25 = require("child_process");
24852
+ var fs60 = __toESM(require("fs"));
24853
+ var os49 = __toESM(require("os"));
24854
+ var path64 = __toESM(require("path"));
24645
24855
 
24646
24856
  // src/beads/install-bd.ts
24647
- var import_child_process22 = require("child_process");
24857
+ var import_child_process23 = require("child_process");
24648
24858
  var INSTALL_SH_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh";
24649
24859
  var INSTALL_PS1_URL = "https://raw.githubusercontent.com/gastownhall/beads/main/install.ps1";
24650
24860
  function resolveInstallStrategy(platform3) {
@@ -24675,7 +24885,7 @@ function _defaultInstallSpawn(strategy) {
24675
24885
  return new Promise((resolve9) => {
24676
24886
  let proc;
24677
24887
  try {
24678
- proc = (0, import_child_process22.spawn)(strategy.command, strategy.args, { env: process.env });
24888
+ proc = (0, import_child_process23.spawn)(strategy.command, strategy.args, { env: process.env });
24679
24889
  } catch (err) {
24680
24890
  resolve9({ ok: false, code: -1, stderr: err.message });
24681
24891
  return;
@@ -24705,10 +24915,10 @@ async function installBd(platform3 = process.platform) {
24705
24915
  }
24706
24916
 
24707
24917
  // src/beads/install-dolt.ts
24708
- var import_child_process23 = require("child_process");
24709
- var fs58 = __toESM(require("fs"));
24710
- var os47 = __toESM(require("os"));
24711
- var path62 = __toESM(require("path"));
24918
+ var import_child_process24 = require("child_process");
24919
+ var fs59 = __toESM(require("fs"));
24920
+ var os48 = __toESM(require("os"));
24921
+ var path63 = __toESM(require("path"));
24712
24922
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
24713
24923
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
24714
24924
  function resolveDoltInstallStrategy(platform3) {
@@ -24797,14 +25007,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
24797
25007
  return result;
24798
25008
  }
24799
25009
  var _doltPathSeam = {
24800
- homedir: () => os47.homedir(),
25010
+ homedir: () => os48.homedir(),
24801
25011
  getPath: () => process.env.PATH ?? "",
24802
25012
  setPath: (p2) => {
24803
25013
  process.env.PATH = p2;
24804
25014
  },
24805
25015
  exists: (p2) => {
24806
25016
  try {
24807
- fs58.accessSync(p2, fs58.constants.F_OK);
25017
+ fs59.accessSync(p2, fs59.constants.F_OK);
24808
25018
  return true;
24809
25019
  } catch {
24810
25020
  return false;
@@ -24815,7 +25025,7 @@ function doltBinaryNames(platform3) {
24815
25025
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
24816
25026
  }
24817
25027
  function knownDoltDirs(platform3) {
24818
- const P3 = platform3 === "win32" ? path62.win32 : path62.posix;
25028
+ const P3 = platform3 === "win32" ? path63.win32 : path63.posix;
24819
25029
  const home = _doltPathSeam.homedir();
24820
25030
  if (platform3 === "win32") {
24821
25031
  return [
@@ -24831,7 +25041,7 @@ function knownDoltDirs(platform3) {
24831
25041
  ].filter(Boolean);
24832
25042
  }
24833
25043
  function ensureDoltResolvable(platform3 = process.platform) {
24834
- const P3 = platform3 === "win32" ? path62.win32 : path62.posix;
25044
+ const P3 = platform3 === "win32" ? path63.win32 : path63.posix;
24835
25045
  const delim = platform3 === "win32" ? ";" : ":";
24836
25046
  const names = doltBinaryNames(platform3);
24837
25047
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -24867,7 +25077,7 @@ function _defaultDoltInstallSpawn(strategy) {
24867
25077
  };
24868
25078
  let proc;
24869
25079
  try {
24870
- proc = (0, import_child_process23.spawn)(strategy.command, strategy.args, {
25080
+ proc = (0, import_child_process24.spawn)(strategy.command, strategy.args, {
24871
25081
  env: process.env,
24872
25082
  stdio: ["ignore", "pipe", "pipe"]
24873
25083
  });
@@ -25008,17 +25218,17 @@ var _provisionSeam = {
25008
25218
  };
25009
25219
  var _linkSeam = {
25010
25220
  platform: () => process.platform,
25011
- homedir: () => os48.homedir(),
25221
+ homedir: () => os49.homedir(),
25012
25222
  isWritableDir: (dir) => {
25013
25223
  try {
25014
- fs59.accessSync(dir, fs59.constants.W_OK);
25224
+ fs60.accessSync(dir, fs60.constants.W_OK);
25015
25225
  return true;
25016
25226
  } catch {
25017
25227
  return false;
25018
25228
  }
25019
25229
  },
25020
25230
  ensureDir: (dir) => {
25021
- fs59.mkdirSync(dir, { recursive: true });
25231
+ fs60.mkdirSync(dir, { recursive: true });
25022
25232
  },
25023
25233
  /**
25024
25234
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -25039,9 +25249,9 @@ var _linkSeam = {
25039
25249
  * which `linkBdOntoPath` creates if missing.
25040
25250
  */
25041
25251
  cliBinDir: () => {
25042
- const pathDirs = (process.env.PATH ?? "").split(path63.delimiter).filter(Boolean);
25252
+ const pathDirs = (process.env.PATH ?? "").split(path64.delimiter).filter(Boolean);
25043
25253
  const home = _linkSeam.homedir();
25044
- const localBin = home ? path63.join(home, ".local", "bin") : null;
25254
+ const localBin = home ? path64.join(home, ".local", "bin") : null;
25045
25255
  if (localBin) {
25046
25256
  try {
25047
25257
  _linkSeam.ensureDir(localBin);
@@ -25051,16 +25261,16 @@ var _linkSeam = {
25051
25261
  const candidates = [];
25052
25262
  if (localBin) candidates.push(localBin);
25053
25263
  try {
25054
- candidates.push(path63.dirname(process.execPath));
25264
+ candidates.push(path64.dirname(process.execPath));
25055
25265
  } catch {
25056
25266
  }
25057
25267
  candidates.push("/usr/local/bin");
25058
25268
  const entry = process.argv[1];
25059
25269
  if (entry) {
25060
25270
  try {
25061
- candidates.push(path63.dirname(fs59.realpathSync(entry)));
25271
+ candidates.push(path64.dirname(fs60.realpathSync(entry)));
25062
25272
  } catch {
25063
- candidates.push(path63.dirname(entry));
25273
+ candidates.push(path64.dirname(entry));
25064
25274
  }
25065
25275
  }
25066
25276
  const onPathWritable = candidates.find(
@@ -25072,20 +25282,20 @@ var _linkSeam = {
25072
25282
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
25073
25283
  readlink: (linkPath) => {
25074
25284
  try {
25075
- return fs59.readlinkSync(linkPath);
25285
+ return fs60.readlinkSync(linkPath);
25076
25286
  } catch {
25077
25287
  return null;
25078
25288
  }
25079
25289
  },
25080
- unlink: (linkPath) => fs59.unlinkSync(linkPath),
25081
- symlink: (target, linkPath) => fs59.symlinkSync(target, linkPath)
25290
+ unlink: (linkPath) => fs60.unlinkSync(linkPath),
25291
+ symlink: (target, linkPath) => fs60.symlinkSync(target, linkPath)
25082
25292
  };
25083
25293
  function linkBdOntoPath(binaryPath) {
25084
25294
  if (_linkSeam.platform() === "win32") return;
25085
25295
  const binDir = _linkSeam.cliBinDir();
25086
25296
  if (!binDir) return;
25087
25297
  _linkSeam.ensureDir(binDir);
25088
- const linkPath = path63.join(binDir, "bd");
25298
+ const linkPath = path64.join(binDir, "bd");
25089
25299
  if (linkPath === binaryPath) return;
25090
25300
  const current2 = _linkSeam.readlink(linkPath);
25091
25301
  if (current2 === binaryPath) return;
@@ -25094,7 +25304,7 @@ function linkBdOntoPath(binaryPath) {
25094
25304
  log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
25095
25305
  }
25096
25306
  function setGitBeadsRole() {
25097
- (0, import_child_process24.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
25307
+ (0, import_child_process25.execFileSync)("git", ["config", "--global", "beads.role", "contributor"], {
25098
25308
  stdio: "ignore"
25099
25309
  });
25100
25310
  }
@@ -25280,7 +25490,7 @@ function dedupeRecipes(agents) {
25280
25490
 
25281
25491
  // src/beads/watcher.ts
25282
25492
  var crypto4 = __toESM(require("crypto"));
25283
- var path64 = __toESM(require("path"));
25493
+ var path65 = __toESM(require("path"));
25284
25494
  var API_BASE6 = resolveApiBaseUrl();
25285
25495
  var DEBOUNCE_MS2 = 400;
25286
25496
  var ZERO_SUMMARY = {
@@ -25304,7 +25514,7 @@ var BeadsWatcher = class {
25304
25514
  constructor(opts) {
25305
25515
  this.opts = opts;
25306
25516
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
25307
- this.feedPath = opts.feedPath ?? path64.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
25517
+ this.feedPath = opts.feedPath ?? path65.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
25308
25518
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
25309
25519
  }
25310
25520
  opts;
@@ -25803,8 +26013,8 @@ function cleanupAttachmentTempFiles() {
25803
26013
  function saveFilesTemp(files) {
25804
26014
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
25805
26015
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
25806
- const tmpPath = path67.join(os52.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
25807
- fs62.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
26016
+ const tmpPath = path68.join(os53.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
26017
+ fs63.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
25808
26018
  pendingAttachmentFiles.add(tmpPath);
25809
26019
  return tmpPath;
25810
26020
  });
@@ -25949,7 +26159,7 @@ var sessionTerminated = async (ctx, cmd) => {
25949
26159
  }
25950
26160
  quiet(() => ctx.agent.kill());
25951
26161
  try {
25952
- const proc = (0, import_child_process25.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
26162
+ const proc = (0, import_child_process26.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
25953
26163
  detached: true,
25954
26164
  stdio: "ignore"
25955
26165
  });
@@ -25968,7 +26178,7 @@ var shutdownSession = async (ctx, cmd) => {
25968
26178
  quiet(() => ctx.agent.kill());
25969
26179
  if (ctx.keepAliveCtx.inCodespace && ctx.keepAliveCtx.codespaceName) {
25970
26180
  try {
25971
- const stopProc = (0, import_child_process25.spawn)(
26181
+ const stopProc = (0, import_child_process26.spawn)(
25972
26182
  "bash",
25973
26183
  ["-lc", `sleep 1; gh codespace stop -c ${JSON.stringify(ctx.keepAliveCtx.codespaceName)} >/dev/null 2>&1 || true`],
25974
26184
  { detached: true, stdio: "ignore" }
@@ -25978,7 +26188,7 @@ var shutdownSession = async (ctx, cmd) => {
25978
26188
  }
25979
26189
  }
25980
26190
  try {
25981
- const proc = (0, import_child_process25.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
26191
+ const proc = (0, import_child_process26.spawn)("bash", ["-lc", "pm2 delete codeam-pair >/dev/null 2>&1 || true"], {
25982
26192
  detached: true,
25983
26193
  stdio: "ignore"
25984
26194
  });
@@ -26022,10 +26232,10 @@ var listFiles = async (ctx, cmd, parsed) => {
26022
26232
  await ctx.relay.sendResult(cmd.id, "completed", result);
26023
26233
  };
26024
26234
  var envReadH = async (ctx, cmd) => {
26025
- const envPath = path67.join(process.cwd(), ".env");
26235
+ const envPath = path68.join(process.cwd(), ".env");
26026
26236
  await restoreProjectEnvIfMissing(process.cwd(), ctx);
26027
26237
  try {
26028
- const raw = await fs62.promises.readFile(envPath, "utf8");
26238
+ const raw = await fs63.promises.readFile(envPath, "utf8");
26029
26239
  await ctx.relay.sendResult(cmd.id, "completed", {
26030
26240
  exists: true,
26031
26241
  vars: parseDotenv(raw)
@@ -26056,15 +26266,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
26056
26266
  }
26057
26267
  seen.add(v.key);
26058
26268
  }
26059
- const envPath = path67.join(process.cwd(), ".env");
26060
- const tmpPath = path67.join(process.cwd(), ".env.codeam.tmp");
26269
+ const envPath = path68.join(process.cwd(), ".env");
26270
+ const tmpPath = path68.join(process.cwd(), ".env.codeam.tmp");
26061
26271
  try {
26062
- await fs62.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
26063
- await fs62.promises.rename(tmpPath, envPath);
26272
+ await fs63.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
26273
+ await fs63.promises.rename(tmpPath, envPath);
26064
26274
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
26065
26275
  void syncProjectEnvUp(process.cwd(), ctx);
26066
26276
  } catch (err) {
26067
- await fs62.promises.rm(tmpPath, { force: true }).catch(() => void 0);
26277
+ await fs63.promises.rm(tmpPath, { force: true }).catch(() => void 0);
26068
26278
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
26069
26279
  }
26070
26280
  };
@@ -26113,7 +26323,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
26113
26323
  let configuredAgent = rawAgentId;
26114
26324
  if (!configuredAgent) {
26115
26325
  try {
26116
- const raw = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
26326
+ const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26117
26327
  configuredAgent = raw.agent ?? "";
26118
26328
  } catch {
26119
26329
  }
@@ -26147,7 +26357,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
26147
26357
  persist: persistHeadroomConfig,
26148
26358
  readEnabled: () => {
26149
26359
  try {
26150
- const raw = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
26360
+ const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26151
26361
  return raw.enabled === true;
26152
26362
  } catch {
26153
26363
  return false;
@@ -26469,7 +26679,7 @@ var headroomBudgetH = async (ctx, cmd) => {
26469
26679
  }
26470
26680
  let headroomActive = false;
26471
26681
  try {
26472
- const raw = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
26682
+ const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26473
26683
  headroomActive = raw.enabled === true;
26474
26684
  } catch {
26475
26685
  }
@@ -26479,7 +26689,7 @@ var headroomBudgetH = async (ctx, cmd) => {
26479
26689
  }
26480
26690
  let existingConfig = { enabled: true };
26481
26691
  try {
26482
- existingConfig = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
26692
+ existingConfig = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26483
26693
  } catch {
26484
26694
  }
26485
26695
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -26583,7 +26793,7 @@ var defaultCliUpdateDeps = {
26583
26793
  // Only a truly local `codeam start` (neither marker) re-execs in place below.
26584
26794
  isSupervised: () => process.env["CODEAM_AUTO_APPROVE"] === "1" || process.env["CODESPACES"] === "true",
26585
26795
  relaunch: (args2) => {
26586
- const child = (0, import_child_process25.spawnSync)("codeam", args2, { stdio: "inherit", env: process.env });
26796
+ const child = (0, import_child_process26.spawnSync)("codeam", args2, { stdio: "inherit", env: process.env });
26587
26797
  process.exit(child.status ?? 0);
26588
26798
  }
26589
26799
  };
@@ -26592,9 +26802,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
26592
26802
  function buildNpmInstallInvocation(opts) {
26593
26803
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
26594
26804
  const execPath = opts?.execPath ?? process.execPath;
26595
- const exists2 = opts?.existsSync ?? fs62.existsSync;
26805
+ const exists2 = opts?.existsSync ?? fs63.existsSync;
26596
26806
  const platform3 = opts?.platform ?? process.platform;
26597
- const p2 = platform3 === "win32" ? path67.win32 : path67.posix;
26807
+ const p2 = platform3 === "win32" ? path68.win32 : path68.posix;
26598
26808
  const normalized = entryScript.split(/[\\/]/).join("/");
26599
26809
  const marker = "/lib/node_modules/codeam-cli/";
26600
26810
  const markerIdx = normalized.indexOf(marker);
@@ -26616,7 +26826,7 @@ function isPermissionError(stderr) {
26616
26826
  function resolveGlobalNodeModulesDir(opts) {
26617
26827
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
26618
26828
  const platform3 = opts?.platform ?? process.platform;
26619
- const p2 = platform3 === "win32" ? path67.win32 : path67.posix;
26829
+ const p2 = platform3 === "win32" ? path68.win32 : path68.posix;
26620
26830
  const marker = "/lib/node_modules/codeam-cli/";
26621
26831
  const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
26622
26832
  if (markerIdx <= 0) return null;
@@ -26626,9 +26836,9 @@ function resolveGlobalNodeModulesDir(opts) {
26626
26836
  var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
26627
26837
  function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
26628
26838
  if (!nodeModulesDir) return 0;
26629
- const readdirSync15 = deps?.readdirSync ?? fs62.readdirSync;
26630
- const statSync17 = deps?.statSync ?? fs62.statSync;
26631
- const rmSync9 = deps?.rmSync ?? fs62.rmSync;
26839
+ const readdirSync15 = deps?.readdirSync ?? fs63.readdirSync;
26840
+ const statSync17 = deps?.statSync ?? fs63.statSync;
26841
+ const rmSync9 = deps?.rmSync ?? fs63.rmSync;
26632
26842
  let removed = 0;
26633
26843
  let entries;
26634
26844
  try {
@@ -26638,7 +26848,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
26638
26848
  }
26639
26849
  for (const name of entries) {
26640
26850
  if (!/^\.codeam-cli-/.test(name)) continue;
26641
- const full = path67.join(nodeModulesDir, name);
26851
+ const full = path68.join(nodeModulesDir, name);
26642
26852
  try {
26643
26853
  const st3 = statSync17(full);
26644
26854
  if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
@@ -26664,7 +26874,7 @@ async function runNpmInstallLatest() {
26664
26874
  const useShell = process.platform === "win32";
26665
26875
  const command2 = useShell && invocation.command.includes(" ") ? `"${invocation.command}"` : invocation.command;
26666
26876
  const result = await new Promise((resolve9) => {
26667
- (0, import_child_process25.execFile)(
26877
+ (0, import_child_process26.execFile)(
26668
26878
  command2,
26669
26879
  invocation.args,
26670
26880
  { timeout: CLI_UPDATE_INSTALL_TIMEOUT_MS, shell: useShell },
@@ -27278,13 +27488,13 @@ async function dispatchCommand(ctx, cmd) {
27278
27488
  }
27279
27489
 
27280
27490
  // src/commands/start/keep-alive.ts
27281
- var import_child_process26 = require("child_process");
27491
+ var import_child_process27 = require("child_process");
27282
27492
  function buildKeepAlive(ctx) {
27283
27493
  let timer = null;
27284
27494
  async function setIdleTimeout(minutes) {
27285
27495
  if (!ctx.inCodespace || !ctx.codespaceName) return;
27286
27496
  await new Promise((resolve9) => {
27287
- const proc = (0, import_child_process26.spawn)(
27497
+ const proc = (0, import_child_process27.spawn)(
27288
27498
  "gh",
27289
27499
  [
27290
27500
  "api",
@@ -27518,7 +27728,7 @@ function resolveTokenValue(args2) {
27518
27728
  if (fileFlag) {
27519
27729
  const path91 = fileFlag.slice("--token-file=".length);
27520
27730
  try {
27521
- const content = fs63.readFileSync(path91, "utf8").trim();
27731
+ const content = fs64.readFileSync(path91, "utf8").trim();
27522
27732
  if (content.length === 0) fail(`--token-file ${path91} is empty`);
27523
27733
  rmIfExistsQuiet(path91);
27524
27734
  return content;
@@ -27549,7 +27759,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
27549
27759
  pluginId,
27550
27760
  ideName: "codeam-cli (codespace)",
27551
27761
  ideVersion: process.env.npm_package_version ?? "unknown",
27552
- hostname: os53.hostname(),
27762
+ hostname: os54.hostname(),
27553
27763
  codespaceName: process.env.CODESPACE_NAME ?? "",
27554
27764
  // Current git branch of the codespace's working directory, so the
27555
27765
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -27610,7 +27820,7 @@ async function claim(token, pluginId, pluginSecretHash) {
27610
27820
  }
27611
27821
  }
27612
27822
  function pairAutoLockPath() {
27613
- return path68.join(os53.homedir(), ".codeam", "pair-auto.lock");
27823
+ return path69.join(os54.homedir(), ".codeam", "pair-auto.lock");
27614
27824
  }
27615
27825
  function isLivePairAuto(pid) {
27616
27826
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -27620,7 +27830,7 @@ function isLivePairAuto(pid) {
27620
27830
  if (e.code !== "EPERM") return false;
27621
27831
  }
27622
27832
  try {
27623
- return fs63.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
27833
+ return fs64.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
27624
27834
  } catch {
27625
27835
  return true;
27626
27836
  }
@@ -27630,24 +27840,24 @@ function isLiveCodeam(pid) {
27630
27840
  }
27631
27841
  function daemonLockPath(sessionId) {
27632
27842
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
27633
- return path68.join(os53.homedir(), ".codeam", `daemon-${safe}.lock`);
27843
+ return path69.join(os54.homedir(), ".codeam", `daemon-${safe}.lock`);
27634
27844
  }
27635
27845
  function acquireDaemonLock(sessionId) {
27636
27846
  const lockPath = daemonLockPath(sessionId);
27637
27847
  try {
27638
- fs63.mkdirSync(path68.dirname(lockPath), { recursive: true });
27848
+ fs64.mkdirSync(path69.dirname(lockPath), { recursive: true });
27639
27849
  try {
27640
- fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27850
+ fs64.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27641
27851
  } catch (e) {
27642
27852
  if (e.code !== "EEXIST") throw e;
27643
- const holder = Number(fs63.readFileSync(lockPath, "utf8").trim());
27853
+ const holder = Number(fs64.readFileSync(lockPath, "utf8").trim());
27644
27854
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
27645
- fs63.writeFileSync(lockPath, String(process.pid));
27855
+ fs64.writeFileSync(lockPath, String(process.pid));
27646
27856
  }
27647
27857
  const release3 = () => {
27648
27858
  try {
27649
- if (fs63.existsSync(lockPath) && Number(fs63.readFileSync(lockPath, "utf8").trim()) === process.pid) {
27650
- fs63.unlinkSync(lockPath);
27859
+ if (fs64.existsSync(lockPath) && Number(fs64.readFileSync(lockPath, "utf8").trim()) === process.pid) {
27860
+ fs64.unlinkSync(lockPath);
27651
27861
  }
27652
27862
  } catch {
27653
27863
  }
@@ -27669,19 +27879,19 @@ function acquireDaemonLock(sessionId) {
27669
27879
  function acquireSingletonLock() {
27670
27880
  const lockPath = pairAutoLockPath();
27671
27881
  try {
27672
- fs63.mkdirSync(path68.dirname(lockPath), { recursive: true });
27882
+ fs64.mkdirSync(path69.dirname(lockPath), { recursive: true });
27673
27883
  try {
27674
- fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27884
+ fs64.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27675
27885
  } catch (e) {
27676
27886
  if (e.code !== "EEXIST") throw e;
27677
- const holder = Number(fs63.readFileSync(lockPath, "utf8").trim());
27887
+ const holder = Number(fs64.readFileSync(lockPath, "utf8").trim());
27678
27888
  if (isLivePairAuto(holder)) return false;
27679
- fs63.writeFileSync(lockPath, String(process.pid));
27889
+ fs64.writeFileSync(lockPath, String(process.pid));
27680
27890
  }
27681
27891
  process.once("exit", () => {
27682
27892
  try {
27683
- if (fs63.existsSync(lockPath) && Number(fs63.readFileSync(lockPath, "utf8").trim()) === process.pid) {
27684
- fs63.unlinkSync(lockPath);
27893
+ if (fs64.existsSync(lockPath) && Number(fs64.readFileSync(lockPath, "utf8").trim()) === process.pid) {
27894
+ fs64.unlinkSync(lockPath);
27685
27895
  }
27686
27896
  } catch {
27687
27897
  }
@@ -28135,178 +28345,6 @@ var AgentService = class _AgentService {
28135
28345
  // src/agents/acp/adapters.ts
28136
28346
  var path70 = __toESM(require("path"));
28137
28347
 
28138
- // src/agents/acp/agent-binary.ts
28139
- var import_fs6 = __toESM(require("fs"));
28140
- var import_os11 = __toESM(require("os"));
28141
- var import_path8 = __toESM(require("path"));
28142
- var import_child_process27 = require("child_process");
28143
- function currentPlatformKey() {
28144
- return `${process.platform}-${process.arch}`;
28145
- }
28146
- var SDK_PKG = "@anthropic-ai/claude-agent-sdk";
28147
- function resolveSdkDirViaRequire(req = require) {
28148
- try {
28149
- return import_path8.default.dirname(req.resolve(`${SDK_PKG}/package.json`));
28150
- } catch {
28151
- }
28152
- try {
28153
- let dir = import_path8.default.dirname(req.resolve(SDK_PKG));
28154
- for (let i = 0; i < 5; i++) {
28155
- if (import_path8.default.basename(dir) === "claude-agent-sdk") return dir;
28156
- const parent = import_path8.default.dirname(dir);
28157
- if (parent === dir) break;
28158
- dir = parent;
28159
- }
28160
- return null;
28161
- } catch {
28162
- return null;
28163
- }
28164
- }
28165
- function defaultSdkDir() {
28166
- return resolveSdkDirViaRequire();
28167
- }
28168
- function resolveClaudeNativeBinary(deps = {}) {
28169
- const existsSync29 = deps.existsSync ?? import_fs6.default.existsSync;
28170
- const platformKey = deps.platformKey ?? currentPlatformKey();
28171
- const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
28172
- if (!sdkDir) return null;
28173
- const scopeDir = import_path8.default.dirname(sdkDir);
28174
- const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
28175
- const candidate = import_path8.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
28176
- return existsSync29(candidate) ? candidate : null;
28177
- }
28178
- var realSleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
28179
- async function waitForClaudeNativeBinary(opts = {}) {
28180
- const timeoutMs = opts.timeoutMs ?? 18e4;
28181
- const pollMs = opts.pollMs ?? 500;
28182
- const now = opts.now ?? Date.now;
28183
- const sleep5 = opts.sleep ?? realSleep;
28184
- const deps = {
28185
- sdkDir: opts.sdkDir,
28186
- platformKey: opts.platformKey,
28187
- existsSync: opts.existsSync
28188
- };
28189
- const deadline = now() + timeoutMs;
28190
- let found = resolveClaudeNativeBinary(deps);
28191
- if (found) return found;
28192
- while (now() < deadline) {
28193
- await sleep5(pollMs);
28194
- found = resolveClaudeNativeBinary(deps);
28195
- if (found) return found;
28196
- }
28197
- return resolveClaudeNativeBinary(deps);
28198
- }
28199
- function isCommandOnPath(cmd, probe = defaultWhich) {
28200
- return probe(cmd);
28201
- }
28202
- function defaultWhich(cmd) {
28203
- const finder = process.platform === "win32" ? "where" : "which";
28204
- try {
28205
- const res = (0, import_child_process27.spawnSync)(finder, [cmd], { stdio: "ignore" });
28206
- return res.status === 0;
28207
- } catch {
28208
- return false;
28209
- }
28210
- }
28211
- async function waitForCommandOnPath(cmd, opts = {}) {
28212
- const timeoutMs = opts.timeoutMs ?? 18e4;
28213
- const pollMs = opts.pollMs ?? 500;
28214
- const now = opts.now ?? Date.now;
28215
- const sleep5 = opts.sleep ?? realSleep;
28216
- const probe = opts.probe;
28217
- const check = () => isCommandOnPath(cmd, probe);
28218
- const deadline = now() + timeoutMs;
28219
- if (check()) return true;
28220
- while (now() < deadline) {
28221
- await sleep5(pollMs);
28222
- if (check()) return true;
28223
- }
28224
- return check();
28225
- }
28226
- function resolveCursorAgentBinary(deps = {}) {
28227
- const existsSync29 = deps.existsSync ?? import_fs6.default.existsSync;
28228
- const platform3 = deps.platform ?? process.platform;
28229
- const env = deps.env ?? process.env;
28230
- if (platform3 === "win32") {
28231
- const localAppData = env.LOCALAPPDATA;
28232
- if (!localAppData) return null;
28233
- const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
28234
- return existsSync29(exe) ? exe : null;
28235
- }
28236
- const home = deps.homedir ?? import_os11.default.homedir();
28237
- const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
28238
- return existsSync29(unix) ? unix : null;
28239
- }
28240
- async function waitForCursorAgent(opts = {}) {
28241
- const timeoutMs = opts.timeoutMs ?? 18e4;
28242
- const pollMs = opts.pollMs ?? 500;
28243
- const now = opts.now ?? Date.now;
28244
- const sleep5 = opts.sleep ?? realSleep;
28245
- const check = () => resolveCursorAgentBinary(opts) !== null || isCommandOnPath("cursor-agent", opts.probe);
28246
- const deadline = now() + timeoutMs;
28247
- if (check()) return true;
28248
- while (now() < deadline) {
28249
- await sleep5(pollMs);
28250
- if (check()) return true;
28251
- }
28252
- return check();
28253
- }
28254
- var ADAPTER_MODULE_LOAD_ERROR_RE = /ERR_MODULE_NOT_FOUND|Cannot find module|ERR_REQUIRE_ESM|ERR_UNKNOWN_BUILTIN_MODULE|ERR_UNSUPPORTED_DIR_IMPORT|ERR_PACKAGE_PATH_NOT_EXPORTED|ERR_INVALID_PACKAGE_CONFIG|ERR_INVALID_PACKAGE_TARGET|ERR_INVALID_MODULE_SPECIFIER|node:internal\/modules\/|Directory import|SyntaxError|Unexpected (token|end|identifier)|missing \) after argument list/i;
28255
- var PERMANENT_ADAPTER_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
28256
- function probeAdapterModuleGraph(command2, args2, opts = {}) {
28257
- const livenessMs = opts.livenessMs ?? 400;
28258
- const spawnFn = opts.spawnFn ?? import_child_process27.spawn;
28259
- return new Promise((resolve9) => {
28260
- let settled = false;
28261
- let stderr = "";
28262
- let timer;
28263
- let child;
28264
- const finish = (r) => {
28265
- if (settled) return;
28266
- settled = true;
28267
- if (timer) clearTimeout(timer);
28268
- try {
28269
- child?.kill("SIGKILL");
28270
- } catch {
28271
- }
28272
- resolve9(r);
28273
- };
28274
- try {
28275
- child = spawnFn(command2, [...args2], { stdio: ["pipe", "ignore", "pipe"] });
28276
- } catch {
28277
- resolve9("ok");
28278
- return;
28279
- }
28280
- child.stderr?.on("data", (d3) => {
28281
- stderr += d3.toString();
28282
- if (stderr.length > 8192) stderr = stderr.slice(-8192);
28283
- });
28284
- child.on("error", () => finish("ok"));
28285
- child.on("exit", (code) => {
28286
- if (code !== 0 && code !== null && !PERMANENT_ADAPTER_STARTUP_RE.test(stderr)) {
28287
- finish("transient");
28288
- } else {
28289
- finish("ok");
28290
- }
28291
- });
28292
- timer = setTimeout(() => finish("ok"), livenessMs);
28293
- });
28294
- }
28295
- async function waitForAdapterModuleGraph(command2, args2, opts = {}) {
28296
- const timeoutMs = opts.timeoutMs ?? 18e4;
28297
- const pollMs = opts.pollMs ?? 500;
28298
- const now = opts.now ?? Date.now;
28299
- const sleep5 = opts.sleep ?? realSleep;
28300
- const probeOpts = { livenessMs: opts.livenessMs, spawnFn: opts.spawnFn };
28301
- const deadline = now() + timeoutMs;
28302
- if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
28303
- while (now() < deadline) {
28304
- await sleep5(pollMs);
28305
- if (await probeAdapterModuleGraph(command2, args2, probeOpts) === "ok") return true;
28306
- }
28307
- return false;
28308
- }
28309
-
28310
28348
  // src/agents/kimi/installer.ts
28311
28349
  var import_node_child_process27 = require("child_process");
28312
28350
  var import_node_os10 = require("os");
@@ -28455,7 +28493,10 @@ var REGISTRY = {
28455
28493
  args: [bin],
28456
28494
  requiresAgentBinary: "codex",
28457
28495
  // codex ships via `npm install -g @openai/codex` → PATH binary.
28458
- waitForBinary: (o) => waitForCommandOnPath("codex", o)
28496
+ waitForBinary: (o) => {
28497
+ augmentUserLocalBinPaths();
28498
+ return waitForCommandOnPath("codex", o);
28499
+ }
28459
28500
  };
28460
28501
  },
28461
28502
  // Cursor speaks ACP NATIVELY via `cursor-agent acp` ("Start the Cursor
@@ -28481,7 +28522,30 @@ var REGISTRY = {
28481
28522
  command: resolveCursorAgentBinary() ?? "cursor-agent",
28482
28523
  args: ["acp"],
28483
28524
  requiresAgentBinary: "cursor-agent",
28484
- waitForBinary: (o) => waitForCursorAgent(o)
28525
+ // Stale-PATH guard — same class as codex/gemini above, kept here so the
28526
+ // PROBE and the SPAWN agree about what "ready" means.
28527
+ //
28528
+ // On an in-session switch the adapter spec is resolved BEFORE the install
28529
+ // (`ensureAgentBinaryForSwitch`'s first step), so with no cursor-agent on
28530
+ // disk yet `resolveCursorAgentBinary()` returns null and the spec is
28531
+ // PERMANENTLY CACHED with the bare name `cursor-agent`. The installer then
28532
+ // drops the binary in ~/.local/bin, which a systemd-minimal PATH lacks,
28533
+ // yet `waitForCursorAgent` still reports READY (it probes the absolute
28534
+ // install location).
28535
+ //
28536
+ // ⚠️ Scope, honestly: this is defence in depth, NOT a live outage fix.
28537
+ // `AcpClient.start` already spawns with `expandPathForAgentBinaries(...)`
28538
+ // (client.ts), which folds the same dirs in, so the production ACP spawn
28539
+ // very likely resolved anyway. What was genuinely wrong is that a probe
28540
+ // could report ready while a *plain* spawn from the same process could not
28541
+ // find the binary — the real-install gate
28542
+ // (`__tests__/integration/agent-install.int.test.ts`) spawns without that
28543
+ // expansion and caught the divergence. Aligning the probe with codex/gemini
28544
+ // costs one idempotent call and removes the discrepancy.
28545
+ waitForBinary: (o) => {
28546
+ augmentUserLocalBinPaths();
28547
+ return waitForCursorAgent(o);
28548
+ }
28485
28549
  }),
28486
28550
  // Gemini speaks ACP natively via `gemini --acp` — no npm adapter
28487
28551
  // package, just the user-installed `gemini` binary on PATH. Same
@@ -28499,7 +28563,12 @@ var REGISTRY = {
28499
28563
  // codeam was launched from.
28500
28564
  args: ["--skip-trust", "--acp"],
28501
28565
  requiresAgentBinary: "gemini",
28502
- waitForBinary: (o) => waitForCommandOnPath("gemini", o)
28566
+ // gemini ships via `npm install -g @google/gemini-cli` → PATH binary,
28567
+ // same stale-PATH exposure as codex above.
28568
+ waitForBinary: (o) => {
28569
+ augmentUserLocalBinPaths();
28570
+ return waitForCommandOnPath("gemini", o);
28571
+ }
28503
28572
  }),
28504
28573
  // Kimi Code (Moonshot) speaks ACP natively via `kimi acp` — a stdio
28505
28574
  // JSON-RPC server that answers `initialize` (agentInfo `Kimi Code CLI`,
@@ -34688,7 +34757,7 @@ async function ensureAgentBinaryForSwitch(agentId, installScript, deps = {}) {
34688
34757
  };
34689
34758
  }
34690
34759
  log.info("switchAgent", `installing ${agentId} binary (missing on PATH)`);
34691
- const res = await runInstall(installScript, { logScope: "switchAgent" });
34760
+ const res = await runInstall(installScript, { logScope: "switchAgent", timeoutMs: 3e5 });
34692
34761
  if (!res.ok) {
34693
34762
  return {
34694
34763
  ok: false,
@@ -34696,6 +34765,22 @@ async function ensureAgentBinaryForSwitch(agentId, installScript, deps = {}) {
34696
34765
  };
34697
34766
  }
34698
34767
  if (await spec.waitForBinary({ timeoutMs: 3e4 })) return { ok: true };
34768
+ log.info(
34769
+ "switchAgent",
34770
+ "install probe failed \u2014 retrying install once (half-finished bin link class)"
34771
+ );
34772
+ deps.onRetry?.();
34773
+ const retryRes = await runInstall(installScript, {
34774
+ logScope: "switchAgent",
34775
+ timeoutMs: 3e5
34776
+ });
34777
+ if (!retryRes.ok) {
34778
+ return {
34779
+ ok: false,
34780
+ error: retryRes.timedOut ? `${displayName(agentId)} install timed out.` : `${displayName(agentId)} install failed.`
34781
+ };
34782
+ }
34783
+ if (await spec.waitForBinary({ timeoutMs: 3e4 })) return { ok: true };
34699
34784
  return {
34700
34785
  ok: false,
34701
34786
  error: `${displayName(agentId)} installed but its binary never appeared on PATH.`
@@ -34729,7 +34814,11 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
34729
34814
  const from = deps.currentAgent();
34730
34815
  const target = resolveSwitchTarget(rawAgentId, from);
34731
34816
  if (!target.ok) {
34732
- return { ok: false, agentId: typeof rawAgentId === "string" ? rawAgentId : "", error: target.error };
34817
+ return {
34818
+ ok: false,
34819
+ agentId: typeof rawAgentId === "string" ? rawAgentId : "",
34820
+ error: target.error
34821
+ };
34733
34822
  }
34734
34823
  const agentId = target.agentId;
34735
34824
  const emitStatus = (status2) => deps.postEvent("switch_agent_status", { ...status2 });
@@ -34760,7 +34849,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
34760
34849
  }
34761
34850
  if (!fastPath.skipInstall) {
34762
34851
  void emitStep("install");
34763
- const bin = await deps.ensureBinary(agentId, installScript);
34852
+ const bin = await deps.ensureBinary(agentId, installScript, () => {
34853
+ void emitStep("install");
34854
+ });
34764
34855
  if (!bin.ok) return fail2(bin.error);
34765
34856
  }
34766
34857
  void emitStep("restart");
@@ -34776,7 +34867,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
34776
34867
  `Switching to ${displayName(agentId)} failed and ${displayName(from)} couldn't be restored \u2014 restart the session.`
34777
34868
  );
34778
34869
  }
34779
- return fail2(`Couldn't start ${displayName(agentId)} \u2014 the session stays on ${displayName(from)}.`);
34870
+ return fail2(
34871
+ `Couldn't start ${displayName(agentId)} \u2014 the session stays on ${displayName(from)}.`
34872
+ );
34780
34873
  }
34781
34874
  try {
34782
34875
  deps.persistAgent(agentId);
@@ -39348,7 +39441,7 @@ async function runAcpSession(opts) {
39348
39441
  provisionCredential: (agentId, auth) => {
39349
39442
  switchCredentialEnv = provisionAgentCredentials(agentId, auth);
39350
39443
  },
39351
- ensureBinary: (agentId, installScript) => ensureAgentBinaryForSwitch(agentId, installScript),
39444
+ ensureBinary: (agentId, installScript, onRetry) => ensureAgentBinaryForSwitch(agentId, installScript, { onRetry }),
39352
39445
  swapRuntime: relaunchWith,
39353
39446
  revertRuntime: relaunchWith,
39354
39447
  persistAgent: (agentId) => setSessionAgent(opts.pluginId, agentId),
@@ -44264,7 +44357,7 @@ function checkChokidar() {
44264
44357
  }
44265
44358
  async function doctor(args2 = []) {
44266
44359
  const json = args2.includes("--json");
44267
- const cliVersion = true ? "2.65.0" : "0.0.0-dev";
44360
+ const cliVersion = true ? "2.65.1" : "0.0.0-dev";
44268
44361
  const apiBase2 = resolveApiBaseUrl();
44269
44362
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
44270
44363
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -44655,7 +44748,7 @@ async function mcpRun(args2) {
44655
44748
  // src/commands/version.ts
44656
44749
  var import_picocolors15 = __toESM(require("picocolors"));
44657
44750
  function version2() {
44658
- const v = true ? "2.65.0" : "unknown";
44751
+ const v = true ? "2.65.1" : "unknown";
44659
44752
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
44660
44753
  }
44661
44754