codeam-cli 2.51.0 → 2.51.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 +20 -0
  2. package/dist/index.js +296 -277
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -522,8 +522,8 @@ var _default = makeConfig();
522
522
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
523
523
 
524
524
  // src/commands/pair-auto.ts
525
- var fs42 = __toESM(require("fs"));
526
- var os35 = __toESM(require("os"));
525
+ var fs43 = __toESM(require("fs"));
526
+ var os36 = __toESM(require("os"));
527
527
  var path48 = __toESM(require("path"));
528
528
  var import_crypto4 = require("crypto");
529
529
 
@@ -5397,7 +5397,7 @@ function readAnonId() {
5397
5397
  }
5398
5398
  function superProperties() {
5399
5399
  return {
5400
- cliVersion: true ? "2.51.0" : "0.0.0-dev",
5400
+ cliVersion: true ? "2.51.1" : "0.0.0-dev",
5401
5401
  nodeVersion: process.version,
5402
5402
  platform: process.platform,
5403
5403
  arch: process.arch,
@@ -5578,7 +5578,7 @@ var os4 = __toESM(require("os"));
5578
5578
  // package.json
5579
5579
  var package_default = {
5580
5580
  name: "codeam-cli",
5581
- version: "2.51.0",
5581
+ version: "2.51.1",
5582
5582
  description: "Workflow-continuity bridge for AI coding agents. Wrap Claude Code or Codex in a PTY and supervise, approve, and redirect the session from any device \u2014 async. The terminal companion for CodeAgent Mobile.",
5583
5583
  type: "commonjs",
5584
5584
  main: "dist/index.js",
@@ -7728,8 +7728,8 @@ function closeAllTerminals() {
7728
7728
  }
7729
7729
 
7730
7730
  // src/commands/start/handlers.ts
7731
- var fs41 = __toESM(require("fs"));
7732
- var os34 = __toESM(require("os"));
7731
+ var fs42 = __toESM(require("fs"));
7732
+ var os35 = __toESM(require("os"));
7733
7733
  var path47 = __toESM(require("path"));
7734
7734
  var import_crypto3 = require("crypto");
7735
7735
  var import_child_process20 = require("child_process");
@@ -11164,10 +11164,10 @@ function buildForPlatform(platform3) {
11164
11164
  var import_node_crypto4 = require("crypto");
11165
11165
 
11166
11166
  // src/agents/claude/resolver.ts
11167
- function buildClaudeLaunch(extraArgs = [], os41 = createOsStrategy()) {
11168
- const found = os41.findInPath("claude") ?? os41.findInPath("claude-code");
11167
+ function buildClaudeLaunch(extraArgs = [], os42 = createOsStrategy()) {
11168
+ const found = os42.findInPath("claude") ?? os42.findInPath("claude-code");
11169
11169
  if (!found) return null;
11170
- return os41.buildLaunch(found, extraArgs);
11170
+ return os42.buildLaunch(found, extraArgs);
11171
11171
  }
11172
11172
 
11173
11173
  // src/agents/claude/installer.ts
@@ -11760,8 +11760,8 @@ var ClaudeRuntimeStrategy = class {
11760
11760
  meta = getAgent("claude");
11761
11761
  mode = "interactive";
11762
11762
  os;
11763
- constructor(os41) {
11764
- this.os = os41;
11763
+ constructor(os42) {
11764
+ this.os = os42;
11765
11765
  }
11766
11766
  /**
11767
11767
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -12438,8 +12438,8 @@ function codexCredentialLocator() {
12438
12438
  function codexLoginLauncher() {
12439
12439
  return {
12440
12440
  async ensureInstalled() {
12441
- const os41 = createOsStrategy();
12442
- return os41.findInPath("codex") !== null;
12441
+ const os42 = createOsStrategy();
12442
+ return os42.findInPath("codex") !== null;
12443
12443
  },
12444
12444
  launch() {
12445
12445
  return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -12462,8 +12462,8 @@ var CodexRuntimeStrategy = class {
12462
12462
  meta = getAgent("codex");
12463
12463
  mode = "interactive";
12464
12464
  os;
12465
- constructor(os41) {
12466
- this.os = os41;
12465
+ constructor(os42) {
12466
+ this.os = os42;
12467
12467
  }
12468
12468
  async prepareLaunch() {
12469
12469
  let binary = this.os.findInPath("codex");
@@ -12562,12 +12562,12 @@ var CodexRuntimeStrategy = class {
12562
12562
  });
12563
12563
  }
12564
12564
  };
12565
- function resolveNpm(os41) {
12566
- return os41.id === "win32" ? "npm.cmd" : "npm";
12565
+ function resolveNpm(os42) {
12566
+ return os42.id === "win32" ? "npm.cmd" : "npm";
12567
12567
  }
12568
- async function installCodexViaNpm(os41) {
12568
+ async function installCodexViaNpm(os42) {
12569
12569
  return new Promise((resolve7, reject) => {
12570
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os41), ["install", "-g", "@openai/codex"], {
12570
+ const proc = (0, import_node_child_process4.spawn)(resolveNpm(os42), ["install", "-g", "@openai/codex"], {
12571
12571
  stdio: "inherit"
12572
12572
  });
12573
12573
  proc.on("close", (code) => {
@@ -12584,16 +12584,16 @@ async function installCodexViaNpm(os41) {
12584
12584
  });
12585
12585
  });
12586
12586
  }
12587
- function augmentNpmGlobalBin(os41) {
12587
+ function augmentNpmGlobalBin(os42) {
12588
12588
  try {
12589
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os41), ["prefix", "-g"], {
12589
+ const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os42), ["prefix", "-g"], {
12590
12590
  stdio: ["ignore", "pipe", "ignore"]
12591
12591
  });
12592
12592
  if (result.status !== 0) return;
12593
12593
  const prefix = result.stdout.toString().trim();
12594
12594
  if (!prefix) return;
12595
- const binDir = os41.id === "win32" ? prefix : path22.join(prefix, "bin");
12596
- os41.augmentPath([binDir]);
12595
+ const binDir = os42.id === "win32" ? prefix : path22.join(prefix, "bin");
12596
+ os42.augmentPath([binDir]);
12597
12597
  } catch {
12598
12598
  }
12599
12599
  }
@@ -12677,9 +12677,9 @@ var import_node_child_process7 = require("child_process");
12677
12677
  // src/agents/coderabbit/installer.ts
12678
12678
  var import_node_child_process5 = require("child_process");
12679
12679
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
12680
- async function ensureCoderabbitInstalled(os41) {
12681
- if (os41.findInPath("coderabbit")) return true;
12682
- if (os41.id === "win32") {
12680
+ async function ensureCoderabbitInstalled(os42) {
12681
+ if (os42.findInPath("coderabbit")) return true;
12682
+ if (os42.id === "win32") {
12683
12683
  console.error(
12684
12684
  "\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
12685
12685
  );
@@ -12694,8 +12694,8 @@ async function ensureCoderabbitInstalled(os41) {
12694
12694
  proc.on("error", () => resolve7(false));
12695
12695
  });
12696
12696
  if (!ok) return false;
12697
- os41.augmentPath([`${os41.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12698
- return os41.findInPath("coderabbit") !== null;
12697
+ os42.augmentPath([`${os42.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
12698
+ return os42.findInPath("coderabbit") !== null;
12699
12699
  }
12700
12700
 
12701
12701
  // src/agents/coderabbit/link.ts
@@ -12730,10 +12730,10 @@ function coderabbitCredentialLocator() {
12730
12730
  validate: validateNonEmptyCredential
12731
12731
  };
12732
12732
  }
12733
- function coderabbitLoginLauncher(os41) {
12733
+ function coderabbitLoginLauncher(os42) {
12734
12734
  return {
12735
12735
  async ensureInstalled() {
12736
- return ensureCoderabbitInstalled(os41);
12736
+ return ensureCoderabbitInstalled(os42);
12737
12737
  },
12738
12738
  launch() {
12739
12739
  return (0, import_node_child_process6.spawn)("coderabbit", ["login"], { stdio: "inherit" });
@@ -12779,8 +12779,8 @@ var CoderabbitRuntimeStrategy = class {
12779
12779
  meta = getAgent("coderabbit");
12780
12780
  mode = "batch";
12781
12781
  os;
12782
- constructor(os41) {
12783
- this.os = os41;
12782
+ constructor(os42) {
12783
+ this.os = os42;
12784
12784
  }
12785
12785
  getDefaultArgs() {
12786
12786
  return ["review"];
@@ -12896,10 +12896,10 @@ function cursorCredentialLocator() {
12896
12896
  validate: validateNonEmptyCredential
12897
12897
  };
12898
12898
  }
12899
- function cursorLoginLauncher(os41) {
12899
+ function cursorLoginLauncher(os42) {
12900
12900
  return {
12901
12901
  async ensureInstalled() {
12902
- if (os41.findInPath("cursor-agent")) return true;
12902
+ if (os42.findInPath("cursor-agent")) return true;
12903
12903
  console.error(
12904
12904
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
12905
12905
  );
@@ -12961,8 +12961,8 @@ var CursorRuntimeStrategy = class {
12961
12961
  meta = getAgent("cursor");
12962
12962
  mode = "interactive";
12963
12963
  os;
12964
- constructor(os41) {
12965
- this.os = os41;
12964
+ constructor(os42) {
12965
+ this.os = os42;
12966
12966
  }
12967
12967
  async prepareLaunch() {
12968
12968
  const binary = this.os.findInPath("cursor-agent");
@@ -13101,10 +13101,10 @@ function aiderCredentialLocator() {
13101
13101
  validate: validateNonEmptyCredential
13102
13102
  };
13103
13103
  }
13104
- function aiderLoginLauncher(os41) {
13104
+ function aiderLoginLauncher(os42) {
13105
13105
  return {
13106
13106
  async ensureInstalled() {
13107
- if (os41.findInPath("aider")) return true;
13107
+ if (os42.findInPath("aider")) return true;
13108
13108
  console.error(
13109
13109
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
13110
13110
  );
@@ -13114,7 +13114,7 @@ function aiderLoginLauncher(os41) {
13114
13114
  console.error(
13115
13115
  "\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
13116
13116
  );
13117
- return (0, import_node_child_process9.spawn)(os41.id === "win32" ? "cmd.exe" : "sh", os41.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13117
+ return (0, import_node_child_process9.spawn)(os42.id === "win32" ? "cmd.exe" : "sh", os42.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
13118
13118
  stdio: "ignore"
13119
13119
  });
13120
13120
  }
@@ -13186,8 +13186,8 @@ var AiderRuntimeStrategy = class {
13186
13186
  meta = getAgent("aider");
13187
13187
  mode = "interactive";
13188
13188
  os;
13189
- constructor(os41) {
13190
- this.os = os41;
13189
+ constructor(os42) {
13190
+ this.os = os42;
13191
13191
  }
13192
13192
  async prepareLaunch() {
13193
13193
  const binary = this.os.findInPath("aider");
@@ -13316,8 +13316,8 @@ function geminiCredentialLocator() {
13316
13316
  function geminiLoginLauncher() {
13317
13317
  return {
13318
13318
  async ensureInstalled() {
13319
- const os41 = createOsStrategy();
13320
- return os41.findInPath("gemini") !== null;
13319
+ const os42 = createOsStrategy();
13320
+ return os42.findInPath("gemini") !== null;
13321
13321
  },
13322
13322
  launch() {
13323
13323
  return (0, import_node_child_process10.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -13350,8 +13350,8 @@ var GeminiRuntimeStrategy = class {
13350
13350
  meta = getAgent("gemini");
13351
13351
  mode = "interactive";
13352
13352
  os;
13353
- constructor(os41) {
13354
- this.os = os41;
13353
+ constructor(os42) {
13354
+ this.os = os42;
13355
13355
  }
13356
13356
  async prepareLaunch() {
13357
13357
  const binary = this.os.findInPath("gemini");
@@ -13450,18 +13450,18 @@ var GeminiRuntimeStrategy = class {
13450
13450
 
13451
13451
  // src/agents/registry.ts
13452
13452
  var runtimeBuilders = {
13453
- claude: (os41) => new ClaudeRuntimeStrategy(os41),
13454
- codex: (os41) => new CodexRuntimeStrategy(os41),
13455
- coderabbit: (os41) => new CoderabbitRuntimeStrategy(os41),
13456
- cursor: (os41) => new CursorRuntimeStrategy(os41),
13457
- aider: (os41) => new AiderRuntimeStrategy(os41),
13458
- gemini: (os41) => new GeminiRuntimeStrategy(os41)
13453
+ claude: (os42) => new ClaudeRuntimeStrategy(os42),
13454
+ codex: (os42) => new CodexRuntimeStrategy(os42),
13455
+ coderabbit: (os42) => new CoderabbitRuntimeStrategy(os42),
13456
+ cursor: (os42) => new CursorRuntimeStrategy(os42),
13457
+ aider: (os42) => new AiderRuntimeStrategy(os42),
13458
+ gemini: (os42) => new GeminiRuntimeStrategy(os42)
13459
13459
  };
13460
13460
  var deployBuilders = {
13461
13461
  claude: () => new ClaudeDeployStrategy(),
13462
13462
  codex: () => new CodexDeployStrategy()
13463
13463
  };
13464
- function createAgentStrategy(agent, os41 = createOsStrategy()) {
13464
+ function createAgentStrategy(agent, os42 = createOsStrategy()) {
13465
13465
  if (!AGENT_REGISTRY[agent]?.enabled) {
13466
13466
  throw new Error(
13467
13467
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -13471,10 +13471,10 @@ function createAgentStrategy(agent, os41 = createOsStrategy()) {
13471
13471
  if (!build) {
13472
13472
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
13473
13473
  }
13474
- return build(os41);
13474
+ return build(os42);
13475
13475
  }
13476
- function createInteractiveAgentStrategy(agent, os41 = createOsStrategy()) {
13477
- const s = createAgentStrategy(agent, os41);
13476
+ function createInteractiveAgentStrategy(agent, os42 = createOsStrategy()) {
13477
+ const s = createAgentStrategy(agent, os42);
13478
13478
  if (s.mode !== "interactive") {
13479
13479
  throw new Error(
13480
13480
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -13877,19 +13877,39 @@ async function linkDryRunPreflight(ctx) {
13877
13877
  }
13878
13878
 
13879
13879
  // src/commands/host-agent.ts
13880
- var import_node_child_process14 = require("child_process");
13881
- var os28 = __toESM(require("os"));
13882
- var fs31 = __toESM(require("fs"));
13880
+ var import_node_child_process15 = require("child_process");
13881
+ var os29 = __toESM(require("os"));
13882
+ var fs32 = __toESM(require("fs"));
13883
13883
  var path36 = __toESM(require("path"));
13884
13884
 
13885
+ // src/util/restrict-to-owner.ts
13886
+ var import_node_fs5 = __toESM(require("fs"));
13887
+ var import_node_os3 = __toESM(require("os"));
13888
+ var import_node_child_process11 = require("child_process");
13889
+ function restrictToOwner(filePath) {
13890
+ try {
13891
+ if (process.platform === "win32") {
13892
+ const username = import_node_os3.default.userInfo().username;
13893
+ (0, import_node_child_process11.execFileSync)(
13894
+ "icacls",
13895
+ [filePath, "/inheritance:r", "/grant:r", `${username}:F`],
13896
+ { stdio: "ignore" }
13897
+ );
13898
+ } else {
13899
+ import_node_fs5.default.chmodSync(filePath, 384);
13900
+ }
13901
+ } catch {
13902
+ }
13903
+ }
13904
+
13885
13905
  // src/commands/host/host-client.ts
13886
- var fs26 = __toESM(require("fs"));
13887
- var os23 = __toESM(require("os"));
13906
+ var fs27 = __toESM(require("fs"));
13907
+ var os24 = __toESM(require("os"));
13888
13908
  var path31 = __toESM(require("path"));
13889
13909
  function sampleCpuTimes() {
13890
13910
  let idle = 0;
13891
13911
  let total = 0;
13892
- for (const cpu of os23.cpus()) {
13912
+ for (const cpu of os24.cpus()) {
13893
13913
  const t2 = cpu.times;
13894
13914
  idle += t2.idle;
13895
13915
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -13908,8 +13928,8 @@ var MetricsCollector = class {
13908
13928
  const prev = this.prevCpu;
13909
13929
  this.prevCpu = current;
13910
13930
  if (!prev) {
13911
- const cores = os23.cpus().length || 1;
13912
- const proxy = os23.loadavg()[0] / cores * 100;
13931
+ const cores = os24.cpus().length || 1;
13932
+ const proxy = os24.loadavg()[0] / cores * 100;
13913
13933
  return Math.min(100, Math.max(0, Math.round(proxy)));
13914
13934
  }
13915
13935
  const idleDelta = current.idle - prev.idle;
@@ -13922,8 +13942,8 @@ var MetricsCollector = class {
13922
13942
  collect() {
13923
13943
  return {
13924
13944
  cpuPct: this.cpuPct(),
13925
- ramUsedMb: Math.round((os23.totalmem() - os23.freemem()) / 1048576),
13926
- ramTotalMb: Math.round(os23.totalmem() / 1048576),
13945
+ ramUsedMb: Math.round((os24.totalmem() - os24.freemem()) / 1048576),
13946
+ ramTotalMb: Math.round(os24.totalmem() / 1048576),
13927
13947
  latencyMs: this.lastLatencyMs
13928
13948
  };
13929
13949
  }
@@ -13932,19 +13952,19 @@ function apiBase() {
13932
13952
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
13933
13953
  }
13934
13954
  function hostIdentityPath() {
13935
- return path31.join(os23.homedir(), ".codeam", "host-agent.json");
13955
+ return path31.join(os24.homedir(), ".codeam", "host-agent.json");
13936
13956
  }
13937
13957
  function collectOsInfo() {
13938
13958
  return {
13939
- distro: os23.platform(),
13940
- arch: os23.arch(),
13941
- kernel: os23.release(),
13959
+ distro: os24.platform(),
13960
+ arch: os24.arch(),
13961
+ kernel: os24.release(),
13942
13962
  nodeVersion: process.versions.node
13943
13963
  };
13944
13964
  }
13945
13965
  function loadHostIdentity() {
13946
13966
  try {
13947
- const raw = fs26.readFileSync(hostIdentityPath(), "utf8");
13967
+ const raw = fs27.readFileSync(hostIdentityPath(), "utf8");
13948
13968
  const parsed = JSON.parse(raw);
13949
13969
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
13950
13970
  const p2 = parsed;
@@ -13957,12 +13977,12 @@ function loadHostIdentity() {
13957
13977
  }
13958
13978
  function saveHostIdentity(identity) {
13959
13979
  const file = hostIdentityPath();
13960
- fs26.mkdirSync(path31.dirname(file), { recursive: true, mode: 448 });
13961
- fs26.writeFileSync(file, JSON.stringify(identity, null, 2), {
13980
+ fs27.mkdirSync(path31.dirname(file), { recursive: true, mode: 448 });
13981
+ fs27.writeFileSync(file, JSON.stringify(identity, null, 2), {
13962
13982
  encoding: "utf8",
13963
13983
  mode: 384
13964
13984
  });
13965
- fs26.chmodSync(file, 384);
13985
+ fs27.chmodSync(file, 384);
13966
13986
  }
13967
13987
  var HostHttpError = class extends Error {
13968
13988
  constructor(message, status2) {
@@ -13985,7 +14005,7 @@ function isHostAuthRejection(err) {
13985
14005
  }
13986
14006
  function deleteHostIdentity() {
13987
14007
  try {
13988
- fs26.rmSync(hostIdentityPath(), { force: true });
14008
+ fs27.rmSync(hostIdentityPath(), { force: true });
13989
14009
  } catch {
13990
14010
  }
13991
14011
  }
@@ -14107,17 +14127,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
14107
14127
  }
14108
14128
 
14109
14129
  // src/commands/host/workspace.ts
14110
- var fs27 = __toESM(require("fs"));
14111
- var os24 = __toESM(require("os"));
14130
+ var fs28 = __toESM(require("fs"));
14131
+ var os25 = __toESM(require("os"));
14112
14132
  var path32 = __toESM(require("path"));
14113
- var import_node_child_process11 = require("child_process");
14133
+ var import_node_child_process12 = require("child_process");
14114
14134
  var import_node_util4 = require("util");
14115
- var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process11.execFile);
14135
+ var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process12.execFile);
14116
14136
  function isAbsolutePathTarget(target) {
14117
14137
  return path32.isAbsolute(target);
14118
14138
  }
14119
14139
  function selfHostedWorkspaceRoot() {
14120
- return path32.join(os24.homedir(), ".codeam", "self-hosted");
14140
+ return path32.join(os25.homedir(), ".codeam", "self-hosted");
14121
14141
  }
14122
14142
  function nonInteractiveGitEnv() {
14123
14143
  return {
@@ -14171,12 +14191,9 @@ async function configureGitCredentials(dest, repoRef, cloneToken) {
14171
14191
  const gh = githubOwnerRepo(repoRef.trim());
14172
14192
  if (!gh || !cloneToken) return;
14173
14193
  const credFile = path32.join(dest, ".git", "codeam-credentials");
14174
- fs27.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
14194
+ fs28.writeFileSync(credFile, `https://x-access-token:${cloneToken}@github.com
14175
14195
  `, { mode: 384 });
14176
- try {
14177
- fs27.chmodSync(credFile, 384);
14178
- } catch {
14179
- }
14196
+ restrictToOwner(credFile);
14180
14197
  const env = nonInteractiveGitEnv();
14181
14198
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
14182
14199
  const credFilePosix = credFile.split(path32.sep).join("/");
@@ -14215,17 +14232,17 @@ function maskToken(text, cloneToken) {
14215
14232
  }
14216
14233
  async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14217
14234
  if (isAbsolutePathTarget(repoOrPath)) {
14218
- if (!fs27.existsSync(repoOrPath)) {
14235
+ if (!fs28.existsSync(repoOrPath)) {
14219
14236
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
14220
14237
  }
14221
14238
  return repoOrPath;
14222
14239
  }
14223
14240
  const dest = path32.join(selfHostedWorkspaceRoot(), deployId);
14224
- if (fs27.existsSync(path32.join(dest, ".git"))) {
14241
+ if (fs28.existsSync(path32.join(dest, ".git"))) {
14225
14242
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken);
14226
14243
  return dest;
14227
14244
  }
14228
- fs27.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
14245
+ fs28.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
14229
14246
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken);
14230
14247
  try {
14231
14248
  await execFileP4("git", ["clone", "--depth", "1", cloneUrl, dest], {
@@ -14242,8 +14259,8 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken) {
14242
14259
  }
14243
14260
 
14244
14261
  // src/commands/host/agent-provisioning.ts
14245
- var fs28 = __toESM(require("fs"));
14246
- var os25 = __toESM(require("os"));
14262
+ var fs29 = __toESM(require("fs"));
14263
+ var os26 = __toESM(require("os"));
14247
14264
  var path33 = __toESM(require("path"));
14248
14265
  var PUBLIC_TO_INTERNAL_AGENT = {
14249
14266
  claude_code: "claude",
@@ -14259,16 +14276,16 @@ function toInternalAgentId(publicAgentId) {
14259
14276
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
14260
14277
  }
14261
14278
  function ensureDir(dir) {
14262
- fs28.mkdirSync(dir, { recursive: true, mode: 448 });
14279
+ fs29.mkdirSync(dir, { recursive: true, mode: 448 });
14263
14280
  }
14264
14281
  function writeFile0600(filePath, contents) {
14265
14282
  ensureDir(path33.dirname(filePath));
14266
- fs28.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
14267
- fs28.chmodSync(filePath, 384);
14283
+ fs29.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
14284
+ restrictToOwner(filePath);
14268
14285
  }
14269
14286
  function rmIfExists(filePath) {
14270
14287
  try {
14271
- fs28.rmSync(filePath, { force: true });
14288
+ fs29.rmSync(filePath, { force: true });
14272
14289
  } catch {
14273
14290
  }
14274
14291
  }
@@ -14287,7 +14304,7 @@ var claudeProvisioner = {
14287
14304
  rmIfExists(credentialsJson);
14288
14305
  }
14289
14306
  const claudeJson = path33.join(home, ".claude.json");
14290
- if (!fs28.existsSync(claudeJson)) {
14307
+ if (!fs29.existsSync(claudeJson)) {
14291
14308
  writeFile0600(
14292
14309
  claudeJson,
14293
14310
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -14360,7 +14377,7 @@ var UnsupportedAgentError = class extends Error {
14360
14377
  this.agentId = agentId;
14361
14378
  }
14362
14379
  };
14363
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os25.homedir()) {
14380
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os26.homedir()) {
14364
14381
  const internal = toInternalAgentId(publicAgentId);
14365
14382
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
14366
14383
  const provisioner = PROVISIONERS[internal];
@@ -14369,12 +14386,12 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os25.homedir(
14369
14386
  }
14370
14387
 
14371
14388
  // src/commands/host/git-tooling.ts
14372
- var import_node_child_process12 = require("child_process");
14373
- var fs29 = __toESM(require("fs"));
14374
- var os26 = __toESM(require("os"));
14389
+ var import_node_child_process13 = require("child_process");
14390
+ var fs30 = __toESM(require("fs"));
14391
+ var os27 = __toESM(require("os"));
14375
14392
  var path34 = __toESM(require("path"));
14376
14393
  function codeamBinDir() {
14377
- return process.env.CODEAM_BIN_DIR ?? path34.join(os26.homedir(), ".codeam", "bin");
14394
+ return process.env.CODEAM_BIN_DIR ?? path34.join(os27.homedir(), ".codeam", "bin");
14378
14395
  }
14379
14396
  var FALLBACK_GH_VERSION = "2.62.0";
14380
14397
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -14406,7 +14423,7 @@ async function download(url, dest) {
14406
14423
  const res = await fetch(url, { headers: { "User-Agent": "codeam-cli" } });
14407
14424
  if (!res.ok || !res.body) return false;
14408
14425
  const buf = Buffer.from(await res.arrayBuffer());
14409
- fs29.writeFileSync(dest, buf);
14426
+ fs30.writeFileSync(dest, buf);
14410
14427
  return true;
14411
14428
  } catch {
14412
14429
  return false;
@@ -14429,7 +14446,7 @@ async function ensureGhCli(runner, token, deps = {}) {
14429
14446
  const version3 = await resolveVersionFn(token);
14430
14447
  const asset = `gh_${version3}_${osToken}_${arch2}`;
14431
14448
  const url = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
14432
- const tmpRoot = fs29.mkdtempSync(path34.join(os26.tmpdir(), "codeam-gh-"));
14449
+ const tmpRoot = fs30.mkdtempSync(path34.join(os27.tmpdir(), "codeam-gh-"));
14433
14450
  const archive = path34.join(tmpRoot, `${asset}.${ext}`);
14434
14451
  if (!await downloadFn(url, archive)) {
14435
14452
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
@@ -14441,15 +14458,15 @@ async function ensureGhCli(runner, token, deps = {}) {
14441
14458
  return null;
14442
14459
  }
14443
14460
  const extractedBin = path34.join(tmpRoot, asset, "bin", binaryName);
14444
- if (!fs29.existsSync(extractedBin)) {
14461
+ if (!fs30.existsSync(extractedBin)) {
14445
14462
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
14446
14463
  return null;
14447
14464
  }
14448
14465
  const binDir = codeamBinDir();
14449
- fs29.mkdirSync(binDir, { recursive: true });
14466
+ fs30.mkdirSync(binDir, { recursive: true });
14450
14467
  const target = path34.join(binDir, binaryName);
14451
- fs29.copyFileSync(extractedBin, target);
14452
- fs29.chmodSync(target, 493);
14468
+ fs30.copyFileSync(extractedBin, target);
14469
+ fs30.chmodSync(target, 493);
14453
14470
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
14454
14471
  return target;
14455
14472
  } catch (e) {
@@ -14483,7 +14500,7 @@ var defaultGitToolingRunner = {
14483
14500
  which(cmd) {
14484
14501
  try {
14485
14502
  const probe = process.platform === "win32" ? "where" : "which";
14486
- (0, import_node_child_process12.execFileSync)(probe, [cmd], { stdio: "ignore" });
14503
+ (0, import_node_child_process13.execFileSync)(probe, [cmd], { stdio: "ignore" });
14487
14504
  return true;
14488
14505
  } catch {
14489
14506
  return false;
@@ -14491,7 +14508,7 @@ var defaultGitToolingRunner = {
14491
14508
  },
14492
14509
  run(cmd, args2, opts = {}) {
14493
14510
  return new Promise((resolve7) => {
14494
- const child = (0, import_node_child_process12.spawn)(cmd, args2, {
14511
+ const child = (0, import_node_child_process13.spawn)(cmd, args2, {
14495
14512
  stdio: [opts.input !== void 0 ? "pipe" : "ignore", "ignore", "pipe"]
14496
14513
  });
14497
14514
  let stderr = "";
@@ -14636,23 +14653,23 @@ function buildBudgetProxyArgs(env) {
14636
14653
  }
14637
14654
 
14638
14655
  // src/lib/updateNotifier.ts
14639
- var fs30 = __toESM(require("fs"));
14640
- var os27 = __toESM(require("os"));
14656
+ var fs31 = __toESM(require("fs"));
14657
+ var os28 = __toESM(require("os"));
14641
14658
  var path35 = __toESM(require("path"));
14642
14659
  var https6 = __toESM(require("https"));
14643
- var import_node_child_process13 = require("child_process");
14660
+ var import_node_child_process14 = require("child_process");
14644
14661
  var import_picocolors3 = __toESM(require("picocolors"));
14645
14662
  var PKG_NAME = "codeam-cli";
14646
14663
  var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
14647
14664
  var TTL_MS = 24 * 60 * 60 * 1e3;
14648
14665
  var REQUEST_TIMEOUT_MS = 1500;
14649
14666
  function cachePath() {
14650
- const dir = path35.join(os27.homedir(), ".codeam");
14667
+ const dir = path35.join(os28.homedir(), ".codeam");
14651
14668
  return path35.join(dir, "update-check.json");
14652
14669
  }
14653
14670
  function readCache() {
14654
14671
  try {
14655
- const raw = fs30.readFileSync(cachePath(), "utf8");
14672
+ const raw = fs31.readFileSync(cachePath(), "utf8");
14656
14673
  const parsed = JSON.parse(raw);
14657
14674
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
14658
14675
  return parsed;
@@ -14663,10 +14680,10 @@ function readCache() {
14663
14680
  function writeCache(cache) {
14664
14681
  try {
14665
14682
  const file = cachePath();
14666
- fs30.mkdirSync(path35.dirname(file), { recursive: true });
14683
+ fs31.mkdirSync(path35.dirname(file), { recursive: true });
14667
14684
  const tmp = `${file}.${process.pid}.tmp`;
14668
- fs30.writeFileSync(tmp, JSON.stringify(cache));
14669
- fs30.renameSync(tmp, file);
14685
+ fs31.writeFileSync(tmp, JSON.stringify(cache));
14686
+ fs31.renameSync(tmp, file);
14670
14687
  } catch {
14671
14688
  }
14672
14689
  }
@@ -14734,14 +14751,14 @@ function notifyIfStale(currentVersion, latest) {
14734
14751
  }
14735
14752
  function isLinkedInstall() {
14736
14753
  try {
14737
- const root = (0, import_node_child_process13.execSync)("npm root -g", {
14754
+ const root = (0, import_node_child_process14.execSync)("npm root -g", {
14738
14755
  encoding: "utf8",
14739
14756
  stdio: ["ignore", "pipe", "ignore"],
14740
14757
  timeout: 2e3
14741
14758
  }).trim();
14742
14759
  if (!root) return false;
14743
14760
  const pkgPath = path35.join(root, PKG_NAME);
14744
- return fs30.lstatSync(pkgPath).isSymbolicLink();
14761
+ return fs31.lstatSync(pkgPath).isSymbolicLink();
14745
14762
  } catch {
14746
14763
  return false;
14747
14764
  }
@@ -14762,7 +14779,7 @@ function maybeAutoUpdate(currentVersion, latest) {
14762
14779
 
14763
14780
  `
14764
14781
  );
14765
- const install = (0, import_node_child_process13.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
14782
+ const install = (0, import_node_child_process14.spawnSync)("npm", ["install", "-g", `${PKG_NAME}@latest`], {
14766
14783
  stdio: "inherit",
14767
14784
  env: process.env
14768
14785
  });
@@ -14777,13 +14794,13 @@ function maybeAutoUpdate(currentVersion, latest) {
14777
14794
  return;
14778
14795
  }
14779
14796
  try {
14780
- fs30.unlinkSync(cachePath());
14797
+ fs31.unlinkSync(cachePath());
14781
14798
  } catch {
14782
14799
  }
14783
14800
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
14784
14801
 
14785
14802
  `);
14786
- const child = (0, import_node_child_process13.spawnSync)("codeam", process.argv.slice(2), {
14803
+ const child = (0, import_node_child_process14.spawnSync)("codeam", process.argv.slice(2), {
14787
14804
  stdio: "inherit",
14788
14805
  env: process.env
14789
14806
  });
@@ -14793,7 +14810,7 @@ async function autoUpgradeBeforeCriticalCommand() {
14793
14810
  if (process.env.NODE_ENV === "test") return;
14794
14811
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14795
14812
  if (process.env.CI) return;
14796
- const current = true ? "2.51.0" : null;
14813
+ const current = true ? "2.51.1" : null;
14797
14814
  if (!current) return;
14798
14815
  const cache = readCache();
14799
14816
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -14810,7 +14827,7 @@ function checkForUpdates() {
14810
14827
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
14811
14828
  if (process.env.CI) return;
14812
14829
  if (!process.stdout.isTTY) return;
14813
- const current = true ? "2.51.0" : null;
14830
+ const current = true ? "2.51.1" : null;
14814
14831
  if (!current) return;
14815
14832
  const cache = readCache();
14816
14833
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -14882,8 +14899,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
14882
14899
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
14883
14900
  try {
14884
14901
  const file = headroomConfigPath();
14885
- if (!fs31.existsSync(file)) return null;
14886
- const cfg = JSON.parse(fs31.readFileSync(file, "utf8"));
14902
+ if (!fs32.existsSync(file)) return null;
14903
+ const cfg = JSON.parse(fs32.readFileSync(file, "utf8"));
14887
14904
  if (!cfg?.enabled) return null;
14888
14905
  const agent = cfg.agent ?? "claude";
14889
14906
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -14974,7 +14991,7 @@ var HEADROOM_MIN_FREE_DISK_BYTES = 2 * 1024 * 1024 * 1024;
14974
14991
  var defaultHeadroomRunner = {
14975
14992
  which(cmd) {
14976
14993
  try {
14977
- (0, import_node_child_process14.execFileSync)("which", [cmd], { stdio: "ignore" });
14994
+ (0, import_node_child_process15.execFileSync)("which", [cmd], { stdio: "ignore" });
14978
14995
  return true;
14979
14996
  } catch {
14980
14997
  return false;
@@ -14983,7 +15000,7 @@ var defaultHeadroomRunner = {
14983
15000
  run(cmd, args2, opts = {}) {
14984
15001
  return new Promise((resolve7) => {
14985
15002
  const spawnEnv = opts.env ?? process.env;
14986
- const child = (0, import_node_child_process14.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
15003
+ const child = (0, import_node_child_process15.spawn)(cmd, args2, { stdio: ["ignore", "pipe", "pipe"], env: spawnEnv });
14987
15004
  let stderrBuf = "";
14988
15005
  let stdoutBuf = "";
14989
15006
  let settled = false;
@@ -15147,15 +15164,16 @@ function isHeadroomSupportedAgent(agentId) {
15147
15164
  return n.startsWith("claude") || n.startsWith("codex") || n.startsWith("copilot");
15148
15165
  }
15149
15166
  function headroomConfigPath() {
15150
- return path36.join(os28.homedir(), ".codeam", "headroom-config.json");
15167
+ return path36.join(os29.homedir(), ".codeam", "headroom-config.json");
15151
15168
  }
15152
15169
  function persistHeadroomConfig(config) {
15153
15170
  try {
15154
15171
  const file = headroomConfigPath();
15155
- fs31.mkdirSync(path36.dirname(file), { recursive: true, mode: 448 });
15172
+ fs32.mkdirSync(path36.dirname(file), { recursive: true, mode: 448 });
15156
15173
  const tmp = `${file}.tmp-${process.pid}`;
15157
- fs31.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15158
- fs31.renameSync(tmp, file);
15174
+ fs32.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
15175
+ fs32.renameSync(tmp, file);
15176
+ restrictToOwner(file);
15159
15177
  } catch (err) {
15160
15178
  log.warn(
15161
15179
  "host-agent",
@@ -15164,7 +15182,7 @@ function persistHeadroomConfig(config) {
15164
15182
  }
15165
15183
  }
15166
15184
  function agentSettingsPath(kind) {
15167
- const home = os28.homedir();
15185
+ const home = os29.homedir();
15168
15186
  if (kind === "claude") return path36.join(home, ".claude", "settings.json");
15169
15187
  if (kind === "codex") return path36.join(home, ".codex", "auth.json");
15170
15188
  if (kind === "copilot") return path36.join(home, ".config", "github-copilot", "hosts.json");
@@ -15174,11 +15192,11 @@ function backupAgentHeadroomConfig(kind) {
15174
15192
  const src = agentSettingsPath(kind);
15175
15193
  if (!src) return;
15176
15194
  try {
15177
- if (!fs31.existsSync(src)) return;
15178
- const dest = path36.join(os28.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15179
- fs31.mkdirSync(path36.dirname(dest), { recursive: true, mode: 448 });
15180
- fs31.copyFileSync(src, dest);
15181
- fs31.chmodSync(dest, 384);
15195
+ if (!fs32.existsSync(src)) return;
15196
+ const dest = path36.join(os29.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15197
+ fs32.mkdirSync(path36.dirname(dest), { recursive: true, mode: 448 });
15198
+ fs32.copyFileSync(src, dest);
15199
+ fs32.chmodSync(dest, 384);
15182
15200
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
15183
15201
  } catch (err) {
15184
15202
  log.warn(
@@ -15190,12 +15208,12 @@ function backupAgentHeadroomConfig(kind) {
15190
15208
  function restoreAgentHeadroomConfig(kind) {
15191
15209
  const dest = agentSettingsPath(kind);
15192
15210
  if (!dest) return false;
15193
- const src = path36.join(os28.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15194
- if (!fs31.existsSync(src)) return false;
15211
+ const src = path36.join(os29.homedir(), ".codeam", `headroom-backup-${kind}.json`);
15212
+ if (!fs32.existsSync(src)) return false;
15195
15213
  try {
15196
- fs31.mkdirSync(path36.dirname(dest), { recursive: true, mode: 448 });
15197
- fs31.copyFileSync(src, dest);
15198
- fs31.chmodSync(dest, 384);
15214
+ fs32.mkdirSync(path36.dirname(dest), { recursive: true, mode: 448 });
15215
+ fs32.copyFileSync(src, dest);
15216
+ fs32.chmodSync(dest, 384);
15199
15217
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
15200
15218
  return true;
15201
15219
  } catch (err) {
@@ -15208,7 +15226,7 @@ function restoreAgentHeadroomConfig(kind) {
15208
15226
  }
15209
15227
  function readHeadroomChildEnv() {
15210
15228
  try {
15211
- const raw = fs31.readFileSync(headroomConfigPath(), "utf8");
15229
+ const raw = fs32.readFileSync(headroomConfigPath(), "utf8");
15212
15230
  const parsed = JSON.parse(raw);
15213
15231
  if (typeof parsed !== "object" || parsed === null) return {};
15214
15232
  const o = parsed;
@@ -15249,21 +15267,21 @@ function bundledClaudeBinDir() {
15249
15267
  const atAnthropic = path36.join(nm, "@anthropic-ai");
15250
15268
  let entries;
15251
15269
  try {
15252
- entries = fs31.readdirSync(atAnthropic);
15270
+ entries = fs32.readdirSync(atAnthropic);
15253
15271
  } catch {
15254
15272
  continue;
15255
15273
  }
15256
15274
  for (const entry of entries) {
15257
15275
  if (!entry.startsWith("claude-agent-sdk-")) continue;
15258
15276
  const bin = path36.join(atAnthropic, entry, "claude");
15259
- if (fs31.existsSync(bin)) return path36.dirname(bin);
15277
+ if (fs32.existsSync(bin)) return path36.dirname(bin);
15260
15278
  }
15261
15279
  }
15262
15280
  return null;
15263
15281
  }
15264
15282
  async function getFreeDiskBytes(dir) {
15265
15283
  try {
15266
- const s = await fs31.promises.statfs(dir);
15284
+ const s = await fs32.promises.statfs(dir);
15267
15285
  return s.bsize * s.bavail;
15268
15286
  } catch {
15269
15287
  return null;
@@ -15479,7 +15497,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15479
15497
  onProgress("proxy");
15480
15498
  try {
15481
15499
  const proxyEnv = { ...process.env, HEADROOM_KOMPRESS_BACKEND: "onnx_cpu" };
15482
- const proxy = (0, import_node_child_process14.spawn)(
15500
+ const proxy = (0, import_node_child_process15.spawn)(
15483
15501
  "headroom",
15484
15502
  ["proxy", "--port", "8787", ...buildBudgetProxyArgs(proxyEnv)],
15485
15503
  {
@@ -15504,18 +15522,18 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
15504
15522
  onProgress("ready");
15505
15523
  return true;
15506
15524
  }
15507
- var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process14.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
15525
+ var defaultSpawner = (env, cwd, args2 = []) => (0, import_node_child_process15.spawn)(process.execPath, [process.argv[1], "pair-auto", ...args2], {
15508
15526
  cwd,
15509
15527
  env: { ...process.env, ...env },
15510
15528
  stdio: ["ignore", "pipe", "pipe"],
15511
15529
  detached: false
15512
15530
  });
15513
15531
  function currentCliVersion() {
15514
- return true ? "2.51.0" : null;
15532
+ return true ? "2.51.1" : null;
15515
15533
  }
15516
15534
  function runCmd(cmd, args2, timeoutMs) {
15517
15535
  return new Promise((resolve7) => {
15518
- (0, import_node_child_process14.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
15536
+ (0, import_node_child_process15.execFile)(cmd, args2, { timeout: timeoutMs }, (err, stdout, stderr) => {
15519
15537
  const code = err && typeof err.code === "number" ? err.code : err ? null : 0;
15520
15538
  resolve7({ code, stdout: stdout ?? "", stderr: stderr ?? "" });
15521
15539
  });
@@ -15586,20 +15604,20 @@ var defaultOnUpdated = (version3) => {
15586
15604
  };
15587
15605
  var defaultDisableService = () => {
15588
15606
  try {
15589
- (0, import_node_child_process14.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
15607
+ (0, import_node_child_process15.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
15590
15608
  } catch {
15591
15609
  }
15592
15610
  };
15593
15611
  var defaultTeardownHeadroom = () => {
15594
15612
  try {
15595
- const kind = JSON.parse(fs31.readFileSync(headroomConfigPath(), "utf8")).agent;
15613
+ const kind = JSON.parse(fs32.readFileSync(headroomConfigPath(), "utf8")).agent;
15596
15614
  if (kind) {
15597
- (0, import_node_child_process14.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
15615
+ (0, import_node_child_process15.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
15598
15616
  }
15599
15617
  } catch {
15600
15618
  }
15601
15619
  try {
15602
- (0, import_node_child_process14.execFileSync)("pkill", ["-TERM", "-f", "headroom.*proxy"], { stdio: "ignore" });
15620
+ (0, import_node_child_process15.execFileSync)("pkill", ["-TERM", "-f", "headroom.*proxy"], { stdio: "ignore" });
15603
15621
  } catch {
15604
15622
  }
15605
15623
  persistHeadroomConfig({ enabled: false });
@@ -15906,9 +15924,9 @@ var HostAgentSupervisor = class {
15906
15924
  API_TIMEOUT_MS: "3000000",
15907
15925
  CODEAM_AUTO_TOKEN: payload.autoPairToken
15908
15926
  };
15909
- const houseConfigDir = path36.join(os28.homedir(), ".codeam", "house-claude");
15927
+ const houseConfigDir = path36.join(os29.homedir(), ".codeam", "house-claude");
15910
15928
  try {
15911
- fs31.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
15929
+ fs32.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
15912
15930
  } catch {
15913
15931
  }
15914
15932
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -15926,7 +15944,7 @@ var HostAgentSupervisor = class {
15926
15944
  report("installing", "installing agent CLI");
15927
15945
  await this.runAgentInstall(payload.agentInstallScript);
15928
15946
  }
15929
- const home = process.env.HOME || os28.homedir();
15947
+ const home = process.env.HOME || os29.homedir();
15930
15948
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
15931
15949
  if (payload.cloneToken) {
15932
15950
  try {
@@ -15949,7 +15967,7 @@ var HostAgentSupervisor = class {
15949
15967
  }
15950
15968
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
15951
15969
  report("headroom", "setting up Headroom proxy");
15952
- const freeBytes = await this.getFreeDisk(os28.homedir());
15970
+ const freeBytes = await this.getFreeDisk(os29.homedir());
15953
15971
  const alreadyInstalled = this.isHeadroomInstalled();
15954
15972
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
15955
15973
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -16071,8 +16089,8 @@ var HostAgentSupervisor = class {
16071
16089
  */
16072
16090
  runAgentInstall(script) {
16073
16091
  return new Promise((resolve7) => {
16074
- const home = process.env.HOME || os28.homedir();
16075
- const child = (0, import_node_child_process14.spawn)("sh", ["-c", script], {
16092
+ const home = process.env.HOME || os29.homedir();
16093
+ const child = (0, import_node_child_process15.spawn)("sh", ["-c", script], {
16076
16094
  env: { ...process.env, HOME: home },
16077
16095
  stdio: ["ignore", "pipe", "pipe"]
16078
16096
  });
@@ -16875,8 +16893,8 @@ function activePreviewSessionIds() {
16875
16893
 
16876
16894
  // src/beads/bd-adapter.ts
16877
16895
  var import_child_process15 = require("child_process");
16878
- var fs36 = __toESM(require("fs"));
16879
- var os30 = __toESM(require("os"));
16896
+ var fs37 = __toESM(require("fs"));
16897
+ var os31 = __toESM(require("os"));
16880
16898
  var path41 = __toESM(require("path"));
16881
16899
  var BD_PACKAGE = "@beads/bd";
16882
16900
  function resolveBundledBdBinary() {
@@ -16893,7 +16911,7 @@ function _defaultResolveBundled() {
16893
16911
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
16894
16912
  const binaryPath = path41.join(binDir, binaryName);
16895
16913
  try {
16896
- fs36.accessSync(binaryPath, fs36.constants.F_OK);
16914
+ fs37.accessSync(binaryPath, fs37.constants.F_OK);
16897
16915
  return binaryPath;
16898
16916
  } catch {
16899
16917
  return null;
@@ -16909,7 +16927,7 @@ function _defaultResolveOnPath() {
16909
16927
  for (const candidate of candidates) {
16910
16928
  const full = path41.join(dir, candidate);
16911
16929
  try {
16912
- fs36.accessSync(full, fs36.constants.F_OK);
16930
+ fs37.accessSync(full, fs37.constants.F_OK);
16913
16931
  return full;
16914
16932
  } catch {
16915
16933
  }
@@ -16994,7 +17012,7 @@ var BdAdapter = class {
16994
17012
  const env = { ...process.env };
16995
17013
  if (!env.HOME) {
16996
17014
  try {
16997
- const home = os30.homedir();
17015
+ const home = os31.homedir();
16998
17016
  if (home) env.HOME = home;
16999
17017
  } catch {
17000
17018
  }
@@ -17083,8 +17101,8 @@ function coerceIssue(row, projectKey) {
17083
17101
 
17084
17102
  // src/beads/provisioner.ts
17085
17103
  var import_child_process19 = require("child_process");
17086
- var fs39 = __toESM(require("fs"));
17087
- var os32 = __toESM(require("os"));
17104
+ var fs40 = __toESM(require("fs"));
17105
+ var os33 = __toESM(require("os"));
17088
17106
  var path44 = __toESM(require("path"));
17089
17107
 
17090
17108
  // src/beads/install-bd.ts
@@ -17150,8 +17168,8 @@ async function installBd(platform3 = process.platform) {
17150
17168
 
17151
17169
  // src/beads/install-dolt.ts
17152
17170
  var import_child_process17 = require("child_process");
17153
- var fs37 = __toESM(require("fs"));
17154
- var os31 = __toESM(require("os"));
17171
+ var fs38 = __toESM(require("fs"));
17172
+ var os32 = __toESM(require("os"));
17155
17173
  var path42 = __toESM(require("path"));
17156
17174
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
17157
17175
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
@@ -17192,11 +17210,11 @@ function resolveDoltInstallStrategy(platform3) {
17192
17210
  }
17193
17211
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
17194
17212
  function doltPlatformTuple(platform3, arch2) {
17195
- const os41 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17213
+ const os42 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
17196
17214
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
17197
17215
  if (!a) return null;
17198
- if (os41 === "windows" && a !== "amd64") return null;
17199
- return `${os41}-${a}`;
17216
+ if (os42 === "windows" && a !== "amd64") return null;
17217
+ return `${os42}-${a}`;
17200
17218
  }
17201
17219
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
17202
17220
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -17241,14 +17259,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
17241
17259
  return result;
17242
17260
  }
17243
17261
  var _doltPathSeam = {
17244
- homedir: () => os31.homedir(),
17262
+ homedir: () => os32.homedir(),
17245
17263
  getPath: () => process.env.PATH ?? "",
17246
17264
  setPath: (p2) => {
17247
17265
  process.env.PATH = p2;
17248
17266
  },
17249
17267
  exists: (p2) => {
17250
17268
  try {
17251
- fs37.accessSync(p2, fs37.constants.F_OK);
17269
+ fs38.accessSync(p2, fs38.constants.F_OK);
17252
17270
  return true;
17253
17271
  } catch {
17254
17272
  return false;
@@ -17411,7 +17429,7 @@ async function ensureSharedServer(adapter, options = {}) {
17411
17429
  // src/beads/project-key.ts
17412
17430
  var import_child_process18 = require("child_process");
17413
17431
  var crypto2 = __toESM(require("crypto"));
17414
- var fs38 = __toESM(require("fs"));
17432
+ var fs39 = __toESM(require("fs"));
17415
17433
  var path43 = __toESM(require("path"));
17416
17434
  function normalizeOrigin(raw) {
17417
17435
  const trimmed = raw.trim();
@@ -17444,7 +17462,7 @@ function findRepoRoot(cwd) {
17444
17462
  if (seen.has(dir)) return null;
17445
17463
  seen.add(dir);
17446
17464
  try {
17447
- const stat3 = fs38.statSync(path43.join(dir, ".git"), { throwIfNoEntry: false });
17465
+ const stat3 = fs39.statSync(path43.join(dir, ".git"), { throwIfNoEntry: false });
17448
17466
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
17449
17467
  } catch {
17450
17468
  }
@@ -17459,7 +17477,7 @@ var _execSeam2 = {
17459
17477
  const out2 = (0, import_child_process18.execFileSync)(file, args2, opts);
17460
17478
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
17461
17479
  },
17462
- realpath: (p2) => fs38.realpathSync(p2)
17480
+ realpath: (p2) => fs39.realpathSync(p2)
17463
17481
  };
17464
17482
  function readOrigin(cwd) {
17465
17483
  try {
@@ -17530,17 +17548,17 @@ var _provisionSeam = {
17530
17548
  };
17531
17549
  var _linkSeam = {
17532
17550
  platform: () => process.platform,
17533
- homedir: () => os32.homedir(),
17551
+ homedir: () => os33.homedir(),
17534
17552
  isWritableDir: (dir) => {
17535
17553
  try {
17536
- fs39.accessSync(dir, fs39.constants.W_OK);
17554
+ fs40.accessSync(dir, fs40.constants.W_OK);
17537
17555
  return true;
17538
17556
  } catch {
17539
17557
  return false;
17540
17558
  }
17541
17559
  },
17542
17560
  ensureDir: (dir) => {
17543
- fs39.mkdirSync(dir, { recursive: true });
17561
+ fs40.mkdirSync(dir, { recursive: true });
17544
17562
  },
17545
17563
  /**
17546
17564
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -17580,7 +17598,7 @@ var _linkSeam = {
17580
17598
  const entry = process.argv[1];
17581
17599
  if (entry) {
17582
17600
  try {
17583
- candidates.push(path44.dirname(fs39.realpathSync(entry)));
17601
+ candidates.push(path44.dirname(fs40.realpathSync(entry)));
17584
17602
  } catch {
17585
17603
  candidates.push(path44.dirname(entry));
17586
17604
  }
@@ -17594,13 +17612,13 @@ var _linkSeam = {
17594
17612
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
17595
17613
  readlink: (linkPath) => {
17596
17614
  try {
17597
- return fs39.readlinkSync(linkPath);
17615
+ return fs40.readlinkSync(linkPath);
17598
17616
  } catch {
17599
17617
  return null;
17600
17618
  }
17601
17619
  },
17602
- unlink: (linkPath) => fs39.unlinkSync(linkPath),
17603
- symlink: (target, linkPath) => fs39.symlinkSync(target, linkPath)
17620
+ unlink: (linkPath) => fs40.unlinkSync(linkPath),
17621
+ symlink: (target, linkPath) => fs40.symlinkSync(target, linkPath)
17604
17622
  };
17605
17623
  function linkBdOntoPath(binaryPath) {
17606
17624
  if (_linkSeam.platform() === "win32") return;
@@ -18076,15 +18094,15 @@ async function handleBeadsActionCommand(action, started) {
18076
18094
  }
18077
18095
 
18078
18096
  // src/beads/config-store.ts
18079
- var import_node_fs5 = __toESM(require("fs"));
18080
- var import_node_os3 = __toESM(require("os"));
18097
+ var import_node_fs6 = __toESM(require("fs"));
18098
+ var import_node_os4 = __toESM(require("os"));
18081
18099
  var import_node_path4 = __toESM(require("path"));
18082
18100
  function beadsConfigPath() {
18083
- return import_node_path4.default.join(import_node_os3.default.homedir(), ".codeam", "beads-config.json");
18101
+ return import_node_path4.default.join(import_node_os4.default.homedir(), ".codeam", "beads-config.json");
18084
18102
  }
18085
18103
  function readBeadsEnabled() {
18086
18104
  try {
18087
- const raw = import_node_fs5.default.readFileSync(beadsConfigPath(), "utf8");
18105
+ const raw = import_node_fs6.default.readFileSync(beadsConfigPath(), "utf8");
18088
18106
  const cfg = JSON.parse(raw);
18089
18107
  return cfg.enabled !== false;
18090
18108
  } catch {
@@ -18093,10 +18111,11 @@ function readBeadsEnabled() {
18093
18111
  }
18094
18112
  function persistBeadsConfig(cfg) {
18095
18113
  const file = beadsConfigPath();
18096
- import_node_fs5.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
18114
+ import_node_fs6.default.mkdirSync(import_node_path4.default.dirname(file), { recursive: true });
18097
18115
  const tmp = `${file}.tmp`;
18098
- import_node_fs5.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
18099
- import_node_fs5.default.renameSync(tmp, file);
18116
+ import_node_fs6.default.writeFileSync(tmp, JSON.stringify(cfg), { mode: 384 });
18117
+ import_node_fs6.default.renameSync(tmp, file);
18118
+ restrictToOwner(file);
18100
18119
  }
18101
18120
 
18102
18121
  // src/beads/wiring.ts
@@ -18235,7 +18254,7 @@ var pendingAttachmentFiles = /* @__PURE__ */ new Set();
18235
18254
  function cleanupAttachmentTempFiles() {
18236
18255
  for (const p2 of pendingAttachmentFiles) {
18237
18256
  try {
18238
- fs41.unlinkSync(p2);
18257
+ fs42.unlinkSync(p2);
18239
18258
  } catch {
18240
18259
  }
18241
18260
  }
@@ -18244,8 +18263,8 @@ function cleanupAttachmentTempFiles() {
18244
18263
  function saveFilesTemp(files) {
18245
18264
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
18246
18265
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
18247
- const tmpPath = path47.join(os34.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18248
- fs41.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18266
+ const tmpPath = path47.join(os35.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
18267
+ fs42.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
18249
18268
  pendingAttachmentFiles.add(tmpPath);
18250
18269
  return tmpPath;
18251
18270
  });
@@ -18265,7 +18284,7 @@ var startTask = (ctx, _cmd, parsed) => {
18265
18284
  setTimeout(() => {
18266
18285
  for (const p2 of paths) {
18267
18286
  try {
18268
- fs41.unlinkSync(p2);
18287
+ fs42.unlinkSync(p2);
18269
18288
  } catch {
18270
18289
  }
18271
18290
  pendingAttachmentFiles.delete(p2);
@@ -18468,7 +18487,7 @@ var listFiles = async (ctx, cmd, parsed) => {
18468
18487
  var envReadH = async (ctx, cmd) => {
18469
18488
  const envPath = path47.join(process.cwd(), ".env");
18470
18489
  try {
18471
- const raw = await fs41.promises.readFile(envPath, "utf8");
18490
+ const raw = await fs42.promises.readFile(envPath, "utf8");
18472
18491
  await ctx.relay.sendResult(cmd.id, "completed", {
18473
18492
  exists: true,
18474
18493
  vars: parseDotenv(raw)
@@ -18502,11 +18521,11 @@ var envWriteH = async (ctx, cmd, parsed) => {
18502
18521
  const envPath = path47.join(process.cwd(), ".env");
18503
18522
  const tmpPath = path47.join(process.cwd(), ".env.codeam.tmp");
18504
18523
  try {
18505
- await fs41.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18506
- await fs41.promises.rename(tmpPath, envPath);
18524
+ await fs42.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
18525
+ await fs42.promises.rename(tmpPath, envPath);
18507
18526
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
18508
18527
  } catch (err) {
18509
- await fs41.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18528
+ await fs42.promises.rm(tmpPath, { force: true }).catch(() => void 0);
18510
18529
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
18511
18530
  }
18512
18531
  };
@@ -18524,7 +18543,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18524
18543
  let configuredAgent = rawAgentId;
18525
18544
  if (!configuredAgent) {
18526
18545
  try {
18527
- const raw = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
18546
+ const raw = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18528
18547
  configuredAgent = raw.agent ?? "";
18529
18548
  } catch {
18530
18549
  }
@@ -18558,7 +18577,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
18558
18577
  persist: persistHeadroomConfig,
18559
18578
  readEnabled: () => {
18560
18579
  try {
18561
- const raw = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
18580
+ const raw = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18562
18581
  return raw.enabled === true;
18563
18582
  } catch {
18564
18583
  return false;
@@ -18652,7 +18671,7 @@ var headroomBudgetH = async (ctx, cmd) => {
18652
18671
  }
18653
18672
  let headroomActive = false;
18654
18673
  try {
18655
- const raw = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
18674
+ const raw = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18656
18675
  headroomActive = raw.enabled === true;
18657
18676
  } catch {
18658
18677
  }
@@ -18662,7 +18681,7 @@ var headroomBudgetH = async (ctx, cmd) => {
18662
18681
  }
18663
18682
  let existingConfig = { enabled: true };
18664
18683
  try {
18665
- existingConfig = JSON.parse(fs41.readFileSync(headroomConfigPath(), "utf8"));
18684
+ existingConfig = JSON.parse(fs42.readFileSync(headroomConfigPath(), "utf8"));
18666
18685
  } catch {
18667
18686
  }
18668
18687
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -19215,7 +19234,7 @@ function normalizeDetectionForSpawn(detection, cwd) {
19215
19234
  const binName = args2[0];
19216
19235
  if (binName.startsWith("-")) return detection;
19217
19236
  const binPath = path47.join(cwd, "node_modules", ".bin", binName);
19218
- if (!fs41.existsSync(binPath)) return detection;
19237
+ if (!fs42.existsSync(binPath)) return detection;
19219
19238
  return {
19220
19239
  ...detection,
19221
19240
  command: binPath,
@@ -20035,10 +20054,10 @@ function readTokenFromArgs(args2) {
20035
20054
  if (fileFlag) {
20036
20055
  const path61 = fileFlag.slice("--token-file=".length);
20037
20056
  try {
20038
- const content = fs42.readFileSync(path61, "utf8").trim();
20057
+ const content = fs43.readFileSync(path61, "utf8").trim();
20039
20058
  if (content.length === 0) fail(`--token-file ${path61} is empty`);
20040
20059
  try {
20041
- fs42.unlinkSync(path61);
20060
+ fs43.unlinkSync(path61);
20042
20061
  } catch {
20043
20062
  }
20044
20063
  return content;
@@ -20064,7 +20083,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
20064
20083
  pluginId,
20065
20084
  ideName: "codeam-cli (codespace)",
20066
20085
  ideVersion: process.env.npm_package_version ?? "unknown",
20067
- hostname: os35.hostname(),
20086
+ hostname: os36.hostname(),
20068
20087
  codespaceName: process.env.CODESPACE_NAME ?? "",
20069
20088
  // Current git branch of the codespace's working directory, so the
20070
20089
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -20125,7 +20144,7 @@ async function claim(token, pluginId, pluginSecretHash) {
20125
20144
  }
20126
20145
  }
20127
20146
  function pairAutoLockPath() {
20128
- return path48.join(os35.homedir(), ".codeam", "pair-auto.lock");
20147
+ return path48.join(os36.homedir(), ".codeam", "pair-auto.lock");
20129
20148
  }
20130
20149
  function isLivePairAuto(pid) {
20131
20150
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -20135,7 +20154,7 @@ function isLivePairAuto(pid) {
20135
20154
  if (e.code !== "EPERM") return false;
20136
20155
  }
20137
20156
  try {
20138
- return fs42.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20157
+ return fs43.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
20139
20158
  } catch {
20140
20159
  return true;
20141
20160
  }
@@ -20145,24 +20164,24 @@ function isLiveCodeam(pid) {
20145
20164
  }
20146
20165
  function daemonLockPath(sessionId) {
20147
20166
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
20148
- return path48.join(os35.homedir(), ".codeam", `daemon-${safe}.lock`);
20167
+ return path48.join(os36.homedir(), ".codeam", `daemon-${safe}.lock`);
20149
20168
  }
20150
20169
  function acquireDaemonLock(sessionId) {
20151
20170
  const lockPath = daemonLockPath(sessionId);
20152
20171
  try {
20153
- fs42.mkdirSync(path48.dirname(lockPath), { recursive: true });
20172
+ fs43.mkdirSync(path48.dirname(lockPath), { recursive: true });
20154
20173
  try {
20155
- fs42.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20174
+ fs43.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20156
20175
  } catch (e) {
20157
20176
  if (e.code !== "EEXIST") throw e;
20158
- const holder = Number(fs42.readFileSync(lockPath, "utf8").trim());
20177
+ const holder = Number(fs43.readFileSync(lockPath, "utf8").trim());
20159
20178
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
20160
- fs42.writeFileSync(lockPath, String(process.pid));
20179
+ fs43.writeFileSync(lockPath, String(process.pid));
20161
20180
  }
20162
20181
  const release3 = () => {
20163
20182
  try {
20164
- if (fs42.existsSync(lockPath) && Number(fs42.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20165
- fs42.unlinkSync(lockPath);
20183
+ if (fs43.existsSync(lockPath) && Number(fs43.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20184
+ fs43.unlinkSync(lockPath);
20166
20185
  }
20167
20186
  } catch {
20168
20187
  }
@@ -20184,19 +20203,19 @@ function acquireDaemonLock(sessionId) {
20184
20203
  function acquireSingletonLock() {
20185
20204
  const lockPath = pairAutoLockPath();
20186
20205
  try {
20187
- fs42.mkdirSync(path48.dirname(lockPath), { recursive: true });
20206
+ fs43.mkdirSync(path48.dirname(lockPath), { recursive: true });
20188
20207
  try {
20189
- fs42.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20208
+ fs43.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
20190
20209
  } catch (e) {
20191
20210
  if (e.code !== "EEXIST") throw e;
20192
- const holder = Number(fs42.readFileSync(lockPath, "utf8").trim());
20211
+ const holder = Number(fs43.readFileSync(lockPath, "utf8").trim());
20193
20212
  if (isLivePairAuto(holder)) return false;
20194
- fs42.writeFileSync(lockPath, String(process.pid));
20213
+ fs43.writeFileSync(lockPath, String(process.pid));
20195
20214
  }
20196
20215
  process.once("exit", () => {
20197
20216
  try {
20198
- if (fs42.existsSync(lockPath) && Number(fs42.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20199
- fs42.unlinkSync(lockPath);
20217
+ if (fs43.existsSync(lockPath) && Number(fs43.readFileSync(lockPath, "utf8").trim()) === process.pid) {
20218
+ fs43.unlinkSync(lockPath);
20200
20219
  }
20201
20220
  } catch {
20202
20221
  }
@@ -20278,7 +20297,7 @@ async function pairAuto(args2) {
20278
20297
  }
20279
20298
 
20280
20299
  // src/services/headroom/wrap-launch.ts
20281
- var import_node_child_process15 = require("child_process");
20300
+ var import_node_child_process16 = require("child_process");
20282
20301
  function wrapWithHeadroom(launch, opts) {
20283
20302
  if (!opts.enabled || !opts.headroomPresent) return launch;
20284
20303
  return {
@@ -20291,7 +20310,7 @@ var _present;
20291
20310
  function headroomPresent() {
20292
20311
  if (_present !== void 0) return Promise.resolve(_present);
20293
20312
  return new Promise((resolve7) => {
20294
- (0, import_node_child_process15.execFile)("headroom", ["--version"], (err) => {
20313
+ (0, import_node_child_process16.execFile)("headroom", ["--version"], (err) => {
20295
20314
  _present = !err;
20296
20315
  resolve7(_present);
20297
20316
  });
@@ -20723,9 +20742,9 @@ function requiresAcp(agent) {
20723
20742
  var import_node_crypto7 = require("crypto");
20724
20743
 
20725
20744
  // src/services/history.service.ts
20726
- var fs43 = __toESM(require("fs"));
20745
+ var fs44 = __toESM(require("fs"));
20727
20746
  var path50 = __toESM(require("path"));
20728
- var os36 = __toESM(require("os"));
20747
+ var os37 = __toESM(require("os"));
20729
20748
  var https7 = __toESM(require("https"));
20730
20749
  var http6 = __toESM(require("http"));
20731
20750
  var import_zod2 = require("zod");
@@ -20752,7 +20771,7 @@ function parseJsonl(filePath) {
20752
20771
  const messages = [];
20753
20772
  let raw;
20754
20773
  try {
20755
- raw = fs43.readFileSync(filePath, "utf8");
20774
+ raw = fs44.readFileSync(filePath, "utf8");
20756
20775
  } catch (err) {
20757
20776
  if (err.code !== "ENOENT") {
20758
20777
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -20893,7 +20912,7 @@ var HistoryService = class _HistoryService {
20893
20912
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
20894
20913
  }
20895
20914
  get projectDir() {
20896
- return this.runtime.resolveHistoryDir(this.cwd) ?? path50.join(os36.homedir(), ".claude", "projects", encodeCwd(this.cwd));
20915
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path50.join(os37.homedir(), ".claude", "projects", encodeCwd(this.cwd));
20897
20916
  }
20898
20917
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
20899
20918
  setCurrentConversationId(id) {
@@ -20942,9 +20961,9 @@ var HistoryService = class _HistoryService {
20942
20961
  const dir = this.projectDir;
20943
20962
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
20944
20963
  try {
20945
- const files = fs43.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
20964
+ const files = fs44.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
20946
20965
  try {
20947
- const stat3 = fs43.statSync(path50.join(dir, e.name));
20966
+ const stat3 = fs44.statSync(path50.join(dir, e.name));
20948
20967
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
20949
20968
  } catch {
20950
20969
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -20985,13 +21004,13 @@ var HistoryService = class _HistoryService {
20985
21004
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
20986
21005
  let entries;
20987
21006
  try {
20988
- entries = fs43.readdirSync(dir, { withFileTypes: true });
21007
+ entries = fs44.readdirSync(dir, { withFileTypes: true });
20989
21008
  } catch {
20990
21009
  return null;
20991
21010
  }
20992
21011
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
20993
21012
  try {
20994
- const stat3 = fs43.statSync(path50.join(dir, e.name));
21013
+ const stat3 = fs44.statSync(path50.join(dir, e.name));
20995
21014
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
20996
21015
  } catch {
20997
21016
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -21005,7 +21024,7 @@ var HistoryService = class _HistoryService {
21005
21024
  extractUsageFromFile(filePath) {
21006
21025
  let raw;
21007
21026
  try {
21008
- raw = fs43.readFileSync(filePath, "utf8");
21027
+ raw = fs44.readFileSync(filePath, "utf8");
21009
21028
  } catch {
21010
21029
  return null;
21011
21030
  }
@@ -21050,9 +21069,9 @@ var HistoryService = class _HistoryService {
21050
21069
  let totalCost = 0;
21051
21070
  let files;
21052
21071
  try {
21053
- files = fs43.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21072
+ files = fs44.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
21054
21073
  try {
21055
- return fs43.statSync(path50.join(projectDir, f)).mtimeMs >= monthStartMs;
21074
+ return fs44.statSync(path50.join(projectDir, f)).mtimeMs >= monthStartMs;
21056
21075
  } catch {
21057
21076
  return false;
21058
21077
  }
@@ -21063,7 +21082,7 @@ var HistoryService = class _HistoryService {
21063
21082
  for (const file of files) {
21064
21083
  let raw;
21065
21084
  try {
21066
- raw = fs43.readFileSync(path50.join(projectDir, file), "utf8");
21085
+ raw = fs44.readFileSync(path50.join(projectDir, file), "utf8");
21067
21086
  } catch {
21068
21087
  continue;
21069
21088
  }
@@ -21232,7 +21251,7 @@ var HistoryService = class _HistoryService {
21232
21251
  if (!filePath) return false;
21233
21252
  let mtimeMs;
21234
21253
  try {
21235
- mtimeMs = fs43.statSync(filePath).mtimeMs;
21254
+ mtimeMs = fs44.statSync(filePath).mtimeMs;
21236
21255
  } catch {
21237
21256
  return false;
21238
21257
  }
@@ -21300,10 +21319,10 @@ var HistoryService = class _HistoryService {
21300
21319
  };
21301
21320
 
21302
21321
  // src/agents/acp/client.ts
21303
- var import_node_child_process16 = require("child_process");
21304
- var fs44 = __toESM(require("fs/promises"));
21322
+ var import_node_child_process17 = require("child_process");
21323
+ var fs45 = __toESM(require("fs/promises"));
21305
21324
  var fsSync = __toESM(require("fs"));
21306
- var os37 = __toESM(require("os"));
21325
+ var os38 = __toESM(require("os"));
21307
21326
  var path51 = __toESM(require("path"));
21308
21327
  var import_node_stream = require("stream");
21309
21328
 
@@ -23851,7 +23870,7 @@ var AcpClient = class {
23851
23870
  "acpClient",
23852
23871
  `spawn cmd=${adapter.command} args=[${adapter.args.join(",")}] cwd=${cwd}`
23853
23872
  );
23854
- const child = (0, import_node_child_process16.spawn)(adapter.command, adapter.args, {
23873
+ const child = (0, import_node_child_process17.spawn)(adapter.command, adapter.args, {
23855
23874
  cwd,
23856
23875
  // extraEnv (e.g. CLAUDE_CODE_DISABLE_1M_CONTEXT=1 on an on-demand
23857
23876
  // re-spawn) layers over process.env; PATH stays last so the augmented
@@ -24137,7 +24156,7 @@ var AcpClient = class {
24137
24156
  },
24138
24157
  readTextFile: async (params) => {
24139
24158
  try {
24140
- const content = await fs44.readFile(params.path, "utf8");
24159
+ const content = await fs45.readFile(params.path, "utf8");
24141
24160
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
24142
24161
  } catch (err) {
24143
24162
  const code = err.code;
@@ -24157,7 +24176,7 @@ var AcpClient = class {
24157
24176
  },
24158
24177
  writeTextFile: async (params) => {
24159
24178
  try {
24160
- await fs44.writeFile(params.path, params.content, "utf8");
24179
+ await fs45.writeFile(params.path, params.content, "utf8");
24161
24180
  return {};
24162
24181
  } catch (err) {
24163
24182
  const code = err.code;
@@ -24206,7 +24225,7 @@ function applyLineRange(content, line, limit) {
24206
24225
  return { content: lines.slice(start2, end).join("\n") };
24207
24226
  }
24208
24227
  function knownAgentBinaryDirs() {
24209
- const home = os37.homedir();
24228
+ const home = os38.homedir();
24210
24229
  const out2 = [];
24211
24230
  out2.push("/tmp/codeam-node20/bin");
24212
24231
  for (const root of [
@@ -24730,15 +24749,15 @@ function commonPrefixLength(a, b) {
24730
24749
 
24731
24750
  // src/agents/acp/onboarding.ts
24732
24751
  var import_child_process22 = require("child_process");
24733
- var fs45 = __toESM(require("fs"));
24734
- var os38 = __toESM(require("os"));
24752
+ var fs46 = __toESM(require("fs"));
24753
+ var os39 = __toESM(require("os"));
24735
24754
  var path52 = __toESM(require("path"));
24736
24755
  var _onboardingSeam = {
24737
- markerPath: (sessionId) => path52.join(os38.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
24738
- exists: (p2) => fs45.existsSync(p2),
24756
+ markerPath: (sessionId) => path52.join(os39.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
24757
+ exists: (p2) => fs46.existsSync(p2),
24739
24758
  write: (p2) => {
24740
- fs45.mkdirSync(path52.dirname(p2), { recursive: true });
24741
- fs45.writeFileSync(p2, "");
24759
+ fs46.mkdirSync(path52.dirname(p2), { recursive: true });
24760
+ fs46.writeFileSync(p2, "");
24742
24761
  },
24743
24762
  disabled: () => {
24744
24763
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -25068,7 +25087,7 @@ var import_crypto5 = require("crypto");
25068
25087
 
25069
25088
  // src/services/turn-files/git-changeset.ts
25070
25089
  var import_child_process23 = require("child_process");
25071
- var fs46 = __toESM(require("fs/promises"));
25090
+ var fs47 = __toESM(require("fs/promises"));
25072
25091
  var path53 = __toESM(require("path"));
25073
25092
  async function collectRepoChangeset(opts) {
25074
25093
  const status2 = await runGit3(opts.repoRoot, ["status", "--porcelain=v1", "-z"]);
@@ -25118,7 +25137,7 @@ function readUntrackedLineCount(absPath) {
25118
25137
  }
25119
25138
  async function defaultReadUntrackedLineCount(absPath) {
25120
25139
  try {
25121
- const content = await fs46.readFile(absPath, "utf8");
25140
+ const content = await fs47.readFile(absPath, "utf8");
25122
25141
  let count = 0;
25123
25142
  let pos = -1;
25124
25143
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -25210,7 +25229,7 @@ function defaultRunGit(cwd, args2) {
25210
25229
  });
25211
25230
  }
25212
25231
  async function discoverRepos(workingDir, maxDepth = 4) {
25213
- const fs50 = await import("fs/promises");
25232
+ const fs51 = await import("fs/promises");
25214
25233
  const out2 = [];
25215
25234
  await walk(workingDir, 0);
25216
25235
  return out2;
@@ -25218,7 +25237,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25218
25237
  if (depth > maxDepth) return;
25219
25238
  let entries = [];
25220
25239
  try {
25221
- const dirents = await fs50.readdir(dir, { withFileTypes: true });
25240
+ const dirents = await fs51.readdir(dir, { withFileTypes: true });
25222
25241
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
25223
25242
  } catch {
25224
25243
  return;
@@ -25244,7 +25263,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
25244
25263
  }
25245
25264
 
25246
25265
  // src/services/turn-files/files-outbox.ts
25247
- var fs47 = __toESM(require("fs/promises"));
25266
+ var fs48 = __toESM(require("fs/promises"));
25248
25267
  var path54 = __toESM(require("path"));
25249
25268
  var import_os7 = require("os");
25250
25269
  var HOME_OUTBOX_DIR = ".codeam/outbox";
@@ -25286,8 +25305,8 @@ var FilesOutbox = class {
25286
25305
  /** Persist the entry to disk and trigger a flush. Returns once the
25287
25306
  * line is durable on disk (not once the POST succeeds). */
25288
25307
  async enqueue(entry) {
25289
- await fs47.mkdir(path54.dirname(this.filePath), { recursive: true });
25290
- await fs47.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25308
+ await fs48.mkdir(path54.dirname(this.filePath), { recursive: true });
25309
+ await fs48.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
25291
25310
  this.backoffIndex = 0;
25292
25311
  if (this.autoSchedule) this.scheduleFlush(0);
25293
25312
  }
@@ -25376,7 +25395,7 @@ var FilesOutbox = class {
25376
25395
  async readAll() {
25377
25396
  let raw = "";
25378
25397
  try {
25379
- raw = await fs47.readFile(this.filePath, "utf8");
25398
+ raw = await fs48.readFile(this.filePath, "utf8");
25380
25399
  } catch {
25381
25400
  return [];
25382
25401
  }
@@ -25400,12 +25419,12 @@ var FilesOutbox = class {
25400
25419
  async rewrite(entries) {
25401
25420
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
25402
25421
  if (entries.length === 0) {
25403
- await fs47.unlink(this.filePath).catch(() => void 0);
25422
+ await fs48.unlink(this.filePath).catch(() => void 0);
25404
25423
  return;
25405
25424
  }
25406
25425
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
25407
- await fs47.writeFile(tmpPath, payload, "utf8");
25408
- await fs47.rename(tmpPath, this.filePath);
25426
+ await fs48.writeFile(tmpPath, payload, "utf8");
25427
+ await fs48.rename(tmpPath, this.filePath);
25409
25428
  }
25410
25429
  };
25411
25430
  function applyJitter(ms) {
@@ -28034,15 +28053,15 @@ function fetchQuotaUsage(runtime, historySvc) {
28034
28053
  }
28035
28054
 
28036
28055
  // src/agents/claude/onboarding.ts
28037
- var fs48 = __toESM(require("fs"));
28038
- var os39 = __toESM(require("os"));
28056
+ var fs49 = __toESM(require("fs"));
28057
+ var os40 = __toESM(require("os"));
28039
28058
  var path55 = __toESM(require("path"));
28040
28059
  function ensureClaudeOnboarded() {
28041
28060
  try {
28042
- const file = path55.join(os39.homedir(), ".claude.json");
28061
+ const file = path55.join(os40.homedir(), ".claude.json");
28043
28062
  let config = {};
28044
28063
  try {
28045
- config = JSON.parse(fs48.readFileSync(file, "utf8"));
28064
+ config = JSON.parse(fs49.readFileSync(file, "utf8"));
28046
28065
  } catch {
28047
28066
  }
28048
28067
  if (config.hasCompletedOnboarding === true && typeof config.theme === "string") {
@@ -28053,8 +28072,8 @@ function ensureClaudeOnboarded() {
28053
28072
  if (typeof config.lastOnboardingVersion !== "string") {
28054
28073
  config.lastOnboardingVersion = "2.1.177";
28055
28074
  }
28056
- fs48.mkdirSync(path55.dirname(file), { recursive: true });
28057
- fs48.writeFileSync(file, JSON.stringify(config, null, 2));
28075
+ fs49.mkdirSync(path55.dirname(file), { recursive: true });
28076
+ fs49.writeFileSync(file, JSON.stringify(config, null, 2));
28058
28077
  log.info("claude", "pre-completed Claude onboarding (skip first-run theme picker)");
28059
28078
  } catch (err) {
28060
28079
  log.warn("claude", `ensureClaudeOnboarded failed (non-fatal): ${err.message}`);
@@ -30749,7 +30768,7 @@ async function invite() {
30749
30768
  var import_node_dns = require("dns");
30750
30769
  var import_node_util5 = require("util");
30751
30770
  var import_node_crypto8 = require("crypto");
30752
- var fs49 = __toESM(require("fs"));
30771
+ var fs50 = __toESM(require("fs"));
30753
30772
  var path60 = __toESM(require("path"));
30754
30773
  var import_picocolors14 = __toESM(require("picocolors"));
30755
30774
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
@@ -30808,11 +30827,11 @@ async function checkHealth(apiBase2) {
30808
30827
  function checkConfigDir() {
30809
30828
  const dir = path60.join(require("os").homedir(), ".codeam");
30810
30829
  try {
30811
- fs49.mkdirSync(dir, { recursive: true, mode: 448 });
30830
+ fs50.mkdirSync(dir, { recursive: true, mode: 448 });
30812
30831
  const probe = path60.join(dir, ".doctor-probe");
30813
- fs49.writeFileSync(probe, "ok", { mode: 384 });
30814
- const read2 = fs49.readFileSync(probe, "utf8");
30815
- fs49.unlinkSync(probe);
30832
+ fs50.writeFileSync(probe, "ok", { mode: 384 });
30833
+ const read2 = fs50.readFileSync(probe, "utf8");
30834
+ fs50.unlinkSync(probe);
30816
30835
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
30817
30836
  return {
30818
30837
  id: "config-dir",
@@ -30852,9 +30871,9 @@ function checkSessions() {
30852
30871
  }
30853
30872
  }
30854
30873
  function checkAgentBinaries() {
30855
- const os41 = createOsStrategy();
30874
+ const os42 = createOsStrategy();
30856
30875
  return getEnabledAgents().map((meta) => {
30857
- const found = os41.findInPath(meta.binaryName);
30876
+ const found = os42.findInPath(meta.binaryName);
30858
30877
  return {
30859
30878
  id: `agent-${meta.id}`,
30860
30879
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -30918,7 +30937,7 @@ function checkChokidar() {
30918
30937
  }
30919
30938
  async function doctor(args2 = []) {
30920
30939
  const json = args2.includes("--json");
30921
- const cliVersion = true ? "2.51.0" : "0.0.0-dev";
30940
+ const cliVersion = true ? "2.51.1" : "0.0.0-dev";
30922
30941
  const apiBase2 = resolveApiBaseUrl();
30923
30942
  const diagnosticId = (0, import_node_crypto8.randomUUID)();
30924
30943
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -31117,7 +31136,7 @@ async function completion(args2) {
31117
31136
  // src/commands/version.ts
31118
31137
  var import_picocolors15 = __toESM(require("picocolors"));
31119
31138
  function version2() {
31120
- const v = true ? "2.51.0" : "unknown";
31139
+ const v = true ? "2.51.1" : "unknown";
31121
31140
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
31122
31141
  }
31123
31142
 
@@ -31266,10 +31285,10 @@ var EXIT_CODE_NAMES = {
31266
31285
  };
31267
31286
 
31268
31287
  // src/index.ts
31269
- var os40 = __toESM(require("os"));
31288
+ var os41 = __toESM(require("os"));
31270
31289
  if (!process.env.HOME) {
31271
31290
  try {
31272
- const home = os40.homedir();
31291
+ const home = os41.homedir();
31273
31292
  if (home) process.env.HOME = home;
31274
31293
  } catch {
31275
31294
  }