codeam-cli 2.75.26 → 2.75.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/index.js +851 -659
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -357,8 +357,8 @@ function defaultSpawn(timeoutMs) {
357
357
  });
358
358
  }
359
359
  function resolveConvexBin(cwd) {
360
- const local = path94.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
361
- if (fs80.existsSync(local)) return { cmd: local, args: [] };
360
+ const local = path95.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
361
+ if (fs81.existsSync(local)) return { cmd: local, args: [] };
362
362
  return { cmd: "npx", args: ["--yes", "convex"] };
363
363
  }
364
364
  function redact(text, key) {
@@ -489,13 +489,13 @@ async function runConvexAdminMcp(client3, id) {
489
489
  });
490
490
  await server.connect(new StdioServerTransport());
491
491
  }
492
- var import_node_child_process32, fs80, path94, TOOLS;
492
+ var import_node_child_process32, fs81, path95, TOOLS;
493
493
  var init_convex_admin_mcp = __esm({
494
494
  "src/integrations/convex-admin-mcp.ts"() {
495
495
  "use strict";
496
496
  import_node_child_process32 = require("child_process");
497
- fs80 = __toESM(require("fs"));
498
- path94 = __toESM(require("path"));
497
+ fs81 = __toESM(require("fs"));
498
+ path95 = __toESM(require("path"));
499
499
  TOOLS = [
500
500
  {
501
501
  name: "tables",
@@ -3431,6 +3431,9 @@ function maybeRotate() {
3431
3431
  } catch {
3432
3432
  return;
3433
3433
  }
3434
+ rotateNow();
3435
+ }
3436
+ function rotateNow() {
3434
3437
  const archivePath = (n) => n === 0 ? `${debugFilePath}.old` : `${debugFilePath}.${n}`;
3435
3438
  for (let i = MAX_ARCHIVES - 1; i >= 0; i--) {
3436
3439
  const src = archivePath(i);
@@ -3454,6 +3457,7 @@ function appendToFile(line) {
3454
3457
  try {
3455
3458
  if (!fileInitialized) {
3456
3459
  fs.mkdirSync(path.dirname(debugFilePath), { recursive: true, mode: 448 });
3460
+ if (fs.existsSync(debugFilePath)) rotateNow();
3457
3461
  const header = jsonMode ? `${JSON.stringify({
3458
3462
  ts: (/* @__PURE__ */ new Date()).toISOString(),
3459
3463
  level: "info",
@@ -3528,11 +3532,11 @@ function quiet(fn) {
3528
3532
  log.debug(TAG, "ignored sync error", err);
3529
3533
  }
3530
3534
  }
3531
- function rmIfExistsQuiet(path96) {
3535
+ function rmIfExistsQuiet(path97) {
3532
3536
  try {
3533
- fs2.rmSync(path96, { force: true });
3537
+ fs2.rmSync(path97, { force: true });
3534
3538
  } catch (err) {
3535
- log.debug(TAG, `rmIfExists failed for ${path96}`, err);
3539
+ log.debug(TAG, `rmIfExists failed for ${path97}`, err);
3536
3540
  }
3537
3541
  }
3538
3542
  function killQuiet(target, signal = "SIGTERM") {
@@ -3736,8 +3740,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
3736
3740
  return decodedFile;
3737
3741
  };
3738
3742
  }
3739
- function normalizeWindowsPath(path96) {
3740
- return path96.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3743
+ function normalizeWindowsPath(path97) {
3744
+ return path97.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3741
3745
  }
3742
3746
 
3743
3747
  // ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
@@ -6470,13 +6474,13 @@ var PostHogCoreStateless = class {
6470
6474
  sentFromRoute += batchMessages.length;
6471
6475
  }
6472
6476
  }
6473
- async _sendOtlpBatch({ path: path96, payload }) {
6477
+ async _sendOtlpBatch({ path: path97, payload }) {
6474
6478
  if (this.disabled) return {
6475
6479
  kind: "fatal",
6476
6480
  error: new Error("The client is disabled")
6477
6481
  };
6478
6482
  const serialized = JSON.stringify(payload);
6479
- const url2 = `${this.host}/i/v1/${path96}?token=${encodeURIComponent(this.apiKey)}`;
6483
+ const url2 = `${this.host}/i/v1/${path97}?token=${encodeURIComponent(this.apiKey)}`;
6480
6484
  const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
6481
6485
  const fetchOptions = {
6482
6486
  method: "POST",
@@ -7716,14 +7720,14 @@ async function addSourceContext(frames, openSourceFile = import_promises.open, l
7716
7720
  LRU_FILE_CONTENTS_CACHE.reduce();
7717
7721
  return frames;
7718
7722
  }
7719
- async function openRegularSourceFile(path96, openSourceFile, logger) {
7723
+ async function openRegularSourceFile(path97, openSourceFile, logger) {
7720
7724
  let fileHandle;
7721
7725
  let isValid = false;
7722
7726
  try {
7723
- fileHandle = await openSourceFile(path96, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
7727
+ fileHandle = await openSourceFile(path97, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
7724
7728
  const fileStat = await fileHandle.stat();
7725
7729
  if (!fileStat.isFile()) return;
7726
- if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path96}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
7730
+ if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path97}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
7727
7731
  isValid = true;
7728
7732
  return fileHandle;
7729
7733
  } catch {
@@ -7733,8 +7737,8 @@ async function openRegularSourceFile(path96, openSourceFile, logger) {
7733
7737
  });
7734
7738
  }
7735
7739
  }
7736
- async function getContextLinesFromFile(path96, ranges, output, cacheKey, openSourceFile, logger) {
7737
- const fileHandle = await openRegularSourceFile(path96, openSourceFile, logger);
7740
+ async function getContextLinesFromFile(path97, ranges, output, cacheKey, openSourceFile, logger) {
7741
+ const fileHandle = await openRegularSourceFile(path97, openSourceFile, logger);
7738
7742
  if (void 0 === fileHandle) return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
7739
7743
  const openedFileHandle = fileHandle;
7740
7744
  return new Promise((resolve12) => {
@@ -7836,22 +7840,22 @@ function clearLineContext(frame) {
7836
7840
  delete frame.context_line;
7837
7841
  delete frame.post_context;
7838
7842
  }
7839
- function shouldSkipContextLinesForFile(path96) {
7840
- return path96.startsWith("node:") || path96.endsWith(".min.js") || path96.endsWith(".min.cjs") || path96.endsWith(".min.mjs") || path96.startsWith("data:");
7843
+ function shouldSkipContextLinesForFile(path97) {
7844
+ return path97.startsWith("node:") || path97.endsWith(".min.js") || path97.endsWith(".min.cjs") || path97.endsWith(".min.mjs") || path97.startsWith("data:");
7841
7845
  }
7842
7846
  function shouldSkipContextLinesForFrame(frame) {
7843
7847
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
7844
7848
  if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
7845
7849
  return false;
7846
7850
  }
7847
- function makeSourceCacheKey(path96, basePath) {
7848
- if ((0, import_node_path.isAbsolute)(path96)) return JSON.stringify([
7851
+ function makeSourceCacheKey(path97, basePath) {
7852
+ if ((0, import_node_path.isAbsolute)(path97)) return JSON.stringify([
7849
7853
  null,
7850
- path96
7854
+ path97
7851
7855
  ]);
7852
7856
  return void 0 === basePath ? void 0 : JSON.stringify([
7853
7857
  basePath,
7854
- path96
7858
+ path97
7855
7859
  ]);
7856
7860
  }
7857
7861
  function rangeExistsInContentCache(cacheKey, range) {
@@ -10512,7 +10516,7 @@ function readAnonId() {
10512
10516
  }
10513
10517
  function superProperties() {
10514
10518
  return {
10515
- cliVersion: true ? "2.75.26" : "0.0.0-dev",
10519
+ cliVersion: true ? "2.75.27" : "0.0.0-dev",
10516
10520
  nodeVersion: process.version,
10517
10521
  platform: process.platform,
10518
10522
  arch: process.arch,
@@ -10754,7 +10758,7 @@ var http = __toESM(require("http"));
10754
10758
  // package.json
10755
10759
  var package_default = {
10756
10760
  name: "codeam-cli",
10757
- version: "2.75.26",
10761
+ version: "2.75.27",
10758
10762
  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.",
10759
10763
  type: "commonjs",
10760
10764
  main: "dist/index.js",
@@ -12084,7 +12088,7 @@ var CommandRelayService = class _CommandRelayService {
12084
12088
  // fresh + clear the "CLI update available" banner after a self-update
12085
12089
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
12086
12090
  // pair/reconnect). Older backends ignore the extra field.
12087
- ..."2.75.26" ? { ideVersion: "2.75.26" } : {}
12091
+ ..."2.75.27" ? { ideVersion: "2.75.27" } : {}
12088
12092
  };
12089
12093
  try {
12090
12094
  const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
@@ -12390,10 +12394,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
12390
12394
  /[\\/]Start Menu([\\/]|$)/i,
12391
12395
  /[\\/]Templates([\\/]|$)/i
12392
12396
  ];
12393
- function isUnsafeWindowsWatchRoot(dir, homedir51) {
12397
+ function isUnsafeWindowsWatchRoot(dir, homedir52) {
12394
12398
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
12395
12399
  const cwd = norm(dir);
12396
- const home = norm(homedir51);
12400
+ const home = norm(homedir52);
12397
12401
  if (cwd === home) return true;
12398
12402
  if (/^[a-z]:$/.test(cwd)) return true;
12399
12403
  const sysRoots = [
@@ -17123,10 +17127,10 @@ function buildForPlatform(platform3) {
17123
17127
  var import_node_crypto4 = require("crypto");
17124
17128
 
17125
17129
  // src/agents/claude/resolver.ts
17126
- function buildClaudeLaunch(extraArgs = [], os65 = createOsStrategy()) {
17127
- const found = os65.findInPath("claude") ?? os65.findInPath("claude-code");
17130
+ function buildClaudeLaunch(extraArgs = [], os66 = createOsStrategy()) {
17131
+ const found = os66.findInPath("claude") ?? os66.findInPath("claude-code");
17128
17132
  if (!found) return null;
17129
- return os65.buildLaunch(found, extraArgs);
17133
+ return os66.buildLaunch(found, extraArgs);
17130
17134
  }
17131
17135
 
17132
17136
  // src/agents/claude/installer.ts
@@ -17904,8 +17908,8 @@ var ClaudeRuntimeStrategy = class {
17904
17908
  meta = getAgent("claude");
17905
17909
  mode = "interactive";
17906
17910
  os;
17907
- constructor(os65) {
17908
- this.os = os65;
17911
+ constructor(os66) {
17912
+ this.os = os66;
17909
17913
  }
17910
17914
  /**
17911
17915
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -18999,8 +19003,8 @@ function codexCredentialLocator() {
18999
19003
  function codexLoginLauncher() {
19000
19004
  return {
19001
19005
  async ensureInstalled() {
19002
- const os65 = createOsStrategy();
19003
- return os65.findInPath("codex") !== null;
19006
+ const os66 = createOsStrategy();
19007
+ return os66.findInPath("codex") !== null;
19004
19008
  },
19005
19009
  launch() {
19006
19010
  return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -19023,8 +19027,8 @@ var CodexRuntimeStrategy = class {
19023
19027
  meta = getAgent("codex");
19024
19028
  mode = "interactive";
19025
19029
  os;
19026
- constructor(os65) {
19027
- this.os = os65;
19030
+ constructor(os66) {
19031
+ this.os = os66;
19028
19032
  }
19029
19033
  async prepareLaunch() {
19030
19034
  let binary = this.os.findInPath("codex");
@@ -19134,12 +19138,12 @@ var CodexRuntimeStrategy = class {
19134
19138
  });
19135
19139
  }
19136
19140
  };
19137
- function resolveNpm(os65) {
19138
- return os65.id === "win32" ? "npm.cmd" : "npm";
19141
+ function resolveNpm(os66) {
19142
+ return os66.id === "win32" ? "npm.cmd" : "npm";
19139
19143
  }
19140
- async function installCodexViaNpm(os65) {
19144
+ async function installCodexViaNpm(os66) {
19141
19145
  return new Promise((resolve12, reject) => {
19142
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os65), ["install", "-g", "@openai/codex"], {
19146
+ const proc = (0, import_node_child_process4.spawn)(resolveNpm(os66), ["install", "-g", "@openai/codex"], {
19143
19147
  stdio: "inherit"
19144
19148
  });
19145
19149
  proc.on("close", (code) => {
@@ -19156,16 +19160,16 @@ async function installCodexViaNpm(os65) {
19156
19160
  });
19157
19161
  });
19158
19162
  }
19159
- function augmentNpmGlobalBin(os65) {
19163
+ function augmentNpmGlobalBin(os66) {
19160
19164
  try {
19161
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os65), ["prefix", "-g"], {
19165
+ const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os66), ["prefix", "-g"], {
19162
19166
  stdio: ["ignore", "pipe", "ignore"]
19163
19167
  });
19164
19168
  if (result.status !== 0) return;
19165
19169
  const prefix = result.stdout.toString().trim();
19166
19170
  if (!prefix) return;
19167
- const binDir = os65.id === "win32" ? prefix : path24.join(prefix, "bin");
19168
- os65.augmentPath([binDir]);
19171
+ const binDir = os66.id === "win32" ? prefix : path24.join(prefix, "bin");
19172
+ os66.augmentPath([binDir]);
19169
19173
  } catch {
19170
19174
  }
19171
19175
  }
@@ -19359,10 +19363,10 @@ function manualInstallHint(runner, tools) {
19359
19363
  const argv = osPackageInstallArgv(detectPackageManager(runner), [...tools]);
19360
19364
  return argv ? `\`sudo ${argv.join(" ")}\`` : `your package manager (e.g. \`${pkgs}\`)`;
19361
19365
  }
19362
- function writeUnzipShim(os65, runner) {
19366
+ function writeUnzipShim(os66, runner) {
19363
19367
  const python = ["python3", "python"].find((p2) => runner.which(p2));
19364
19368
  if (!python) return null;
19365
- const dir = os65.scratchPath("codeam-cr-prereq");
19369
+ const dir = os66.scratchPath("codeam-cr-prereq");
19366
19370
  const shim = path26.join(dir, "unzip");
19367
19371
  const script = `#!/bin/sh
19368
19372
  set -e
@@ -19384,9 +19388,9 @@ exec ${python} -m zipfile -e "$archive" "$dest"
19384
19388
  (0, import_node_fs5.chmodSync)(shim, 448);
19385
19389
  return dir;
19386
19390
  }
19387
- async function ensureInstallPrerequisites(os65, deps = {}) {
19391
+ async function ensureInstallPrerequisites(os66, deps = {}) {
19388
19392
  const runner = deps.runner ?? defaultOsRunner;
19389
- const missing = REQUIRED_TOOLS.filter((t2) => os65.findInPath(t2) === null);
19393
+ const missing = REQUIRED_TOOLS.filter((t2) => os66.findInPath(t2) === null);
19390
19394
  if (missing.length === 0) return { ok: true, extraPath: [] };
19391
19395
  log.info(
19392
19396
  "coderabbit",
@@ -19405,10 +19409,10 @@ async function ensureInstallPrerequisites(os65, deps = {}) {
19405
19409
  );
19406
19410
  }
19407
19411
  }
19408
- const stillMissing = REQUIRED_TOOLS.filter((t2) => os65.findInPath(t2) === null);
19412
+ const stillMissing = REQUIRED_TOOLS.filter((t2) => os66.findInPath(t2) === null);
19409
19413
  if (stillMissing.length === 0) return { ok: true, extraPath: [] };
19410
19414
  if (stillMissing.length === 1 && stillMissing[0] === "unzip") {
19411
- const shimDir = writeUnzipShim(os65, runner);
19415
+ const shimDir = writeUnzipShim(os66, runner);
19412
19416
  if (shimDir) {
19413
19417
  log.info("coderabbit", "unzip is unavailable \u2014 using a scoped python zipfile shim");
19414
19418
  return { ok: true, extraPath: [shimDir] };
@@ -19471,15 +19475,15 @@ function summarizeInstallFailure(output) {
19471
19475
  }
19472
19476
  return lines.length > 0 ? lines[lines.length - 1] : null;
19473
19477
  }
19474
- async function ensureCoderabbitInstalled(os65, deps = {}) {
19475
- if (os65.findInPath("coderabbit")) return { ok: true };
19476
- if (os65.id === "win32") {
19478
+ async function ensureCoderabbitInstalled(os66, deps = {}) {
19479
+ if (os66.findInPath("coderabbit")) return { ok: true };
19480
+ if (os66.id === "win32") {
19477
19481
  return {
19478
19482
  ok: false,
19479
19483
  error: "CodeRabbit on Windows requires WSL. Install the CLI inside your WSL distribution (curl -fsSL https://cli.coderabbit.ai/install.sh | sh), then try again."
19480
19484
  };
19481
19485
  }
19482
- const prereq = await ensureInstallPrerequisites(os65, deps);
19486
+ const prereq = await ensureInstallPrerequisites(os66, deps);
19483
19487
  if (!prereq.ok) return { ok: false, error: prereq.error };
19484
19488
  const env = { ...process.env };
19485
19489
  if (prereq.extraPath.length > 0) {
@@ -19488,8 +19492,8 @@ async function ensureCoderabbitInstalled(os65, deps = {}) {
19488
19492
  log.info("coderabbit", "CodeRabbit CLI not found \u2014 installing via the official script");
19489
19493
  const run = deps.runInstallScript ?? defaultRunInstallScript;
19490
19494
  const { code, output } = await run(env);
19491
- os65.augmentPath([`${os65.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
19492
- const binary = os65.findInPath("coderabbit");
19495
+ os66.augmentPath([`${os66.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
19496
+ const binary = os66.findInPath("coderabbit");
19493
19497
  const detail = summarizeInstallFailure(output);
19494
19498
  if (binary !== null) {
19495
19499
  if (code === 0) return { ok: true };
@@ -19543,10 +19547,10 @@ function coderabbitCredentialLocator() {
19543
19547
  validate: validateNonEmptyCredential
19544
19548
  };
19545
19549
  }
19546
- function coderabbitLoginLauncher(os65) {
19550
+ function coderabbitLoginLauncher(os66) {
19547
19551
  return {
19548
19552
  async ensureInstalled() {
19549
- const result = await ensureCoderabbitInstalled(os65);
19553
+ const result = await ensureCoderabbitInstalled(os66);
19550
19554
  if (!result.ok && result.error) console.error(`
19551
19555
  \u2717 ${result.error}
19552
19556
  `);
@@ -19606,8 +19610,8 @@ function pickLine(obj) {
19606
19610
  function toHunk(raw, groupSeverity) {
19607
19611
  if (!raw || typeof raw !== "object") return null;
19608
19612
  const o = raw;
19609
- const path96 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
19610
- if (!path96) return null;
19613
+ const path97 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
19614
+ if (!path97) return null;
19611
19615
  const message = asString(
19612
19616
  pick(o, [
19613
19617
  "comment",
@@ -19624,7 +19628,7 @@ function toHunk(raw, groupSeverity) {
19624
19628
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
19625
19629
  const locObj = pick(o, ["location"]) ?? o;
19626
19630
  return {
19627
- path: path96.trim(),
19631
+ path: path97.trim(),
19628
19632
  line: pickLine(o) ?? pickLine(locObj),
19629
19633
  severity,
19630
19634
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -19707,10 +19711,10 @@ function parsePlain(stdout) {
19707
19711
  for (const line of stdout.split(/\r?\n/)) {
19708
19712
  const m = line.match(HUNK_LINE_RE);
19709
19713
  if (!m) continue;
19710
- const [, path96, lineNo, sevToken, message] = m;
19711
- if (!path96 || !lineNo || !message) continue;
19714
+ const [, path97, lineNo, sevToken, message] = m;
19715
+ if (!path97 || !lineNo || !message) continue;
19712
19716
  hunks.push({
19713
- path: path96.trim(),
19717
+ path: path97.trim(),
19714
19718
  line: Number(lineNo),
19715
19719
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
19716
19720
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -19770,8 +19774,8 @@ var CoderabbitRuntimeStrategy = class {
19770
19774
  meta = getAgent("coderabbit");
19771
19775
  mode = "batch";
19772
19776
  os;
19773
- constructor(os65) {
19774
- this.os = os65;
19777
+ constructor(os66) {
19778
+ this.os = os66;
19775
19779
  }
19776
19780
  getDefaultArgs() {
19777
19781
  return ["review", "--agent"];
@@ -20042,10 +20046,10 @@ function cursorCredentialLocator() {
20042
20046
  validate: validateNonEmptyCredential
20043
20047
  };
20044
20048
  }
20045
- function cursorLoginLauncher(os65) {
20049
+ function cursorLoginLauncher(os66) {
20046
20050
  return {
20047
20051
  async ensureInstalled() {
20048
- if (os65.findInPath("cursor-agent")) return true;
20052
+ if (os66.findInPath("cursor-agent")) return true;
20049
20053
  console.error(
20050
20054
  "\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"
20051
20055
  );
@@ -20109,8 +20113,8 @@ var CursorRuntimeStrategy = class {
20109
20113
  meta = getAgent("cursor");
20110
20114
  mode = "interactive";
20111
20115
  os;
20112
- constructor(os65) {
20113
- this.os = os65;
20116
+ constructor(os66) {
20117
+ this.os = os66;
20114
20118
  }
20115
20119
  async prepareLaunch() {
20116
20120
  const binary = this.os.findInPath("cursor-agent");
@@ -20327,10 +20331,10 @@ function aiderCredentialLocator() {
20327
20331
  validate: validateNonEmptyCredential
20328
20332
  };
20329
20333
  }
20330
- function aiderLoginLauncher(os65) {
20334
+ function aiderLoginLauncher(os66) {
20331
20335
  return {
20332
20336
  async ensureInstalled() {
20333
- if (os65.findInPath("aider")) return true;
20337
+ if (os66.findInPath("aider")) return true;
20334
20338
  console.error(
20335
20339
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
20336
20340
  );
@@ -20340,7 +20344,7 @@ function aiderLoginLauncher(os65) {
20340
20344
  console.error(
20341
20345
  "\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"
20342
20346
  );
20343
- return (0, import_node_child_process11.spawn)(os65.id === "win32" ? "cmd.exe" : "sh", os65.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
20347
+ return (0, import_node_child_process11.spawn)(os66.id === "win32" ? "cmd.exe" : "sh", os66.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
20344
20348
  stdio: "ignore"
20345
20349
  });
20346
20350
  }
@@ -20429,14 +20433,14 @@ function defaultSdkDir() {
20429
20433
  return resolveSdkDirViaRequire();
20430
20434
  }
20431
20435
  function resolveClaudeNativeBinary(deps = {}) {
20432
- const existsSync28 = deps.existsSync ?? import_fs.default.existsSync;
20436
+ const existsSync30 = deps.existsSync ?? import_fs.default.existsSync;
20433
20437
  const platformKey = deps.platformKey ?? currentPlatformKey();
20434
20438
  const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
20435
20439
  if (!sdkDir) return null;
20436
20440
  const scopeDir = import_path4.default.dirname(sdkDir);
20437
20441
  const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
20438
20442
  const candidate = import_path4.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
20439
- return existsSync28(candidate) ? candidate : null;
20443
+ return existsSync30(candidate) ? candidate : null;
20440
20444
  }
20441
20445
  var realSleep = (ms) => new Promise((resolve12) => setTimeout(resolve12, ms));
20442
20446
  async function waitForClaudeNativeBinary(opts = {}) {
@@ -20518,18 +20522,18 @@ function augmentUserLocalBinPaths(deps = {}) {
20518
20522
  env.PATH = [...additions, ...parts].join(p2.delimiter);
20519
20523
  }
20520
20524
  function resolveCursorAgentBinary(deps = {}) {
20521
- const existsSync28 = deps.existsSync ?? import_fs.default.existsSync;
20525
+ const existsSync30 = deps.existsSync ?? import_fs.default.existsSync;
20522
20526
  const platform3 = deps.platform ?? process.platform;
20523
20527
  const env = deps.env ?? process.env;
20524
20528
  if (platform3 === "win32") {
20525
20529
  const localAppData = env.LOCALAPPDATA;
20526
20530
  if (!localAppData) return null;
20527
20531
  const exe = import_path4.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
20528
- return existsSync28(exe) ? exe : null;
20532
+ return existsSync30(exe) ? exe : null;
20529
20533
  }
20530
20534
  const home = deps.homedir ?? import_os4.default.homedir();
20531
20535
  const unix = import_path4.default.posix.join(home, ".local", "bin", "cursor-agent");
20532
- return existsSync28(unix) ? unix : null;
20536
+ return existsSync30(unix) ? unix : null;
20533
20537
  }
20534
20538
  async function waitForCursorAgent(opts = {}) {
20535
20539
  const timeoutMs = opts.timeoutMs ?? 18e4;
@@ -20615,8 +20619,8 @@ var AiderRuntimeStrategy = class {
20615
20619
  meta = getAgent("aider");
20616
20620
  mode = "interactive";
20617
20621
  os;
20618
- constructor(os65) {
20619
- this.os = os65;
20622
+ constructor(os66) {
20623
+ this.os = os66;
20620
20624
  }
20621
20625
  async prepareLaunch() {
20622
20626
  augmentUserLocalBinPaths();
@@ -20749,8 +20753,8 @@ function geminiCredentialLocator() {
20749
20753
  function geminiLoginLauncher() {
20750
20754
  return {
20751
20755
  async ensureInstalled() {
20752
- const os65 = createOsStrategy();
20753
- return os65.findInPath("gemini") !== null;
20756
+ const os66 = createOsStrategy();
20757
+ return os66.findInPath("gemini") !== null;
20754
20758
  },
20755
20759
  launch() {
20756
20760
  return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -20940,8 +20944,8 @@ var GeminiRuntimeStrategy = class {
20940
20944
  meta = getAgent("gemini");
20941
20945
  mode = "interactive";
20942
20946
  os;
20943
- constructor(os65) {
20944
- this.os = os65;
20947
+ constructor(os66) {
20948
+ this.os = os66;
20945
20949
  }
20946
20950
  async prepareLaunch() {
20947
20951
  const binary = this.os.findInPath("gemini");
@@ -21233,8 +21237,8 @@ var KimiRuntimeStrategy = class {
21233
21237
  meta = getAgent("kimi");
21234
21238
  mode = "interactive";
21235
21239
  os;
21236
- constructor(os65) {
21237
- this.os = os65;
21240
+ constructor(os66) {
21241
+ this.os = os66;
21238
21242
  }
21239
21243
  async prepareLaunch() {
21240
21244
  const binary = this.os.findInPath("kimi");
@@ -21377,8 +21381,8 @@ var OpencodeRuntimeStrategy = class {
21377
21381
  meta = getAgent("opencode");
21378
21382
  mode = "interactive";
21379
21383
  os;
21380
- constructor(os65) {
21381
- this.os = os65;
21384
+ constructor(os66) {
21385
+ this.os = os66;
21382
21386
  }
21383
21387
  async prepareLaunch() {
21384
21388
  const binary = this.os.findInPath("opencode");
@@ -21463,20 +21467,20 @@ var OpencodeRuntimeStrategy = class {
21463
21467
 
21464
21468
  // src/agents/registry.ts
21465
21469
  var runtimeBuilders = {
21466
- claude: (os65) => new ClaudeRuntimeStrategy(os65),
21467
- codex: (os65) => new CodexRuntimeStrategy(os65),
21468
- coderabbit: (os65) => new CoderabbitRuntimeStrategy(os65),
21469
- cursor: (os65) => new CursorRuntimeStrategy(os65),
21470
- aider: (os65) => new AiderRuntimeStrategy(os65),
21471
- gemini: (os65) => new GeminiRuntimeStrategy(os65),
21472
- kimi: (os65) => new KimiRuntimeStrategy(os65),
21473
- opencode: (os65) => new OpencodeRuntimeStrategy(os65)
21470
+ claude: (os66) => new ClaudeRuntimeStrategy(os66),
21471
+ codex: (os66) => new CodexRuntimeStrategy(os66),
21472
+ coderabbit: (os66) => new CoderabbitRuntimeStrategy(os66),
21473
+ cursor: (os66) => new CursorRuntimeStrategy(os66),
21474
+ aider: (os66) => new AiderRuntimeStrategy(os66),
21475
+ gemini: (os66) => new GeminiRuntimeStrategy(os66),
21476
+ kimi: (os66) => new KimiRuntimeStrategy(os66),
21477
+ opencode: (os66) => new OpencodeRuntimeStrategy(os66)
21474
21478
  };
21475
21479
  var deployBuilders = {
21476
21480
  claude: () => new ClaudeDeployStrategy(),
21477
21481
  codex: () => new CodexDeployStrategy()
21478
21482
  };
21479
- function createAgentStrategy(agent, os65 = createOsStrategy()) {
21483
+ function createAgentStrategy(agent, os66 = createOsStrategy()) {
21480
21484
  if (!AGENT_REGISTRY[agent]?.enabled) {
21481
21485
  throw new Error(
21482
21486
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -21486,10 +21490,10 @@ function createAgentStrategy(agent, os65 = createOsStrategy()) {
21486
21490
  if (!build) {
21487
21491
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
21488
21492
  }
21489
- return build(os65);
21493
+ return build(os66);
21490
21494
  }
21491
- function createInteractiveAgentStrategy(agent, os65 = createOsStrategy()) {
21492
- const s = createAgentStrategy(agent, os65);
21495
+ function createInteractiveAgentStrategy(agent, os66 = createOsStrategy()) {
21496
+ const s = createAgentStrategy(agent, os66);
21493
21497
  if (s.mode !== "interactive") {
21494
21498
  throw new Error(
21495
21499
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -22199,8 +22203,8 @@ function collectChangedFiles(cwd) {
22199
22203
  }
22200
22204
  return [...byPath.values()];
22201
22205
  }
22202
- function restoreCoderabbitOauthBlob(os65, value) {
22203
- const dir = path38.join(os65.homeDir(), ".coderabbit");
22206
+ function restoreCoderabbitOauthBlob(os66, value) {
22207
+ const dir = path38.join(os66.homeDir(), ".coderabbit");
22204
22208
  (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
22205
22209
  let file = "auth.json";
22206
22210
  let contents = value.trim();
@@ -22220,26 +22224,26 @@ function installFailureMessage(result) {
22220
22224
  return result.error ?? "CodeRabbit CLI could not be installed";
22221
22225
  }
22222
22226
  async function configureCoderabbit(input, deps = {}) {
22223
- const os65 = deps.os ?? createOsStrategy();
22227
+ const os66 = deps.os ?? createOsStrategy();
22224
22228
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
22225
22229
  const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
22226
22230
  const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
22227
22231
  const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
22228
22232
  const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
22229
22233
  const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
22230
- const home = os65.homeDir();
22231
- os65.augmentPath(
22232
- os65.id === "win32" ? [
22234
+ const home = os66.homeDir();
22235
+ os66.augmentPath(
22236
+ os66.id === "win32" ? [
22233
22237
  path38.join(home, ".local", "bin"),
22234
22238
  path38.join(process.env.APPDATA ?? path38.join(home, "AppData", "Roaming"), "npm"),
22235
22239
  path38.join(home, "scoop", "shims")
22236
22240
  ] : [path38.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
22237
22241
  );
22238
- const installed2 = os65.findInPath("coderabbit") !== null;
22242
+ const installed2 = os66.findInPath("coderabbit") !== null;
22239
22243
  const base = () => ({
22240
22244
  action: input.action,
22241
22245
  supported: true,
22242
- installed: os65.findInPath("coderabbit") !== null,
22246
+ installed: os66.findInPath("coderabbit") !== null,
22243
22247
  loggedIn: false
22244
22248
  });
22245
22249
  if (input.action === "status") {
@@ -22253,7 +22257,7 @@ async function configureCoderabbit(input, deps = {}) {
22253
22257
  const key = (input.apiKey ?? "").trim();
22254
22258
  if (!key) return { ...res2, error: "No API key provided" };
22255
22259
  if (!res2.installed) {
22256
- const inst = await ensureInstalled(os65);
22260
+ const inst = await ensureInstalled(os66);
22257
22261
  res2.installed = inst.ok;
22258
22262
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
22259
22263
  }
@@ -22277,7 +22281,7 @@ async function configureCoderabbit(input, deps = {}) {
22277
22281
  }
22278
22282
  if (!res2.installed) {
22279
22283
  deps.onEvent?.({ kind: "installing" });
22280
- const inst = await ensureInstalled(os65);
22284
+ const inst = await ensureInstalled(os66);
22281
22285
  res2.installed = inst.ok;
22282
22286
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
22283
22287
  }
@@ -22294,7 +22298,7 @@ async function configureCoderabbit(input, deps = {}) {
22294
22298
  return { ...res2, loggedIn: true, linked: true };
22295
22299
  }
22296
22300
  try {
22297
- restoreCoderabbitOauthBlob(os65, cred.credential);
22301
+ restoreCoderabbitOauthBlob(os66, cred.credential);
22298
22302
  } catch (err) {
22299
22303
  return {
22300
22304
  ...res2,
@@ -22318,7 +22322,7 @@ async function configureCoderabbit(input, deps = {}) {
22318
22322
  const res2 = base();
22319
22323
  if (!installed2) {
22320
22324
  deps.onEvent?.({ kind: "installing" });
22321
- const inst = await ensureInstalled(os65);
22325
+ const inst = await ensureInstalled(os66);
22322
22326
  res2.installed = inst.ok;
22323
22327
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
22324
22328
  }
@@ -22358,7 +22362,7 @@ async function configureCoderabbit(input, deps = {}) {
22358
22362
  }
22359
22363
  const res = base();
22360
22364
  if (!res.installed) {
22361
- const inst = await ensureInstalled(os65);
22365
+ const inst = await ensureInstalled(os66);
22362
22366
  res.installed = inst.ok;
22363
22367
  if (!inst.ok) return { ...res, error: installFailureMessage(inst) };
22364
22368
  }
@@ -25667,11 +25671,11 @@ function resolveDoltInstallStrategy(platform3) {
25667
25671
  }
25668
25672
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
25669
25673
  function doltPlatformTuple(platform3, arch2) {
25670
- const os65 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25674
+ const os66 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25671
25675
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
25672
25676
  if (!a) return null;
25673
- if (os65 === "windows" && a !== "amd64") return null;
25674
- return `${os65}-${a}`;
25677
+ if (os66 === "windows" && a !== "amd64") return null;
25678
+ return `${os66}-${a}`;
25675
25679
  }
25676
25680
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
25677
25681
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -27360,7 +27364,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
27360
27364
  });
27361
27365
  const token = ctx.pluginAuthToken;
27362
27366
  void (async () => {
27363
- const os65 = createOsStrategy();
27367
+ const os66 = createOsStrategy();
27364
27368
  try {
27365
27369
  const report = await reviewPullRequest(
27366
27370
  {
@@ -27369,7 +27373,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
27369
27373
  baseBranch: parsed.baseBranch
27370
27374
  },
27371
27375
  {
27372
- runReview: (input) => new CoderabbitRuntimeStrategy(os65).runOneShot(input),
27376
+ runReview: (input) => new CoderabbitRuntimeStrategy(os66).runOneShot(input),
27373
27377
  runGh: (args2) => defaultRunGh(args2),
27374
27378
  postReport: async (r) => {
27375
27379
  if (!token) return;
@@ -27507,13 +27511,13 @@ function resolveGlobalNodeModulesDir(opts) {
27507
27511
  var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
27508
27512
  function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
27509
27513
  if (!nodeModulesDir) return 0;
27510
- const readdirSync13 = deps?.readdirSync ?? fs51.readdirSync;
27514
+ const readdirSync14 = deps?.readdirSync ?? fs51.readdirSync;
27511
27515
  const statSync15 = deps?.statSync ?? fs51.statSync;
27512
27516
  const rmSync9 = deps?.rmSync ?? fs51.rmSync;
27513
27517
  let removed = 0;
27514
27518
  let entries;
27515
27519
  try {
27516
- entries = readdirSync13(nodeModulesDir);
27520
+ entries = readdirSync14(nodeModulesDir);
27517
27521
  } catch {
27518
27522
  return 0;
27519
27523
  }
@@ -28536,11 +28540,11 @@ function resolveTokenValue(args2) {
28536
28540
  }
28537
28541
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
28538
28542
  if (fileFlag) {
28539
- const path96 = fileFlag.slice("--token-file=".length);
28543
+ const path97 = fileFlag.slice("--token-file=".length);
28540
28544
  try {
28541
- const content = fs52.readFileSync(path96, "utf8").trim();
28542
- if (content.length === 0) fail(`--token-file ${path96} is empty`);
28543
- rmIfExistsQuiet(path96);
28545
+ const content = fs52.readFileSync(path97, "utf8").trim();
28546
+ if (content.length === 0) fail(`--token-file ${path97} is empty`);
28547
+ rmIfExistsQuiet(path97);
28544
28548
  return content;
28545
28549
  } catch (err) {
28546
28550
  fail(`Could not read --token-file: ${err.message}`);
@@ -29472,32 +29476,200 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
29472
29476
  return null;
29473
29477
  }
29474
29478
 
29479
+ // src/commands/host/workspace.ts
29480
+ var fs53 = __toESM(require("fs"));
29481
+ var os41 = __toESM(require("os"));
29482
+ var path62 = __toESM(require("path"));
29483
+ var import_node_child_process21 = require("child_process");
29484
+ var import_node_util5 = require("util");
29485
+ var execFileP5 = (0, import_node_util5.promisify)(import_node_child_process21.execFile);
29486
+ function isAbsolutePathTarget(target) {
29487
+ return path62.isAbsolute(target);
29488
+ }
29489
+ function selfHostedWorkspaceRoot() {
29490
+ return path62.join(os41.homedir(), ".codeam", "self-hosted");
29491
+ }
29492
+ function deployIdFromWorkspace(cwd) {
29493
+ if (!cwd) return null;
29494
+ const root = selfHostedWorkspaceRoot();
29495
+ const resolved = path62.resolve(cwd);
29496
+ const rel = path62.relative(root, resolved);
29497
+ if (!rel || rel.startsWith("..") || path62.isAbsolute(rel)) return null;
29498
+ const parts = rel.split(path62.sep).filter(Boolean);
29499
+ if (parts.length !== 1) return null;
29500
+ return parts[0];
29501
+ }
29502
+ function nonInteractiveGitEnv() {
29503
+ return {
29504
+ ...process.env,
29505
+ GIT_TERMINAL_PROMPT: "0",
29506
+ GIT_ASKPASS: "",
29507
+ GCM_INTERACTIVE: "never"
29508
+ };
29509
+ }
29510
+ function githubOwnerRepo(repoRef) {
29511
+ const trimmed = repoRef.trim();
29512
+ const shorthand = /^([^/\s]+)\/([^/\s]+?)(?:\.git)?$/.exec(trimmed);
29513
+ if (shorthand && !/^https?:\/\//.test(trimmed) && !trimmed.startsWith("git@")) {
29514
+ return { owner: shorthand[1], repo: shorthand[2] };
29515
+ }
29516
+ const httpsMatch = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/.exec(trimmed);
29517
+ if (httpsMatch) return { owner: httpsMatch[1], repo: httpsMatch[2] };
29518
+ return null;
29519
+ }
29520
+ function gitlabProjectPath(repoRef) {
29521
+ const trimmed = repoRef.trim();
29522
+ const https9 = /^https?:\/\/gitlab\.com\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
29523
+ if (https9) return https9[1];
29524
+ if (!/^https?:\/\//.test(trimmed) && !trimmed.startsWith("git@") && trimmed.includes("/")) {
29525
+ return trimmed.replace(/\.git$/, "");
29526
+ }
29527
+ return null;
29528
+ }
29529
+ function repoCloneUrl(repoRef, cloneToken, provider = "github") {
29530
+ const trimmed = repoRef.trim();
29531
+ if (provider === "gitlab") {
29532
+ const glPath = gitlabProjectPath(trimmed);
29533
+ if (glPath) {
29534
+ return cloneToken ? `https://oauth2:${cloneToken}@gitlab.com/${glPath}.git` : `https://gitlab.com/${glPath}.git`;
29535
+ }
29536
+ if (/^https?:\/\//.test(trimmed) || trimmed.startsWith("git@")) return trimmed;
29537
+ }
29538
+ if (cloneToken) {
29539
+ const gh = githubOwnerRepo(trimmed);
29540
+ if (gh) {
29541
+ return `https://x-access-token:${cloneToken}@github.com/${gh.owner}/${gh.repo}.git`;
29542
+ }
29543
+ }
29544
+ if (/^https?:\/\//.test(trimmed) || trimmed.startsWith("git@")) return trimmed;
29545
+ return `https://github.com/${trimmed.replace(/\.git$/, "")}.git`;
29546
+ }
29547
+ function maskCloneUrl(url2) {
29548
+ return url2.replace(/(https?:\/\/)[^@/]+@/, "$1***@");
29549
+ }
29550
+ async function fetchGithubIdentity(token) {
29551
+ try {
29552
+ const res = await fetch("https://api.github.com/user", {
29553
+ headers: {
29554
+ Authorization: `Bearer ${token}`,
29555
+ "User-Agent": "codeam-cli",
29556
+ Accept: "application/vnd.github+json"
29557
+ }
29558
+ });
29559
+ if (!res.ok) return null;
29560
+ const body = await res.json();
29561
+ return { login: body.login, email: body.email ?? void 0 };
29562
+ } catch {
29563
+ return null;
29564
+ }
29565
+ }
29566
+ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "github") {
29567
+ const isGitlab = provider === "gitlab";
29568
+ if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
29569
+ if (!cloneToken) return;
29570
+ const credFile = path62.join(dest, ".git", "codeam-credentials");
29571
+ const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
29572
+ ` : `https://x-access-token:${cloneToken}@github.com
29573
+ `;
29574
+ fs53.writeFileSync(credFile, credLine, { mode: 384 });
29575
+ restrictToOwner(credFile);
29576
+ const env = nonInteractiveGitEnv();
29577
+ const git2 = (args2) => execFileP5("git", ["-C", dest, ...args2], { timeout: 3e4, env });
29578
+ const credFilePosix = credFile.split(path62.sep).join("/");
29579
+ await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
29580
+ });
29581
+ await git2([
29582
+ "config",
29583
+ "--local",
29584
+ "--add",
29585
+ "credential.helper",
29586
+ `store --file=${credFilePosix}`
29587
+ ]).catch(() => {
29588
+ });
29589
+ await git2(["remote", "set-url", "origin", repoCloneUrl(repoRef, void 0, provider)]).catch(() => {
29590
+ });
29591
+ const hasIdentity = await git2(["config", "user.email"]).then(() => true).catch(() => false);
29592
+ if (!hasIdentity) {
29593
+ const who = isGitlab ? null : await fetchGithubIdentity(cloneToken);
29594
+ const login = who?.login ?? "CodeAgent";
29595
+ await git2(["config", "--local", "user.name", login]).catch(() => {
29596
+ });
29597
+ const email = who?.email ?? (isGitlab ? "agent@codeagent-mobile.com" : `${login}@users.noreply.github.com`);
29598
+ await git2(["config", "--local", "user.email", email]).catch(() => {
29599
+ });
29600
+ }
29601
+ }
29602
+ function maskToken(text, cloneToken) {
29603
+ const masked = maskCloneUrl(text);
29604
+ if (cloneToken && cloneToken.length > 0) {
29605
+ return masked.split(cloneToken).join("***");
29606
+ }
29607
+ return masked;
29608
+ }
29609
+ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
29610
+ if (isAbsolutePathTarget(repoOrPath)) {
29611
+ if (!fs53.existsSync(repoOrPath)) {
29612
+ throw new Error(`deploy target path does not exist: ${repoOrPath}`);
29613
+ }
29614
+ return repoOrPath;
29615
+ }
29616
+ const dest = path62.join(selfHostedWorkspaceRoot(), deployId);
29617
+ if (fs53.existsSync(path62.join(dest, ".git"))) {
29618
+ if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
29619
+ return dest;
29620
+ }
29621
+ fs53.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
29622
+ const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
29623
+ const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
29624
+ try {
29625
+ await execFileP5("git", cloneArgs, {
29626
+ timeout: 12e4,
29627
+ maxBuffer: 16 * 1024 * 1024,
29628
+ env: nonInteractiveGitEnv()
29629
+ });
29630
+ } catch (err) {
29631
+ const reason = err instanceof Error ? err.message : String(err);
29632
+ throw new Error(`git clone failed for ${maskCloneUrl(cloneUrl)}: ${maskToken(reason, cloneToken)}`);
29633
+ }
29634
+ if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
29635
+ return dest;
29636
+ }
29637
+
29475
29638
  // src/agents/acp/runner.ts
29476
29639
  var import_node_crypto11 = require("crypto");
29477
- var fs69 = __toESM(require("fs"));
29478
- var os53 = __toESM(require("os"));
29479
- var path80 = __toESM(require("path"));
29640
+ var fs71 = __toESM(require("fs"));
29641
+ var os55 = __toESM(require("os"));
29642
+ var path82 = __toESM(require("path"));
29480
29643
 
29481
29644
  // src/lib/provider-routing.ts
29645
+ var fs55 = __toESM(require("fs"));
29646
+ var os43 = __toESM(require("os"));
29647
+ var path64 = __toESM(require("path"));
29648
+
29649
+ // src/commands/host/house-proxy-config.ts
29482
29650
  var fs54 = __toESM(require("fs"));
29483
29651
  var os42 = __toESM(require("os"));
29484
29652
  var path63 = __toESM(require("path"));
29485
-
29486
- // src/commands/host/house-proxy-config.ts
29487
- var fs53 = __toESM(require("fs"));
29488
- var os41 = __toESM(require("os"));
29489
- var path62 = __toESM(require("path"));
29490
29653
  function houseProxyConfigPath() {
29491
- return path62.join(os41.homedir(), ".codeam", "house-proxy.json");
29654
+ return path63.join(os42.homedir(), ".codeam", "house-proxy.json");
29655
+ }
29656
+ var DEPLOY_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
29657
+ function deployHouseProxyConfigPath(deployId) {
29658
+ if (!DEPLOY_ID_RE.test(deployId) || deployId.includes("..")) return null;
29659
+ return path63.join(os42.homedir(), ".codeam", "house-proxy", `${deployId}.json`);
29660
+ }
29661
+ function writeJson0600(file, value) {
29662
+ fs54.mkdirSync(path63.dirname(file), { recursive: true, mode: 448 });
29663
+ const tmp = `${file}.tmp-${process.pid}`;
29664
+ fs54.writeFileSync(tmp, JSON.stringify(value, null, 2), { encoding: "utf8", mode: 384 });
29665
+ fs54.renameSync(tmp, file);
29666
+ restrictToOwner(file);
29492
29667
  }
29493
- function persistHouseProxyConfig(config) {
29668
+ function persistHouseProxyConfig(config, deployId) {
29494
29669
  try {
29495
- const file = houseProxyConfigPath();
29496
- fs53.mkdirSync(path62.dirname(file), { recursive: true, mode: 448 });
29497
- const tmp = `${file}.tmp-${process.pid}`;
29498
- fs53.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
29499
- fs53.renameSync(tmp, file);
29500
- restrictToOwner(file);
29670
+ const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
29671
+ if (perDeploy) writeJson0600(perDeploy, config);
29672
+ writeJson0600(houseProxyConfigPath(), config);
29501
29673
  } catch (err) {
29502
29674
  log.warn(
29503
29675
  "host-agent",
@@ -29505,18 +29677,23 @@ function persistHouseProxyConfig(config) {
29505
29677
  );
29506
29678
  }
29507
29679
  }
29508
- function clearHouseProxyConfig() {
29680
+ function clearHouseProxyConfig(deployId) {
29509
29681
  try {
29510
- fs53.rmSync(houseProxyConfigPath(), { force: true });
29682
+ fs54.rmSync(houseProxyConfigPath(), { force: true });
29683
+ const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
29684
+ if (perDeploy) writeJson0600(perDeploy, { none: true });
29511
29685
  } catch {
29512
29686
  }
29513
29687
  }
29514
- function readHouseProxyChildEnv() {
29688
+ function readHouseProxyChildEnv(deployId) {
29515
29689
  try {
29516
- const raw = fs53.readFileSync(houseProxyConfigPath(), "utf8");
29690
+ const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
29691
+ const file = perDeploy && fs54.existsSync(perDeploy) ? perDeploy : houseProxyConfigPath();
29692
+ const raw = fs54.readFileSync(file, "utf8");
29517
29693
  const parsed = JSON.parse(raw);
29518
29694
  if (typeof parsed !== "object" || parsed === null) return {};
29519
29695
  const o = parsed;
29696
+ if (o.none === true) return {};
29520
29697
  if (typeof o.baseUrl !== "string" || !o.baseUrl) return {};
29521
29698
  if (typeof o.token !== "string" || !o.token) return {};
29522
29699
  return buildHouseProxyChildEnv({
@@ -29639,15 +29816,15 @@ function redactUrlToOrigin(raw) {
29639
29816
  }
29640
29817
  }
29641
29818
  function readOpencodeProviderOrigins(opts = {}) {
29642
- const home = opts.homeDir ?? os42.homedir();
29643
- const readFile7 = opts.readFile ?? ((f) => fs54.readFileSync(f, "utf8"));
29819
+ const home = opts.homeDir ?? os43.homedir();
29820
+ const readFile7 = opts.readFile ?? ((f) => fs55.readFileSync(f, "utf8"));
29644
29821
  const candidates = [];
29645
29822
  if (opts.cwd) {
29646
- candidates.push(path63.join(opts.cwd, "opencode.json"), path63.join(opts.cwd, "opencode.jsonc"));
29823
+ candidates.push(path64.join(opts.cwd, "opencode.json"), path64.join(opts.cwd, "opencode.jsonc"));
29647
29824
  }
29648
29825
  candidates.push(
29649
- path63.join(home, ".config", "opencode", "opencode.json"),
29650
- path63.join(home, ".config", "opencode", "opencode.jsonc")
29826
+ path64.join(home, ".config", "opencode", "opencode.json"),
29827
+ path64.join(home, ".config", "opencode", "opencode.jsonc")
29651
29828
  );
29652
29829
  const out2 = [];
29653
29830
  const seen2 = /* @__PURE__ */ new Set();
@@ -29754,9 +29931,9 @@ function noteProviderBillingSignal(opts) {
29754
29931
  }
29755
29932
 
29756
29933
  // src/services/history.service.ts
29757
- var fs55 = __toESM(require("fs"));
29758
- var path64 = __toESM(require("path"));
29759
- var os43 = __toESM(require("os"));
29934
+ var fs56 = __toESM(require("fs"));
29935
+ var path65 = __toESM(require("path"));
29936
+ var os44 = __toESM(require("os"));
29760
29937
  var https6 = __toESM(require("https"));
29761
29938
  var http9 = __toESM(require("http"));
29762
29939
  var import_zod2 = require("zod");
@@ -29817,7 +29994,7 @@ function parseJsonl(filePath) {
29817
29994
  const messages = [];
29818
29995
  let raw;
29819
29996
  try {
29820
- raw = fs55.readFileSync(filePath, "utf8");
29997
+ raw = fs56.readFileSync(filePath, "utf8");
29821
29998
  } catch (err) {
29822
29999
  if (err.code !== "ENOENT") {
29823
30000
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -29971,7 +30148,7 @@ var HistoryService = class _HistoryService {
29971
30148
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
29972
30149
  }
29973
30150
  get projectDir() {
29974
- return this.runtime.resolveHistoryDir(this.cwd) ?? path64.join(os43.homedir(), ".claude", "projects", encodeCwd(this.cwd));
30151
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path65.join(os44.homedir(), ".claude", "projects", encodeCwd(this.cwd));
29975
30152
  }
29976
30153
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
29977
30154
  setCurrentConversationId(id) {
@@ -29983,7 +30160,7 @@ var HistoryService = class _HistoryService {
29983
30160
  /** Return the current message count in the active conversation. */
29984
30161
  getCurrentMessageCount() {
29985
30162
  if (!this.currentConversationId) return 0;
29986
- const filePath = path64.join(this.projectDir, `${this.currentConversationId}.jsonl`);
30163
+ const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
29987
30164
  return parseJsonl(filePath).length;
29988
30165
  }
29989
30166
  /**
@@ -29994,7 +30171,7 @@ var HistoryService = class _HistoryService {
29994
30171
  const deadline = Date.now() + timeoutMs;
29995
30172
  while (Date.now() < deadline) {
29996
30173
  if (!this.currentConversationId) return null;
29997
- const filePath = path64.join(this.projectDir, `${this.currentConversationId}.jsonl`);
30174
+ const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
29998
30175
  const messages = parseJsonl(filePath);
29999
30176
  if (messages.length > previousCount) {
30000
30177
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -30020,16 +30197,16 @@ var HistoryService = class _HistoryService {
30020
30197
  const dir = this.projectDir;
30021
30198
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
30022
30199
  try {
30023
- const files = fs55.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
30200
+ const files = fs56.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
30024
30201
  try {
30025
- const stat3 = fs55.statSync(path64.join(dir, e.name));
30202
+ const stat3 = fs56.statSync(path65.join(dir, e.name));
30026
30203
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
30027
30204
  } catch {
30028
30205
  return { name: e.name, mtime: 0, birthtime: 0 };
30029
30206
  }
30030
30207
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
30031
30208
  if (files.length > 0) {
30032
- this.currentConversationId = path64.basename(files[0].name, ".jsonl");
30209
+ this.currentConversationId = path65.basename(files[0].name, ".jsonl");
30033
30210
  }
30034
30211
  } catch {
30035
30212
  }
@@ -30063,13 +30240,13 @@ var HistoryService = class _HistoryService {
30063
30240
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
30064
30241
  let entries;
30065
30242
  try {
30066
- entries = fs55.readdirSync(dir, { withFileTypes: true });
30243
+ entries = fs56.readdirSync(dir, { withFileTypes: true });
30067
30244
  } catch {
30068
30245
  return null;
30069
30246
  }
30070
30247
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
30071
30248
  try {
30072
- const stat3 = fs55.statSync(path64.join(dir, e.name));
30249
+ const stat3 = fs56.statSync(path65.join(dir, e.name));
30073
30250
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
30074
30251
  } catch {
30075
30252
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -30078,12 +30255,12 @@ var HistoryService = class _HistoryService {
30078
30255
  if (files.length === 0) return null;
30079
30256
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
30080
30257
  if (!files.some((f) => f.name === targetFile)) return null;
30081
- return this.extractUsageFromFile(path64.join(dir, targetFile));
30258
+ return this.extractUsageFromFile(path65.join(dir, targetFile));
30082
30259
  }
30083
30260
  extractUsageFromFile(filePath) {
30084
30261
  let raw;
30085
30262
  try {
30086
- raw = fs55.readFileSync(filePath, "utf8");
30263
+ raw = fs56.readFileSync(filePath, "utf8");
30087
30264
  } catch {
30088
30265
  return null;
30089
30266
  }
@@ -30135,9 +30312,9 @@ var HistoryService = class _HistoryService {
30135
30312
  let totalCost = 0;
30136
30313
  let files;
30137
30314
  try {
30138
- files = fs55.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
30315
+ files = fs56.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
30139
30316
  try {
30140
- return fs55.statSync(path64.join(projectDir, f)).mtimeMs >= monthStartMs;
30317
+ return fs56.statSync(path65.join(projectDir, f)).mtimeMs >= monthStartMs;
30141
30318
  } catch {
30142
30319
  return false;
30143
30320
  }
@@ -30148,7 +30325,7 @@ var HistoryService = class _HistoryService {
30148
30325
  for (const file of files) {
30149
30326
  let raw;
30150
30327
  try {
30151
- raw = fs55.readFileSync(path64.join(projectDir, file), "utf8");
30328
+ raw = fs56.readFileSync(path65.join(projectDir, file), "utf8");
30152
30329
  } catch {
30153
30330
  continue;
30154
30331
  }
@@ -30227,7 +30404,7 @@ var HistoryService = class _HistoryService {
30227
30404
  if (this.runtime.resolveHistoryFile) {
30228
30405
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
30229
30406
  }
30230
- return path64.join(this.projectDir, `${sessionId}.jsonl`);
30407
+ return path65.join(this.projectDir, `${sessionId}.jsonl`);
30231
30408
  }
30232
30409
  /**
30233
30410
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -30265,7 +30442,7 @@ var HistoryService = class _HistoryService {
30265
30442
  };
30266
30443
  });
30267
30444
  }
30268
- return parseJsonl(path64.join(this.projectDir, `${sessionId}.jsonl`));
30445
+ return parseJsonl(path65.join(this.projectDir, `${sessionId}.jsonl`));
30269
30446
  }
30270
30447
  /** One in-flight full upload per conversation — the baton mirror and a
30271
30448
  * `get_conversation` used to upload the same transcript concurrently. */
@@ -30347,7 +30524,7 @@ var HistoryService = class _HistoryService {
30347
30524
  if (!filePath) return false;
30348
30525
  let mtimeMs;
30349
30526
  try {
30350
- mtimeMs = fs55.statSync(filePath).mtimeMs;
30527
+ mtimeMs = fs56.statSync(filePath).mtimeMs;
30351
30528
  } catch {
30352
30529
  return false;
30353
30530
  }
@@ -30421,11 +30598,11 @@ var HistoryService = class _HistoryService {
30421
30598
  };
30422
30599
 
30423
30600
  // src/agents/acp/client.ts
30424
- var import_node_child_process21 = require("child_process");
30425
- var fs56 = __toESM(require("fs/promises"));
30601
+ var import_node_child_process22 = require("child_process");
30602
+ var fs57 = __toESM(require("fs/promises"));
30426
30603
  var fsSync = __toESM(require("fs"));
30427
- var os45 = __toESM(require("os"));
30428
- var path66 = __toESM(require("path"));
30604
+ var os46 = __toESM(require("os"));
30605
+ var path67 = __toESM(require("path"));
30429
30606
  var import_node_stream = require("stream");
30430
30607
 
30431
30608
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -34451,8 +34628,8 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
34451
34628
  }
34452
34629
 
34453
34630
  // src/agents/acp/internal-paths.ts
34454
- var path65 = __toESM(require("path"));
34455
- var os44 = __toESM(require("os"));
34631
+ var path66 = __toESM(require("path"));
34632
+ var os45 = __toESM(require("os"));
34456
34633
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
34457
34634
  var PROSE_ONLY_TOOL_KINDS = /* @__PURE__ */ new Set(["think", "switch_mode"]);
34458
34635
  function isProseOnlyToolKind(kind) {
@@ -34464,13 +34641,13 @@ function textReferencesInternal(text) {
34464
34641
  const scrubbed = text.replace(SELF_HOSTED_WORKSPACE_RE, " ");
34465
34642
  return INTERNAL_TOKENS.some((t2) => scrubbed.includes(t2));
34466
34643
  }
34467
- function pathIsInternal(p2, homeDir2 = os44.homedir()) {
34644
+ function pathIsInternal(p2, homeDir2 = os45.homedir()) {
34468
34645
  if (!p2) return false;
34469
- const abs = path65.resolve(p2);
34470
- const home = path65.resolve(homeDir2);
34471
- const within = (root) => abs === root || abs.startsWith(root + path65.sep);
34472
- if (within(path65.join(home, ".codeam", "self-hosted"))) return false;
34473
- return within(path65.join(home, ".codeam")) || within(path65.join(home, ".beads")) || abs === path65.join(home, ".codeam-host.log") || abs.includes(`${path65.sep}house-claude${path65.sep}`) || abs.endsWith(`${path65.sep}house-claude`);
34646
+ const abs = path66.resolve(p2);
34647
+ const home = path66.resolve(homeDir2);
34648
+ const within = (root) => abs === root || abs.startsWith(root + path66.sep);
34649
+ if (within(path66.join(home, ".codeam", "self-hosted"))) return false;
34650
+ return within(path66.join(home, ".codeam")) || within(path66.join(home, ".beads")) || abs === path66.join(home, ".codeam-host.log") || abs.includes(`${path66.sep}house-claude${path66.sep}`) || abs.endsWith(`${path66.sep}house-claude`);
34474
34651
  }
34475
34652
  function toolCallReferencesInternal(call, homeDir2) {
34476
34653
  if (call.locations?.some((l) => pathIsInternal(l.path, homeDir2))) return true;
@@ -34798,7 +34975,7 @@ var AcpClient = class {
34798
34975
  "acpClient",
34799
34976
  `provider routing ${formatProviderRouting(describeProviderRouting(childEnv, { cwd }), adapter.command)}`
34800
34977
  );
34801
- const child = (0, import_node_child_process21.spawn)(adapter.command, adapter.args, {
34978
+ const child = (0, import_node_child_process22.spawn)(adapter.command, adapter.args, {
34802
34979
  cwd,
34803
34980
  env: childEnv,
34804
34981
  stdio: ["pipe", "pipe", "pipe"],
@@ -35483,7 +35660,7 @@ var AcpClient = class {
35483
35660
  try {
35484
35661
  const pid = child.pid;
35485
35662
  if (process.platform === "win32") {
35486
- if (pid) (0, import_node_child_process21.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pid)], { stdio: "ignore" });
35663
+ if (pid) (0, import_node_child_process22.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pid)], { stdio: "ignore" });
35487
35664
  } else if (pid) {
35488
35665
  killQuiet(-pid, "SIGTERM");
35489
35666
  } else {
@@ -35565,7 +35742,7 @@ var AcpClient = class {
35565
35742
  throw new RequestError(-32002, GUARDRAIL_SECRET_READ_BLOCK_REASON, { uri: params.path });
35566
35743
  }
35567
35744
  try {
35568
- const content = await fs56.readFile(params.path, "utf8");
35745
+ const content = await fs57.readFile(params.path, "utf8");
35569
35746
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
35570
35747
  } catch (err) {
35571
35748
  const code = err.code;
@@ -35586,7 +35763,7 @@ var AcpClient = class {
35586
35763
  throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
35587
35764
  }
35588
35765
  try {
35589
- await fs56.writeFile(params.path, params.content, "utf8");
35766
+ await fs57.writeFile(params.path, params.content, "utf8");
35590
35767
  return {};
35591
35768
  } catch (err) {
35592
35769
  const code = err.code;
@@ -35674,30 +35851,30 @@ function applyLineRange(content, line, limit) {
35674
35851
  return { content: lines.slice(start2, end).join("\n") };
35675
35852
  }
35676
35853
  function knownAgentBinaryDirs() {
35677
- const home = os45.homedir();
35854
+ const home = os46.homedir();
35678
35855
  const out2 = [];
35679
35856
  out2.push("/tmp/codeam-node20/bin");
35680
35857
  for (const root of [
35681
35858
  "/usr/local/share/nvm/versions/node",
35682
- path66.join(home, ".nvm/versions/node")
35859
+ path67.join(home, ".nvm/versions/node")
35683
35860
  ]) {
35684
35861
  try {
35685
35862
  for (const child of fsSync.readdirSync(root)) {
35686
- out2.push(path66.join(root, child, "bin"));
35863
+ out2.push(path67.join(root, child, "bin"));
35687
35864
  }
35688
35865
  } catch {
35689
35866
  }
35690
35867
  }
35691
- out2.push(path66.join(home, ".volta/bin"));
35868
+ out2.push(path67.join(home, ".volta/bin"));
35692
35869
  out2.push("/usr/local/bin");
35693
35870
  out2.push("/usr/bin");
35694
- out2.push(path66.join(home, ".local/bin"));
35695
- out2.push(path66.join(home, "bin"));
35871
+ out2.push(path67.join(home, ".local/bin"));
35872
+ out2.push(path67.join(home, "bin"));
35696
35873
  out2.push(...agentInstallBinDirs());
35697
35874
  if (process.platform === "win32") {
35698
35875
  const { LOCALAPPDATA, APPDATA } = process.env;
35699
- if (LOCALAPPDATA) out2.push(path66.join(LOCALAPPDATA, "cursor-agent"));
35700
- if (APPDATA) out2.push(path66.join(APPDATA, "npm"));
35876
+ if (LOCALAPPDATA) out2.push(path67.join(LOCALAPPDATA, "cursor-agent"));
35877
+ if (APPDATA) out2.push(path67.join(APPDATA, "npm"));
35701
35878
  }
35702
35879
  return out2.filter((p2) => {
35703
35880
  try {
@@ -35708,7 +35885,7 @@ function knownAgentBinaryDirs() {
35708
35885
  });
35709
35886
  }
35710
35887
  function expandPathForAgentBinaries(existingPath) {
35711
- const existing = new Set(existingPath.split(path66.delimiter).filter((p2) => p2.length > 0));
35888
+ const existing = new Set(existingPath.split(path67.delimiter).filter((p2) => p2.length > 0));
35712
35889
  const additions = [];
35713
35890
  for (const dir of knownAgentBinaryDirs()) {
35714
35891
  if (!existing.has(dir)) {
@@ -35717,17 +35894,17 @@ function expandPathForAgentBinaries(existingPath) {
35717
35894
  }
35718
35895
  }
35719
35896
  if (additions.length === 0) return existingPath;
35720
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path66.delimiter);
35897
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path67.delimiter);
35721
35898
  }
35722
35899
 
35723
35900
  // src/commands/host/agent-install.ts
35724
35901
  var import_child_process27 = require("child_process");
35725
- var os46 = __toESM(require("os"));
35902
+ var os47 = __toESM(require("os"));
35726
35903
  function runAgentInstallScript(script, opts = {}) {
35727
35904
  const timeoutMs = opts.timeoutMs ?? 18e4;
35728
35905
  const scope = opts.logScope ?? "agent-install";
35729
35906
  return new Promise((resolve12) => {
35730
- const home = process.env.HOME || os46.homedir();
35907
+ const home = process.env.HOME || os47.homedir();
35731
35908
  const child = (0, import_child_process27.spawn)("sh", ["-c", script], {
35732
35909
  env: { ...process.env, HOME: home },
35733
35910
  stdio: ["ignore", "pipe", "pipe"]
@@ -35989,9 +36166,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
35989
36166
  }
35990
36167
 
35991
36168
  // src/commands/host/agent-provisioning.ts
35992
- var fs57 = __toESM(require("fs"));
35993
- var os47 = __toESM(require("os"));
35994
- var path67 = __toESM(require("path"));
36169
+ var fs58 = __toESM(require("fs"));
36170
+ var os48 = __toESM(require("os"));
36171
+ var path68 = __toESM(require("path"));
35995
36172
  var PUBLIC_TO_INTERNAL_AGENT = {
35996
36173
  claude_code: "claude",
35997
36174
  claude: "claude",
@@ -36008,22 +36185,22 @@ function toInternalAgentId(publicAgentId) {
36008
36185
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
36009
36186
  }
36010
36187
  function ensureDir(dir) {
36011
- fs57.mkdirSync(dir, { recursive: true, mode: 448 });
36188
+ fs58.mkdirSync(dir, { recursive: true, mode: 448 });
36012
36189
  }
36013
36190
  function writeFile0600(filePath, contents) {
36014
- ensureDir(path67.dirname(filePath));
36015
- fs57.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
36191
+ ensureDir(path68.dirname(filePath));
36192
+ fs58.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
36016
36193
  restrictToOwner(filePath);
36017
36194
  }
36018
36195
  function rmIfExists(filePath) {
36019
36196
  try {
36020
- fs57.rmSync(filePath, { force: true });
36197
+ fs58.rmSync(filePath, { force: true });
36021
36198
  } catch {
36022
36199
  }
36023
36200
  }
36024
36201
  var claudeProvisioner = {
36025
36202
  write(auth, home) {
36026
- const credentialsJson = path67.join(home, ".claude", ".credentials.json");
36203
+ const credentialsJson = path68.join(home, ".claude", ".credentials.json");
36027
36204
  if (auth.kind === "api_key") {
36028
36205
  rmIfExists(credentialsJson);
36029
36206
  return { ANTHROPIC_API_KEY: auth.value };
@@ -36035,8 +36212,8 @@ var claudeProvisioner = {
36035
36212
  } else {
36036
36213
  rmIfExists(credentialsJson);
36037
36214
  }
36038
- const claudeJson = path67.join(home, ".claude.json");
36039
- if (!fs57.existsSync(claudeJson)) {
36215
+ const claudeJson = path68.join(home, ".claude.json");
36216
+ if (!fs58.existsSync(claudeJson)) {
36040
36217
  writeFile0600(
36041
36218
  claudeJson,
36042
36219
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -36047,7 +36224,7 @@ var claudeProvisioner = {
36047
36224
  };
36048
36225
  var codexProvisioner = {
36049
36226
  write(auth, home) {
36050
- const authJson = path67.join(home, ".codex", "auth.json");
36227
+ const authJson = path68.join(home, ".codex", "auth.json");
36051
36228
  if (auth.kind === "api_key") {
36052
36229
  writeFile0600(authJson, JSON.stringify({ auth_mode: "apikey", OPENAI_API_KEY: auth.value }));
36053
36230
  return { OPENAI_API_KEY: auth.value };
@@ -36058,8 +36235,8 @@ var codexProvisioner = {
36058
36235
  };
36059
36236
  var geminiProvisioner = {
36060
36237
  write(auth, home) {
36061
- const settingsJson = path67.join(home, ".gemini", "settings.json");
36062
- const oauthCreds = path67.join(home, ".gemini", "oauth_creds.json");
36238
+ const settingsJson = path68.join(home, ".gemini", "settings.json");
36239
+ const oauthCreds = path68.join(home, ".gemini", "oauth_creds.json");
36063
36240
  if (auth.kind === "api_key") {
36064
36241
  rmIfExists(oauthCreds);
36065
36242
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -36072,7 +36249,7 @@ var geminiProvisioner = {
36072
36249
  };
36073
36250
  var cursorProvisioner = {
36074
36251
  write(auth, home) {
36075
- const authJson = path67.join(home, ".config", "cursor", "auth.json");
36252
+ const authJson = path68.join(home, ".config", "cursor", "auth.json");
36076
36253
  if (auth.kind === "api_key") {
36077
36254
  rmIfExists(authJson);
36078
36255
  return { CURSOR_API_KEY: auth.value };
@@ -36114,22 +36291,22 @@ max_context_size = 262144
36114
36291
  var kimiProvisioner = {
36115
36292
  write(auth, home) {
36116
36293
  const credentialsFiles = [
36117
- path67.join(home, ".kimi", "credentials", "kimi-code.json"),
36118
- path67.join(home, ".kimi-code", "credentials", "kimi-code.json")
36294
+ path68.join(home, ".kimi", "credentials", "kimi-code.json"),
36295
+ path68.join(home, ".kimi-code", "credentials", "kimi-code.json")
36119
36296
  ];
36120
36297
  if (auth.kind === "api_key") {
36121
36298
  credentialsFiles.forEach(rmIfExists);
36122
36299
  return { KIMI_API_KEY: auth.value };
36123
36300
  }
36124
36301
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
36125
- writeFile0600(path67.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
36302
+ writeFile0600(path68.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
36126
36303
  return {};
36127
36304
  }
36128
36305
  };
36129
36306
  var coderabbitProvisioner = {
36130
36307
  write(auth, home) {
36131
- const dir = path67.join(home, ".coderabbit");
36132
- const authJson = path67.join(dir, "auth.json");
36308
+ const dir = path68.join(home, ".coderabbit");
36309
+ const authJson = path68.join(dir, "auth.json");
36133
36310
  if (auth.kind === "api_key") {
36134
36311
  rmIfExists(authJson);
36135
36312
  return { CODERABBIT_API_KEY: auth.value };
@@ -36141,13 +36318,13 @@ var coderabbitProvisioner = {
36141
36318
  try {
36142
36319
  const parsed = JSON.parse(value);
36143
36320
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
36144
- file = path67.basename(parsed.file);
36321
+ file = path68.basename(parsed.file);
36145
36322
  contents = parsed.contents;
36146
36323
  }
36147
36324
  } catch {
36148
36325
  }
36149
36326
  }
36150
- writeFile0600(path67.join(dir, file), contents);
36327
+ writeFile0600(path68.join(dir, file), contents);
36151
36328
  return {};
36152
36329
  }
36153
36330
  };
@@ -36175,7 +36352,7 @@ var UnsupportedAgentError = class extends Error {
36175
36352
  this.agentId = agentId;
36176
36353
  }
36177
36354
  };
36178
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os47.homedir()) {
36355
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os48.homedir()) {
36179
36356
  const internal = toInternalAgentId(publicAgentId);
36180
36357
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
36181
36358
  const provisioner = PROVISIONERS[internal];
@@ -36184,16 +36361,16 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os47.homedir(
36184
36361
  }
36185
36362
 
36186
36363
  // src/beads/workflow-hint.ts
36187
- var fs58 = __toESM(require("fs"));
36188
- var path69 = __toESM(require("path"));
36364
+ var fs59 = __toESM(require("fs"));
36365
+ var path70 = __toESM(require("path"));
36189
36366
 
36190
36367
  // src/agents/claude-memory-file.ts
36191
- var os48 = __toESM(require("os"));
36192
- var path68 = __toESM(require("path"));
36368
+ var os49 = __toESM(require("os"));
36369
+ var path69 = __toESM(require("path"));
36193
36370
  function claudeMemoryFile(homeDir2, env = process.env) {
36194
- if (homeDir2) return path68.join(homeDir2, ".claude", "CLAUDE.md");
36371
+ if (homeDir2) return path69.join(homeDir2, ".claude", "CLAUDE.md");
36195
36372
  const configDir = env.CLAUDE_CONFIG_DIR?.trim();
36196
- return configDir ? path68.join(configDir, "CLAUDE.md") : path68.join(os48.homedir(), ".claude", "CLAUDE.md");
36373
+ return configDir ? path69.join(configDir, "CLAUDE.md") : path69.join(os49.homedir(), ".claude", "CLAUDE.md");
36197
36374
  }
36198
36375
 
36199
36376
  // src/beads/workflow-hint.ts
@@ -36223,11 +36400,11 @@ function ensureBeadsWorkflowHint(homeDir2, file = claudeMemoryFile(homeDir2)) {
36223
36400
  try {
36224
36401
  let existing = "";
36225
36402
  try {
36226
- existing = fs58.readFileSync(file, "utf8");
36403
+ existing = fs59.readFileSync(file, "utf8");
36227
36404
  } catch {
36228
36405
  }
36229
36406
  if (existing.includes(BEADS_HINT)) return;
36230
- fs58.mkdirSync(path69.dirname(file), { recursive: true });
36407
+ fs59.mkdirSync(path70.dirname(file), { recursive: true });
36231
36408
  let next;
36232
36409
  const open = existing.indexOf(BEADS_HINT_MARKER);
36233
36410
  const close = open === -1 ? -1 : existing.indexOf(BEADS_HINT_MARKER, open + BEADS_HINT_MARKER.length);
@@ -36240,40 +36417,40 @@ ${BEADS_HINT}
36240
36417
  ` : `${BEADS_HINT}
36241
36418
  `;
36242
36419
  }
36243
- fs58.writeFileSync(file, next);
36420
+ fs59.writeFileSync(file, next);
36244
36421
  } catch {
36245
36422
  }
36246
36423
  }
36247
36424
 
36248
36425
  // src/agents/agent-standard.ts
36249
- var fs59 = __toESM(require("fs"));
36250
- var path70 = __toESM(require("path"));
36251
- var os49 = __toESM(require("os"));
36426
+ var fs60 = __toESM(require("fs"));
36427
+ var path71 = __toESM(require("path"));
36428
+ var os50 = __toESM(require("os"));
36252
36429
  function ensureAgentStandard(homeDir2, file = claudeMemoryFile(homeDir2)) {
36253
36430
  try {
36254
36431
  let existing = "";
36255
36432
  try {
36256
- existing = fs59.readFileSync(file, "utf8");
36433
+ existing = fs60.readFileSync(file, "utf8");
36257
36434
  } catch {
36258
36435
  }
36259
36436
  if (existing.includes(AGENT_STANDARD_MARKER)) return;
36260
- fs59.mkdirSync(path70.dirname(file), { recursive: true });
36437
+ fs60.mkdirSync(path71.dirname(file), { recursive: true });
36261
36438
  const next = existing.trim() ? `${existing.trimEnd()}
36262
36439
 
36263
36440
  ${AGENT_STANDARD_BLOCK}
36264
36441
  ` : `${AGENT_STANDARD_BLOCK}
36265
36442
  `;
36266
- fs59.writeFileSync(file, next);
36443
+ fs60.writeFileSync(file, next);
36267
36444
  } catch {
36268
36445
  }
36269
36446
  }
36270
36447
  var _agentStandardSeam = {
36271
36448
  isLocalSession: () => isLocalSession(),
36272
- markerPath: (sessionId) => path70.join(os49.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36273
- exists: (p2) => fs59.existsSync(p2),
36449
+ markerPath: (sessionId) => path71.join(os50.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36450
+ exists: (p2) => fs60.existsSync(p2),
36274
36451
  write: (p2) => {
36275
- fs59.mkdirSync(path70.dirname(p2), { recursive: true });
36276
- fs59.writeFileSync(p2, "");
36452
+ fs60.mkdirSync(path71.dirname(p2), { recursive: true });
36453
+ fs60.writeFileSync(p2, "");
36277
36454
  }
36278
36455
  };
36279
36456
  function isClaude(agent) {
@@ -36966,15 +37143,15 @@ function withholdTrailingPartialFenceMarker(text) {
36966
37143
 
36967
37144
  // src/agents/acp/onboarding.ts
36968
37145
  var import_child_process28 = require("child_process");
36969
- var fs60 = __toESM(require("fs"));
36970
- var os50 = __toESM(require("os"));
36971
- var path71 = __toESM(require("path"));
37146
+ var fs61 = __toESM(require("fs"));
37147
+ var os51 = __toESM(require("os"));
37148
+ var path72 = __toESM(require("path"));
36972
37149
  var _onboardingSeam = {
36973
- markerPath: (sessionId) => path71.join(os50.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
36974
- exists: (p2) => fs60.existsSync(p2),
37150
+ markerPath: (sessionId) => path72.join(os51.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
37151
+ exists: (p2) => fs61.existsSync(p2),
36975
37152
  write: (p2) => {
36976
- fs60.mkdirSync(path71.dirname(p2), { recursive: true });
36977
- fs60.writeFileSync(p2, "");
37153
+ fs61.mkdirSync(path72.dirname(p2), { recursive: true });
37154
+ fs61.writeFileSync(p2, "");
36978
37155
  },
36979
37156
  disabled: () => {
36980
37157
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -37011,7 +37188,7 @@ function resolveRepoName(cwd) {
37011
37188
  if (name) return name;
37012
37189
  }
37013
37190
  }
37014
- const base = path71.basename(cwd || "");
37191
+ const base = path72.basename(cwd || "");
37015
37192
  if (base && !isUuid(base)) return base;
37016
37193
  return "this project";
37017
37194
  }
@@ -37403,13 +37580,13 @@ var import_crypto4 = require("crypto");
37403
37580
 
37404
37581
  // src/services/turn-files/git-changeset.ts
37405
37582
  var import_child_process29 = require("child_process");
37406
- var fs62 = __toESM(require("fs/promises"));
37407
- var path73 = __toESM(require("path"));
37583
+ var fs63 = __toESM(require("fs/promises"));
37584
+ var path74 = __toESM(require("path"));
37408
37585
 
37409
37586
  // src/services/turn-files/review-ignore.ts
37410
37587
  var import_ignore2 = __toESM(require("ignore"));
37411
- var fs61 = __toESM(require("fs"));
37412
- var path72 = __toESM(require("path"));
37588
+ var fs62 = __toESM(require("fs"));
37589
+ var path73 = __toESM(require("path"));
37413
37590
  var CURATED_REVIEW_IGNORE = [
37414
37591
  // Google Cloud SDK (the incident) — installs a huge python tree.
37415
37592
  "google-cloud-sdk/",
@@ -37448,7 +37625,7 @@ var CURATED_REVIEW_IGNORE = [
37448
37625
  function makeReviewIgnore(repoRoot) {
37449
37626
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
37450
37627
  try {
37451
- const custom = fs61.readFileSync(path72.join(repoRoot, ".codeam", "reviewignore"), "utf8");
37628
+ const custom = fs62.readFileSync(path73.join(repoRoot, ".codeam", "reviewignore"), "utf8");
37452
37629
  ig.add(custom);
37453
37630
  } catch {
37454
37631
  }
@@ -37493,7 +37670,7 @@ async function collectRepoChangeset(opts) {
37493
37670
  let stats;
37494
37671
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
37495
37672
  const lineCount = await readUntrackedLineCount(
37496
- path73.join(opts.repoRoot, row.filePath)
37673
+ path74.join(opts.repoRoot, row.filePath)
37497
37674
  );
37498
37675
  stats = { added: lineCount, removed: 0 };
37499
37676
  } else {
@@ -37524,7 +37701,7 @@ function readUntrackedLineCount(absPath) {
37524
37701
  }
37525
37702
  async function defaultReadUntrackedLineCount(absPath) {
37526
37703
  try {
37527
- const content = await fs62.readFile(absPath, "utf8");
37704
+ const content = await fs63.readFile(absPath, "utf8");
37528
37705
  let count = 0;
37529
37706
  let pos = -1;
37530
37707
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -37616,7 +37793,7 @@ function defaultRunGit(cwd, args2) {
37616
37793
  });
37617
37794
  }
37618
37795
  async function discoverRepos(workingDir, maxDepth = 4) {
37619
- const fs81 = await import("fs/promises");
37796
+ const fs82 = await import("fs/promises");
37620
37797
  const out2 = [];
37621
37798
  await walk(workingDir, 0);
37622
37799
  return out2;
@@ -37624,7 +37801,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
37624
37801
  if (depth > maxDepth) return;
37625
37802
  let entries = [];
37626
37803
  try {
37627
- const dirents = await fs81.readdir(dir, { withFileTypes: true });
37804
+ const dirents = await fs82.readdir(dir, { withFileTypes: true });
37628
37805
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
37629
37806
  } catch {
37630
37807
  return;
@@ -37635,8 +37812,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
37635
37812
  if (hasGit) {
37636
37813
  out2.push({
37637
37814
  repoRoot: dir,
37638
- repoPath: path73.relative(workingDir, dir),
37639
- repoName: path73.basename(dir)
37815
+ repoPath: path74.relative(workingDir, dir),
37816
+ repoName: path74.basename(dir)
37640
37817
  });
37641
37818
  return;
37642
37819
  }
@@ -37644,14 +37821,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
37644
37821
  if (!entry.isDirectory) continue;
37645
37822
  if (entry.name === "node_modules") continue;
37646
37823
  if (entry.name === "dist" || entry.name === "build") continue;
37647
- await walk(path73.join(dir, entry.name), depth + 1);
37824
+ await walk(path74.join(dir, entry.name), depth + 1);
37648
37825
  }
37649
37826
  }
37650
37827
  }
37651
37828
 
37652
37829
  // src/services/turn-files/files-outbox.ts
37653
- var fs63 = __toESM(require("fs/promises"));
37654
- var path74 = __toESM(require("path"));
37830
+ var fs64 = __toESM(require("fs/promises"));
37831
+ var path75 = __toESM(require("path"));
37655
37832
  var import_os12 = require("os");
37656
37833
  var HOME_OUTBOX_DIR = ".codeam/outbox";
37657
37834
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -37684,16 +37861,16 @@ var FilesOutbox = class {
37684
37861
  backoffIndex = 0;
37685
37862
  stopped = false;
37686
37863
  constructor(opts) {
37687
- const base = opts.baseDir ?? path74.join(homeDir(), HOME_OUTBOX_DIR);
37688
- this.filePath = path74.join(base, `${opts.sessionId}.jsonl`);
37864
+ const base = opts.baseDir ?? path75.join(homeDir(), HOME_OUTBOX_DIR);
37865
+ this.filePath = path75.join(base, `${opts.sessionId}.jsonl`);
37689
37866
  this.post = opts.post;
37690
37867
  this.autoSchedule = opts.autoSchedule !== false;
37691
37868
  }
37692
37869
  /** Persist the entry to disk and trigger a flush. Returns once the
37693
37870
  * line is durable on disk (not once the POST succeeds). */
37694
37871
  async enqueue(entry) {
37695
- await fs63.mkdir(path74.dirname(this.filePath), { recursive: true });
37696
- await fs63.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
37872
+ await fs64.mkdir(path75.dirname(this.filePath), { recursive: true });
37873
+ await fs64.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
37697
37874
  this.backoffIndex = 0;
37698
37875
  if (this.autoSchedule) this.scheduleFlush(0);
37699
37876
  }
@@ -37784,7 +37961,7 @@ var FilesOutbox = class {
37784
37961
  async readAll() {
37785
37962
  let raw = "";
37786
37963
  try {
37787
- raw = await fs63.readFile(this.filePath, "utf8");
37964
+ raw = await fs64.readFile(this.filePath, "utf8");
37788
37965
  } catch {
37789
37966
  return [];
37790
37967
  }
@@ -37808,12 +37985,12 @@ var FilesOutbox = class {
37808
37985
  async rewrite(entries) {
37809
37986
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
37810
37987
  if (entries.length === 0) {
37811
- await fs63.unlink(this.filePath).catch(() => void 0);
37988
+ await fs64.unlink(this.filePath).catch(() => void 0);
37812
37989
  return;
37813
37990
  }
37814
37991
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
37815
- await fs63.writeFile(tmpPath, payload, "utf8");
37816
- await fs63.rename(tmpPath, this.filePath);
37992
+ await fs64.writeFile(tmpPath, payload, "utf8");
37993
+ await fs64.rename(tmpPath, this.filePath);
37817
37994
  }
37818
37995
  };
37819
37996
  function applyJitter(ms) {
@@ -38360,11 +38537,11 @@ async function postCredentialSync(opts, fetchImpl = fetch) {
38360
38537
  }
38361
38538
 
38362
38539
  // src/packs/gates.ts
38363
- var import_node_child_process22 = require("child_process");
38364
- var fs64 = __toESM(require("fs"));
38365
- var path75 = __toESM(require("path"));
38540
+ var import_node_child_process23 = require("child_process");
38541
+ var fs65 = __toESM(require("fs"));
38542
+ var path76 = __toESM(require("path"));
38366
38543
  var defaultCommandRunner = (file, args2, cwd, timeoutMs, env) => new Promise((resolve12) => {
38367
- (0, import_node_child_process22.execFile)(
38544
+ (0, import_node_child_process23.execFile)(
38368
38545
  file,
38369
38546
  args2,
38370
38547
  {
@@ -38412,7 +38589,7 @@ async function changedFiles(run, cwd, from, to) {
38412
38589
  }
38413
38590
  function readWorkspaceFile(cwd, relPath) {
38414
38591
  try {
38415
- return fs64.readFileSync(path75.join(cwd, relPath), "utf8");
38592
+ return fs65.readFileSync(path76.join(cwd, relPath), "utf8");
38416
38593
  } catch {
38417
38594
  return null;
38418
38595
  }
@@ -38421,14 +38598,14 @@ var NO_TEST_PLACEHOLDER = 'echo "Error: no test specified"';
38421
38598
  var CHECKS_TIMEOUT_MS = 5 * 6e4;
38422
38599
  function detectChecksCommand(cwd) {
38423
38600
  try {
38424
- const cfg = JSON.parse(fs64.readFileSync(path75.join(cwd, ".codeam", "pack.json"), "utf8"));
38601
+ const cfg = JSON.parse(fs65.readFileSync(path76.join(cwd, ".codeam", "pack.json"), "utf8"));
38425
38602
  if (typeof cfg.checksCommand === "string" && cfg.checksCommand.trim().length > 0) {
38426
38603
  return cfg.checksCommand.trim();
38427
38604
  }
38428
38605
  } catch {
38429
38606
  }
38430
38607
  try {
38431
- const pkg = JSON.parse(fs64.readFileSync(path75.join(cwd, "package.json"), "utf8"));
38608
+ const pkg = JSON.parse(fs65.readFileSync(path76.join(cwd, "package.json"), "utf8"));
38432
38609
  const test = pkg.scripts?.test;
38433
38610
  if (typeof test === "string" && test.trim().length > 0 && !test.includes(NO_TEST_PLACEHOLDER)) {
38434
38611
  return "npm test";
@@ -38446,39 +38623,39 @@ ${res.stderr}`.trim();
38446
38623
  }
38447
38624
 
38448
38625
  // src/packs/run-store.ts
38449
- var fs65 = __toESM(require("fs"));
38450
- var path76 = __toESM(require("path"));
38626
+ var fs66 = __toESM(require("fs"));
38627
+ var path77 = __toESM(require("path"));
38451
38628
  var crypto5 = __toESM(require("crypto"));
38452
38629
  function packsDir(cwd) {
38453
- return path76.join(cwd, ".codeam", "packs");
38630
+ return path77.join(cwd, ".codeam", "packs");
38454
38631
  }
38455
38632
  function runDir(cwd, runId) {
38456
- return path76.join(packsDir(cwd), runId);
38633
+ return path77.join(packsDir(cwd), runId);
38457
38634
  }
38458
38635
  function newRunId() {
38459
38636
  return `pk_${Date.now().toString(36)}_${crypto5.randomBytes(4).toString("hex")}`;
38460
38637
  }
38461
38638
  function writeJsonAtomic(file, value) {
38462
- fs65.mkdirSync(path76.dirname(file), { recursive: true });
38639
+ fs66.mkdirSync(path77.dirname(file), { recursive: true });
38463
38640
  const tmp = `${file}.tmp`;
38464
- fs65.writeFileSync(tmp, JSON.stringify(value, null, 2));
38465
- fs65.renameSync(tmp, file);
38641
+ fs66.writeFileSync(tmp, JSON.stringify(value, null, 2));
38642
+ fs66.renameSync(tmp, file);
38466
38643
  }
38467
38644
  function saveRun(cwd, state) {
38468
- writeJsonAtomic(path76.join(runDir(cwd, state.runId), "run.json"), state);
38645
+ writeJsonAtomic(path77.join(runDir(cwd, state.runId), "run.json"), state);
38469
38646
  }
38470
38647
  function saveStageHandoff(cwd, runId, stageIndex, role, handoff) {
38471
38648
  const name = `${String(stageIndex + 1).padStart(2, "0")}-${role}.json`;
38472
- writeJsonAtomic(path76.join(runDir(cwd, runId), name), handoff);
38649
+ writeJsonAtomic(path77.join(runDir(cwd, runId), name), handoff);
38473
38650
  }
38474
38651
  function loadLatestRun(cwd) {
38475
38652
  try {
38476
38653
  const dir = packsDir(cwd);
38477
- const entries = fs65.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
38654
+ const entries = fs66.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
38478
38655
  for (let i = entries.length - 1; i >= 0; i--) {
38479
- const file = path76.join(dir, entries[i], "run.json");
38656
+ const file = path77.join(dir, entries[i], "run.json");
38480
38657
  try {
38481
- const parsed = JSON.parse(fs65.readFileSync(file, "utf8"));
38658
+ const parsed = JSON.parse(fs66.readFileSync(file, "utf8"));
38482
38659
  if (parsed && typeof parsed.runId === "string") return parsed;
38483
38660
  } catch {
38484
38661
  }
@@ -38489,17 +38666,17 @@ function loadLatestRun(cwd) {
38489
38666
  }
38490
38667
  function ensureLedgerIgnored(cwd) {
38491
38668
  try {
38492
- const gitDir = path76.join(cwd, ".git");
38493
- if (!fs65.existsSync(gitDir)) return;
38494
- const exclude = path76.join(gitDir, "info", "exclude");
38669
+ const gitDir = path77.join(cwd, ".git");
38670
+ if (!fs66.existsSync(gitDir)) return;
38671
+ const exclude = path77.join(gitDir, "info", "exclude");
38495
38672
  let existing = "";
38496
38673
  try {
38497
- existing = fs65.readFileSync(exclude, "utf8");
38674
+ existing = fs66.readFileSync(exclude, "utf8");
38498
38675
  } catch {
38499
38676
  }
38500
38677
  if (existing.includes(".codeam/packs/")) return;
38501
- fs65.mkdirSync(path76.dirname(exclude), { recursive: true });
38502
- fs65.writeFileSync(exclude, `${existing.trimEnd()}
38678
+ fs66.mkdirSync(path77.dirname(exclude), { recursive: true });
38679
+ fs66.writeFileSync(exclude, `${existing.trimEnd()}
38503
38680
  .codeam/packs/
38504
38681
  `.trimStart());
38505
38682
  } catch {
@@ -39479,6 +39656,93 @@ async function mcpRouter() {
39479
39656
  });
39480
39657
  }
39481
39658
 
39659
+ // src/integrations/mcp-secrets.ts
39660
+ var fs68 = __toESM(require("fs"));
39661
+ var os53 = __toESM(require("os"));
39662
+ var path79 = __toESM(require("path"));
39663
+ var MCP_SECRETS_FILE_ENV = "CODEAM_MCP_SECRETS_FILE";
39664
+ function mcpSecretsDir() {
39665
+ return path79.join(os53.homedir(), ".codeam", "mcp-secrets");
39666
+ }
39667
+ function mcpSecretsPath(scope, pid = process.pid) {
39668
+ return path79.join(mcpSecretsDir(), `${pid}-${scope}.json`);
39669
+ }
39670
+ var registeredForCleanup = /* @__PURE__ */ new Set();
39671
+ function readFileVars(file) {
39672
+ try {
39673
+ const parsed = JSON.parse(fs68.readFileSync(file, "utf8"));
39674
+ if (!parsed || typeof parsed !== "object") return {};
39675
+ const out2 = {};
39676
+ for (const [k2, v] of Object.entries(parsed)) {
39677
+ if (typeof v === "string") out2[k2] = v;
39678
+ }
39679
+ return out2;
39680
+ } catch {
39681
+ return {};
39682
+ }
39683
+ }
39684
+ function pidAlive(pid) {
39685
+ try {
39686
+ process.kill(pid, 0);
39687
+ return true;
39688
+ } catch (err) {
39689
+ return err.code === "EPERM";
39690
+ }
39691
+ }
39692
+ function pruneStale(dir) {
39693
+ let names = [];
39694
+ try {
39695
+ names = fs68.readdirSync(dir);
39696
+ } catch {
39697
+ return;
39698
+ }
39699
+ for (const name of names) {
39700
+ const m = /^(\d+)-[a-z]+\.json$/.exec(name);
39701
+ if (!m) continue;
39702
+ const pid = Number(m[1]);
39703
+ if (pid === process.pid || pidAlive(pid)) continue;
39704
+ try {
39705
+ fs68.unlinkSync(path79.join(dir, name));
39706
+ } catch {
39707
+ }
39708
+ }
39709
+ }
39710
+ function writeMcpSecrets(vars, file) {
39711
+ try {
39712
+ const dir = path79.dirname(file);
39713
+ fs68.mkdirSync(dir, { recursive: true, mode: 448 });
39714
+ pruneStale(dir);
39715
+ const tmp = `${file}.${process.pid}.tmp`;
39716
+ fs68.writeFileSync(tmp, JSON.stringify(vars), { mode: 384 });
39717
+ fs68.renameSync(tmp, file);
39718
+ fs68.chmodSync(file, 384);
39719
+ if (!registeredForCleanup.has(file)) {
39720
+ registeredForCleanup.add(file);
39721
+ process.once("exit", () => {
39722
+ try {
39723
+ fs68.unlinkSync(file);
39724
+ } catch {
39725
+ }
39726
+ });
39727
+ }
39728
+ return file;
39729
+ } catch {
39730
+ return null;
39731
+ }
39732
+ }
39733
+ function mcpSecretEnv(scope, vars) {
39734
+ const file = writeMcpSecrets(vars, mcpSecretsPath(scope));
39735
+ if (file) return [{ name: MCP_SECRETS_FILE_ENV, value: file }];
39736
+ return Object.entries(vars).map(([name, value]) => ({ name, value }));
39737
+ }
39738
+ function loadMcpSecrets(env = process.env) {
39739
+ const file = env[MCP_SECRETS_FILE_ENV];
39740
+ if (!file) return;
39741
+ for (const [k2, v] of Object.entries(readFileVars(file))) {
39742
+ if (env[k2] === void 0) env[k2] = v;
39743
+ }
39744
+ }
39745
+
39482
39746
  // src/commands/preview-mcp.ts
39483
39747
  var PREVIEW_MCP_SERVER_NAME = "codeagent_preview";
39484
39748
  var PREVIEW_IPC_URL_ENV = "CODEAM_PREVIEW_IPC_URL";
@@ -39536,18 +39800,17 @@ function previewMcpServer(bridge) {
39536
39800
  // Same runtime + entrypoint as this CLI — never trust the agent's PATH.
39537
39801
  command: process.execPath,
39538
39802
  args: [process.argv[1], "preview-mcp"],
39539
- env: [
39540
- { name: PREVIEW_IPC_URL_ENV, value: bridge.url },
39541
- { name: PREVIEW_IPC_TOKEN_ENV, value: bridge.token }
39542
- ]
39803
+ // The token rides the owner-only secrets file, never this env: the
39804
+ // claude ACP adapter copies MCP env onto argv (codeagent-5bew).
39805
+ env: [{ name: PREVIEW_IPC_URL_ENV, value: bridge.url }, ...mcpSecretEnv("preview", { [PREVIEW_IPC_TOKEN_ENV]: bridge.token })]
39543
39806
  };
39544
39807
  }
39545
39808
  function httpCall(baseUrl, token) {
39546
- return async (path96, method, body, timeoutMs) => {
39809
+ return async (path97, method, body, timeoutMs) => {
39547
39810
  const ac = new AbortController();
39548
39811
  const timer = setTimeout(() => ac.abort(), timeoutMs);
39549
39812
  try {
39550
- const res = await fetch(`${baseUrl}${path96}`, {
39813
+ const res = await fetch(`${baseUrl}${path97}`, {
39551
39814
  method,
39552
39815
  headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
39553
39816
  ...method === "POST" ? { body: JSON.stringify(body ?? {}) } : {},
@@ -39642,6 +39905,12 @@ async function previewMcp() {
39642
39905
  }
39643
39906
 
39644
39907
  // src/integrations/provision.ts
39908
+ function secretVars(ctx) {
39909
+ return {
39910
+ ...ctx.pluginAuthToken ? { CODEAM_MCP_PLUGIN_TOKEN: ctx.pluginAuthToken } : {},
39911
+ ...ctx.pollSecret ? { CODEAM_MCP_POLL_SECRET: ctx.pollSecret } : {}
39912
+ };
39913
+ }
39645
39914
  function buildMcpServersForStart(ctx) {
39646
39915
  const servers = buildIntegrationMcpServers(ctx);
39647
39916
  const preview = previewMcpServer(ctx.preview ?? null);
@@ -39661,9 +39930,10 @@ function buildIntegrationMcpServers(ctx) {
39661
39930
  { name: "CODEAM_MCP_INTEGRATION_ID", value: entry.id },
39662
39931
  { name: "CODEAM_MCP_SESSION_ID", value: ctx.sessionId },
39663
39932
  { name: "CODEAM_MCP_PLUGIN_ID", value: ctx.pluginId },
39664
- // Plugin token in ENV, never argv — argv is visible via `ps`.
39665
- { name: "CODEAM_MCP_PLUGIN_TOKEN", value: ctx.pluginAuthToken },
39666
- ...ctx.pollSecret ? [{ name: "CODEAM_MCP_POLL_SECRET", value: ctx.pollSecret }] : []
39933
+ // ⚠️ Secrets via an owner-only FILE, not env values: the claude ACP
39934
+ // adapter copies this env onto the agent's argv (`--mcp-config`), where
39935
+ // `ps` shows it (codeagent-5bew). See `mcp-secrets.ts`.
39936
+ ...mcpSecretEnv("integrations", secretVars(ctx))
39667
39937
  ];
39668
39938
  servers.push({
39669
39939
  name: entry.id,
@@ -39692,8 +39962,7 @@ function buildIntegrationMcpServers(ctx) {
39692
39962
  env: [
39693
39963
  { name: "CODEAM_MCP_SESSION_ID", value: ctx.sessionId },
39694
39964
  { name: "CODEAM_MCP_PLUGIN_ID", value: ctx.pluginId },
39695
- { name: "CODEAM_MCP_PLUGIN_TOKEN", value: ctx.pluginAuthToken },
39696
- ...ctx.pollSecret ? [{ name: "CODEAM_MCP_POLL_SECRET", value: ctx.pollSecret }] : []
39965
+ ...mcpSecretEnv("integrations", secretVars(ctx))
39697
39966
  ]
39698
39967
  }
39699
39968
  ];
@@ -40263,7 +40532,7 @@ function logMentionOutcome(result) {
40263
40532
  }
40264
40533
 
40265
40534
  // src/agents/acp/command-handlers.ts
40266
- var import_node_child_process23 = require("child_process");
40535
+ var import_node_child_process24 = require("child_process");
40267
40536
 
40268
40537
  // src/agents/acp/buildAcpPromptBlocks.ts
40269
40538
  var MIME_FROM_EXT = {
@@ -41225,7 +41494,7 @@ async function prewarmNewMcpEntries(manifest, previousIds) {
41225
41494
  fresh.map(
41226
41495
  (e) => new Promise((resolve12) => {
41227
41496
  const mcp = e.delivery.mcp;
41228
- const child = (0, import_node_child_process23.execFile)(
41497
+ const child = (0, import_node_child_process24.execFile)(
41229
41498
  mcp.command,
41230
41499
  [...mcp.args, "--help"],
41231
41500
  { timeout: 9e4 },
@@ -42394,11 +42663,11 @@ async function runAcpSession(opts) {
42394
42663
  if (swapOpts.house) {
42395
42664
  houseWireId = swapOpts.wireId ?? HOUSE_AGENT_ID;
42396
42665
  if (pendingHouseConfig) {
42397
- persistHouseProxyConfig(pendingHouseConfig);
42666
+ persistHouseProxyConfig(pendingHouseConfig, deployIdFromWorkspace(process.cwd()) ?? void 0);
42398
42667
  pendingHouseConfig = null;
42399
42668
  }
42400
42669
  } else if (wasHouse) {
42401
- clearHouseProxyConfig();
42670
+ clearHouseProxyConfig(deployIdFromWorkspace(process.cwd()) ?? void 0);
42402
42671
  }
42403
42672
  const managedBanner = swapOpts.house && isManagedProviderId(houseWireId) ? houseWireId : null;
42404
42673
  void publisher.publishOutput({
@@ -42437,17 +42706,17 @@ async function runAcpSession(opts) {
42437
42706
  switchCredentialEnv = provisionAgentCredentials(agentId, auth);
42438
42707
  },
42439
42708
  provisionHouseProxy: ({ baseUrl, token, model, managedAgentId }) => {
42440
- const claudeConfigDir = path80.join(
42441
- os53.homedir(),
42709
+ const claudeConfigDir = path82.join(
42710
+ os55.homedir(),
42442
42711
  ".codeam",
42443
42712
  "house-claude",
42444
42713
  `switch-${opts.pluginId}`
42445
42714
  );
42446
42715
  try {
42447
- fs69.mkdirSync(claudeConfigDir, { recursive: true, mode: 448 });
42716
+ fs71.mkdirSync(claudeConfigDir, { recursive: true, mode: 448 });
42448
42717
  } catch {
42449
42718
  }
42450
- const memoryFile = path80.join(claudeConfigDir, "CLAUDE.md");
42719
+ const memoryFile = path82.join(claudeConfigDir, "CLAUDE.md");
42451
42720
  ensureBeadsWorkflowHint(void 0, memoryFile);
42452
42721
  ensureAgentStandard(void 0, memoryFile);
42453
42722
  const cfg = {
@@ -43670,9 +43939,9 @@ function pickPinnedSession(pinnedId, listSessions2) {
43670
43939
  }
43671
43940
 
43672
43941
  // src/agents/retired-proxy-cleanup.ts
43673
- var fs70 = __toESM(require("fs"));
43674
- var path81 = __toESM(require("path"));
43675
- var os54 = __toESM(require("os"));
43942
+ var fs72 = __toESM(require("fs"));
43943
+ var path83 = __toESM(require("path"));
43944
+ var os56 = __toESM(require("os"));
43676
43945
  var RETIRED_PROXY_RE = /^https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):8787(?:[/?#]|$)/i;
43677
43946
  var HEADROOM_CMD_RE = /(^|[\s/"'])headroom(\s|$)/i;
43678
43947
  var MARKETPLACE_KEY = "headroom-marketplace";
@@ -43681,12 +43950,12 @@ function isHeadroomHook(group) {
43681
43950
  (h) => typeof h?.command === "string" && HEADROOM_CMD_RE.test(h.command)
43682
43951
  );
43683
43952
  }
43684
- function sanitizeRetiredProxyConfig(homeDir2 = os54.homedir()) {
43953
+ function sanitizeRetiredProxyConfig(homeDir2 = os56.homedir()) {
43685
43954
  const out2 = { inspected: false, changed: false, removed: [] };
43686
- const file = path81.join(homeDir2, ".claude", "settings.json");
43955
+ const file = path83.join(homeDir2, ".claude", "settings.json");
43687
43956
  let parsed;
43688
43957
  try {
43689
- parsed = JSON.parse(fs70.readFileSync(file, "utf8"));
43958
+ parsed = JSON.parse(fs72.readFileSync(file, "utf8"));
43690
43959
  } catch {
43691
43960
  return out2;
43692
43961
  }
@@ -43728,9 +43997,9 @@ function sanitizeRetiredProxyConfig(homeDir2 = os54.homedir()) {
43728
43997
  if (!out2.changed) return out2;
43729
43998
  try {
43730
43999
  const tmp = `${file}.codeam.tmp`;
43731
- fs70.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
44000
+ fs72.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
43732
44001
  `, { mode: 384 });
43733
- fs70.renameSync(tmp, file);
44002
+ fs72.renameSync(tmp, file);
43734
44003
  } catch {
43735
44004
  out2.changed = false;
43736
44005
  }
@@ -44262,7 +44531,7 @@ var AcpDriver = class {
44262
44531
  };
44263
44532
 
44264
44533
  // src/baton/transcript-mirror.ts
44265
- var fs71 = __toESM(require("fs"));
44534
+ var fs73 = __toESM(require("fs"));
44266
44535
  var TranscriptMirror = class {
44267
44536
  constructor(deps) {
44268
44537
  this.deps = deps;
@@ -44356,7 +44625,7 @@ var TranscriptMirror = class {
44356
44625
  }
44357
44626
  };
44358
44627
  function defaultWatch(file, onChange) {
44359
- const w3 = fs71.watch(file, { persistent: false }, () => onChange());
44628
+ const w3 = fs73.watch(file, { persistent: false }, () => onChange());
44360
44629
  return () => w3.close();
44361
44630
  }
44362
44631
 
@@ -44666,7 +44935,7 @@ function toEpochMs(ts) {
44666
44935
  }
44667
44936
 
44668
44937
  // src/services/keep-awake.ts
44669
- var import_node_child_process24 = require("child_process");
44938
+ var import_node_child_process25 = require("child_process");
44670
44939
  function keepDeviceAwake(deps = {}) {
44671
44940
  const env = deps.env ?? process.env;
44672
44941
  const isLocal = deps.isLocal ?? isLocalSession(env);
@@ -44676,7 +44945,7 @@ function keepDeviceAwake(deps = {}) {
44676
44945
  if (env.CODEAM_NO_KEEP_AWAKE === "1") return noop;
44677
44946
  const command2 = deps.command !== void 0 ? deps.command : createOsStrategy().keepAwakeCommand(deps.pid ?? process.pid);
44678
44947
  if (!command2) return noop;
44679
- const spawnFn = deps.spawnFn ?? import_node_child_process24.spawn;
44948
+ const spawnFn = deps.spawnFn ?? import_node_child_process25.spawn;
44680
44949
  let child = null;
44681
44950
  try {
44682
44951
  child = spawnFn(command2.cmd, command2.args, { stdio: "ignore", detached: true });
@@ -44702,16 +44971,16 @@ function keepDeviceAwake(deps = {}) {
44702
44971
  }
44703
44972
 
44704
44973
  // src/agents/claude/onboarding.ts
44705
- var fs72 = __toESM(require("fs"));
44706
- var os56 = __toESM(require("os"));
44707
- var path82 = __toESM(require("path"));
44974
+ var fs74 = __toESM(require("fs"));
44975
+ var os58 = __toESM(require("os"));
44976
+ var path84 = __toESM(require("path"));
44708
44977
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
44709
44978
  function ensureClaudeOnboarded(cwd) {
44710
44979
  try {
44711
- const file = path82.join(os56.homedir(), ".claude.json");
44980
+ const file = path84.join(os58.homedir(), ".claude.json");
44712
44981
  let config = {};
44713
44982
  try {
44714
- config = JSON.parse(fs72.readFileSync(file, "utf8"));
44983
+ config = JSON.parse(fs74.readFileSync(file, "utf8"));
44715
44984
  } catch {
44716
44985
  }
44717
44986
  let changed = false;
@@ -44736,8 +45005,8 @@ function ensureClaudeOnboarded(cwd) {
44736
45005
  }
44737
45006
  }
44738
45007
  if (!changed) return;
44739
- fs72.mkdirSync(path82.dirname(file), { recursive: true });
44740
- fs72.writeFileSync(file, JSON.stringify(config, null, 2));
45008
+ fs74.mkdirSync(path84.dirname(file), { recursive: true });
45009
+ fs74.writeFileSync(file, JSON.stringify(config, null, 2));
44741
45010
  log.info(
44742
45011
  "claude",
44743
45012
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -45514,8 +45783,8 @@ var import_picocolors10 = __toESM(require("picocolors"));
45514
45783
  var import_child_process30 = require("child_process");
45515
45784
  var import_util4 = require("util");
45516
45785
  var import_picocolors8 = __toESM(require("picocolors"));
45517
- var path83 = __toESM(require("path"));
45518
- var execFileP5 = (0, import_util4.promisify)(import_child_process30.execFile);
45786
+ var path85 = __toESM(require("path"));
45787
+ var execFileP6 = (0, import_util4.promisify)(import_child_process30.execFile);
45519
45788
  var MAX_BUFFER = 8 * 1024 * 1024;
45520
45789
  function resetStdinForChild() {
45521
45790
  if (process.stdin.isTTY) {
@@ -45532,11 +45801,11 @@ var GitHubCodespacesProvider = class {
45532
45801
  available = true;
45533
45802
  async authorize() {
45534
45803
  try {
45535
- await execFileP5("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45804
+ await execFileP6("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45536
45805
  } catch {
45537
45806
  await this.tryInstallGh();
45538
45807
  try {
45539
- await execFileP5("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45808
+ await execFileP6("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45540
45809
  } catch {
45541
45810
  throw new Error(
45542
45811
  [
@@ -45552,7 +45821,7 @@ var GitHubCodespacesProvider = class {
45552
45821
  }
45553
45822
  let isAuthed = false;
45554
45823
  try {
45555
- await execFileP5("gh", ["auth", "status"], { maxBuffer: MAX_BUFFER });
45824
+ await execFileP6("gh", ["auth", "status"], { maxBuffer: MAX_BUFFER });
45556
45825
  isAuthed = true;
45557
45826
  } catch {
45558
45827
  }
@@ -45628,7 +45897,7 @@ var GitHubCodespacesProvider = class {
45628
45897
  */
45629
45898
  async getActiveGhUser() {
45630
45899
  try {
45631
- const { stdout } = await execFileP5(
45900
+ const { stdout } = await execFileP6(
45632
45901
  "gh",
45633
45902
  ["api", "user", "--jq", ".login"],
45634
45903
  { maxBuffer: MAX_BUFFER }
@@ -45648,7 +45917,7 @@ var GitHubCodespacesProvider = class {
45648
45917
  */
45649
45918
  async hasCodespaceScope() {
45650
45919
  try {
45651
- const { stdout } = await execFileP5(
45920
+ const { stdout } = await execFileP6(
45652
45921
  "gh",
45653
45922
  ["api", "-i", "user"],
45654
45923
  { maxBuffer: MAX_BUFFER }
@@ -45697,7 +45966,7 @@ var GitHubCodespacesProvider = class {
45697
45966
  let installCmd = null;
45698
45967
  if (platform3 === "darwin") {
45699
45968
  try {
45700
- await execFileP5("brew", ["--version"], { maxBuffer: MAX_BUFFER });
45969
+ await execFileP6("brew", ["--version"], { maxBuffer: MAX_BUFFER });
45701
45970
  } catch {
45702
45971
  wt(
45703
45972
  [
@@ -45716,7 +45985,7 @@ var GitHubCodespacesProvider = class {
45716
45985
  };
45717
45986
  } else if (platform3 === "win32") {
45718
45987
  try {
45719
- await execFileP5("winget", ["--version"], { maxBuffer: MAX_BUFFER });
45988
+ await execFileP6("winget", ["--version"], { maxBuffer: MAX_BUFFER });
45720
45989
  } catch {
45721
45990
  wt(
45722
45991
  [
@@ -45795,7 +46064,7 @@ var GitHubCodespacesProvider = class {
45795
46064
  "200"
45796
46065
  );
45797
46066
  try {
45798
- const { stdout } = await execFileP5("gh", args2, { maxBuffer: MAX_BUFFER });
46067
+ const { stdout } = await execFileP6("gh", args2, { maxBuffer: MAX_BUFFER });
45799
46068
  return JSON.parse(stdout);
45800
46069
  } catch {
45801
46070
  return [];
@@ -45804,7 +46073,7 @@ var GitHubCodespacesProvider = class {
45804
46073
  const own = await fetchRepos();
45805
46074
  let orgRepos = [];
45806
46075
  try {
45807
- const { stdout } = await execFileP5(
46076
+ const { stdout } = await execFileP6(
45808
46077
  "gh",
45809
46078
  ["api", "--paginate", "user/orgs", "--jq", ".[].login"],
45810
46079
  { maxBuffer: MAX_BUFFER }
@@ -45841,7 +46110,7 @@ var GitHubCodespacesProvider = class {
45841
46110
  */
45842
46111
  async listMachineTypes(projectId) {
45843
46112
  try {
45844
- const { stdout } = await execFileP5(
46113
+ const { stdout } = await execFileP6(
45845
46114
  "gh",
45846
46115
  ["api", `/repos/${projectId}/codespaces/machines`],
45847
46116
  { maxBuffer: MAX_BUFFER }
@@ -45872,7 +46141,7 @@ var GitHubCodespacesProvider = class {
45872
46141
  const machine = machineTypeId ?? await this.pickDefaultMachine(projectId);
45873
46142
  const args2 = ["codespace", "create", "-R", projectId, "--default-permissions"];
45874
46143
  if (machine) args2.push("-m", machine);
45875
- const { stdout } = await execFileP5(
46144
+ const { stdout } = await execFileP6(
45876
46145
  "gh",
45877
46146
  args2,
45878
46147
  { maxBuffer: MAX_BUFFER, timeout: 12e4 }
@@ -45912,7 +46181,7 @@ var GitHubCodespacesProvider = class {
45912
46181
  async waitUntilAvailable(name) {
45913
46182
  const deadline = Date.now() + 5 * 60 * 1e3;
45914
46183
  while (Date.now() < deadline) {
45915
- const { stdout } = await execFileP5(
46184
+ const { stdout } = await execFileP6(
45916
46185
  "gh",
45917
46186
  ["codespace", "list", "--json", "name,state"],
45918
46187
  { maxBuffer: MAX_BUFFER }
@@ -45930,7 +46199,7 @@ var GitHubCodespacesProvider = class {
45930
46199
  }
45931
46200
  async exec(workspaceId, command2) {
45932
46201
  try {
45933
- const { stdout, stderr } = await execFileP5(
46202
+ const { stdout, stderr } = await execFileP6(
45934
46203
  "gh",
45935
46204
  ["codespace", "ssh", "-c", workspaceId, "--", command2],
45936
46205
  { maxBuffer: MAX_BUFFER, timeout: 6e5 }
@@ -46003,7 +46272,7 @@ var GitHubCodespacesProvider = class {
46003
46272
  });
46004
46273
  }
46005
46274
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46006
- const remoteDir = path83.posix.dirname(remotePath);
46275
+ const remoteDir = path85.posix.dirname(remotePath);
46007
46276
  const parts = [
46008
46277
  `mkdir -p ${shellQuote(remoteDir)}`,
46009
46278
  `cat > ${shellQuote(remotePath)}`
@@ -46035,7 +46304,7 @@ var GitHubCodespacesProvider = class {
46035
46304
  try {
46036
46305
  const args2 = ["codespace", "list", "--json", "name,displayName,state,lastUsedAt"];
46037
46306
  if (projectId) args2.push("--repo", projectId);
46038
- const { stdout } = await execFileP5("gh", args2, { maxBuffer: MAX_BUFFER });
46307
+ const { stdout } = await execFileP6("gh", args2, { maxBuffer: MAX_BUFFER });
46039
46308
  const list = JSON.parse(stdout);
46040
46309
  return list.map((c2) => ({
46041
46310
  id: c2.name,
@@ -46050,7 +46319,7 @@ var GitHubCodespacesProvider = class {
46050
46319
  }
46051
46320
  async startWorkspace(workspaceId) {
46052
46321
  try {
46053
- await execFileP5(
46322
+ await execFileP6(
46054
46323
  "gh",
46055
46324
  ["api", "-X", "POST", `/user/codespaces/${workspaceId}/start`],
46056
46325
  { maxBuffer: MAX_BUFFER, timeout: 6e4 }
@@ -46073,9 +46342,9 @@ function shellQuote(s) {
46073
46342
  // src/services/providers/gitpod.ts
46074
46343
  var import_child_process31 = require("child_process");
46075
46344
  var import_util5 = require("util");
46076
- var path84 = __toESM(require("path"));
46345
+ var path86 = __toESM(require("path"));
46077
46346
  var import_picocolors9 = __toESM(require("picocolors"));
46078
- var execFileP6 = (0, import_util5.promisify)(import_child_process31.execFile);
46347
+ var execFileP7 = (0, import_util5.promisify)(import_child_process31.execFile);
46079
46348
  var MAX_BUFFER2 = 8 * 1024 * 1024;
46080
46349
  function resetStdinForChild2() {
46081
46350
  if (process.stdin.isTTY) {
@@ -46092,7 +46361,7 @@ var GitpodProvider = class {
46092
46361
  available = true;
46093
46362
  async authorize() {
46094
46363
  try {
46095
- await execFileP6("gitpod", ["--version"], { maxBuffer: MAX_BUFFER2 });
46364
+ await execFileP7("gitpod", ["--version"], { maxBuffer: MAX_BUFFER2 });
46096
46365
  } catch {
46097
46366
  throw new Error(
46098
46367
  [
@@ -46105,7 +46374,7 @@ var GitpodProvider = class {
46105
46374
  );
46106
46375
  }
46107
46376
  try {
46108
- await execFileP6("gitpod", ["whoami"], { maxBuffer: MAX_BUFFER2 });
46377
+ await execFileP7("gitpod", ["whoami"], { maxBuffer: MAX_BUFFER2 });
46109
46378
  return;
46110
46379
  } catch {
46111
46380
  }
@@ -46125,7 +46394,7 @@ var GitpodProvider = class {
46125
46394
  }
46126
46395
  async listProjects() {
46127
46396
  try {
46128
- const { stdout } = await execFileP6(
46397
+ const { stdout } = await execFileP7(
46129
46398
  "gitpod",
46130
46399
  ["workspace", "list", "--output", "json", "--limit", "200"],
46131
46400
  { maxBuffer: MAX_BUFFER2 }
@@ -46158,7 +46427,7 @@ var GitpodProvider = class {
46158
46427
  async createWorkspace(projectId, machineTypeId) {
46159
46428
  const args2 = ["workspace", "create", projectId, "--start", "--output", "json"];
46160
46429
  if (machineTypeId) args2.push("--class", machineTypeId);
46161
- const { stdout } = await execFileP6("gitpod", args2, {
46430
+ const { stdout } = await execFileP7("gitpod", args2, {
46162
46431
  maxBuffer: MAX_BUFFER2,
46163
46432
  timeout: 3e5
46164
46433
  });
@@ -46182,7 +46451,7 @@ var GitpodProvider = class {
46182
46451
  const deadline = Date.now() + 5 * 60 * 1e3;
46183
46452
  while (Date.now() < deadline) {
46184
46453
  try {
46185
- const { stdout } = await execFileP6(
46454
+ const { stdout } = await execFileP7(
46186
46455
  "gitpod",
46187
46456
  ["workspace", "get", workspaceId, "--output", "json"],
46188
46457
  { maxBuffer: MAX_BUFFER2 }
@@ -46200,7 +46469,7 @@ var GitpodProvider = class {
46200
46469
  }
46201
46470
  async listMachineTypes(_projectId) {
46202
46471
  try {
46203
- const { stdout } = await execFileP6(
46472
+ const { stdout } = await execFileP7(
46204
46473
  "gitpod",
46205
46474
  ["organization", "list-classes", "--output", "json"],
46206
46475
  { maxBuffer: MAX_BUFFER2 }
@@ -46218,7 +46487,7 @@ var GitpodProvider = class {
46218
46487
  async listExistingWorkspaces(projectId) {
46219
46488
  try {
46220
46489
  const args2 = ["workspace", "list", "--output", "json", "--limit", "200"];
46221
- const { stdout } = await execFileP6("gitpod", args2, { maxBuffer: MAX_BUFFER2 });
46490
+ const { stdout } = await execFileP7("gitpod", args2, { maxBuffer: MAX_BUFFER2 });
46222
46491
  const list = JSON.parse(stdout);
46223
46492
  return list.filter((w3) => !projectId || w3.contextUrl === projectId).map((w3) => ({
46224
46493
  id: w3.id,
@@ -46233,7 +46502,7 @@ var GitpodProvider = class {
46233
46502
  }
46234
46503
  async startWorkspace(workspaceId) {
46235
46504
  try {
46236
- await execFileP6(
46505
+ await execFileP7(
46237
46506
  "gitpod",
46238
46507
  ["workspace", "start", workspaceId],
46239
46508
  { maxBuffer: MAX_BUFFER2, timeout: 6e4 }
@@ -46249,7 +46518,7 @@ var GitpodProvider = class {
46249
46518
  }
46250
46519
  async exec(workspaceId, command2) {
46251
46520
  try {
46252
- const { stdout, stderr } = await execFileP6(
46521
+ const { stdout, stderr } = await execFileP7(
46253
46522
  "gitpod",
46254
46523
  ["workspace", "ssh", workspaceId, "--", command2],
46255
46524
  { maxBuffer: MAX_BUFFER2, timeout: 6e5 }
@@ -46313,7 +46582,7 @@ var GitpodProvider = class {
46313
46582
  });
46314
46583
  }
46315
46584
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46316
- const remoteDir = path84.posix.dirname(remotePath);
46585
+ const remoteDir = path86.posix.dirname(remotePath);
46317
46586
  const parts = [
46318
46587
  `mkdir -p ${shellQuote2(remoteDir)}`,
46319
46588
  `cat > ${shellQuote2(remotePath)}`
@@ -46349,8 +46618,8 @@ function shellQuote2(s) {
46349
46618
  // src/services/providers/gitlab-workspaces.ts
46350
46619
  var import_child_process32 = require("child_process");
46351
46620
  var import_util6 = require("util");
46352
- var path85 = __toESM(require("path"));
46353
- var execFileP7 = (0, import_util6.promisify)(import_child_process32.execFile);
46621
+ var path87 = __toESM(require("path"));
46622
+ var execFileP8 = (0, import_util6.promisify)(import_child_process32.execFile);
46354
46623
  var MAX_BUFFER3 = 8 * 1024 * 1024;
46355
46624
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
46356
46625
  function resetStdinForChild3() {
@@ -46368,7 +46637,7 @@ var GitLabWorkspacesProvider = class {
46368
46637
  available = true;
46369
46638
  async authorize() {
46370
46639
  try {
46371
- await execFileP7("glab", ["--version"], { maxBuffer: MAX_BUFFER3 });
46640
+ await execFileP8("glab", ["--version"], { maxBuffer: MAX_BUFFER3 });
46372
46641
  } catch {
46373
46642
  throw new Error(
46374
46643
  [
@@ -46382,7 +46651,7 @@ var GitLabWorkspacesProvider = class {
46382
46651
  );
46383
46652
  }
46384
46653
  try {
46385
- await execFileP7("glab", ["auth", "status"], { maxBuffer: MAX_BUFFER3 });
46654
+ await execFileP8("glab", ["auth", "status"], { maxBuffer: MAX_BUFFER3 });
46386
46655
  return;
46387
46656
  } catch {
46388
46657
  }
@@ -46406,7 +46675,7 @@ var GitLabWorkspacesProvider = class {
46406
46675
  }
46407
46676
  async listProjects() {
46408
46677
  try {
46409
- const { stdout } = await execFileP7(
46678
+ const { stdout } = await execFileP8(
46410
46679
  "glab",
46411
46680
  ["repo", "list", "--per-page", "200", "--output", "json"],
46412
46681
  { maxBuffer: MAX_BUFFER3 }
@@ -46538,7 +46807,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
46538
46807
  async exec(workspaceId, command2) {
46539
46808
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
46540
46809
  try {
46541
- const { stdout, stderr } = await execFileP7(
46810
+ const { stdout, stderr } = await execFileP8(
46542
46811
  "ssh",
46543
46812
  [
46544
46813
  "-o",
@@ -46609,7 +46878,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
46609
46878
  }
46610
46879
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46611
46880
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
46612
- const remoteDir = path85.posix.dirname(remotePath);
46881
+ const remoteDir = path87.posix.dirname(remotePath);
46613
46882
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
46614
46883
  if (options.mode != null) {
46615
46884
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -46641,7 +46910,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
46641
46910
  */
46642
46911
  async getGlabToken() {
46643
46912
  try {
46644
- const { stdout, stderr } = await execFileP7(
46913
+ const { stdout, stderr } = await execFileP8(
46645
46914
  "glab",
46646
46915
  ["auth", "status", "--show-token"],
46647
46916
  { maxBuffer: MAX_BUFFER3 }
@@ -46677,8 +46946,8 @@ function shellQuote3(s) {
46677
46946
  // src/services/providers/railway.ts
46678
46947
  var import_child_process33 = require("child_process");
46679
46948
  var import_util7 = require("util");
46680
- var path86 = __toESM(require("path"));
46681
- var execFileP8 = (0, import_util7.promisify)(import_child_process33.execFile);
46949
+ var path88 = __toESM(require("path"));
46950
+ var execFileP9 = (0, import_util7.promisify)(import_child_process33.execFile);
46682
46951
  var MAX_BUFFER4 = 8 * 1024 * 1024;
46683
46952
  function resetStdinForChild4() {
46684
46953
  if (process.stdin.isTTY) {
@@ -46695,7 +46964,7 @@ var RailwayProvider = class {
46695
46964
  available = true;
46696
46965
  async authorize() {
46697
46966
  try {
46698
- await execFileP8("railway", ["--version"], { maxBuffer: MAX_BUFFER4 });
46967
+ await execFileP9("railway", ["--version"], { maxBuffer: MAX_BUFFER4 });
46699
46968
  } catch {
46700
46969
  throw new Error(
46701
46970
  [
@@ -46709,7 +46978,7 @@ var RailwayProvider = class {
46709
46978
  );
46710
46979
  }
46711
46980
  try {
46712
- await execFileP8("railway", ["whoami"], { maxBuffer: MAX_BUFFER4 });
46981
+ await execFileP9("railway", ["whoami"], { maxBuffer: MAX_BUFFER4 });
46713
46982
  return;
46714
46983
  } catch {
46715
46984
  }
@@ -46729,7 +46998,7 @@ var RailwayProvider = class {
46729
46998
  }
46730
46999
  async listProjects() {
46731
47000
  try {
46732
- const { stdout } = await execFileP8(
47001
+ const { stdout } = await execFileP9(
46733
47002
  "railway",
46734
47003
  ["list", "--json"],
46735
47004
  { maxBuffer: MAX_BUFFER4 }
@@ -46745,7 +47014,7 @@ var RailwayProvider = class {
46745
47014
  }));
46746
47015
  } catch {
46747
47016
  try {
46748
- const { stdout } = await execFileP8("railway", ["list"], { maxBuffer: MAX_BUFFER4 });
47017
+ const { stdout } = await execFileP9("railway", ["list"], { maxBuffer: MAX_BUFFER4 });
46749
47018
  const projects = [];
46750
47019
  for (const line of stdout.split("\n")) {
46751
47020
  const trimmed = line.trim();
@@ -46796,7 +47065,7 @@ var RailwayProvider = class {
46796
47065
  async listExistingWorkspaces(projectId) {
46797
47066
  if (!projectId) return [];
46798
47067
  try {
46799
- const { stdout } = await execFileP8(
47068
+ const { stdout } = await execFileP9(
46800
47069
  "railway",
46801
47070
  ["service", "list", "--project", projectId, "--json"],
46802
47071
  { maxBuffer: MAX_BUFFER4 }
@@ -46821,7 +47090,7 @@ var RailwayProvider = class {
46821
47090
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
46822
47091
  }
46823
47092
  try {
46824
- await execFileP8(
47093
+ await execFileP9(
46825
47094
  "railway",
46826
47095
  ["service", "restart", "--service", serviceId, "--project", projectId],
46827
47096
  { maxBuffer: MAX_BUFFER4, timeout: 6e4 }
@@ -46840,7 +47109,7 @@ var RailwayProvider = class {
46840
47109
  };
46841
47110
  }
46842
47111
  try {
46843
- const { stdout, stderr } = await execFileP8(
47112
+ const { stdout, stderr } = await execFileP9(
46844
47113
  "railway",
46845
47114
  ["run", "--project", projectId, "--service", serviceId, "--", "bash", "-lc", command2],
46846
47115
  { maxBuffer: MAX_BUFFER4, timeout: 6e5 }
@@ -46913,7 +47182,7 @@ var RailwayProvider = class {
46913
47182
  if (!projectId || !serviceId) {
46914
47183
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
46915
47184
  }
46916
- const remoteDir = path86.posix.dirname(remotePath);
47185
+ const remoteDir = path88.posix.dirname(remotePath);
46917
47186
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
46918
47187
  if (options.mode != null) {
46919
47188
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -47453,14 +47722,14 @@ async function stopWorkspaceFromLocal(target) {
47453
47722
  }
47454
47723
 
47455
47724
  // src/commands/host/host-client.ts
47456
- var fs73 = __toESM(require("fs"));
47457
- var os57 = __toESM(require("os"));
47458
- var path87 = __toESM(require("path"));
47725
+ var fs75 = __toESM(require("fs"));
47726
+ var os59 = __toESM(require("os"));
47727
+ var path89 = __toESM(require("path"));
47459
47728
  var import_node_crypto12 = require("crypto");
47460
47729
  function sampleCpuTimes() {
47461
47730
  let idle = 0;
47462
47731
  let total = 0;
47463
- for (const cpu of os57.cpus()) {
47732
+ for (const cpu of os59.cpus()) {
47464
47733
  const t2 = cpu.times;
47465
47734
  idle += t2.idle;
47466
47735
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -47479,8 +47748,8 @@ var MetricsCollector = class {
47479
47748
  const prev = this.prevCpu;
47480
47749
  this.prevCpu = current2;
47481
47750
  if (!prev) {
47482
- const cores = os57.cpus().length || 1;
47483
- const proxy = os57.loadavg()[0] / cores * 100;
47751
+ const cores = os59.cpus().length || 1;
47752
+ const proxy = os59.loadavg()[0] / cores * 100;
47484
47753
  return Math.min(100, Math.max(0, Math.round(proxy)));
47485
47754
  }
47486
47755
  const idleDelta = current2.idle - prev.idle;
@@ -47493,8 +47762,8 @@ var MetricsCollector = class {
47493
47762
  collect() {
47494
47763
  return {
47495
47764
  cpuPct: this.cpuPct(),
47496
- ramUsedMb: Math.round((os57.totalmem() - os57.freemem()) / 1048576),
47497
- ramTotalMb: Math.round(os57.totalmem() / 1048576),
47765
+ ramUsedMb: Math.round((os59.totalmem() - os59.freemem()) / 1048576),
47766
+ ramTotalMb: Math.round(os59.totalmem() / 1048576),
47498
47767
  latencyMs: this.lastLatencyMs
47499
47768
  };
47500
47769
  }
@@ -47503,19 +47772,19 @@ function apiBase() {
47503
47772
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
47504
47773
  }
47505
47774
  function hostIdentityPath() {
47506
- return path87.join(os57.homedir(), ".codeam", "host-agent.json");
47775
+ return path89.join(os59.homedir(), ".codeam", "host-agent.json");
47507
47776
  }
47508
47777
  function collectOsInfo() {
47509
47778
  return {
47510
- distro: os57.platform(),
47511
- arch: os57.arch(),
47512
- kernel: os57.release(),
47779
+ distro: os59.platform(),
47780
+ arch: os59.arch(),
47781
+ kernel: os59.release(),
47513
47782
  nodeVersion: process.versions.node
47514
47783
  };
47515
47784
  }
47516
47785
  function loadHostIdentity() {
47517
47786
  try {
47518
- const raw = fs73.readFileSync(hostIdentityPath(), "utf8");
47787
+ const raw = fs75.readFileSync(hostIdentityPath(), "utf8");
47519
47788
  const parsed = JSON.parse(raw);
47520
47789
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
47521
47790
  const p2 = parsed;
@@ -47534,8 +47803,8 @@ function loadHostIdentity() {
47534
47803
  }
47535
47804
  function saveHostIdentity(identity) {
47536
47805
  const file = hostIdentityPath();
47537
- fs73.mkdirSync(path87.dirname(file), { recursive: true, mode: 448 });
47538
- fs73.writeFileSync(file, JSON.stringify(identity, null, 2), {
47806
+ fs75.mkdirSync(path89.dirname(file), { recursive: true, mode: 448 });
47807
+ fs75.writeFileSync(file, JSON.stringify(identity, null, 2), {
47539
47808
  encoding: "utf8",
47540
47809
  mode: 384
47541
47810
  });
@@ -47580,7 +47849,7 @@ function isTerminalEnrollError(err) {
47580
47849
  }
47581
47850
  function deleteHostIdentity() {
47582
47851
  try {
47583
- fs73.rmSync(hostIdentityPath(), { force: true });
47852
+ fs75.rmSync(hostIdentityPath(), { force: true });
47584
47853
  } catch {
47585
47854
  }
47586
47855
  }
@@ -47604,7 +47873,7 @@ async function postJson(pathname, body) {
47604
47873
  function resolveHostLabel(label) {
47605
47874
  const explicit = label?.trim();
47606
47875
  const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
47607
- const resolved = explicit || envLabel || os57.hostname();
47876
+ const resolved = explicit || envLabel || os59.hostname();
47608
47877
  return resolved.slice(0, 80);
47609
47878
  }
47610
47879
  async function redeemEnrollToken(token, label) {
@@ -47793,9 +48062,9 @@ async function host(args2) {
47793
48062
 
47794
48063
  // src/commands/host-agent.ts
47795
48064
  var import_node_child_process30 = require("child_process");
47796
- var os62 = __toESM(require("os"));
47797
- var fs78 = __toESM(require("fs"));
47798
- var path92 = __toESM(require("path"));
48065
+ var os63 = __toESM(require("os"));
48066
+ var fs79 = __toESM(require("fs"));
48067
+ var path93 = __toESM(require("path"));
47799
48068
 
47800
48069
  // src/skills/persist-from-payload.ts
47801
48070
  function persistOrClearSkillsFromPayload(skills) {
@@ -47804,13 +48073,13 @@ function persistOrClearSkillsFromPayload(skills) {
47804
48073
  }
47805
48074
 
47806
48075
  // src/commands/host/session-state.ts
47807
- var fs74 = __toESM(require("fs"));
47808
- var os58 = __toESM(require("os"));
47809
- var path88 = __toESM(require("path"));
48076
+ var fs76 = __toESM(require("fs"));
48077
+ var os60 = __toESM(require("os"));
48078
+ var path90 = __toESM(require("path"));
47810
48079
  function hostSessionStatePath(env = process.env) {
47811
48080
  const override = env.CODEAM_HOST_SESSION_STATE_FILE;
47812
48081
  if (override && override.trim()) return override.trim();
47813
- return path88.join(os58.homedir(), ".codeam", "host-agent-sessions.json");
48082
+ return path90.join(os60.homedir(), ".codeam", "host-agent-sessions.json");
47814
48083
  }
47815
48084
  function isRecord5(v) {
47816
48085
  if (typeof v !== "object" || v === null) return false;
@@ -47821,7 +48090,7 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
47821
48090
  return {
47822
48091
  load() {
47823
48092
  try {
47824
- const raw = JSON.parse(fs74.readFileSync(file, "utf8"));
48093
+ const raw = JSON.parse(fs76.readFileSync(file, "utf8"));
47825
48094
  return Array.isArray(raw?.sessions) ? raw.sessions.filter(isRecord5) : [];
47826
48095
  } catch {
47827
48096
  return [];
@@ -47829,18 +48098,18 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
47829
48098
  },
47830
48099
  save(list) {
47831
48100
  try {
47832
- fs74.mkdirSync(path88.dirname(file), { recursive: true, mode: 448 });
48101
+ fs76.mkdirSync(path90.dirname(file), { recursive: true, mode: 448 });
47833
48102
  const tmp = `${file}.${process.pid}.tmp`;
47834
- fs74.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
48103
+ fs76.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
47835
48104
  mode: 384
47836
48105
  });
47837
- fs74.renameSync(tmp, file);
48106
+ fs76.renameSync(tmp, file);
47838
48107
  } catch {
47839
48108
  }
47840
48109
  },
47841
48110
  clear() {
47842
48111
  try {
47843
- fs74.rmSync(file, { force: true });
48112
+ fs76.rmSync(file, { force: true });
47844
48113
  } catch {
47845
48114
  }
47846
48115
  }
@@ -47863,181 +48132,22 @@ function planSessionResume(records, max) {
47863
48132
  return { resume: ordered.slice(0, bound), dropped: ordered.slice(bound) };
47864
48133
  }
47865
48134
  function pickSavedSessionForWorkspace(sessions3, cwd) {
47866
- const target = path88.resolve(cwd);
48135
+ const target = path90.resolve(cwd);
47867
48136
  const matches = sessions3.filter(
47868
- (s) => !!s.cwd && path88.resolve(s.cwd) === target && !!s.pluginId && !!s.pollSecret && !!s.agent
48137
+ (s) => !!s.cwd && path90.resolve(s.cwd) === target && !!s.pluginId && !!s.pollSecret && !!s.agent
47869
48138
  );
47870
48139
  if (matches.length === 0) return null;
47871
48140
  matches.sort((a, b) => b.pairedAt - a.pairedAt);
47872
48141
  return matches[0];
47873
48142
  }
47874
48143
 
47875
- // src/commands/host/workspace.ts
47876
- var fs75 = __toESM(require("fs"));
47877
- var os59 = __toESM(require("os"));
47878
- var path89 = __toESM(require("path"));
47879
- var import_node_child_process25 = require("child_process");
47880
- var import_node_util5 = require("util");
47881
- var execFileP9 = (0, import_node_util5.promisify)(import_node_child_process25.execFile);
47882
- function isAbsolutePathTarget(target) {
47883
- return path89.isAbsolute(target);
47884
- }
47885
- function selfHostedWorkspaceRoot() {
47886
- return path89.join(os59.homedir(), ".codeam", "self-hosted");
47887
- }
47888
- function deployIdFromWorkspace(cwd) {
47889
- if (!cwd) return null;
47890
- const root = selfHostedWorkspaceRoot();
47891
- const resolved = path89.resolve(cwd);
47892
- const rel = path89.relative(root, resolved);
47893
- if (!rel || rel.startsWith("..") || path89.isAbsolute(rel)) return null;
47894
- const parts = rel.split(path89.sep).filter(Boolean);
47895
- if (parts.length !== 1) return null;
47896
- return parts[0];
47897
- }
47898
- function nonInteractiveGitEnv() {
47899
- return {
47900
- ...process.env,
47901
- GIT_TERMINAL_PROMPT: "0",
47902
- GIT_ASKPASS: "",
47903
- GCM_INTERACTIVE: "never"
47904
- };
47905
- }
47906
- function githubOwnerRepo(repoRef) {
47907
- const trimmed = repoRef.trim();
47908
- const shorthand = /^([^/\s]+)\/([^/\s]+?)(?:\.git)?$/.exec(trimmed);
47909
- if (shorthand && !/^https?:\/\//.test(trimmed) && !trimmed.startsWith("git@")) {
47910
- return { owner: shorthand[1], repo: shorthand[2] };
47911
- }
47912
- const httpsMatch = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/.exec(trimmed);
47913
- if (httpsMatch) return { owner: httpsMatch[1], repo: httpsMatch[2] };
47914
- return null;
47915
- }
47916
- function gitlabProjectPath(repoRef) {
47917
- const trimmed = repoRef.trim();
47918
- const https9 = /^https?:\/\/gitlab\.com\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
47919
- if (https9) return https9[1];
47920
- if (!/^https?:\/\//.test(trimmed) && !trimmed.startsWith("git@") && trimmed.includes("/")) {
47921
- return trimmed.replace(/\.git$/, "");
47922
- }
47923
- return null;
47924
- }
47925
- function repoCloneUrl(repoRef, cloneToken, provider = "github") {
47926
- const trimmed = repoRef.trim();
47927
- if (provider === "gitlab") {
47928
- const glPath = gitlabProjectPath(trimmed);
47929
- if (glPath) {
47930
- return cloneToken ? `https://oauth2:${cloneToken}@gitlab.com/${glPath}.git` : `https://gitlab.com/${glPath}.git`;
47931
- }
47932
- if (/^https?:\/\//.test(trimmed) || trimmed.startsWith("git@")) return trimmed;
47933
- }
47934
- if (cloneToken) {
47935
- const gh = githubOwnerRepo(trimmed);
47936
- if (gh) {
47937
- return `https://x-access-token:${cloneToken}@github.com/${gh.owner}/${gh.repo}.git`;
47938
- }
47939
- }
47940
- if (/^https?:\/\//.test(trimmed) || trimmed.startsWith("git@")) return trimmed;
47941
- return `https://github.com/${trimmed.replace(/\.git$/, "")}.git`;
47942
- }
47943
- function maskCloneUrl(url2) {
47944
- return url2.replace(/(https?:\/\/)[^@/]+@/, "$1***@");
47945
- }
47946
- async function fetchGithubIdentity(token) {
47947
- try {
47948
- const res = await fetch("https://api.github.com/user", {
47949
- headers: {
47950
- Authorization: `Bearer ${token}`,
47951
- "User-Agent": "codeam-cli",
47952
- Accept: "application/vnd.github+json"
47953
- }
47954
- });
47955
- if (!res.ok) return null;
47956
- const body = await res.json();
47957
- return { login: body.login, email: body.email ?? void 0 };
47958
- } catch {
47959
- return null;
47960
- }
47961
- }
47962
- async function configureGitCredentials(dest, repoRef, cloneToken, provider = "github") {
47963
- const isGitlab = provider === "gitlab";
47964
- if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
47965
- if (!cloneToken) return;
47966
- const credFile = path89.join(dest, ".git", "codeam-credentials");
47967
- const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
47968
- ` : `https://x-access-token:${cloneToken}@github.com
47969
- `;
47970
- fs75.writeFileSync(credFile, credLine, { mode: 384 });
47971
- restrictToOwner(credFile);
47972
- const env = nonInteractiveGitEnv();
47973
- const git2 = (args2) => execFileP9("git", ["-C", dest, ...args2], { timeout: 3e4, env });
47974
- const credFilePosix = credFile.split(path89.sep).join("/");
47975
- await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
47976
- });
47977
- await git2([
47978
- "config",
47979
- "--local",
47980
- "--add",
47981
- "credential.helper",
47982
- `store --file=${credFilePosix}`
47983
- ]).catch(() => {
47984
- });
47985
- await git2(["remote", "set-url", "origin", repoCloneUrl(repoRef, void 0, provider)]).catch(() => {
47986
- });
47987
- const hasIdentity = await git2(["config", "user.email"]).then(() => true).catch(() => false);
47988
- if (!hasIdentity) {
47989
- const who = isGitlab ? null : await fetchGithubIdentity(cloneToken);
47990
- const login = who?.login ?? "CodeAgent";
47991
- await git2(["config", "--local", "user.name", login]).catch(() => {
47992
- });
47993
- const email = who?.email ?? (isGitlab ? "agent@codeagent-mobile.com" : `${login}@users.noreply.github.com`);
47994
- await git2(["config", "--local", "user.email", email]).catch(() => {
47995
- });
47996
- }
47997
- }
47998
- function maskToken(text, cloneToken) {
47999
- const masked = maskCloneUrl(text);
48000
- if (cloneToken && cloneToken.length > 0) {
48001
- return masked.split(cloneToken).join("***");
48002
- }
48003
- return masked;
48004
- }
48005
- async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
48006
- if (isAbsolutePathTarget(repoOrPath)) {
48007
- if (!fs75.existsSync(repoOrPath)) {
48008
- throw new Error(`deploy target path does not exist: ${repoOrPath}`);
48009
- }
48010
- return repoOrPath;
48011
- }
48012
- const dest = path89.join(selfHostedWorkspaceRoot(), deployId);
48013
- if (fs75.existsSync(path89.join(dest, ".git"))) {
48014
- if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
48015
- return dest;
48016
- }
48017
- fs75.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
48018
- const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
48019
- const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
48020
- try {
48021
- await execFileP9("git", cloneArgs, {
48022
- timeout: 12e4,
48023
- maxBuffer: 16 * 1024 * 1024,
48024
- env: nonInteractiveGitEnv()
48025
- });
48026
- } catch (err) {
48027
- const reason = err instanceof Error ? err.message : String(err);
48028
- throw new Error(`git clone failed for ${maskCloneUrl(cloneUrl)}: ${maskToken(reason, cloneToken)}`);
48029
- }
48030
- if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
48031
- return dest;
48032
- }
48033
-
48034
48144
  // src/commands/host/git-tooling.ts
48035
48145
  var import_node_child_process26 = require("child_process");
48036
- var fs76 = __toESM(require("fs"));
48037
- var os60 = __toESM(require("os"));
48038
- var path90 = __toESM(require("path"));
48146
+ var fs77 = __toESM(require("fs"));
48147
+ var os61 = __toESM(require("os"));
48148
+ var path91 = __toESM(require("path"));
48039
48149
  function codeamBinDir() {
48040
- return process.env.CODEAM_BIN_DIR ?? path90.join(os60.homedir(), ".codeam", "bin");
48150
+ return process.env.CODEAM_BIN_DIR ?? path91.join(os61.homedir(), ".codeam", "bin");
48041
48151
  }
48042
48152
  var FALLBACK_GH_VERSION = "2.62.0";
48043
48153
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -48069,7 +48179,7 @@ async function download(url2, dest) {
48069
48179
  const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
48070
48180
  if (!res.ok || !res.body) return false;
48071
48181
  const buf = Buffer.from(await res.arrayBuffer());
48072
- fs76.writeFileSync(dest, buf);
48182
+ fs77.writeFileSync(dest, buf);
48073
48183
  return true;
48074
48184
  } catch {
48075
48185
  return false;
@@ -48092,8 +48202,8 @@ async function ensureGhCli(runner, token, deps = {}) {
48092
48202
  const version3 = await resolveVersionFn(token);
48093
48203
  const asset = `gh_${version3}_${osToken}_${arch2}`;
48094
48204
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
48095
- const tmpRoot = fs76.mkdtempSync(path90.join(os60.tmpdir(), "codeam-gh-"));
48096
- const archive = path90.join(tmpRoot, `${asset}.${ext}`);
48205
+ const tmpRoot = fs77.mkdtempSync(path91.join(os61.tmpdir(), "codeam-gh-"));
48206
+ const archive = path91.join(tmpRoot, `${asset}.${ext}`);
48097
48207
  if (!await downloadFn(url2, archive)) {
48098
48208
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
48099
48209
  return null;
@@ -48103,16 +48213,16 @@ async function ensureGhCli(runner, token, deps = {}) {
48103
48213
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
48104
48214
  return null;
48105
48215
  }
48106
- const extractedBin = path90.join(tmpRoot, asset, "bin", binaryName);
48107
- if (!fs76.existsSync(extractedBin)) {
48216
+ const extractedBin = path91.join(tmpRoot, asset, "bin", binaryName);
48217
+ if (!fs77.existsSync(extractedBin)) {
48108
48218
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
48109
48219
  return null;
48110
48220
  }
48111
48221
  const binDir = codeamBinDir();
48112
- fs76.mkdirSync(binDir, { recursive: true });
48113
- const target = path90.join(binDir, binaryName);
48114
- fs76.copyFileSync(extractedBin, target);
48115
- fs76.chmodSync(target, 493);
48222
+ fs77.mkdirSync(binDir, { recursive: true });
48223
+ const target = path91.join(binDir, binaryName);
48224
+ fs77.copyFileSync(extractedBin, target);
48225
+ fs77.chmodSync(target, 493);
48116
48226
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
48117
48227
  return target;
48118
48228
  } catch (e) {
@@ -48149,19 +48259,19 @@ async function ensureGhAuth(runner, ghCmd, token) {
48149
48259
  }
48150
48260
  function ghConfigDir() {
48151
48261
  if (process.env.GH_CONFIG_DIR) return process.env.GH_CONFIG_DIR;
48152
- if (process.env.XDG_CONFIG_HOME) return path90.join(process.env.XDG_CONFIG_HOME, "gh");
48262
+ if (process.env.XDG_CONFIG_HOME) return path91.join(process.env.XDG_CONFIG_HOME, "gh");
48153
48263
  if (process.platform === "win32" && process.env.APPDATA) {
48154
- return path90.join(process.env.APPDATA, "GitHub CLI");
48264
+ return path91.join(process.env.APPDATA, "GitHub CLI");
48155
48265
  }
48156
- return path90.join(os60.homedir(), ".config", "gh");
48266
+ return path91.join(os61.homedir(), ".config", "gh");
48157
48267
  }
48158
48268
  function writeGhHostsToken(token) {
48159
48269
  try {
48160
48270
  const dir = ghConfigDir();
48161
- const file = path90.join(dir, "hosts.yml");
48162
- if (fs76.existsSync(file)) return false;
48163
- fs76.mkdirSync(dir, { recursive: true, mode: 448 });
48164
- fs76.writeFileSync(
48271
+ const file = path91.join(dir, "hosts.yml");
48272
+ if (fs77.existsSync(file)) return false;
48273
+ fs77.mkdirSync(dir, { recursive: true, mode: 448 });
48274
+ fs77.writeFileSync(
48165
48275
  file,
48166
48276
  `github.com:
48167
48277
  oauth_token: ${token}
@@ -48204,8 +48314,8 @@ async function ensureGlabCli(runner, deps = {}) {
48204
48314
  const version3 = await resolveLatestGlabVersion();
48205
48315
  const asset = `glab_${version3}_${osToken}_${arch2}`;
48206
48316
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
48207
- const tmpRoot = fs76.mkdtempSync(path90.join(os60.tmpdir(), "codeam-glab-"));
48208
- const archive = path90.join(tmpRoot, `${asset}.${ext}`);
48317
+ const tmpRoot = fs77.mkdtempSync(path91.join(os61.tmpdir(), "codeam-glab-"));
48318
+ const archive = path91.join(tmpRoot, `${asset}.${ext}`);
48209
48319
  if (!await downloadFn(url2, archive)) {
48210
48320
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
48211
48321
  return null;
@@ -48216,20 +48326,20 @@ async function ensureGlabCli(runner, deps = {}) {
48216
48326
  return null;
48217
48327
  }
48218
48328
  const candidates = [
48219
- path90.join(tmpRoot, "bin", binaryName),
48220
- path90.join(tmpRoot, asset, "bin", binaryName),
48221
- path90.join(tmpRoot, binaryName)
48329
+ path91.join(tmpRoot, "bin", binaryName),
48330
+ path91.join(tmpRoot, asset, "bin", binaryName),
48331
+ path91.join(tmpRoot, binaryName)
48222
48332
  ];
48223
- const extractedBin = candidates.find((c2) => fs76.existsSync(c2));
48333
+ const extractedBin = candidates.find((c2) => fs77.existsSync(c2));
48224
48334
  if (!extractedBin) {
48225
48335
  log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
48226
48336
  return null;
48227
48337
  }
48228
48338
  const binDir = codeamBinDir();
48229
- fs76.mkdirSync(binDir, { recursive: true });
48230
- const target = path90.join(binDir, binaryName);
48231
- fs76.copyFileSync(extractedBin, target);
48232
- fs76.chmodSync(target, 493);
48339
+ fs77.mkdirSync(binDir, { recursive: true });
48340
+ const target = path91.join(binDir, binaryName);
48341
+ fs77.copyFileSync(extractedBin, target);
48342
+ fs77.chmodSync(target, 493);
48233
48343
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
48234
48344
  return target;
48235
48345
  } catch (e) {
@@ -48311,9 +48421,9 @@ var defaultGitToolingRunner = {
48311
48421
  var import_node_child_process28 = require("child_process");
48312
48422
 
48313
48423
  // src/lib/updateNotifier.ts
48314
- var fs77 = __toESM(require("fs"));
48315
- var os61 = __toESM(require("os"));
48316
- var path91 = __toESM(require("path"));
48424
+ var fs78 = __toESM(require("fs"));
48425
+ var os62 = __toESM(require("os"));
48426
+ var path92 = __toESM(require("path"));
48317
48427
  var https8 = __toESM(require("https"));
48318
48428
  var import_node_child_process27 = require("child_process");
48319
48429
  var import_picocolors12 = __toESM(require("picocolors"));
@@ -48322,12 +48432,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
48322
48432
  var TTL_MS = 24 * 60 * 60 * 1e3;
48323
48433
  var REQUEST_TIMEOUT_MS = 1500;
48324
48434
  function cachePath() {
48325
- const dir = path91.join(os61.homedir(), ".codeam");
48326
- return path91.join(dir, "update-check.json");
48435
+ const dir = path92.join(os62.homedir(), ".codeam");
48436
+ return path92.join(dir, "update-check.json");
48327
48437
  }
48328
48438
  function readCache() {
48329
48439
  try {
48330
- const raw = fs77.readFileSync(cachePath(), "utf8");
48440
+ const raw = fs78.readFileSync(cachePath(), "utf8");
48331
48441
  const parsed = JSON.parse(raw);
48332
48442
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
48333
48443
  return parsed;
@@ -48338,10 +48448,10 @@ function readCache() {
48338
48448
  function writeCache(cache) {
48339
48449
  try {
48340
48450
  const file = cachePath();
48341
- fs77.mkdirSync(path91.dirname(file), { recursive: true });
48451
+ fs78.mkdirSync(path92.dirname(file), { recursive: true });
48342
48452
  const tmp = `${file}.${process.pid}.tmp`;
48343
- fs77.writeFileSync(tmp, JSON.stringify(cache));
48344
- fs77.renameSync(tmp, file);
48453
+ fs78.writeFileSync(tmp, JSON.stringify(cache));
48454
+ fs78.renameSync(tmp, file);
48345
48455
  } catch {
48346
48456
  }
48347
48457
  }
@@ -48415,8 +48525,8 @@ function isLinkedInstall() {
48415
48525
  timeout: 2e3
48416
48526
  }).trim();
48417
48527
  if (!root) return false;
48418
- const pkgPath = path91.join(root, PKG_NAME);
48419
- return fs77.lstatSync(pkgPath).isSymbolicLink();
48528
+ const pkgPath = path92.join(root, PKG_NAME);
48529
+ return fs78.lstatSync(pkgPath).isSymbolicLink();
48420
48530
  } catch {
48421
48531
  return false;
48422
48532
  }
@@ -48452,7 +48562,7 @@ function maybeAutoUpdate(currentVersion, latest) {
48452
48562
  return;
48453
48563
  }
48454
48564
  try {
48455
- fs77.unlinkSync(cachePath());
48565
+ fs78.unlinkSync(cachePath());
48456
48566
  } catch {
48457
48567
  }
48458
48568
  process.stderr.write(` ${import_picocolors12.default.green("\u2713")} Updated. Resuming session...
@@ -48468,7 +48578,7 @@ async function autoUpgradeBeforeCriticalCommand() {
48468
48578
  if (process.env.NODE_ENV === "test") return;
48469
48579
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
48470
48580
  if (process.env.CI) return;
48471
- const current2 = true ? "2.75.26" : null;
48581
+ const current2 = true ? "2.75.27" : null;
48472
48582
  if (!current2) return;
48473
48583
  const cache = readCache();
48474
48584
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -48485,7 +48595,7 @@ function checkForUpdates() {
48485
48595
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
48486
48596
  if (process.env.CI) return;
48487
48597
  if (!process.stdout.isTTY) return;
48488
- const current2 = true ? "2.75.26" : null;
48598
+ const current2 = true ? "2.75.27" : null;
48489
48599
  if (!current2) return;
48490
48600
  const cache = readCache();
48491
48601
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -48508,7 +48618,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
48508
48618
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
48509
48619
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
48510
48620
  function currentCliVersion() {
48511
- return true ? "2.75.26" : null;
48621
+ return true ? "2.75.27" : null;
48512
48622
  }
48513
48623
  async function installedVersion(deps) {
48514
48624
  const ls = await deps.run(
@@ -48657,6 +48767,9 @@ function isDeployPayload(p2) {
48657
48767
  function isStopPayload(p2) {
48658
48768
  return typeof p2.sessionId === "string";
48659
48769
  }
48770
+ function isResumePayload(p2) {
48771
+ return typeof p2.sessionId === "string" && p2.sessionId.length > 0;
48772
+ }
48660
48773
  function isCleanupPayload(p2) {
48661
48774
  return typeof p2.deployId === "string" && p2.deployId.length > 0;
48662
48775
  }
@@ -48945,10 +49058,7 @@ var HostAgentSupervisor = class {
48945
49058
  this.heartbeatTimer = setInterval(() => void this.beat(), HEARTBEAT_INTERVAL_MS);
48946
49059
  this.heartbeatTimer.unref?.();
48947
49060
  this.resumePersistedSessions();
48948
- void reportSessionEvent(
48949
- { hostId: this.identity.hostId, hostToken: this.identity.hostToken },
48950
- { event: "reconcile", activeDeployIds: this.activeSessions().map((s) => s.id) }
48951
- ).catch((err) => log.trace("host-agent", "boot reconcile failed (best-effort)", err));
49061
+ this.reportLiveSet("boot");
48952
49062
  const updateMs = this.selfUpdateIntervalMs();
48953
49063
  if (updateMs > 0) {
48954
49064
  this.selfUpdateTimer = setInterval(() => void this.selfUpdateTick(), updateMs);
@@ -49194,6 +49304,14 @@ var HostAgentSupervisor = class {
49194
49304
  this.stopChild(cmd.payload.sessionId);
49195
49305
  return;
49196
49306
  }
49307
+ if (cmd.type === "self_hosted_resume") {
49308
+ if (!isResumePayload(cmd.payload)) {
49309
+ log.warn("host-agent", `ignoring malformed self_hosted_resume id=${cmd.id}`);
49310
+ return;
49311
+ }
49312
+ this.resumeSavedSession(cmd.payload.sessionId);
49313
+ return;
49314
+ }
49197
49315
  if (cmd.type === "self_hosted_cleanup") {
49198
49316
  if (!isCleanupPayload(cmd.payload)) {
49199
49317
  log.warn("host-agent", `ignoring malformed self_hosted_cleanup id=${cmd.id}`);
@@ -49241,13 +49359,13 @@ var HostAgentSupervisor = class {
49241
49359
  const relay = this.relay;
49242
49360
  if (!relay) return;
49243
49361
  const raw = cmd.payload?.path;
49244
- const target = typeof raw === "string" && raw.trim() ? path92.resolve(raw.trim()) : os62.homedir();
49362
+ const target = typeof raw === "string" && raw.trim() ? path93.resolve(raw.trim()) : os63.homedir();
49245
49363
  try {
49246
- const dirents = await fs78.promises.readdir(target, { withFileTypes: true });
49364
+ const dirents = await fs79.promises.readdir(target, { withFileTypes: true });
49247
49365
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
49248
49366
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
49249
49367
  );
49250
- const parent = path92.dirname(target);
49368
+ const parent = path93.dirname(target);
49251
49369
  await relay.sendResult(cmd.id, "completed", {
49252
49370
  path: target,
49253
49371
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -49594,14 +49712,14 @@ var HostAgentSupervisor = class {
49594
49712
  ...buildHouseProxyChildEnv({ baseUrl, token, openRouter: openRouter === true }),
49595
49713
  CODEAM_AUTO_TOKEN: payload.autoPairToken
49596
49714
  };
49597
- const houseConfigDir = path92.join(
49598
- os62.homedir(),
49715
+ const houseConfigDir = path93.join(
49716
+ os63.homedir(),
49599
49717
  ".codeam",
49600
49718
  "house-claude",
49601
49719
  payload.deployId
49602
49720
  );
49603
49721
  try {
49604
- fs78.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
49722
+ fs79.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
49605
49723
  } catch {
49606
49724
  }
49607
49725
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -49611,7 +49729,7 @@ var HostAgentSupervisor = class {
49611
49729
  token,
49612
49730
  openRouter: !!openRouter,
49613
49731
  claudeConfigDir: houseConfigDir
49614
- });
49732
+ }, payload.deployId);
49615
49733
  } else {
49616
49734
  const auth = await this.resolveAgentAuth(this.identity, payload.sealedAgentAuth);
49617
49735
  const credEnv = provisionAgentCredentials(payload.agentId, auth, void 0);
@@ -49619,7 +49737,7 @@ var HostAgentSupervisor = class {
49619
49737
  ...credEnv,
49620
49738
  CODEAM_AUTO_TOKEN: payload.autoPairToken
49621
49739
  };
49622
- clearHouseProxyConfig();
49740
+ clearHouseProxyConfig(payload.deployId);
49623
49741
  }
49624
49742
  childEnv = { ...childEnv, CODEAM_AUTO_APPROVE: "1" };
49625
49743
  childEnv = { ...childEnv, CODEAM_HOST_AGENT_CHILD: "1" };
@@ -49627,7 +49745,7 @@ var HostAgentSupervisor = class {
49627
49745
  report("installing", "installing agent CLI");
49628
49746
  await this.runAgentInstall(payload.agentInstallScript);
49629
49747
  }
49630
- const home = process.env.HOME || os62.homedir();
49748
+ const home = process.env.HOME || os63.homedir();
49631
49749
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
49632
49750
  if (payload.cloneToken) {
49633
49751
  try {
@@ -49635,13 +49753,13 @@ var HostAgentSupervisor = class {
49635
49753
  if ((payload.repoProvider ?? "github") === "gitlab") {
49636
49754
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
49637
49755
  if (glabCmd) {
49638
- childEnv.PATH = `${codeamBinDir()}${path92.delimiter}${childEnv.PATH}`;
49756
+ childEnv.PATH = `${codeamBinDir()}${path93.delimiter}${childEnv.PATH}`;
49639
49757
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
49640
49758
  }
49641
49759
  } else {
49642
49760
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
49643
49761
  if (ghCmd) {
49644
- childEnv.PATH = `${codeamBinDir()}${path92.delimiter}${childEnv.PATH}`;
49762
+ childEnv.PATH = `${codeamBinDir()}${path93.delimiter}${childEnv.PATH}`;
49645
49763
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
49646
49764
  }
49647
49765
  }
@@ -49669,9 +49787,9 @@ var HostAgentSupervisor = class {
49669
49787
  );
49670
49788
  if (!payload.suppressOnboardingWelcome) {
49671
49789
  try {
49672
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path92.join(os62.homedir(), ".claude");
49673
- const projectDir = path92.join(cfgDir, "projects", encodeCwd(cwd));
49674
- const hasPriorConversation = fs78.existsSync(projectDir) && fs78.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
49790
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path93.join(os63.homedir(), ".claude");
49791
+ const projectDir = path93.join(cfgDir, "projects", encodeCwd(cwd));
49792
+ const hasPriorConversation = fs79.existsSync(projectDir) && fs79.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
49675
49793
  if (hasPriorConversation) {
49676
49794
  childEnv.CODEAM_RESUME_LATEST = "1";
49677
49795
  log.info(
@@ -49799,7 +49917,7 @@ var HostAgentSupervisor = class {
49799
49917
  );
49800
49918
  continue;
49801
49919
  }
49802
- this.resumeOne({ deployId: rec.deployId, cwd: rec.cwd, session });
49920
+ this.resumeOne({ deployId: rec.deployId, cwd: rec.cwd, session, agent: rec.agent });
49803
49921
  resumed += 1;
49804
49922
  }
49805
49923
  log.info(
@@ -49822,7 +49940,7 @@ var HostAgentSupervisor = class {
49822
49940
  fallbackResumeTarget() {
49823
49941
  const session = getActiveSession();
49824
49942
  if (!session || !session.pluginId || !session.pollSecret || !session.agent) return null;
49825
- const cwd = session.cwd && fs78.existsSync(session.cwd) ? session.cwd : process.cwd();
49943
+ const cwd = session.cwd && fs79.existsSync(session.cwd) ? session.cwd : process.cwd();
49826
49944
  const deployId = deployIdFromWorkspace(session.cwd) ?? session.id;
49827
49945
  return { deployId, cwd, session };
49828
49946
  }
@@ -49836,23 +49954,94 @@ var HostAgentSupervisor = class {
49836
49954
  }
49837
49955
  return st3;
49838
49956
  }
49957
+ /**
49958
+ * `self_hosted_resume` — the user opened (or reconnected) a session this box
49959
+ * is not running. A boot resumes only the children that were LIVE when the
49960
+ * box went down, so any other saved session was a dead card: the app said
49961
+ * "waking up — your message is queued", the box woke, and the session never
49962
+ * came back (codeagent-o7lm, QA box 2026-09-25: 4 saved sessions, 2 resumed).
49963
+ *
49964
+ * Resumes it through the same `resumeOne` a boot uses (bounded retries,
49965
+ * house-proxy env, persisted into the live set), then re-reports the live
49966
+ * set so the backend restores the session's host link. No-op when the
49967
+ * session is unknown, lacks its pairing, or its workspace is gone — the app
49968
+ * then keeps its offline state instead of a phantom "waking".
49969
+ */
49970
+ resumeSavedSession(sessionId) {
49971
+ const session = this.listSavedSessions().find((s) => s.id === sessionId);
49972
+ if (!session || !session.pluginId || !session.pollSecret || !session.agent) {
49973
+ log.warn("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: no saved pairing on this box`);
49974
+ return;
49975
+ }
49976
+ if (!session.cwd || !fs79.existsSync(session.cwd)) {
49977
+ log.warn("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: workspace is gone`);
49978
+ return;
49979
+ }
49980
+ const deployId = deployIdFromWorkspace(session.cwd) ?? session.id;
49981
+ if (this.children.has(deployId)) {
49982
+ log.info("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: already live`);
49983
+ return;
49984
+ }
49985
+ this.resumeOne({ deployId, cwd: session.cwd, session });
49986
+ this.reportLiveSet("resume");
49987
+ }
49988
+ /**
49989
+ * Tell the backend exactly which sessions this host runs. `activeSessions`
49990
+ * (additive) carries the PairedSession id of every child that knows it, so a
49991
+ * link lost to host-identity churn is rebuilt instead of the session
49992
+ * rendering as LOCAL with a reconnect the user cannot perform.
49993
+ */
49994
+ reportLiveSet(why) {
49995
+ const children = [...this.children.values()];
49996
+ void reportSessionEvent(
49997
+ { hostId: this.identity.hostId, hostToken: this.identity.hostToken },
49998
+ {
49999
+ event: "reconcile",
50000
+ activeDeployIds: children.map((c2) => c2.deployId),
50001
+ activeSessions: children.filter((c2) => typeof c2.sessionId === "string").map((c2) => ({ deployId: c2.deployId, sessionId: c2.sessionId, agent: c2.agent })),
50002
+ knownSessions: this.knownSavedSessions()
50003
+ }
50004
+ ).catch((err) => log.trace("host-agent", `${why} reconcile failed (best-effort)`, err));
50005
+ }
50006
+ /**
50007
+ * Every saved session this host could resume — a pairing whose deploy
50008
+ * workspace is still on disk — live or not. The backend links the non-live
50009
+ * ones too, so the app knows they belong to THIS box and wakes + resumes it
50010
+ * when the user opens one, instead of showing a LOCAL session with a
50011
+ * "run codeam in your terminal" the user cannot do (codeagent-bbou).
50012
+ */
50013
+ knownSavedSessions() {
50014
+ try {
50015
+ const persisted = new Map(this.sessionStore.load().map((r) => [r.deployId, r.agent]));
50016
+ for (const c2 of this.children.values()) persisted.set(c2.deployId, c2.agent);
50017
+ return this.listSavedSessions().map((s) => ({ s, deployId: deployIdFromWorkspace(s.cwd) })).filter(
50018
+ (x) => x.deployId !== null && !!x.s.cwd && fs79.existsSync(x.s.cwd)
50019
+ ).map(({ s, deployId }) => {
50020
+ const agent = persisted.get(deployId);
50021
+ return { deployId, sessionId: s.id, ...agent ? { agent } : {} };
50022
+ });
50023
+ } catch {
50024
+ return [];
50025
+ }
50026
+ }
49839
50027
  /** Spawn ONE resume child for `target` (boot, retry, or re-probe). */
49840
50028
  resumeOne(target) {
49841
50029
  const { session, deployId } = target;
49842
50030
  if (this.children.has(deployId)) return;
49843
50031
  const st3 = this.resumeStateFor(target);
49844
50032
  try {
49845
- const cwd = fs78.existsSync(target.cwd) ? target.cwd : process.cwd();
50033
+ const cwd = fs79.existsSync(target.cwd) ? target.cwd : process.cwd();
49846
50034
  const proc = this.resumeSpawner(
49847
- { ...readHouseProxyChildEnv(), CODEAM_RESUME_SESSION_ID: session.id },
50035
+ { ...readHouseProxyChildEnv(deployId), CODEAM_RESUME_SESSION_ID: session.id },
49848
50036
  cwd
49849
50037
  );
49850
50038
  const child = {
49851
50039
  deployId,
49852
50040
  proc,
49853
50041
  cwd,
49854
- agent: session.agent,
49855
- startedAt: Date.now()
50042
+ agent: target.agent ?? session.agent,
50043
+ startedAt: Date.now(),
50044
+ sessionId: session.id
49856
50045
  };
49857
50046
  this.trackChild(child);
49858
50047
  let tail = "";
@@ -49868,7 +50057,7 @@ var HostAgentSupervisor = class {
49868
50057
  return;
49869
50058
  }
49870
50059
  if (tracked && signal) {
49871
- this.onResumeChildExit(target, 128 + (os62.constants.signals[signal] ?? 9), `signal ${signal}`);
50060
+ this.onResumeChildExit(target, 128 + (os63.constants.signals[signal] ?? 9), `signal ${signal}`);
49872
50061
  return;
49873
50062
  }
49874
50063
  log.warn(
@@ -49911,7 +50100,7 @@ var HostAgentSupervisor = class {
49911
50100
  if (Date.now() - child.startedAt < CRASH_RESPAWN_MIN_UPTIME_MS) return false;
49912
50101
  const session = pickSavedSessionForWorkspace(this.listSavedSessions(), child.cwd);
49913
50102
  if (!session) return false;
49914
- const exitCode = typeof code === "number" ? code : 128 + (signal ? os62.constants.signals[signal] ?? 9 : 9);
50103
+ const exitCode = typeof code === "number" ? code : 128 + (signal ? os63.constants.signals[signal] ?? 9 : 9);
49915
50104
  log.warn(
49916
50105
  "host-agent",
49917
50106
  `session deploy=${child.deployId.slice(0, 8)} died (${signal ?? code}) after ${Math.round((Date.now() - child.startedAt) / 1e3)}s \u2014 respawning it (resume)`
@@ -50060,12 +50249,12 @@ var HostAgentSupervisor = class {
50060
50249
  this.untrackChild(deployId);
50061
50250
  }
50062
50251
  const dirs = [
50063
- path92.join(selfHostedWorkspaceRoot(), deployId),
50064
- path92.join(os62.homedir(), ".codeam", "house-claude", deployId)
50252
+ path93.join(selfHostedWorkspaceRoot(), deployId),
50253
+ path93.join(os63.homedir(), ".codeam", "house-claude", deployId)
50065
50254
  ];
50066
50255
  for (const dir of dirs) {
50067
50256
  try {
50068
- fs78.rmSync(dir, { recursive: true, force: true });
50257
+ fs79.rmSync(dir, { recursive: true, force: true });
50069
50258
  } catch (err) {
50070
50259
  log.warn(
50071
50260
  "host-agent",
@@ -50225,8 +50414,8 @@ async function invite() {
50225
50414
  var import_node_dns = require("dns");
50226
50415
  var import_node_util6 = require("util");
50227
50416
  var import_node_crypto13 = require("crypto");
50228
- var fs79 = __toESM(require("fs"));
50229
- var path93 = __toESM(require("path"));
50417
+ var fs80 = __toESM(require("fs"));
50418
+ var path94 = __toESM(require("path"));
50230
50419
  var import_picocolors14 = __toESM(require("picocolors"));
50231
50420
  var dnsResolveP = (0, import_node_util6.promisify)(import_node_dns.resolve);
50232
50421
  async function checkDns(apiBase2) {
@@ -50282,13 +50471,13 @@ async function checkHealth(apiBase2) {
50282
50471
  }
50283
50472
  }
50284
50473
  function checkConfigDir() {
50285
- const dir = path93.join(require("os").homedir(), ".codeam");
50474
+ const dir = path94.join(require("os").homedir(), ".codeam");
50286
50475
  try {
50287
- fs79.mkdirSync(dir, { recursive: true, mode: 448 });
50288
- const probe = path93.join(dir, ".doctor-probe");
50289
- fs79.writeFileSync(probe, "ok", { mode: 384 });
50290
- const read = fs79.readFileSync(probe, "utf8");
50291
- fs79.unlinkSync(probe);
50476
+ fs80.mkdirSync(dir, { recursive: true, mode: 448 });
50477
+ const probe = path94.join(dir, ".doctor-probe");
50478
+ fs80.writeFileSync(probe, "ok", { mode: 384 });
50479
+ const read = fs80.readFileSync(probe, "utf8");
50480
+ fs80.unlinkSync(probe);
50292
50481
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
50293
50482
  return {
50294
50483
  id: "config-dir",
@@ -50328,9 +50517,9 @@ function checkSessions() {
50328
50517
  }
50329
50518
  }
50330
50519
  function checkAgentBinaries() {
50331
- const os65 = createOsStrategy();
50520
+ const os66 = createOsStrategy();
50332
50521
  return getEnabledAgents().map((meta) => {
50333
- const found = os65.findInPath(meta.binaryName);
50522
+ const found = os66.findInPath(meta.binaryName);
50334
50523
  return {
50335
50524
  id: `agent-${meta.id}`,
50336
50525
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -50352,7 +50541,7 @@ function checkNodePty() {
50352
50541
  detail: "not required on this platform"
50353
50542
  };
50354
50543
  }
50355
- const vendoredPath = path93.join(__dirname, "vendor", "node-pty");
50544
+ const vendoredPath = path94.join(__dirname, "vendor", "node-pty");
50356
50545
  for (const target of [vendoredPath, "node-pty"]) {
50357
50546
  try {
50358
50547
  require(target);
@@ -50394,7 +50583,7 @@ function checkChokidar() {
50394
50583
  }
50395
50584
  async function doctor(args2 = []) {
50396
50585
  const json = args2.includes("--json");
50397
- const cliVersion = true ? "2.75.26" : "0.0.0-dev";
50586
+ const cliVersion = true ? "2.75.27" : "0.0.0-dev";
50398
50587
  const apiBase2 = resolveApiBaseUrl();
50399
50588
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
50400
50589
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -50918,7 +51107,7 @@ async function mcpWarm(argv = [], opts = {}) {
50918
51107
  // src/commands/version.ts
50919
51108
  var import_picocolors15 = __toESM(require("picocolors"));
50920
51109
  function version2() {
50921
- const v = true ? "2.75.26" : "unknown";
51110
+ const v = true ? "2.75.27" : "unknown";
50922
51111
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
50923
51112
  }
50924
51113
 
@@ -51067,10 +51256,10 @@ var EXIT_CODE_NAMES = {
51067
51256
  };
51068
51257
 
51069
51258
  // src/index.ts
51070
- var os64 = __toESM(require("os"));
51259
+ var os65 = __toESM(require("os"));
51071
51260
  if (!process.env.HOME) {
51072
51261
  try {
51073
- const home = os64.homedir();
51262
+ const home = os65.homedir();
51074
51263
  if (home) process.env.HOME = home;
51075
51264
  } catch {
51076
51265
  }
@@ -51116,6 +51305,9 @@ async function main() {
51116
51305
  await commands[command]();
51117
51306
  return;
51118
51307
  }
51308
+ if (command === "mcp-run" || command === "mcp-router" || command === "preview-mcp") {
51309
+ loadMcpSecrets();
51310
+ }
51119
51311
  if (command === "mcp-run") {
51120
51312
  return mcpRun(args);
51121
51313
  }