codeam-cli 2.75.26 → 2.75.28

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.
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.28" : "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.28",
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.28" ? { ideVersion: "2.75.28" } : {}
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
  }
@@ -24864,9 +24868,10 @@ async function bringUpInspector(targetPort, deps = {}) {
24864
24868
  const start2 = deps.start ?? startInspectorProxy;
24865
24869
  const proxy = await start2({
24866
24870
  targetPort,
24871
+ ...deps.targetHost ? { targetHost: deps.targetHost } : {},
24867
24872
  script: inspectorClientSource({ allowedOrigins: resolveInspectorOrigins(env) })
24868
24873
  });
24869
- log2(`preview inspector proxy on :${proxy.port} \u2192 :${targetPort}`);
24874
+ log2(`preview inspector proxy on :${proxy.port} \u2192 ${deps.targetHost ?? "127.0.0.1"}:${targetPort}`);
24870
24875
  return { port: proxy.port, proxy };
24871
24876
  } catch (e) {
24872
24877
  log2(`preview inspector unavailable (${e.message}) \u2014 going direct`);
@@ -24874,6 +24879,30 @@ async function bringUpInspector(targetPort, deps = {}) {
24874
24879
  }
24875
24880
  }
24876
24881
 
24882
+ // src/services/preview/served-address.ts
24883
+ var LOOPBACK_HOSTS = ["127.0.0.1", "::1"];
24884
+ var ANSI_RE2 = /\x1b\[[0-9;]*m/g;
24885
+ var LOCAL_URL_RE = /https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1?\]|\[::\]):(\d{2,5})\b/gi;
24886
+ function announcedPorts(output) {
24887
+ const clean = output.replace(ANSI_RE2, "");
24888
+ const ports = [];
24889
+ for (const m of clean.matchAll(LOCAL_URL_RE)) {
24890
+ const port = Number(m[1]);
24891
+ if (port > 0 && port < 65536) ports.push(port);
24892
+ }
24893
+ return [...new Set(ports.reverse())];
24894
+ }
24895
+ async function resolveServedAddress(output, detectedPort, deps = {}) {
24896
+ const listening = deps.listening ?? isPortListening;
24897
+ const candidates = [.../* @__PURE__ */ new Set([...announcedPorts(output), detectedPort])];
24898
+ for (const port of candidates) {
24899
+ for (const host2 of LOOPBACK_HOSTS) {
24900
+ if (await listening(port, host2)) return { host: host2, port };
24901
+ }
24902
+ }
24903
+ return { host: "127.0.0.1", port: detectedPort };
24904
+ }
24905
+
24877
24906
  // src/services/preview/start-orchestrator.ts
24878
24907
  var INSTALL_TIMEOUT_MS2 = 5 * 6e4;
24879
24908
  var SETUP_TIMEOUT_MS = 2 * 6e4;
@@ -25182,7 +25211,10 @@ async function startDevServer(ctx, extraEnv = {}) {
25182
25211
  if (verdict.adopt) {
25183
25212
  log.info("preview", `adopting the dev server already serving on port ${detection.port}`);
25184
25213
  emitProgress("READY_DETECTED", `adopted the server already on port ${detection.port}`);
25185
- return { devServer: null };
25214
+ return {
25215
+ devServer: null,
25216
+ served: await resolveServedAddress("", detection.port)
25217
+ };
25186
25218
  }
25187
25219
  emit2(USER_EVENTS.PREVIEW_ERROR, {
25188
25220
  stage: "spawn",
@@ -25245,15 +25277,23 @@ async function startDevServer(ctx, extraEnv = {}) {
25245
25277
  });
25246
25278
  return null;
25247
25279
  }
25248
- emitProgress("READY_DETECTED", `port ${detection.port}`);
25249
- return { devServer };
25280
+ const served = await resolveServedAddress(outputTail, detection.port);
25281
+ if (served.port !== detection.port || served.host !== "127.0.0.1") {
25282
+ log.info(
25283
+ "preview",
25284
+ `dev server serves on ${served.host}:${served.port} (detection said :${detection.port})`
25285
+ );
25286
+ }
25287
+ emitProgress("READY_DETECTED", `port ${served.port}`);
25288
+ return { devServer, served };
25250
25289
  }
25251
25290
  var MAX_TUNNEL_ATTEMPTS = 3;
25252
25291
  async function establishTunnel(ctx, dev) {
25253
25292
  const { detection, emit: emit2, emitProgress } = ctx;
25254
25293
  const { devServer } = dev;
25255
25294
  emitProgress("TUNNEL_STARTING", "cloudflared quick tunnel");
25256
- const inspection = await bringUpInspector(detection.port, {
25295
+ const inspection = await bringUpInspector(dev.served.port, {
25296
+ targetHost: dev.served.host,
25257
25297
  log: (m) => log.info("preview", m)
25258
25298
  });
25259
25299
  const pub = await bringUpPublicUrl(ctx, inspection.port);
@@ -25667,11 +25707,11 @@ function resolveDoltInstallStrategy(platform3) {
25667
25707
  }
25668
25708
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
25669
25709
  function doltPlatformTuple(platform3, arch2) {
25670
- const os65 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25710
+ const os66 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25671
25711
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
25672
25712
  if (!a) return null;
25673
- if (os65 === "windows" && a !== "amd64") return null;
25674
- return `${os65}-${a}`;
25713
+ if (os66 === "windows" && a !== "amd64") return null;
25714
+ return `${os66}-${a}`;
25675
25715
  }
25676
25716
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
25677
25717
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -27360,7 +27400,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
27360
27400
  });
27361
27401
  const token = ctx.pluginAuthToken;
27362
27402
  void (async () => {
27363
- const os65 = createOsStrategy();
27403
+ const os66 = createOsStrategy();
27364
27404
  try {
27365
27405
  const report = await reviewPullRequest(
27366
27406
  {
@@ -27369,7 +27409,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
27369
27409
  baseBranch: parsed.baseBranch
27370
27410
  },
27371
27411
  {
27372
- runReview: (input) => new CoderabbitRuntimeStrategy(os65).runOneShot(input),
27412
+ runReview: (input) => new CoderabbitRuntimeStrategy(os66).runOneShot(input),
27373
27413
  runGh: (args2) => defaultRunGh(args2),
27374
27414
  postReport: async (r) => {
27375
27415
  if (!token) return;
@@ -27507,13 +27547,13 @@ function resolveGlobalNodeModulesDir(opts) {
27507
27547
  var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
27508
27548
  function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
27509
27549
  if (!nodeModulesDir) return 0;
27510
- const readdirSync13 = deps?.readdirSync ?? fs51.readdirSync;
27550
+ const readdirSync14 = deps?.readdirSync ?? fs51.readdirSync;
27511
27551
  const statSync15 = deps?.statSync ?? fs51.statSync;
27512
27552
  const rmSync9 = deps?.rmSync ?? fs51.rmSync;
27513
27553
  let removed = 0;
27514
27554
  let entries;
27515
27555
  try {
27516
- entries = readdirSync13(nodeModulesDir);
27556
+ entries = readdirSync14(nodeModulesDir);
27517
27557
  } catch {
27518
27558
  return 0;
27519
27559
  }
@@ -28536,11 +28576,11 @@ function resolveTokenValue(args2) {
28536
28576
  }
28537
28577
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
28538
28578
  if (fileFlag) {
28539
- const path96 = fileFlag.slice("--token-file=".length);
28579
+ const path97 = fileFlag.slice("--token-file=".length);
28540
28580
  try {
28541
- const content = fs52.readFileSync(path96, "utf8").trim();
28542
- if (content.length === 0) fail(`--token-file ${path96} is empty`);
28543
- rmIfExistsQuiet(path96);
28581
+ const content = fs52.readFileSync(path97, "utf8").trim();
28582
+ if (content.length === 0) fail(`--token-file ${path97} is empty`);
28583
+ rmIfExistsQuiet(path97);
28544
28584
  return content;
28545
28585
  } catch (err) {
28546
28586
  fail(`Could not read --token-file: ${err.message}`);
@@ -29472,32 +29512,200 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
29472
29512
  return null;
29473
29513
  }
29474
29514
 
29515
+ // src/commands/host/workspace.ts
29516
+ var fs53 = __toESM(require("fs"));
29517
+ var os41 = __toESM(require("os"));
29518
+ var path62 = __toESM(require("path"));
29519
+ var import_node_child_process21 = require("child_process");
29520
+ var import_node_util5 = require("util");
29521
+ var execFileP5 = (0, import_node_util5.promisify)(import_node_child_process21.execFile);
29522
+ function isAbsolutePathTarget(target) {
29523
+ return path62.isAbsolute(target);
29524
+ }
29525
+ function selfHostedWorkspaceRoot() {
29526
+ return path62.join(os41.homedir(), ".codeam", "self-hosted");
29527
+ }
29528
+ function deployIdFromWorkspace(cwd) {
29529
+ if (!cwd) return null;
29530
+ const root = selfHostedWorkspaceRoot();
29531
+ const resolved = path62.resolve(cwd);
29532
+ const rel = path62.relative(root, resolved);
29533
+ if (!rel || rel.startsWith("..") || path62.isAbsolute(rel)) return null;
29534
+ const parts = rel.split(path62.sep).filter(Boolean);
29535
+ if (parts.length !== 1) return null;
29536
+ return parts[0];
29537
+ }
29538
+ function nonInteractiveGitEnv() {
29539
+ return {
29540
+ ...process.env,
29541
+ GIT_TERMINAL_PROMPT: "0",
29542
+ GIT_ASKPASS: "",
29543
+ GCM_INTERACTIVE: "never"
29544
+ };
29545
+ }
29546
+ function githubOwnerRepo(repoRef) {
29547
+ const trimmed = repoRef.trim();
29548
+ const shorthand = /^([^/\s]+)\/([^/\s]+?)(?:\.git)?$/.exec(trimmed);
29549
+ if (shorthand && !/^https?:\/\//.test(trimmed) && !trimmed.startsWith("git@")) {
29550
+ return { owner: shorthand[1], repo: shorthand[2] };
29551
+ }
29552
+ const httpsMatch = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/.exec(trimmed);
29553
+ if (httpsMatch) return { owner: httpsMatch[1], repo: httpsMatch[2] };
29554
+ return null;
29555
+ }
29556
+ function gitlabProjectPath(repoRef) {
29557
+ const trimmed = repoRef.trim();
29558
+ const https9 = /^https?:\/\/gitlab\.com\/(.+?)(?:\.git)?\/?$/.exec(trimmed);
29559
+ if (https9) return https9[1];
29560
+ if (!/^https?:\/\//.test(trimmed) && !trimmed.startsWith("git@") && trimmed.includes("/")) {
29561
+ return trimmed.replace(/\.git$/, "");
29562
+ }
29563
+ return null;
29564
+ }
29565
+ function repoCloneUrl(repoRef, cloneToken, provider = "github") {
29566
+ const trimmed = repoRef.trim();
29567
+ if (provider === "gitlab") {
29568
+ const glPath = gitlabProjectPath(trimmed);
29569
+ if (glPath) {
29570
+ return cloneToken ? `https://oauth2:${cloneToken}@gitlab.com/${glPath}.git` : `https://gitlab.com/${glPath}.git`;
29571
+ }
29572
+ if (/^https?:\/\//.test(trimmed) || trimmed.startsWith("git@")) return trimmed;
29573
+ }
29574
+ if (cloneToken) {
29575
+ const gh = githubOwnerRepo(trimmed);
29576
+ if (gh) {
29577
+ return `https://x-access-token:${cloneToken}@github.com/${gh.owner}/${gh.repo}.git`;
29578
+ }
29579
+ }
29580
+ if (/^https?:\/\//.test(trimmed) || trimmed.startsWith("git@")) return trimmed;
29581
+ return `https://github.com/${trimmed.replace(/\.git$/, "")}.git`;
29582
+ }
29583
+ function maskCloneUrl(url2) {
29584
+ return url2.replace(/(https?:\/\/)[^@/]+@/, "$1***@");
29585
+ }
29586
+ async function fetchGithubIdentity(token) {
29587
+ try {
29588
+ const res = await fetch("https://api.github.com/user", {
29589
+ headers: {
29590
+ Authorization: `Bearer ${token}`,
29591
+ "User-Agent": "codeam-cli",
29592
+ Accept: "application/vnd.github+json"
29593
+ }
29594
+ });
29595
+ if (!res.ok) return null;
29596
+ const body = await res.json();
29597
+ return { login: body.login, email: body.email ?? void 0 };
29598
+ } catch {
29599
+ return null;
29600
+ }
29601
+ }
29602
+ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "github") {
29603
+ const isGitlab = provider === "gitlab";
29604
+ if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
29605
+ if (!cloneToken) return;
29606
+ const credFile = path62.join(dest, ".git", "codeam-credentials");
29607
+ const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
29608
+ ` : `https://x-access-token:${cloneToken}@github.com
29609
+ `;
29610
+ fs53.writeFileSync(credFile, credLine, { mode: 384 });
29611
+ restrictToOwner(credFile);
29612
+ const env = nonInteractiveGitEnv();
29613
+ const git2 = (args2) => execFileP5("git", ["-C", dest, ...args2], { timeout: 3e4, env });
29614
+ const credFilePosix = credFile.split(path62.sep).join("/");
29615
+ await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
29616
+ });
29617
+ await git2([
29618
+ "config",
29619
+ "--local",
29620
+ "--add",
29621
+ "credential.helper",
29622
+ `store --file=${credFilePosix}`
29623
+ ]).catch(() => {
29624
+ });
29625
+ await git2(["remote", "set-url", "origin", repoCloneUrl(repoRef, void 0, provider)]).catch(() => {
29626
+ });
29627
+ const hasIdentity = await git2(["config", "user.email"]).then(() => true).catch(() => false);
29628
+ if (!hasIdentity) {
29629
+ const who = isGitlab ? null : await fetchGithubIdentity(cloneToken);
29630
+ const login = who?.login ?? "CodeAgent";
29631
+ await git2(["config", "--local", "user.name", login]).catch(() => {
29632
+ });
29633
+ const email = who?.email ?? (isGitlab ? "agent@codeagent-mobile.com" : `${login}@users.noreply.github.com`);
29634
+ await git2(["config", "--local", "user.email", email]).catch(() => {
29635
+ });
29636
+ }
29637
+ }
29638
+ function maskToken(text, cloneToken) {
29639
+ const masked = maskCloneUrl(text);
29640
+ if (cloneToken && cloneToken.length > 0) {
29641
+ return masked.split(cloneToken).join("***");
29642
+ }
29643
+ return masked;
29644
+ }
29645
+ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
29646
+ if (isAbsolutePathTarget(repoOrPath)) {
29647
+ if (!fs53.existsSync(repoOrPath)) {
29648
+ throw new Error(`deploy target path does not exist: ${repoOrPath}`);
29649
+ }
29650
+ return repoOrPath;
29651
+ }
29652
+ const dest = path62.join(selfHostedWorkspaceRoot(), deployId);
29653
+ if (fs53.existsSync(path62.join(dest, ".git"))) {
29654
+ if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
29655
+ return dest;
29656
+ }
29657
+ fs53.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
29658
+ const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
29659
+ const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
29660
+ try {
29661
+ await execFileP5("git", cloneArgs, {
29662
+ timeout: 12e4,
29663
+ maxBuffer: 16 * 1024 * 1024,
29664
+ env: nonInteractiveGitEnv()
29665
+ });
29666
+ } catch (err) {
29667
+ const reason = err instanceof Error ? err.message : String(err);
29668
+ throw new Error(`git clone failed for ${maskCloneUrl(cloneUrl)}: ${maskToken(reason, cloneToken)}`);
29669
+ }
29670
+ if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
29671
+ return dest;
29672
+ }
29673
+
29475
29674
  // src/agents/acp/runner.ts
29476
29675
  var import_node_crypto11 = require("crypto");
29477
- var fs69 = __toESM(require("fs"));
29478
- var os53 = __toESM(require("os"));
29479
- var path80 = __toESM(require("path"));
29676
+ var fs71 = __toESM(require("fs"));
29677
+ var os55 = __toESM(require("os"));
29678
+ var path82 = __toESM(require("path"));
29480
29679
 
29481
29680
  // src/lib/provider-routing.ts
29681
+ var fs55 = __toESM(require("fs"));
29682
+ var os43 = __toESM(require("os"));
29683
+ var path64 = __toESM(require("path"));
29684
+
29685
+ // src/commands/host/house-proxy-config.ts
29482
29686
  var fs54 = __toESM(require("fs"));
29483
29687
  var os42 = __toESM(require("os"));
29484
29688
  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
29689
  function houseProxyConfigPath() {
29491
- return path62.join(os41.homedir(), ".codeam", "house-proxy.json");
29690
+ return path63.join(os42.homedir(), ".codeam", "house-proxy.json");
29691
+ }
29692
+ var DEPLOY_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
29693
+ function deployHouseProxyConfigPath(deployId) {
29694
+ if (!DEPLOY_ID_RE.test(deployId) || deployId.includes("..")) return null;
29695
+ return path63.join(os42.homedir(), ".codeam", "house-proxy", `${deployId}.json`);
29696
+ }
29697
+ function writeJson0600(file, value) {
29698
+ fs54.mkdirSync(path63.dirname(file), { recursive: true, mode: 448 });
29699
+ const tmp = `${file}.tmp-${process.pid}`;
29700
+ fs54.writeFileSync(tmp, JSON.stringify(value, null, 2), { encoding: "utf8", mode: 384 });
29701
+ fs54.renameSync(tmp, file);
29702
+ restrictToOwner(file);
29492
29703
  }
29493
- function persistHouseProxyConfig(config) {
29704
+ function persistHouseProxyConfig(config, deployId) {
29494
29705
  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);
29706
+ const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
29707
+ if (perDeploy) writeJson0600(perDeploy, config);
29708
+ writeJson0600(houseProxyConfigPath(), config);
29501
29709
  } catch (err) {
29502
29710
  log.warn(
29503
29711
  "host-agent",
@@ -29505,18 +29713,23 @@ function persistHouseProxyConfig(config) {
29505
29713
  );
29506
29714
  }
29507
29715
  }
29508
- function clearHouseProxyConfig() {
29716
+ function clearHouseProxyConfig(deployId) {
29509
29717
  try {
29510
- fs53.rmSync(houseProxyConfigPath(), { force: true });
29718
+ fs54.rmSync(houseProxyConfigPath(), { force: true });
29719
+ const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
29720
+ if (perDeploy) writeJson0600(perDeploy, { none: true });
29511
29721
  } catch {
29512
29722
  }
29513
29723
  }
29514
- function readHouseProxyChildEnv() {
29724
+ function readHouseProxyChildEnv(deployId) {
29515
29725
  try {
29516
- const raw = fs53.readFileSync(houseProxyConfigPath(), "utf8");
29726
+ const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
29727
+ const file = perDeploy && fs54.existsSync(perDeploy) ? perDeploy : houseProxyConfigPath();
29728
+ const raw = fs54.readFileSync(file, "utf8");
29517
29729
  const parsed = JSON.parse(raw);
29518
29730
  if (typeof parsed !== "object" || parsed === null) return {};
29519
29731
  const o = parsed;
29732
+ if (o.none === true) return {};
29520
29733
  if (typeof o.baseUrl !== "string" || !o.baseUrl) return {};
29521
29734
  if (typeof o.token !== "string" || !o.token) return {};
29522
29735
  return buildHouseProxyChildEnv({
@@ -29639,15 +29852,15 @@ function redactUrlToOrigin(raw) {
29639
29852
  }
29640
29853
  }
29641
29854
  function readOpencodeProviderOrigins(opts = {}) {
29642
- const home = opts.homeDir ?? os42.homedir();
29643
- const readFile7 = opts.readFile ?? ((f) => fs54.readFileSync(f, "utf8"));
29855
+ const home = opts.homeDir ?? os43.homedir();
29856
+ const readFile7 = opts.readFile ?? ((f) => fs55.readFileSync(f, "utf8"));
29644
29857
  const candidates = [];
29645
29858
  if (opts.cwd) {
29646
- candidates.push(path63.join(opts.cwd, "opencode.json"), path63.join(opts.cwd, "opencode.jsonc"));
29859
+ candidates.push(path64.join(opts.cwd, "opencode.json"), path64.join(opts.cwd, "opencode.jsonc"));
29647
29860
  }
29648
29861
  candidates.push(
29649
- path63.join(home, ".config", "opencode", "opencode.json"),
29650
- path63.join(home, ".config", "opencode", "opencode.jsonc")
29862
+ path64.join(home, ".config", "opencode", "opencode.json"),
29863
+ path64.join(home, ".config", "opencode", "opencode.jsonc")
29651
29864
  );
29652
29865
  const out2 = [];
29653
29866
  const seen2 = /* @__PURE__ */ new Set();
@@ -29754,9 +29967,9 @@ function noteProviderBillingSignal(opts) {
29754
29967
  }
29755
29968
 
29756
29969
  // src/services/history.service.ts
29757
- var fs55 = __toESM(require("fs"));
29758
- var path64 = __toESM(require("path"));
29759
- var os43 = __toESM(require("os"));
29970
+ var fs56 = __toESM(require("fs"));
29971
+ var path65 = __toESM(require("path"));
29972
+ var os44 = __toESM(require("os"));
29760
29973
  var https6 = __toESM(require("https"));
29761
29974
  var http9 = __toESM(require("http"));
29762
29975
  var import_zod2 = require("zod");
@@ -29817,7 +30030,7 @@ function parseJsonl(filePath) {
29817
30030
  const messages = [];
29818
30031
  let raw;
29819
30032
  try {
29820
- raw = fs55.readFileSync(filePath, "utf8");
30033
+ raw = fs56.readFileSync(filePath, "utf8");
29821
30034
  } catch (err) {
29822
30035
  if (err.code !== "ENOENT") {
29823
30036
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -29971,7 +30184,7 @@ var HistoryService = class _HistoryService {
29971
30184
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
29972
30185
  }
29973
30186
  get projectDir() {
29974
- return this.runtime.resolveHistoryDir(this.cwd) ?? path64.join(os43.homedir(), ".claude", "projects", encodeCwd(this.cwd));
30187
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path65.join(os44.homedir(), ".claude", "projects", encodeCwd(this.cwd));
29975
30188
  }
29976
30189
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
29977
30190
  setCurrentConversationId(id) {
@@ -29983,7 +30196,7 @@ var HistoryService = class _HistoryService {
29983
30196
  /** Return the current message count in the active conversation. */
29984
30197
  getCurrentMessageCount() {
29985
30198
  if (!this.currentConversationId) return 0;
29986
- const filePath = path64.join(this.projectDir, `${this.currentConversationId}.jsonl`);
30199
+ const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
29987
30200
  return parseJsonl(filePath).length;
29988
30201
  }
29989
30202
  /**
@@ -29994,7 +30207,7 @@ var HistoryService = class _HistoryService {
29994
30207
  const deadline = Date.now() + timeoutMs;
29995
30208
  while (Date.now() < deadline) {
29996
30209
  if (!this.currentConversationId) return null;
29997
- const filePath = path64.join(this.projectDir, `${this.currentConversationId}.jsonl`);
30210
+ const filePath = path65.join(this.projectDir, `${this.currentConversationId}.jsonl`);
29998
30211
  const messages = parseJsonl(filePath);
29999
30212
  if (messages.length > previousCount) {
30000
30213
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -30020,16 +30233,16 @@ var HistoryService = class _HistoryService {
30020
30233
  const dir = this.projectDir;
30021
30234
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
30022
30235
  try {
30023
- const files = fs55.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
30236
+ const files = fs56.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
30024
30237
  try {
30025
- const stat3 = fs55.statSync(path64.join(dir, e.name));
30238
+ const stat3 = fs56.statSync(path65.join(dir, e.name));
30026
30239
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
30027
30240
  } catch {
30028
30241
  return { name: e.name, mtime: 0, birthtime: 0 };
30029
30242
  }
30030
30243
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
30031
30244
  if (files.length > 0) {
30032
- this.currentConversationId = path64.basename(files[0].name, ".jsonl");
30245
+ this.currentConversationId = path65.basename(files[0].name, ".jsonl");
30033
30246
  }
30034
30247
  } catch {
30035
30248
  }
@@ -30063,13 +30276,13 @@ var HistoryService = class _HistoryService {
30063
30276
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
30064
30277
  let entries;
30065
30278
  try {
30066
- entries = fs55.readdirSync(dir, { withFileTypes: true });
30279
+ entries = fs56.readdirSync(dir, { withFileTypes: true });
30067
30280
  } catch {
30068
30281
  return null;
30069
30282
  }
30070
30283
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
30071
30284
  try {
30072
- const stat3 = fs55.statSync(path64.join(dir, e.name));
30285
+ const stat3 = fs56.statSync(path65.join(dir, e.name));
30073
30286
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
30074
30287
  } catch {
30075
30288
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -30078,12 +30291,12 @@ var HistoryService = class _HistoryService {
30078
30291
  if (files.length === 0) return null;
30079
30292
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
30080
30293
  if (!files.some((f) => f.name === targetFile)) return null;
30081
- return this.extractUsageFromFile(path64.join(dir, targetFile));
30294
+ return this.extractUsageFromFile(path65.join(dir, targetFile));
30082
30295
  }
30083
30296
  extractUsageFromFile(filePath) {
30084
30297
  let raw;
30085
30298
  try {
30086
- raw = fs55.readFileSync(filePath, "utf8");
30299
+ raw = fs56.readFileSync(filePath, "utf8");
30087
30300
  } catch {
30088
30301
  return null;
30089
30302
  }
@@ -30135,9 +30348,9 @@ var HistoryService = class _HistoryService {
30135
30348
  let totalCost = 0;
30136
30349
  let files;
30137
30350
  try {
30138
- files = fs55.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
30351
+ files = fs56.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
30139
30352
  try {
30140
- return fs55.statSync(path64.join(projectDir, f)).mtimeMs >= monthStartMs;
30353
+ return fs56.statSync(path65.join(projectDir, f)).mtimeMs >= monthStartMs;
30141
30354
  } catch {
30142
30355
  return false;
30143
30356
  }
@@ -30148,7 +30361,7 @@ var HistoryService = class _HistoryService {
30148
30361
  for (const file of files) {
30149
30362
  let raw;
30150
30363
  try {
30151
- raw = fs55.readFileSync(path64.join(projectDir, file), "utf8");
30364
+ raw = fs56.readFileSync(path65.join(projectDir, file), "utf8");
30152
30365
  } catch {
30153
30366
  continue;
30154
30367
  }
@@ -30227,7 +30440,7 @@ var HistoryService = class _HistoryService {
30227
30440
  if (this.runtime.resolveHistoryFile) {
30228
30441
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
30229
30442
  }
30230
- return path64.join(this.projectDir, `${sessionId}.jsonl`);
30443
+ return path65.join(this.projectDir, `${sessionId}.jsonl`);
30231
30444
  }
30232
30445
  /**
30233
30446
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -30265,7 +30478,7 @@ var HistoryService = class _HistoryService {
30265
30478
  };
30266
30479
  });
30267
30480
  }
30268
- return parseJsonl(path64.join(this.projectDir, `${sessionId}.jsonl`));
30481
+ return parseJsonl(path65.join(this.projectDir, `${sessionId}.jsonl`));
30269
30482
  }
30270
30483
  /** One in-flight full upload per conversation — the baton mirror and a
30271
30484
  * `get_conversation` used to upload the same transcript concurrently. */
@@ -30347,7 +30560,7 @@ var HistoryService = class _HistoryService {
30347
30560
  if (!filePath) return false;
30348
30561
  let mtimeMs;
30349
30562
  try {
30350
- mtimeMs = fs55.statSync(filePath).mtimeMs;
30563
+ mtimeMs = fs56.statSync(filePath).mtimeMs;
30351
30564
  } catch {
30352
30565
  return false;
30353
30566
  }
@@ -30421,11 +30634,11 @@ var HistoryService = class _HistoryService {
30421
30634
  };
30422
30635
 
30423
30636
  // src/agents/acp/client.ts
30424
- var import_node_child_process21 = require("child_process");
30425
- var fs56 = __toESM(require("fs/promises"));
30637
+ var import_node_child_process22 = require("child_process");
30638
+ var fs57 = __toESM(require("fs/promises"));
30426
30639
  var fsSync = __toESM(require("fs"));
30427
- var os45 = __toESM(require("os"));
30428
- var path66 = __toESM(require("path"));
30640
+ var os46 = __toESM(require("os"));
30641
+ var path67 = __toESM(require("path"));
30429
30642
  var import_node_stream = require("stream");
30430
30643
 
30431
30644
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -34451,8 +34664,8 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
34451
34664
  }
34452
34665
 
34453
34666
  // src/agents/acp/internal-paths.ts
34454
- var path65 = __toESM(require("path"));
34455
- var os44 = __toESM(require("os"));
34667
+ var path66 = __toESM(require("path"));
34668
+ var os45 = __toESM(require("os"));
34456
34669
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
34457
34670
  var PROSE_ONLY_TOOL_KINDS = /* @__PURE__ */ new Set(["think", "switch_mode"]);
34458
34671
  function isProseOnlyToolKind(kind) {
@@ -34464,13 +34677,13 @@ function textReferencesInternal(text) {
34464
34677
  const scrubbed = text.replace(SELF_HOSTED_WORKSPACE_RE, " ");
34465
34678
  return INTERNAL_TOKENS.some((t2) => scrubbed.includes(t2));
34466
34679
  }
34467
- function pathIsInternal(p2, homeDir2 = os44.homedir()) {
34680
+ function pathIsInternal(p2, homeDir2 = os45.homedir()) {
34468
34681
  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`);
34682
+ const abs = path66.resolve(p2);
34683
+ const home = path66.resolve(homeDir2);
34684
+ const within = (root) => abs === root || abs.startsWith(root + path66.sep);
34685
+ if (within(path66.join(home, ".codeam", "self-hosted"))) return false;
34686
+ 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
34687
  }
34475
34688
  function toolCallReferencesInternal(call, homeDir2) {
34476
34689
  if (call.locations?.some((l) => pathIsInternal(l.path, homeDir2))) return true;
@@ -34798,7 +35011,7 @@ var AcpClient = class {
34798
35011
  "acpClient",
34799
35012
  `provider routing ${formatProviderRouting(describeProviderRouting(childEnv, { cwd }), adapter.command)}`
34800
35013
  );
34801
- const child = (0, import_node_child_process21.spawn)(adapter.command, adapter.args, {
35014
+ const child = (0, import_node_child_process22.spawn)(adapter.command, adapter.args, {
34802
35015
  cwd,
34803
35016
  env: childEnv,
34804
35017
  stdio: ["pipe", "pipe", "pipe"],
@@ -35483,7 +35696,7 @@ var AcpClient = class {
35483
35696
  try {
35484
35697
  const pid = child.pid;
35485
35698
  if (process.platform === "win32") {
35486
- if (pid) (0, import_node_child_process21.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pid)], { stdio: "ignore" });
35699
+ if (pid) (0, import_node_child_process22.spawnSync)("taskkill", ["/F", "/T", "/PID", String(pid)], { stdio: "ignore" });
35487
35700
  } else if (pid) {
35488
35701
  killQuiet(-pid, "SIGTERM");
35489
35702
  } else {
@@ -35565,7 +35778,7 @@ var AcpClient = class {
35565
35778
  throw new RequestError(-32002, GUARDRAIL_SECRET_READ_BLOCK_REASON, { uri: params.path });
35566
35779
  }
35567
35780
  try {
35568
- const content = await fs56.readFile(params.path, "utf8");
35781
+ const content = await fs57.readFile(params.path, "utf8");
35569
35782
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
35570
35783
  } catch (err) {
35571
35784
  const code = err.code;
@@ -35586,7 +35799,7 @@ var AcpClient = class {
35586
35799
  throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
35587
35800
  }
35588
35801
  try {
35589
- await fs56.writeFile(params.path, params.content, "utf8");
35802
+ await fs57.writeFile(params.path, params.content, "utf8");
35590
35803
  return {};
35591
35804
  } catch (err) {
35592
35805
  const code = err.code;
@@ -35674,30 +35887,30 @@ function applyLineRange(content, line, limit) {
35674
35887
  return { content: lines.slice(start2, end).join("\n") };
35675
35888
  }
35676
35889
  function knownAgentBinaryDirs() {
35677
- const home = os45.homedir();
35890
+ const home = os46.homedir();
35678
35891
  const out2 = [];
35679
35892
  out2.push("/tmp/codeam-node20/bin");
35680
35893
  for (const root of [
35681
35894
  "/usr/local/share/nvm/versions/node",
35682
- path66.join(home, ".nvm/versions/node")
35895
+ path67.join(home, ".nvm/versions/node")
35683
35896
  ]) {
35684
35897
  try {
35685
35898
  for (const child of fsSync.readdirSync(root)) {
35686
- out2.push(path66.join(root, child, "bin"));
35899
+ out2.push(path67.join(root, child, "bin"));
35687
35900
  }
35688
35901
  } catch {
35689
35902
  }
35690
35903
  }
35691
- out2.push(path66.join(home, ".volta/bin"));
35904
+ out2.push(path67.join(home, ".volta/bin"));
35692
35905
  out2.push("/usr/local/bin");
35693
35906
  out2.push("/usr/bin");
35694
- out2.push(path66.join(home, ".local/bin"));
35695
- out2.push(path66.join(home, "bin"));
35907
+ out2.push(path67.join(home, ".local/bin"));
35908
+ out2.push(path67.join(home, "bin"));
35696
35909
  out2.push(...agentInstallBinDirs());
35697
35910
  if (process.platform === "win32") {
35698
35911
  const { LOCALAPPDATA, APPDATA } = process.env;
35699
- if (LOCALAPPDATA) out2.push(path66.join(LOCALAPPDATA, "cursor-agent"));
35700
- if (APPDATA) out2.push(path66.join(APPDATA, "npm"));
35912
+ if (LOCALAPPDATA) out2.push(path67.join(LOCALAPPDATA, "cursor-agent"));
35913
+ if (APPDATA) out2.push(path67.join(APPDATA, "npm"));
35701
35914
  }
35702
35915
  return out2.filter((p2) => {
35703
35916
  try {
@@ -35708,7 +35921,7 @@ function knownAgentBinaryDirs() {
35708
35921
  });
35709
35922
  }
35710
35923
  function expandPathForAgentBinaries(existingPath) {
35711
- const existing = new Set(existingPath.split(path66.delimiter).filter((p2) => p2.length > 0));
35924
+ const existing = new Set(existingPath.split(path67.delimiter).filter((p2) => p2.length > 0));
35712
35925
  const additions = [];
35713
35926
  for (const dir of knownAgentBinaryDirs()) {
35714
35927
  if (!existing.has(dir)) {
@@ -35717,17 +35930,17 @@ function expandPathForAgentBinaries(existingPath) {
35717
35930
  }
35718
35931
  }
35719
35932
  if (additions.length === 0) return existingPath;
35720
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path66.delimiter);
35933
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path67.delimiter);
35721
35934
  }
35722
35935
 
35723
35936
  // src/commands/host/agent-install.ts
35724
35937
  var import_child_process27 = require("child_process");
35725
- var os46 = __toESM(require("os"));
35938
+ var os47 = __toESM(require("os"));
35726
35939
  function runAgentInstallScript(script, opts = {}) {
35727
35940
  const timeoutMs = opts.timeoutMs ?? 18e4;
35728
35941
  const scope = opts.logScope ?? "agent-install";
35729
35942
  return new Promise((resolve12) => {
35730
- const home = process.env.HOME || os46.homedir();
35943
+ const home = process.env.HOME || os47.homedir();
35731
35944
  const child = (0, import_child_process27.spawn)("sh", ["-c", script], {
35732
35945
  env: { ...process.env, HOME: home },
35733
35946
  stdio: ["ignore", "pipe", "pipe"]
@@ -35989,9 +36202,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
35989
36202
  }
35990
36203
 
35991
36204
  // src/commands/host/agent-provisioning.ts
35992
- var fs57 = __toESM(require("fs"));
35993
- var os47 = __toESM(require("os"));
35994
- var path67 = __toESM(require("path"));
36205
+ var fs58 = __toESM(require("fs"));
36206
+ var os48 = __toESM(require("os"));
36207
+ var path68 = __toESM(require("path"));
35995
36208
  var PUBLIC_TO_INTERNAL_AGENT = {
35996
36209
  claude_code: "claude",
35997
36210
  claude: "claude",
@@ -36008,22 +36221,22 @@ function toInternalAgentId(publicAgentId) {
36008
36221
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
36009
36222
  }
36010
36223
  function ensureDir(dir) {
36011
- fs57.mkdirSync(dir, { recursive: true, mode: 448 });
36224
+ fs58.mkdirSync(dir, { recursive: true, mode: 448 });
36012
36225
  }
36013
36226
  function writeFile0600(filePath, contents) {
36014
- ensureDir(path67.dirname(filePath));
36015
- fs57.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
36227
+ ensureDir(path68.dirname(filePath));
36228
+ fs58.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
36016
36229
  restrictToOwner(filePath);
36017
36230
  }
36018
36231
  function rmIfExists(filePath) {
36019
36232
  try {
36020
- fs57.rmSync(filePath, { force: true });
36233
+ fs58.rmSync(filePath, { force: true });
36021
36234
  } catch {
36022
36235
  }
36023
36236
  }
36024
36237
  var claudeProvisioner = {
36025
36238
  write(auth, home) {
36026
- const credentialsJson = path67.join(home, ".claude", ".credentials.json");
36239
+ const credentialsJson = path68.join(home, ".claude", ".credentials.json");
36027
36240
  if (auth.kind === "api_key") {
36028
36241
  rmIfExists(credentialsJson);
36029
36242
  return { ANTHROPIC_API_KEY: auth.value };
@@ -36035,8 +36248,8 @@ var claudeProvisioner = {
36035
36248
  } else {
36036
36249
  rmIfExists(credentialsJson);
36037
36250
  }
36038
- const claudeJson = path67.join(home, ".claude.json");
36039
- if (!fs57.existsSync(claudeJson)) {
36251
+ const claudeJson = path68.join(home, ".claude.json");
36252
+ if (!fs58.existsSync(claudeJson)) {
36040
36253
  writeFile0600(
36041
36254
  claudeJson,
36042
36255
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -36047,7 +36260,7 @@ var claudeProvisioner = {
36047
36260
  };
36048
36261
  var codexProvisioner = {
36049
36262
  write(auth, home) {
36050
- const authJson = path67.join(home, ".codex", "auth.json");
36263
+ const authJson = path68.join(home, ".codex", "auth.json");
36051
36264
  if (auth.kind === "api_key") {
36052
36265
  writeFile0600(authJson, JSON.stringify({ auth_mode: "apikey", OPENAI_API_KEY: auth.value }));
36053
36266
  return { OPENAI_API_KEY: auth.value };
@@ -36058,8 +36271,8 @@ var codexProvisioner = {
36058
36271
  };
36059
36272
  var geminiProvisioner = {
36060
36273
  write(auth, home) {
36061
- const settingsJson = path67.join(home, ".gemini", "settings.json");
36062
- const oauthCreds = path67.join(home, ".gemini", "oauth_creds.json");
36274
+ const settingsJson = path68.join(home, ".gemini", "settings.json");
36275
+ const oauthCreds = path68.join(home, ".gemini", "oauth_creds.json");
36063
36276
  if (auth.kind === "api_key") {
36064
36277
  rmIfExists(oauthCreds);
36065
36278
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -36072,7 +36285,7 @@ var geminiProvisioner = {
36072
36285
  };
36073
36286
  var cursorProvisioner = {
36074
36287
  write(auth, home) {
36075
- const authJson = path67.join(home, ".config", "cursor", "auth.json");
36288
+ const authJson = path68.join(home, ".config", "cursor", "auth.json");
36076
36289
  if (auth.kind === "api_key") {
36077
36290
  rmIfExists(authJson);
36078
36291
  return { CURSOR_API_KEY: auth.value };
@@ -36114,22 +36327,22 @@ max_context_size = 262144
36114
36327
  var kimiProvisioner = {
36115
36328
  write(auth, home) {
36116
36329
  const credentialsFiles = [
36117
- path67.join(home, ".kimi", "credentials", "kimi-code.json"),
36118
- path67.join(home, ".kimi-code", "credentials", "kimi-code.json")
36330
+ path68.join(home, ".kimi", "credentials", "kimi-code.json"),
36331
+ path68.join(home, ".kimi-code", "credentials", "kimi-code.json")
36119
36332
  ];
36120
36333
  if (auth.kind === "api_key") {
36121
36334
  credentialsFiles.forEach(rmIfExists);
36122
36335
  return { KIMI_API_KEY: auth.value };
36123
36336
  }
36124
36337
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
36125
- writeFile0600(path67.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
36338
+ writeFile0600(path68.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
36126
36339
  return {};
36127
36340
  }
36128
36341
  };
36129
36342
  var coderabbitProvisioner = {
36130
36343
  write(auth, home) {
36131
- const dir = path67.join(home, ".coderabbit");
36132
- const authJson = path67.join(dir, "auth.json");
36344
+ const dir = path68.join(home, ".coderabbit");
36345
+ const authJson = path68.join(dir, "auth.json");
36133
36346
  if (auth.kind === "api_key") {
36134
36347
  rmIfExists(authJson);
36135
36348
  return { CODERABBIT_API_KEY: auth.value };
@@ -36141,13 +36354,13 @@ var coderabbitProvisioner = {
36141
36354
  try {
36142
36355
  const parsed = JSON.parse(value);
36143
36356
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
36144
- file = path67.basename(parsed.file);
36357
+ file = path68.basename(parsed.file);
36145
36358
  contents = parsed.contents;
36146
36359
  }
36147
36360
  } catch {
36148
36361
  }
36149
36362
  }
36150
- writeFile0600(path67.join(dir, file), contents);
36363
+ writeFile0600(path68.join(dir, file), contents);
36151
36364
  return {};
36152
36365
  }
36153
36366
  };
@@ -36175,7 +36388,7 @@ var UnsupportedAgentError = class extends Error {
36175
36388
  this.agentId = agentId;
36176
36389
  }
36177
36390
  };
36178
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os47.homedir()) {
36391
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os48.homedir()) {
36179
36392
  const internal = toInternalAgentId(publicAgentId);
36180
36393
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
36181
36394
  const provisioner = PROVISIONERS[internal];
@@ -36184,16 +36397,16 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os47.homedir(
36184
36397
  }
36185
36398
 
36186
36399
  // src/beads/workflow-hint.ts
36187
- var fs58 = __toESM(require("fs"));
36188
- var path69 = __toESM(require("path"));
36400
+ var fs59 = __toESM(require("fs"));
36401
+ var path70 = __toESM(require("path"));
36189
36402
 
36190
36403
  // src/agents/claude-memory-file.ts
36191
- var os48 = __toESM(require("os"));
36192
- var path68 = __toESM(require("path"));
36404
+ var os49 = __toESM(require("os"));
36405
+ var path69 = __toESM(require("path"));
36193
36406
  function claudeMemoryFile(homeDir2, env = process.env) {
36194
- if (homeDir2) return path68.join(homeDir2, ".claude", "CLAUDE.md");
36407
+ if (homeDir2) return path69.join(homeDir2, ".claude", "CLAUDE.md");
36195
36408
  const configDir = env.CLAUDE_CONFIG_DIR?.trim();
36196
- return configDir ? path68.join(configDir, "CLAUDE.md") : path68.join(os48.homedir(), ".claude", "CLAUDE.md");
36409
+ return configDir ? path69.join(configDir, "CLAUDE.md") : path69.join(os49.homedir(), ".claude", "CLAUDE.md");
36197
36410
  }
36198
36411
 
36199
36412
  // src/beads/workflow-hint.ts
@@ -36223,11 +36436,11 @@ function ensureBeadsWorkflowHint(homeDir2, file = claudeMemoryFile(homeDir2)) {
36223
36436
  try {
36224
36437
  let existing = "";
36225
36438
  try {
36226
- existing = fs58.readFileSync(file, "utf8");
36439
+ existing = fs59.readFileSync(file, "utf8");
36227
36440
  } catch {
36228
36441
  }
36229
36442
  if (existing.includes(BEADS_HINT)) return;
36230
- fs58.mkdirSync(path69.dirname(file), { recursive: true });
36443
+ fs59.mkdirSync(path70.dirname(file), { recursive: true });
36231
36444
  let next;
36232
36445
  const open = existing.indexOf(BEADS_HINT_MARKER);
36233
36446
  const close = open === -1 ? -1 : existing.indexOf(BEADS_HINT_MARKER, open + BEADS_HINT_MARKER.length);
@@ -36240,40 +36453,40 @@ ${BEADS_HINT}
36240
36453
  ` : `${BEADS_HINT}
36241
36454
  `;
36242
36455
  }
36243
- fs58.writeFileSync(file, next);
36456
+ fs59.writeFileSync(file, next);
36244
36457
  } catch {
36245
36458
  }
36246
36459
  }
36247
36460
 
36248
36461
  // src/agents/agent-standard.ts
36249
- var fs59 = __toESM(require("fs"));
36250
- var path70 = __toESM(require("path"));
36251
- var os49 = __toESM(require("os"));
36462
+ var fs60 = __toESM(require("fs"));
36463
+ var path71 = __toESM(require("path"));
36464
+ var os50 = __toESM(require("os"));
36252
36465
  function ensureAgentStandard(homeDir2, file = claudeMemoryFile(homeDir2)) {
36253
36466
  try {
36254
36467
  let existing = "";
36255
36468
  try {
36256
- existing = fs59.readFileSync(file, "utf8");
36469
+ existing = fs60.readFileSync(file, "utf8");
36257
36470
  } catch {
36258
36471
  }
36259
36472
  if (existing.includes(AGENT_STANDARD_MARKER)) return;
36260
- fs59.mkdirSync(path70.dirname(file), { recursive: true });
36473
+ fs60.mkdirSync(path71.dirname(file), { recursive: true });
36261
36474
  const next = existing.trim() ? `${existing.trimEnd()}
36262
36475
 
36263
36476
  ${AGENT_STANDARD_BLOCK}
36264
36477
  ` : `${AGENT_STANDARD_BLOCK}
36265
36478
  `;
36266
- fs59.writeFileSync(file, next);
36479
+ fs60.writeFileSync(file, next);
36267
36480
  } catch {
36268
36481
  }
36269
36482
  }
36270
36483
  var _agentStandardSeam = {
36271
36484
  isLocalSession: () => isLocalSession(),
36272
- markerPath: (sessionId) => path70.join(os49.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36273
- exists: (p2) => fs59.existsSync(p2),
36485
+ markerPath: (sessionId) => path71.join(os50.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
36486
+ exists: (p2) => fs60.existsSync(p2),
36274
36487
  write: (p2) => {
36275
- fs59.mkdirSync(path70.dirname(p2), { recursive: true });
36276
- fs59.writeFileSync(p2, "");
36488
+ fs60.mkdirSync(path71.dirname(p2), { recursive: true });
36489
+ fs60.writeFileSync(p2, "");
36277
36490
  }
36278
36491
  };
36279
36492
  function isClaude(agent) {
@@ -36966,15 +37179,15 @@ function withholdTrailingPartialFenceMarker(text) {
36966
37179
 
36967
37180
  // src/agents/acp/onboarding.ts
36968
37181
  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"));
37182
+ var fs61 = __toESM(require("fs"));
37183
+ var os51 = __toESM(require("os"));
37184
+ var path72 = __toESM(require("path"));
36972
37185
  var _onboardingSeam = {
36973
- markerPath: (sessionId) => path71.join(os50.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
36974
- exists: (p2) => fs60.existsSync(p2),
37186
+ markerPath: (sessionId) => path72.join(os51.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
37187
+ exists: (p2) => fs61.existsSync(p2),
36975
37188
  write: (p2) => {
36976
- fs60.mkdirSync(path71.dirname(p2), { recursive: true });
36977
- fs60.writeFileSync(p2, "");
37189
+ fs61.mkdirSync(path72.dirname(p2), { recursive: true });
37190
+ fs61.writeFileSync(p2, "");
36978
37191
  },
36979
37192
  disabled: () => {
36980
37193
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -37011,7 +37224,7 @@ function resolveRepoName(cwd) {
37011
37224
  if (name) return name;
37012
37225
  }
37013
37226
  }
37014
- const base = path71.basename(cwd || "");
37227
+ const base = path72.basename(cwd || "");
37015
37228
  if (base && !isUuid(base)) return base;
37016
37229
  return "this project";
37017
37230
  }
@@ -37403,13 +37616,13 @@ var import_crypto4 = require("crypto");
37403
37616
 
37404
37617
  // src/services/turn-files/git-changeset.ts
37405
37618
  var import_child_process29 = require("child_process");
37406
- var fs62 = __toESM(require("fs/promises"));
37407
- var path73 = __toESM(require("path"));
37619
+ var fs63 = __toESM(require("fs/promises"));
37620
+ var path74 = __toESM(require("path"));
37408
37621
 
37409
37622
  // src/services/turn-files/review-ignore.ts
37410
37623
  var import_ignore2 = __toESM(require("ignore"));
37411
- var fs61 = __toESM(require("fs"));
37412
- var path72 = __toESM(require("path"));
37624
+ var fs62 = __toESM(require("fs"));
37625
+ var path73 = __toESM(require("path"));
37413
37626
  var CURATED_REVIEW_IGNORE = [
37414
37627
  // Google Cloud SDK (the incident) — installs a huge python tree.
37415
37628
  "google-cloud-sdk/",
@@ -37448,7 +37661,7 @@ var CURATED_REVIEW_IGNORE = [
37448
37661
  function makeReviewIgnore(repoRoot) {
37449
37662
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
37450
37663
  try {
37451
- const custom = fs61.readFileSync(path72.join(repoRoot, ".codeam", "reviewignore"), "utf8");
37664
+ const custom = fs62.readFileSync(path73.join(repoRoot, ".codeam", "reviewignore"), "utf8");
37452
37665
  ig.add(custom);
37453
37666
  } catch {
37454
37667
  }
@@ -37493,7 +37706,7 @@ async function collectRepoChangeset(opts) {
37493
37706
  let stats;
37494
37707
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
37495
37708
  const lineCount = await readUntrackedLineCount(
37496
- path73.join(opts.repoRoot, row.filePath)
37709
+ path74.join(opts.repoRoot, row.filePath)
37497
37710
  );
37498
37711
  stats = { added: lineCount, removed: 0 };
37499
37712
  } else {
@@ -37524,7 +37737,7 @@ function readUntrackedLineCount(absPath) {
37524
37737
  }
37525
37738
  async function defaultReadUntrackedLineCount(absPath) {
37526
37739
  try {
37527
- const content = await fs62.readFile(absPath, "utf8");
37740
+ const content = await fs63.readFile(absPath, "utf8");
37528
37741
  let count = 0;
37529
37742
  let pos = -1;
37530
37743
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -37616,7 +37829,7 @@ function defaultRunGit(cwd, args2) {
37616
37829
  });
37617
37830
  }
37618
37831
  async function discoverRepos(workingDir, maxDepth = 4) {
37619
- const fs81 = await import("fs/promises");
37832
+ const fs82 = await import("fs/promises");
37620
37833
  const out2 = [];
37621
37834
  await walk(workingDir, 0);
37622
37835
  return out2;
@@ -37624,7 +37837,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
37624
37837
  if (depth > maxDepth) return;
37625
37838
  let entries = [];
37626
37839
  try {
37627
- const dirents = await fs81.readdir(dir, { withFileTypes: true });
37840
+ const dirents = await fs82.readdir(dir, { withFileTypes: true });
37628
37841
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
37629
37842
  } catch {
37630
37843
  return;
@@ -37635,8 +37848,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
37635
37848
  if (hasGit) {
37636
37849
  out2.push({
37637
37850
  repoRoot: dir,
37638
- repoPath: path73.relative(workingDir, dir),
37639
- repoName: path73.basename(dir)
37851
+ repoPath: path74.relative(workingDir, dir),
37852
+ repoName: path74.basename(dir)
37640
37853
  });
37641
37854
  return;
37642
37855
  }
@@ -37644,14 +37857,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
37644
37857
  if (!entry.isDirectory) continue;
37645
37858
  if (entry.name === "node_modules") continue;
37646
37859
  if (entry.name === "dist" || entry.name === "build") continue;
37647
- await walk(path73.join(dir, entry.name), depth + 1);
37860
+ await walk(path74.join(dir, entry.name), depth + 1);
37648
37861
  }
37649
37862
  }
37650
37863
  }
37651
37864
 
37652
37865
  // src/services/turn-files/files-outbox.ts
37653
- var fs63 = __toESM(require("fs/promises"));
37654
- var path74 = __toESM(require("path"));
37866
+ var fs64 = __toESM(require("fs/promises"));
37867
+ var path75 = __toESM(require("path"));
37655
37868
  var import_os12 = require("os");
37656
37869
  var HOME_OUTBOX_DIR = ".codeam/outbox";
37657
37870
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -37684,16 +37897,16 @@ var FilesOutbox = class {
37684
37897
  backoffIndex = 0;
37685
37898
  stopped = false;
37686
37899
  constructor(opts) {
37687
- const base = opts.baseDir ?? path74.join(homeDir(), HOME_OUTBOX_DIR);
37688
- this.filePath = path74.join(base, `${opts.sessionId}.jsonl`);
37900
+ const base = opts.baseDir ?? path75.join(homeDir(), HOME_OUTBOX_DIR);
37901
+ this.filePath = path75.join(base, `${opts.sessionId}.jsonl`);
37689
37902
  this.post = opts.post;
37690
37903
  this.autoSchedule = opts.autoSchedule !== false;
37691
37904
  }
37692
37905
  /** Persist the entry to disk and trigger a flush. Returns once the
37693
37906
  * line is durable on disk (not once the POST succeeds). */
37694
37907
  async enqueue(entry) {
37695
- await fs63.mkdir(path74.dirname(this.filePath), { recursive: true });
37696
- await fs63.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
37908
+ await fs64.mkdir(path75.dirname(this.filePath), { recursive: true });
37909
+ await fs64.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
37697
37910
  this.backoffIndex = 0;
37698
37911
  if (this.autoSchedule) this.scheduleFlush(0);
37699
37912
  }
@@ -37784,7 +37997,7 @@ var FilesOutbox = class {
37784
37997
  async readAll() {
37785
37998
  let raw = "";
37786
37999
  try {
37787
- raw = await fs63.readFile(this.filePath, "utf8");
38000
+ raw = await fs64.readFile(this.filePath, "utf8");
37788
38001
  } catch {
37789
38002
  return [];
37790
38003
  }
@@ -37808,12 +38021,12 @@ var FilesOutbox = class {
37808
38021
  async rewrite(entries) {
37809
38022
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
37810
38023
  if (entries.length === 0) {
37811
- await fs63.unlink(this.filePath).catch(() => void 0);
38024
+ await fs64.unlink(this.filePath).catch(() => void 0);
37812
38025
  return;
37813
38026
  }
37814
38027
  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);
38028
+ await fs64.writeFile(tmpPath, payload, "utf8");
38029
+ await fs64.rename(tmpPath, this.filePath);
37817
38030
  }
37818
38031
  };
37819
38032
  function applyJitter(ms) {
@@ -38360,11 +38573,11 @@ async function postCredentialSync(opts, fetchImpl = fetch) {
38360
38573
  }
38361
38574
 
38362
38575
  // 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"));
38576
+ var import_node_child_process23 = require("child_process");
38577
+ var fs65 = __toESM(require("fs"));
38578
+ var path76 = __toESM(require("path"));
38366
38579
  var defaultCommandRunner = (file, args2, cwd, timeoutMs, env) => new Promise((resolve12) => {
38367
- (0, import_node_child_process22.execFile)(
38580
+ (0, import_node_child_process23.execFile)(
38368
38581
  file,
38369
38582
  args2,
38370
38583
  {
@@ -38412,7 +38625,7 @@ async function changedFiles(run, cwd, from, to) {
38412
38625
  }
38413
38626
  function readWorkspaceFile(cwd, relPath) {
38414
38627
  try {
38415
- return fs64.readFileSync(path75.join(cwd, relPath), "utf8");
38628
+ return fs65.readFileSync(path76.join(cwd, relPath), "utf8");
38416
38629
  } catch {
38417
38630
  return null;
38418
38631
  }
@@ -38421,14 +38634,14 @@ var NO_TEST_PLACEHOLDER = 'echo "Error: no test specified"';
38421
38634
  var CHECKS_TIMEOUT_MS = 5 * 6e4;
38422
38635
  function detectChecksCommand(cwd) {
38423
38636
  try {
38424
- const cfg = JSON.parse(fs64.readFileSync(path75.join(cwd, ".codeam", "pack.json"), "utf8"));
38637
+ const cfg = JSON.parse(fs65.readFileSync(path76.join(cwd, ".codeam", "pack.json"), "utf8"));
38425
38638
  if (typeof cfg.checksCommand === "string" && cfg.checksCommand.trim().length > 0) {
38426
38639
  return cfg.checksCommand.trim();
38427
38640
  }
38428
38641
  } catch {
38429
38642
  }
38430
38643
  try {
38431
- const pkg = JSON.parse(fs64.readFileSync(path75.join(cwd, "package.json"), "utf8"));
38644
+ const pkg = JSON.parse(fs65.readFileSync(path76.join(cwd, "package.json"), "utf8"));
38432
38645
  const test = pkg.scripts?.test;
38433
38646
  if (typeof test === "string" && test.trim().length > 0 && !test.includes(NO_TEST_PLACEHOLDER)) {
38434
38647
  return "npm test";
@@ -38446,39 +38659,39 @@ ${res.stderr}`.trim();
38446
38659
  }
38447
38660
 
38448
38661
  // src/packs/run-store.ts
38449
- var fs65 = __toESM(require("fs"));
38450
- var path76 = __toESM(require("path"));
38662
+ var fs66 = __toESM(require("fs"));
38663
+ var path77 = __toESM(require("path"));
38451
38664
  var crypto5 = __toESM(require("crypto"));
38452
38665
  function packsDir(cwd) {
38453
- return path76.join(cwd, ".codeam", "packs");
38666
+ return path77.join(cwd, ".codeam", "packs");
38454
38667
  }
38455
38668
  function runDir(cwd, runId) {
38456
- return path76.join(packsDir(cwd), runId);
38669
+ return path77.join(packsDir(cwd), runId);
38457
38670
  }
38458
38671
  function newRunId() {
38459
38672
  return `pk_${Date.now().toString(36)}_${crypto5.randomBytes(4).toString("hex")}`;
38460
38673
  }
38461
38674
  function writeJsonAtomic(file, value) {
38462
- fs65.mkdirSync(path76.dirname(file), { recursive: true });
38675
+ fs66.mkdirSync(path77.dirname(file), { recursive: true });
38463
38676
  const tmp = `${file}.tmp`;
38464
- fs65.writeFileSync(tmp, JSON.stringify(value, null, 2));
38465
- fs65.renameSync(tmp, file);
38677
+ fs66.writeFileSync(tmp, JSON.stringify(value, null, 2));
38678
+ fs66.renameSync(tmp, file);
38466
38679
  }
38467
38680
  function saveRun(cwd, state) {
38468
- writeJsonAtomic(path76.join(runDir(cwd, state.runId), "run.json"), state);
38681
+ writeJsonAtomic(path77.join(runDir(cwd, state.runId), "run.json"), state);
38469
38682
  }
38470
38683
  function saveStageHandoff(cwd, runId, stageIndex, role, handoff) {
38471
38684
  const name = `${String(stageIndex + 1).padStart(2, "0")}-${role}.json`;
38472
- writeJsonAtomic(path76.join(runDir(cwd, runId), name), handoff);
38685
+ writeJsonAtomic(path77.join(runDir(cwd, runId), name), handoff);
38473
38686
  }
38474
38687
  function loadLatestRun(cwd) {
38475
38688
  try {
38476
38689
  const dir = packsDir(cwd);
38477
- const entries = fs65.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
38690
+ const entries = fs66.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
38478
38691
  for (let i = entries.length - 1; i >= 0; i--) {
38479
- const file = path76.join(dir, entries[i], "run.json");
38692
+ const file = path77.join(dir, entries[i], "run.json");
38480
38693
  try {
38481
- const parsed = JSON.parse(fs65.readFileSync(file, "utf8"));
38694
+ const parsed = JSON.parse(fs66.readFileSync(file, "utf8"));
38482
38695
  if (parsed && typeof parsed.runId === "string") return parsed;
38483
38696
  } catch {
38484
38697
  }
@@ -38489,17 +38702,17 @@ function loadLatestRun(cwd) {
38489
38702
  }
38490
38703
  function ensureLedgerIgnored(cwd) {
38491
38704
  try {
38492
- const gitDir = path76.join(cwd, ".git");
38493
- if (!fs65.existsSync(gitDir)) return;
38494
- const exclude = path76.join(gitDir, "info", "exclude");
38705
+ const gitDir = path77.join(cwd, ".git");
38706
+ if (!fs66.existsSync(gitDir)) return;
38707
+ const exclude = path77.join(gitDir, "info", "exclude");
38495
38708
  let existing = "";
38496
38709
  try {
38497
- existing = fs65.readFileSync(exclude, "utf8");
38710
+ existing = fs66.readFileSync(exclude, "utf8");
38498
38711
  } catch {
38499
38712
  }
38500
38713
  if (existing.includes(".codeam/packs/")) return;
38501
- fs65.mkdirSync(path76.dirname(exclude), { recursive: true });
38502
- fs65.writeFileSync(exclude, `${existing.trimEnd()}
38714
+ fs66.mkdirSync(path77.dirname(exclude), { recursive: true });
38715
+ fs66.writeFileSync(exclude, `${existing.trimEnd()}
38503
38716
  .codeam/packs/
38504
38717
  `.trimStart());
38505
38718
  } catch {
@@ -39479,6 +39692,93 @@ async function mcpRouter() {
39479
39692
  });
39480
39693
  }
39481
39694
 
39695
+ // src/integrations/mcp-secrets.ts
39696
+ var fs68 = __toESM(require("fs"));
39697
+ var os53 = __toESM(require("os"));
39698
+ var path79 = __toESM(require("path"));
39699
+ var MCP_SECRETS_FILE_ENV = "CODEAM_MCP_SECRETS_FILE";
39700
+ function mcpSecretsDir() {
39701
+ return path79.join(os53.homedir(), ".codeam", "mcp-secrets");
39702
+ }
39703
+ function mcpSecretsPath(scope, pid = process.pid) {
39704
+ return path79.join(mcpSecretsDir(), `${pid}-${scope}.json`);
39705
+ }
39706
+ var registeredForCleanup = /* @__PURE__ */ new Set();
39707
+ function readFileVars(file) {
39708
+ try {
39709
+ const parsed = JSON.parse(fs68.readFileSync(file, "utf8"));
39710
+ if (!parsed || typeof parsed !== "object") return {};
39711
+ const out2 = {};
39712
+ for (const [k2, v] of Object.entries(parsed)) {
39713
+ if (typeof v === "string") out2[k2] = v;
39714
+ }
39715
+ return out2;
39716
+ } catch {
39717
+ return {};
39718
+ }
39719
+ }
39720
+ function pidAlive(pid) {
39721
+ try {
39722
+ process.kill(pid, 0);
39723
+ return true;
39724
+ } catch (err) {
39725
+ return err.code === "EPERM";
39726
+ }
39727
+ }
39728
+ function pruneStale(dir) {
39729
+ let names = [];
39730
+ try {
39731
+ names = fs68.readdirSync(dir);
39732
+ } catch {
39733
+ return;
39734
+ }
39735
+ for (const name of names) {
39736
+ const m = /^(\d+)-[a-z]+\.json$/.exec(name);
39737
+ if (!m) continue;
39738
+ const pid = Number(m[1]);
39739
+ if (pid === process.pid || pidAlive(pid)) continue;
39740
+ try {
39741
+ fs68.unlinkSync(path79.join(dir, name));
39742
+ } catch {
39743
+ }
39744
+ }
39745
+ }
39746
+ function writeMcpSecrets(vars, file) {
39747
+ try {
39748
+ const dir = path79.dirname(file);
39749
+ fs68.mkdirSync(dir, { recursive: true, mode: 448 });
39750
+ pruneStale(dir);
39751
+ const tmp = `${file}.${process.pid}.tmp`;
39752
+ fs68.writeFileSync(tmp, JSON.stringify(vars), { mode: 384 });
39753
+ fs68.renameSync(tmp, file);
39754
+ fs68.chmodSync(file, 384);
39755
+ if (!registeredForCleanup.has(file)) {
39756
+ registeredForCleanup.add(file);
39757
+ process.once("exit", () => {
39758
+ try {
39759
+ fs68.unlinkSync(file);
39760
+ } catch {
39761
+ }
39762
+ });
39763
+ }
39764
+ return file;
39765
+ } catch {
39766
+ return null;
39767
+ }
39768
+ }
39769
+ function mcpSecretEnv(scope, vars) {
39770
+ const file = writeMcpSecrets(vars, mcpSecretsPath(scope));
39771
+ if (file) return [{ name: MCP_SECRETS_FILE_ENV, value: file }];
39772
+ return Object.entries(vars).map(([name, value]) => ({ name, value }));
39773
+ }
39774
+ function loadMcpSecrets(env = process.env) {
39775
+ const file = env[MCP_SECRETS_FILE_ENV];
39776
+ if (!file) return;
39777
+ for (const [k2, v] of Object.entries(readFileVars(file))) {
39778
+ if (env[k2] === void 0) env[k2] = v;
39779
+ }
39780
+ }
39781
+
39482
39782
  // src/commands/preview-mcp.ts
39483
39783
  var PREVIEW_MCP_SERVER_NAME = "codeagent_preview";
39484
39784
  var PREVIEW_IPC_URL_ENV = "CODEAM_PREVIEW_IPC_URL";
@@ -39536,18 +39836,17 @@ function previewMcpServer(bridge) {
39536
39836
  // Same runtime + entrypoint as this CLI — never trust the agent's PATH.
39537
39837
  command: process.execPath,
39538
39838
  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
- ]
39839
+ // The token rides the owner-only secrets file, never this env: the
39840
+ // claude ACP adapter copies MCP env onto argv (codeagent-5bew).
39841
+ env: [{ name: PREVIEW_IPC_URL_ENV, value: bridge.url }, ...mcpSecretEnv("preview", { [PREVIEW_IPC_TOKEN_ENV]: bridge.token })]
39543
39842
  };
39544
39843
  }
39545
39844
  function httpCall(baseUrl, token) {
39546
- return async (path96, method, body, timeoutMs) => {
39845
+ return async (path97, method, body, timeoutMs) => {
39547
39846
  const ac = new AbortController();
39548
39847
  const timer = setTimeout(() => ac.abort(), timeoutMs);
39549
39848
  try {
39550
- const res = await fetch(`${baseUrl}${path96}`, {
39849
+ const res = await fetch(`${baseUrl}${path97}`, {
39551
39850
  method,
39552
39851
  headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
39553
39852
  ...method === "POST" ? { body: JSON.stringify(body ?? {}) } : {},
@@ -39642,6 +39941,12 @@ async function previewMcp() {
39642
39941
  }
39643
39942
 
39644
39943
  // src/integrations/provision.ts
39944
+ function secretVars(ctx) {
39945
+ return {
39946
+ ...ctx.pluginAuthToken ? { CODEAM_MCP_PLUGIN_TOKEN: ctx.pluginAuthToken } : {},
39947
+ ...ctx.pollSecret ? { CODEAM_MCP_POLL_SECRET: ctx.pollSecret } : {}
39948
+ };
39949
+ }
39645
39950
  function buildMcpServersForStart(ctx) {
39646
39951
  const servers = buildIntegrationMcpServers(ctx);
39647
39952
  const preview = previewMcpServer(ctx.preview ?? null);
@@ -39661,9 +39966,10 @@ function buildIntegrationMcpServers(ctx) {
39661
39966
  { name: "CODEAM_MCP_INTEGRATION_ID", value: entry.id },
39662
39967
  { name: "CODEAM_MCP_SESSION_ID", value: ctx.sessionId },
39663
39968
  { 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 }] : []
39969
+ // ⚠️ Secrets via an owner-only FILE, not env values: the claude ACP
39970
+ // adapter copies this env onto the agent's argv (`--mcp-config`), where
39971
+ // `ps` shows it (codeagent-5bew). See `mcp-secrets.ts`.
39972
+ ...mcpSecretEnv("integrations", secretVars(ctx))
39667
39973
  ];
39668
39974
  servers.push({
39669
39975
  name: entry.id,
@@ -39692,8 +39998,7 @@ function buildIntegrationMcpServers(ctx) {
39692
39998
  env: [
39693
39999
  { name: "CODEAM_MCP_SESSION_ID", value: ctx.sessionId },
39694
40000
  { 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 }] : []
40001
+ ...mcpSecretEnv("integrations", secretVars(ctx))
39697
40002
  ]
39698
40003
  }
39699
40004
  ];
@@ -40263,7 +40568,7 @@ function logMentionOutcome(result) {
40263
40568
  }
40264
40569
 
40265
40570
  // src/agents/acp/command-handlers.ts
40266
- var import_node_child_process23 = require("child_process");
40571
+ var import_node_child_process24 = require("child_process");
40267
40572
 
40268
40573
  // src/agents/acp/buildAcpPromptBlocks.ts
40269
40574
  var MIME_FROM_EXT = {
@@ -41225,7 +41530,7 @@ async function prewarmNewMcpEntries(manifest, previousIds) {
41225
41530
  fresh.map(
41226
41531
  (e) => new Promise((resolve12) => {
41227
41532
  const mcp = e.delivery.mcp;
41228
- const child = (0, import_node_child_process23.execFile)(
41533
+ const child = (0, import_node_child_process24.execFile)(
41229
41534
  mcp.command,
41230
41535
  [...mcp.args, "--help"],
41231
41536
  { timeout: 9e4 },
@@ -42394,11 +42699,11 @@ async function runAcpSession(opts) {
42394
42699
  if (swapOpts.house) {
42395
42700
  houseWireId = swapOpts.wireId ?? HOUSE_AGENT_ID;
42396
42701
  if (pendingHouseConfig) {
42397
- persistHouseProxyConfig(pendingHouseConfig);
42702
+ persistHouseProxyConfig(pendingHouseConfig, deployIdFromWorkspace(process.cwd()) ?? void 0);
42398
42703
  pendingHouseConfig = null;
42399
42704
  }
42400
42705
  } else if (wasHouse) {
42401
- clearHouseProxyConfig();
42706
+ clearHouseProxyConfig(deployIdFromWorkspace(process.cwd()) ?? void 0);
42402
42707
  }
42403
42708
  const managedBanner = swapOpts.house && isManagedProviderId(houseWireId) ? houseWireId : null;
42404
42709
  void publisher.publishOutput({
@@ -42437,17 +42742,17 @@ async function runAcpSession(opts) {
42437
42742
  switchCredentialEnv = provisionAgentCredentials(agentId, auth);
42438
42743
  },
42439
42744
  provisionHouseProxy: ({ baseUrl, token, model, managedAgentId }) => {
42440
- const claudeConfigDir = path80.join(
42441
- os53.homedir(),
42745
+ const claudeConfigDir = path82.join(
42746
+ os55.homedir(),
42442
42747
  ".codeam",
42443
42748
  "house-claude",
42444
42749
  `switch-${opts.pluginId}`
42445
42750
  );
42446
42751
  try {
42447
- fs69.mkdirSync(claudeConfigDir, { recursive: true, mode: 448 });
42752
+ fs71.mkdirSync(claudeConfigDir, { recursive: true, mode: 448 });
42448
42753
  } catch {
42449
42754
  }
42450
- const memoryFile = path80.join(claudeConfigDir, "CLAUDE.md");
42755
+ const memoryFile = path82.join(claudeConfigDir, "CLAUDE.md");
42451
42756
  ensureBeadsWorkflowHint(void 0, memoryFile);
42452
42757
  ensureAgentStandard(void 0, memoryFile);
42453
42758
  const cfg = {
@@ -43670,9 +43975,9 @@ function pickPinnedSession(pinnedId, listSessions2) {
43670
43975
  }
43671
43976
 
43672
43977
  // src/agents/retired-proxy-cleanup.ts
43673
- var fs70 = __toESM(require("fs"));
43674
- var path81 = __toESM(require("path"));
43675
- var os54 = __toESM(require("os"));
43978
+ var fs72 = __toESM(require("fs"));
43979
+ var path83 = __toESM(require("path"));
43980
+ var os56 = __toESM(require("os"));
43676
43981
  var RETIRED_PROXY_RE = /^https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):8787(?:[/?#]|$)/i;
43677
43982
  var HEADROOM_CMD_RE = /(^|[\s/"'])headroom(\s|$)/i;
43678
43983
  var MARKETPLACE_KEY = "headroom-marketplace";
@@ -43681,12 +43986,12 @@ function isHeadroomHook(group) {
43681
43986
  (h) => typeof h?.command === "string" && HEADROOM_CMD_RE.test(h.command)
43682
43987
  );
43683
43988
  }
43684
- function sanitizeRetiredProxyConfig(homeDir2 = os54.homedir()) {
43989
+ function sanitizeRetiredProxyConfig(homeDir2 = os56.homedir()) {
43685
43990
  const out2 = { inspected: false, changed: false, removed: [] };
43686
- const file = path81.join(homeDir2, ".claude", "settings.json");
43991
+ const file = path83.join(homeDir2, ".claude", "settings.json");
43687
43992
  let parsed;
43688
43993
  try {
43689
- parsed = JSON.parse(fs70.readFileSync(file, "utf8"));
43994
+ parsed = JSON.parse(fs72.readFileSync(file, "utf8"));
43690
43995
  } catch {
43691
43996
  return out2;
43692
43997
  }
@@ -43728,9 +44033,9 @@ function sanitizeRetiredProxyConfig(homeDir2 = os54.homedir()) {
43728
44033
  if (!out2.changed) return out2;
43729
44034
  try {
43730
44035
  const tmp = `${file}.codeam.tmp`;
43731
- fs70.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
44036
+ fs72.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
43732
44037
  `, { mode: 384 });
43733
- fs70.renameSync(tmp, file);
44038
+ fs72.renameSync(tmp, file);
43734
44039
  } catch {
43735
44040
  out2.changed = false;
43736
44041
  }
@@ -44262,7 +44567,7 @@ var AcpDriver = class {
44262
44567
  };
44263
44568
 
44264
44569
  // src/baton/transcript-mirror.ts
44265
- var fs71 = __toESM(require("fs"));
44570
+ var fs73 = __toESM(require("fs"));
44266
44571
  var TranscriptMirror = class {
44267
44572
  constructor(deps) {
44268
44573
  this.deps = deps;
@@ -44356,7 +44661,7 @@ var TranscriptMirror = class {
44356
44661
  }
44357
44662
  };
44358
44663
  function defaultWatch(file, onChange) {
44359
- const w3 = fs71.watch(file, { persistent: false }, () => onChange());
44664
+ const w3 = fs73.watch(file, { persistent: false }, () => onChange());
44360
44665
  return () => w3.close();
44361
44666
  }
44362
44667
 
@@ -44666,7 +44971,7 @@ function toEpochMs(ts) {
44666
44971
  }
44667
44972
 
44668
44973
  // src/services/keep-awake.ts
44669
- var import_node_child_process24 = require("child_process");
44974
+ var import_node_child_process25 = require("child_process");
44670
44975
  function keepDeviceAwake(deps = {}) {
44671
44976
  const env = deps.env ?? process.env;
44672
44977
  const isLocal = deps.isLocal ?? isLocalSession(env);
@@ -44676,7 +44981,7 @@ function keepDeviceAwake(deps = {}) {
44676
44981
  if (env.CODEAM_NO_KEEP_AWAKE === "1") return noop;
44677
44982
  const command2 = deps.command !== void 0 ? deps.command : createOsStrategy().keepAwakeCommand(deps.pid ?? process.pid);
44678
44983
  if (!command2) return noop;
44679
- const spawnFn = deps.spawnFn ?? import_node_child_process24.spawn;
44984
+ const spawnFn = deps.spawnFn ?? import_node_child_process25.spawn;
44680
44985
  let child = null;
44681
44986
  try {
44682
44987
  child = spawnFn(command2.cmd, command2.args, { stdio: "ignore", detached: true });
@@ -44702,16 +45007,16 @@ function keepDeviceAwake(deps = {}) {
44702
45007
  }
44703
45008
 
44704
45009
  // src/agents/claude/onboarding.ts
44705
- var fs72 = __toESM(require("fs"));
44706
- var os56 = __toESM(require("os"));
44707
- var path82 = __toESM(require("path"));
45010
+ var fs74 = __toESM(require("fs"));
45011
+ var os58 = __toESM(require("os"));
45012
+ var path84 = __toESM(require("path"));
44708
45013
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
44709
45014
  function ensureClaudeOnboarded(cwd) {
44710
45015
  try {
44711
- const file = path82.join(os56.homedir(), ".claude.json");
45016
+ const file = path84.join(os58.homedir(), ".claude.json");
44712
45017
  let config = {};
44713
45018
  try {
44714
- config = JSON.parse(fs72.readFileSync(file, "utf8"));
45019
+ config = JSON.parse(fs74.readFileSync(file, "utf8"));
44715
45020
  } catch {
44716
45021
  }
44717
45022
  let changed = false;
@@ -44736,8 +45041,8 @@ function ensureClaudeOnboarded(cwd) {
44736
45041
  }
44737
45042
  }
44738
45043
  if (!changed) return;
44739
- fs72.mkdirSync(path82.dirname(file), { recursive: true });
44740
- fs72.writeFileSync(file, JSON.stringify(config, null, 2));
45044
+ fs74.mkdirSync(path84.dirname(file), { recursive: true });
45045
+ fs74.writeFileSync(file, JSON.stringify(config, null, 2));
44741
45046
  log.info(
44742
45047
  "claude",
44743
45048
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -45514,8 +45819,8 @@ var import_picocolors10 = __toESM(require("picocolors"));
45514
45819
  var import_child_process30 = require("child_process");
45515
45820
  var import_util4 = require("util");
45516
45821
  var import_picocolors8 = __toESM(require("picocolors"));
45517
- var path83 = __toESM(require("path"));
45518
- var execFileP5 = (0, import_util4.promisify)(import_child_process30.execFile);
45822
+ var path85 = __toESM(require("path"));
45823
+ var execFileP6 = (0, import_util4.promisify)(import_child_process30.execFile);
45519
45824
  var MAX_BUFFER = 8 * 1024 * 1024;
45520
45825
  function resetStdinForChild() {
45521
45826
  if (process.stdin.isTTY) {
@@ -45532,11 +45837,11 @@ var GitHubCodespacesProvider = class {
45532
45837
  available = true;
45533
45838
  async authorize() {
45534
45839
  try {
45535
- await execFileP5("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45840
+ await execFileP6("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45536
45841
  } catch {
45537
45842
  await this.tryInstallGh();
45538
45843
  try {
45539
- await execFileP5("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45844
+ await execFileP6("gh", ["--version"], { maxBuffer: MAX_BUFFER });
45540
45845
  } catch {
45541
45846
  throw new Error(
45542
45847
  [
@@ -45552,7 +45857,7 @@ var GitHubCodespacesProvider = class {
45552
45857
  }
45553
45858
  let isAuthed = false;
45554
45859
  try {
45555
- await execFileP5("gh", ["auth", "status"], { maxBuffer: MAX_BUFFER });
45860
+ await execFileP6("gh", ["auth", "status"], { maxBuffer: MAX_BUFFER });
45556
45861
  isAuthed = true;
45557
45862
  } catch {
45558
45863
  }
@@ -45628,7 +45933,7 @@ var GitHubCodespacesProvider = class {
45628
45933
  */
45629
45934
  async getActiveGhUser() {
45630
45935
  try {
45631
- const { stdout } = await execFileP5(
45936
+ const { stdout } = await execFileP6(
45632
45937
  "gh",
45633
45938
  ["api", "user", "--jq", ".login"],
45634
45939
  { maxBuffer: MAX_BUFFER }
@@ -45648,7 +45953,7 @@ var GitHubCodespacesProvider = class {
45648
45953
  */
45649
45954
  async hasCodespaceScope() {
45650
45955
  try {
45651
- const { stdout } = await execFileP5(
45956
+ const { stdout } = await execFileP6(
45652
45957
  "gh",
45653
45958
  ["api", "-i", "user"],
45654
45959
  { maxBuffer: MAX_BUFFER }
@@ -45697,7 +46002,7 @@ var GitHubCodespacesProvider = class {
45697
46002
  let installCmd = null;
45698
46003
  if (platform3 === "darwin") {
45699
46004
  try {
45700
- await execFileP5("brew", ["--version"], { maxBuffer: MAX_BUFFER });
46005
+ await execFileP6("brew", ["--version"], { maxBuffer: MAX_BUFFER });
45701
46006
  } catch {
45702
46007
  wt(
45703
46008
  [
@@ -45716,7 +46021,7 @@ var GitHubCodespacesProvider = class {
45716
46021
  };
45717
46022
  } else if (platform3 === "win32") {
45718
46023
  try {
45719
- await execFileP5("winget", ["--version"], { maxBuffer: MAX_BUFFER });
46024
+ await execFileP6("winget", ["--version"], { maxBuffer: MAX_BUFFER });
45720
46025
  } catch {
45721
46026
  wt(
45722
46027
  [
@@ -45795,7 +46100,7 @@ var GitHubCodespacesProvider = class {
45795
46100
  "200"
45796
46101
  );
45797
46102
  try {
45798
- const { stdout } = await execFileP5("gh", args2, { maxBuffer: MAX_BUFFER });
46103
+ const { stdout } = await execFileP6("gh", args2, { maxBuffer: MAX_BUFFER });
45799
46104
  return JSON.parse(stdout);
45800
46105
  } catch {
45801
46106
  return [];
@@ -45804,7 +46109,7 @@ var GitHubCodespacesProvider = class {
45804
46109
  const own = await fetchRepos();
45805
46110
  let orgRepos = [];
45806
46111
  try {
45807
- const { stdout } = await execFileP5(
46112
+ const { stdout } = await execFileP6(
45808
46113
  "gh",
45809
46114
  ["api", "--paginate", "user/orgs", "--jq", ".[].login"],
45810
46115
  { maxBuffer: MAX_BUFFER }
@@ -45841,7 +46146,7 @@ var GitHubCodespacesProvider = class {
45841
46146
  */
45842
46147
  async listMachineTypes(projectId) {
45843
46148
  try {
45844
- const { stdout } = await execFileP5(
46149
+ const { stdout } = await execFileP6(
45845
46150
  "gh",
45846
46151
  ["api", `/repos/${projectId}/codespaces/machines`],
45847
46152
  { maxBuffer: MAX_BUFFER }
@@ -45872,7 +46177,7 @@ var GitHubCodespacesProvider = class {
45872
46177
  const machine = machineTypeId ?? await this.pickDefaultMachine(projectId);
45873
46178
  const args2 = ["codespace", "create", "-R", projectId, "--default-permissions"];
45874
46179
  if (machine) args2.push("-m", machine);
45875
- const { stdout } = await execFileP5(
46180
+ const { stdout } = await execFileP6(
45876
46181
  "gh",
45877
46182
  args2,
45878
46183
  { maxBuffer: MAX_BUFFER, timeout: 12e4 }
@@ -45912,7 +46217,7 @@ var GitHubCodespacesProvider = class {
45912
46217
  async waitUntilAvailable(name) {
45913
46218
  const deadline = Date.now() + 5 * 60 * 1e3;
45914
46219
  while (Date.now() < deadline) {
45915
- const { stdout } = await execFileP5(
46220
+ const { stdout } = await execFileP6(
45916
46221
  "gh",
45917
46222
  ["codespace", "list", "--json", "name,state"],
45918
46223
  { maxBuffer: MAX_BUFFER }
@@ -45930,7 +46235,7 @@ var GitHubCodespacesProvider = class {
45930
46235
  }
45931
46236
  async exec(workspaceId, command2) {
45932
46237
  try {
45933
- const { stdout, stderr } = await execFileP5(
46238
+ const { stdout, stderr } = await execFileP6(
45934
46239
  "gh",
45935
46240
  ["codespace", "ssh", "-c", workspaceId, "--", command2],
45936
46241
  { maxBuffer: MAX_BUFFER, timeout: 6e5 }
@@ -46003,7 +46308,7 @@ var GitHubCodespacesProvider = class {
46003
46308
  });
46004
46309
  }
46005
46310
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46006
- const remoteDir = path83.posix.dirname(remotePath);
46311
+ const remoteDir = path85.posix.dirname(remotePath);
46007
46312
  const parts = [
46008
46313
  `mkdir -p ${shellQuote(remoteDir)}`,
46009
46314
  `cat > ${shellQuote(remotePath)}`
@@ -46035,7 +46340,7 @@ var GitHubCodespacesProvider = class {
46035
46340
  try {
46036
46341
  const args2 = ["codespace", "list", "--json", "name,displayName,state,lastUsedAt"];
46037
46342
  if (projectId) args2.push("--repo", projectId);
46038
- const { stdout } = await execFileP5("gh", args2, { maxBuffer: MAX_BUFFER });
46343
+ const { stdout } = await execFileP6("gh", args2, { maxBuffer: MAX_BUFFER });
46039
46344
  const list = JSON.parse(stdout);
46040
46345
  return list.map((c2) => ({
46041
46346
  id: c2.name,
@@ -46050,7 +46355,7 @@ var GitHubCodespacesProvider = class {
46050
46355
  }
46051
46356
  async startWorkspace(workspaceId) {
46052
46357
  try {
46053
- await execFileP5(
46358
+ await execFileP6(
46054
46359
  "gh",
46055
46360
  ["api", "-X", "POST", `/user/codespaces/${workspaceId}/start`],
46056
46361
  { maxBuffer: MAX_BUFFER, timeout: 6e4 }
@@ -46073,9 +46378,9 @@ function shellQuote(s) {
46073
46378
  // src/services/providers/gitpod.ts
46074
46379
  var import_child_process31 = require("child_process");
46075
46380
  var import_util5 = require("util");
46076
- var path84 = __toESM(require("path"));
46381
+ var path86 = __toESM(require("path"));
46077
46382
  var import_picocolors9 = __toESM(require("picocolors"));
46078
- var execFileP6 = (0, import_util5.promisify)(import_child_process31.execFile);
46383
+ var execFileP7 = (0, import_util5.promisify)(import_child_process31.execFile);
46079
46384
  var MAX_BUFFER2 = 8 * 1024 * 1024;
46080
46385
  function resetStdinForChild2() {
46081
46386
  if (process.stdin.isTTY) {
@@ -46092,7 +46397,7 @@ var GitpodProvider = class {
46092
46397
  available = true;
46093
46398
  async authorize() {
46094
46399
  try {
46095
- await execFileP6("gitpod", ["--version"], { maxBuffer: MAX_BUFFER2 });
46400
+ await execFileP7("gitpod", ["--version"], { maxBuffer: MAX_BUFFER2 });
46096
46401
  } catch {
46097
46402
  throw new Error(
46098
46403
  [
@@ -46105,7 +46410,7 @@ var GitpodProvider = class {
46105
46410
  );
46106
46411
  }
46107
46412
  try {
46108
- await execFileP6("gitpod", ["whoami"], { maxBuffer: MAX_BUFFER2 });
46413
+ await execFileP7("gitpod", ["whoami"], { maxBuffer: MAX_BUFFER2 });
46109
46414
  return;
46110
46415
  } catch {
46111
46416
  }
@@ -46125,7 +46430,7 @@ var GitpodProvider = class {
46125
46430
  }
46126
46431
  async listProjects() {
46127
46432
  try {
46128
- const { stdout } = await execFileP6(
46433
+ const { stdout } = await execFileP7(
46129
46434
  "gitpod",
46130
46435
  ["workspace", "list", "--output", "json", "--limit", "200"],
46131
46436
  { maxBuffer: MAX_BUFFER2 }
@@ -46158,7 +46463,7 @@ var GitpodProvider = class {
46158
46463
  async createWorkspace(projectId, machineTypeId) {
46159
46464
  const args2 = ["workspace", "create", projectId, "--start", "--output", "json"];
46160
46465
  if (machineTypeId) args2.push("--class", machineTypeId);
46161
- const { stdout } = await execFileP6("gitpod", args2, {
46466
+ const { stdout } = await execFileP7("gitpod", args2, {
46162
46467
  maxBuffer: MAX_BUFFER2,
46163
46468
  timeout: 3e5
46164
46469
  });
@@ -46182,7 +46487,7 @@ var GitpodProvider = class {
46182
46487
  const deadline = Date.now() + 5 * 60 * 1e3;
46183
46488
  while (Date.now() < deadline) {
46184
46489
  try {
46185
- const { stdout } = await execFileP6(
46490
+ const { stdout } = await execFileP7(
46186
46491
  "gitpod",
46187
46492
  ["workspace", "get", workspaceId, "--output", "json"],
46188
46493
  { maxBuffer: MAX_BUFFER2 }
@@ -46200,7 +46505,7 @@ var GitpodProvider = class {
46200
46505
  }
46201
46506
  async listMachineTypes(_projectId) {
46202
46507
  try {
46203
- const { stdout } = await execFileP6(
46508
+ const { stdout } = await execFileP7(
46204
46509
  "gitpod",
46205
46510
  ["organization", "list-classes", "--output", "json"],
46206
46511
  { maxBuffer: MAX_BUFFER2 }
@@ -46218,7 +46523,7 @@ var GitpodProvider = class {
46218
46523
  async listExistingWorkspaces(projectId) {
46219
46524
  try {
46220
46525
  const args2 = ["workspace", "list", "--output", "json", "--limit", "200"];
46221
- const { stdout } = await execFileP6("gitpod", args2, { maxBuffer: MAX_BUFFER2 });
46526
+ const { stdout } = await execFileP7("gitpod", args2, { maxBuffer: MAX_BUFFER2 });
46222
46527
  const list = JSON.parse(stdout);
46223
46528
  return list.filter((w3) => !projectId || w3.contextUrl === projectId).map((w3) => ({
46224
46529
  id: w3.id,
@@ -46233,7 +46538,7 @@ var GitpodProvider = class {
46233
46538
  }
46234
46539
  async startWorkspace(workspaceId) {
46235
46540
  try {
46236
- await execFileP6(
46541
+ await execFileP7(
46237
46542
  "gitpod",
46238
46543
  ["workspace", "start", workspaceId],
46239
46544
  { maxBuffer: MAX_BUFFER2, timeout: 6e4 }
@@ -46249,7 +46554,7 @@ var GitpodProvider = class {
46249
46554
  }
46250
46555
  async exec(workspaceId, command2) {
46251
46556
  try {
46252
- const { stdout, stderr } = await execFileP6(
46557
+ const { stdout, stderr } = await execFileP7(
46253
46558
  "gitpod",
46254
46559
  ["workspace", "ssh", workspaceId, "--", command2],
46255
46560
  { maxBuffer: MAX_BUFFER2, timeout: 6e5 }
@@ -46313,7 +46618,7 @@ var GitpodProvider = class {
46313
46618
  });
46314
46619
  }
46315
46620
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46316
- const remoteDir = path84.posix.dirname(remotePath);
46621
+ const remoteDir = path86.posix.dirname(remotePath);
46317
46622
  const parts = [
46318
46623
  `mkdir -p ${shellQuote2(remoteDir)}`,
46319
46624
  `cat > ${shellQuote2(remotePath)}`
@@ -46349,8 +46654,8 @@ function shellQuote2(s) {
46349
46654
  // src/services/providers/gitlab-workspaces.ts
46350
46655
  var import_child_process32 = require("child_process");
46351
46656
  var import_util6 = require("util");
46352
- var path85 = __toESM(require("path"));
46353
- var execFileP7 = (0, import_util6.promisify)(import_child_process32.execFile);
46657
+ var path87 = __toESM(require("path"));
46658
+ var execFileP8 = (0, import_util6.promisify)(import_child_process32.execFile);
46354
46659
  var MAX_BUFFER3 = 8 * 1024 * 1024;
46355
46660
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
46356
46661
  function resetStdinForChild3() {
@@ -46368,7 +46673,7 @@ var GitLabWorkspacesProvider = class {
46368
46673
  available = true;
46369
46674
  async authorize() {
46370
46675
  try {
46371
- await execFileP7("glab", ["--version"], { maxBuffer: MAX_BUFFER3 });
46676
+ await execFileP8("glab", ["--version"], { maxBuffer: MAX_BUFFER3 });
46372
46677
  } catch {
46373
46678
  throw new Error(
46374
46679
  [
@@ -46382,7 +46687,7 @@ var GitLabWorkspacesProvider = class {
46382
46687
  );
46383
46688
  }
46384
46689
  try {
46385
- await execFileP7("glab", ["auth", "status"], { maxBuffer: MAX_BUFFER3 });
46690
+ await execFileP8("glab", ["auth", "status"], { maxBuffer: MAX_BUFFER3 });
46386
46691
  return;
46387
46692
  } catch {
46388
46693
  }
@@ -46406,7 +46711,7 @@ var GitLabWorkspacesProvider = class {
46406
46711
  }
46407
46712
  async listProjects() {
46408
46713
  try {
46409
- const { stdout } = await execFileP7(
46714
+ const { stdout } = await execFileP8(
46410
46715
  "glab",
46411
46716
  ["repo", "list", "--per-page", "200", "--output", "json"],
46412
46717
  { maxBuffer: MAX_BUFFER3 }
@@ -46538,7 +46843,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
46538
46843
  async exec(workspaceId, command2) {
46539
46844
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
46540
46845
  try {
46541
- const { stdout, stderr } = await execFileP7(
46846
+ const { stdout, stderr } = await execFileP8(
46542
46847
  "ssh",
46543
46848
  [
46544
46849
  "-o",
@@ -46609,7 +46914,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
46609
46914
  }
46610
46915
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46611
46916
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
46612
- const remoteDir = path85.posix.dirname(remotePath);
46917
+ const remoteDir = path87.posix.dirname(remotePath);
46613
46918
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
46614
46919
  if (options.mode != null) {
46615
46920
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -46641,7 +46946,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
46641
46946
  */
46642
46947
  async getGlabToken() {
46643
46948
  try {
46644
- const { stdout, stderr } = await execFileP7(
46949
+ const { stdout, stderr } = await execFileP8(
46645
46950
  "glab",
46646
46951
  ["auth", "status", "--show-token"],
46647
46952
  { maxBuffer: MAX_BUFFER3 }
@@ -46677,8 +46982,8 @@ function shellQuote3(s) {
46677
46982
  // src/services/providers/railway.ts
46678
46983
  var import_child_process33 = require("child_process");
46679
46984
  var import_util7 = require("util");
46680
- var path86 = __toESM(require("path"));
46681
- var execFileP8 = (0, import_util7.promisify)(import_child_process33.execFile);
46985
+ var path88 = __toESM(require("path"));
46986
+ var execFileP9 = (0, import_util7.promisify)(import_child_process33.execFile);
46682
46987
  var MAX_BUFFER4 = 8 * 1024 * 1024;
46683
46988
  function resetStdinForChild4() {
46684
46989
  if (process.stdin.isTTY) {
@@ -46695,7 +47000,7 @@ var RailwayProvider = class {
46695
47000
  available = true;
46696
47001
  async authorize() {
46697
47002
  try {
46698
- await execFileP8("railway", ["--version"], { maxBuffer: MAX_BUFFER4 });
47003
+ await execFileP9("railway", ["--version"], { maxBuffer: MAX_BUFFER4 });
46699
47004
  } catch {
46700
47005
  throw new Error(
46701
47006
  [
@@ -46709,7 +47014,7 @@ var RailwayProvider = class {
46709
47014
  );
46710
47015
  }
46711
47016
  try {
46712
- await execFileP8("railway", ["whoami"], { maxBuffer: MAX_BUFFER4 });
47017
+ await execFileP9("railway", ["whoami"], { maxBuffer: MAX_BUFFER4 });
46713
47018
  return;
46714
47019
  } catch {
46715
47020
  }
@@ -46729,7 +47034,7 @@ var RailwayProvider = class {
46729
47034
  }
46730
47035
  async listProjects() {
46731
47036
  try {
46732
- const { stdout } = await execFileP8(
47037
+ const { stdout } = await execFileP9(
46733
47038
  "railway",
46734
47039
  ["list", "--json"],
46735
47040
  { maxBuffer: MAX_BUFFER4 }
@@ -46745,7 +47050,7 @@ var RailwayProvider = class {
46745
47050
  }));
46746
47051
  } catch {
46747
47052
  try {
46748
- const { stdout } = await execFileP8("railway", ["list"], { maxBuffer: MAX_BUFFER4 });
47053
+ const { stdout } = await execFileP9("railway", ["list"], { maxBuffer: MAX_BUFFER4 });
46749
47054
  const projects = [];
46750
47055
  for (const line of stdout.split("\n")) {
46751
47056
  const trimmed = line.trim();
@@ -46796,7 +47101,7 @@ var RailwayProvider = class {
46796
47101
  async listExistingWorkspaces(projectId) {
46797
47102
  if (!projectId) return [];
46798
47103
  try {
46799
- const { stdout } = await execFileP8(
47104
+ const { stdout } = await execFileP9(
46800
47105
  "railway",
46801
47106
  ["service", "list", "--project", projectId, "--json"],
46802
47107
  { maxBuffer: MAX_BUFFER4 }
@@ -46821,7 +47126,7 @@ var RailwayProvider = class {
46821
47126
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
46822
47127
  }
46823
47128
  try {
46824
- await execFileP8(
47129
+ await execFileP9(
46825
47130
  "railway",
46826
47131
  ["service", "restart", "--service", serviceId, "--project", projectId],
46827
47132
  { maxBuffer: MAX_BUFFER4, timeout: 6e4 }
@@ -46840,7 +47145,7 @@ var RailwayProvider = class {
46840
47145
  };
46841
47146
  }
46842
47147
  try {
46843
- const { stdout, stderr } = await execFileP8(
47148
+ const { stdout, stderr } = await execFileP9(
46844
47149
  "railway",
46845
47150
  ["run", "--project", projectId, "--service", serviceId, "--", "bash", "-lc", command2],
46846
47151
  { maxBuffer: MAX_BUFFER4, timeout: 6e5 }
@@ -46913,7 +47218,7 @@ var RailwayProvider = class {
46913
47218
  if (!projectId || !serviceId) {
46914
47219
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
46915
47220
  }
46916
- const remoteDir = path86.posix.dirname(remotePath);
47221
+ const remoteDir = path88.posix.dirname(remotePath);
46917
47222
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
46918
47223
  if (options.mode != null) {
46919
47224
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -47453,14 +47758,14 @@ async function stopWorkspaceFromLocal(target) {
47453
47758
  }
47454
47759
 
47455
47760
  // src/commands/host/host-client.ts
47456
- var fs73 = __toESM(require("fs"));
47457
- var os57 = __toESM(require("os"));
47458
- var path87 = __toESM(require("path"));
47761
+ var fs75 = __toESM(require("fs"));
47762
+ var os59 = __toESM(require("os"));
47763
+ var path89 = __toESM(require("path"));
47459
47764
  var import_node_crypto12 = require("crypto");
47460
47765
  function sampleCpuTimes() {
47461
47766
  let idle = 0;
47462
47767
  let total = 0;
47463
- for (const cpu of os57.cpus()) {
47768
+ for (const cpu of os59.cpus()) {
47464
47769
  const t2 = cpu.times;
47465
47770
  idle += t2.idle;
47466
47771
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -47479,8 +47784,8 @@ var MetricsCollector = class {
47479
47784
  const prev = this.prevCpu;
47480
47785
  this.prevCpu = current2;
47481
47786
  if (!prev) {
47482
- const cores = os57.cpus().length || 1;
47483
- const proxy = os57.loadavg()[0] / cores * 100;
47787
+ const cores = os59.cpus().length || 1;
47788
+ const proxy = os59.loadavg()[0] / cores * 100;
47484
47789
  return Math.min(100, Math.max(0, Math.round(proxy)));
47485
47790
  }
47486
47791
  const idleDelta = current2.idle - prev.idle;
@@ -47493,8 +47798,8 @@ var MetricsCollector = class {
47493
47798
  collect() {
47494
47799
  return {
47495
47800
  cpuPct: this.cpuPct(),
47496
- ramUsedMb: Math.round((os57.totalmem() - os57.freemem()) / 1048576),
47497
- ramTotalMb: Math.round(os57.totalmem() / 1048576),
47801
+ ramUsedMb: Math.round((os59.totalmem() - os59.freemem()) / 1048576),
47802
+ ramTotalMb: Math.round(os59.totalmem() / 1048576),
47498
47803
  latencyMs: this.lastLatencyMs
47499
47804
  };
47500
47805
  }
@@ -47503,19 +47808,19 @@ function apiBase() {
47503
47808
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
47504
47809
  }
47505
47810
  function hostIdentityPath() {
47506
- return path87.join(os57.homedir(), ".codeam", "host-agent.json");
47811
+ return path89.join(os59.homedir(), ".codeam", "host-agent.json");
47507
47812
  }
47508
47813
  function collectOsInfo() {
47509
47814
  return {
47510
- distro: os57.platform(),
47511
- arch: os57.arch(),
47512
- kernel: os57.release(),
47815
+ distro: os59.platform(),
47816
+ arch: os59.arch(),
47817
+ kernel: os59.release(),
47513
47818
  nodeVersion: process.versions.node
47514
47819
  };
47515
47820
  }
47516
47821
  function loadHostIdentity() {
47517
47822
  try {
47518
- const raw = fs73.readFileSync(hostIdentityPath(), "utf8");
47823
+ const raw = fs75.readFileSync(hostIdentityPath(), "utf8");
47519
47824
  const parsed = JSON.parse(raw);
47520
47825
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
47521
47826
  const p2 = parsed;
@@ -47534,8 +47839,8 @@ function loadHostIdentity() {
47534
47839
  }
47535
47840
  function saveHostIdentity(identity) {
47536
47841
  const file = hostIdentityPath();
47537
- fs73.mkdirSync(path87.dirname(file), { recursive: true, mode: 448 });
47538
- fs73.writeFileSync(file, JSON.stringify(identity, null, 2), {
47842
+ fs75.mkdirSync(path89.dirname(file), { recursive: true, mode: 448 });
47843
+ fs75.writeFileSync(file, JSON.stringify(identity, null, 2), {
47539
47844
  encoding: "utf8",
47540
47845
  mode: 384
47541
47846
  });
@@ -47580,7 +47885,7 @@ function isTerminalEnrollError(err) {
47580
47885
  }
47581
47886
  function deleteHostIdentity() {
47582
47887
  try {
47583
- fs73.rmSync(hostIdentityPath(), { force: true });
47888
+ fs75.rmSync(hostIdentityPath(), { force: true });
47584
47889
  } catch {
47585
47890
  }
47586
47891
  }
@@ -47604,7 +47909,7 @@ async function postJson(pathname, body) {
47604
47909
  function resolveHostLabel(label) {
47605
47910
  const explicit = label?.trim();
47606
47911
  const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
47607
- const resolved = explicit || envLabel || os57.hostname();
47912
+ const resolved = explicit || envLabel || os59.hostname();
47608
47913
  return resolved.slice(0, 80);
47609
47914
  }
47610
47915
  async function redeemEnrollToken(token, label) {
@@ -47793,9 +48098,9 @@ async function host(args2) {
47793
48098
 
47794
48099
  // src/commands/host-agent.ts
47795
48100
  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"));
48101
+ var os63 = __toESM(require("os"));
48102
+ var fs79 = __toESM(require("fs"));
48103
+ var path93 = __toESM(require("path"));
47799
48104
 
47800
48105
  // src/skills/persist-from-payload.ts
47801
48106
  function persistOrClearSkillsFromPayload(skills) {
@@ -47804,13 +48109,13 @@ function persistOrClearSkillsFromPayload(skills) {
47804
48109
  }
47805
48110
 
47806
48111
  // src/commands/host/session-state.ts
47807
- var fs74 = __toESM(require("fs"));
47808
- var os58 = __toESM(require("os"));
47809
- var path88 = __toESM(require("path"));
48112
+ var fs76 = __toESM(require("fs"));
48113
+ var os60 = __toESM(require("os"));
48114
+ var path90 = __toESM(require("path"));
47810
48115
  function hostSessionStatePath(env = process.env) {
47811
48116
  const override = env.CODEAM_HOST_SESSION_STATE_FILE;
47812
48117
  if (override && override.trim()) return override.trim();
47813
- return path88.join(os58.homedir(), ".codeam", "host-agent-sessions.json");
48118
+ return path90.join(os60.homedir(), ".codeam", "host-agent-sessions.json");
47814
48119
  }
47815
48120
  function isRecord5(v) {
47816
48121
  if (typeof v !== "object" || v === null) return false;
@@ -47821,7 +48126,7 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
47821
48126
  return {
47822
48127
  load() {
47823
48128
  try {
47824
- const raw = JSON.parse(fs74.readFileSync(file, "utf8"));
48129
+ const raw = JSON.parse(fs76.readFileSync(file, "utf8"));
47825
48130
  return Array.isArray(raw?.sessions) ? raw.sessions.filter(isRecord5) : [];
47826
48131
  } catch {
47827
48132
  return [];
@@ -47829,18 +48134,18 @@ function fileSessionChildStore(file = hostSessionStatePath()) {
47829
48134
  },
47830
48135
  save(list) {
47831
48136
  try {
47832
- fs74.mkdirSync(path88.dirname(file), { recursive: true, mode: 448 });
48137
+ fs76.mkdirSync(path90.dirname(file), { recursive: true, mode: 448 });
47833
48138
  const tmp = `${file}.${process.pid}.tmp`;
47834
- fs74.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
48139
+ fs76.writeFileSync(tmp, JSON.stringify({ version: 1, sessions: list }, null, 2), {
47835
48140
  mode: 384
47836
48141
  });
47837
- fs74.renameSync(tmp, file);
48142
+ fs76.renameSync(tmp, file);
47838
48143
  } catch {
47839
48144
  }
47840
48145
  },
47841
48146
  clear() {
47842
48147
  try {
47843
- fs74.rmSync(file, { force: true });
48148
+ fs76.rmSync(file, { force: true });
47844
48149
  } catch {
47845
48150
  }
47846
48151
  }
@@ -47863,181 +48168,22 @@ function planSessionResume(records, max) {
47863
48168
  return { resume: ordered.slice(0, bound), dropped: ordered.slice(bound) };
47864
48169
  }
47865
48170
  function pickSavedSessionForWorkspace(sessions3, cwd) {
47866
- const target = path88.resolve(cwd);
48171
+ const target = path90.resolve(cwd);
47867
48172
  const matches = sessions3.filter(
47868
- (s) => !!s.cwd && path88.resolve(s.cwd) === target && !!s.pluginId && !!s.pollSecret && !!s.agent
48173
+ (s) => !!s.cwd && path90.resolve(s.cwd) === target && !!s.pluginId && !!s.pollSecret && !!s.agent
47869
48174
  );
47870
48175
  if (matches.length === 0) return null;
47871
48176
  matches.sort((a, b) => b.pairedAt - a.pairedAt);
47872
48177
  return matches[0];
47873
48178
  }
47874
48179
 
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
48180
  // src/commands/host/git-tooling.ts
48035
48181
  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"));
48182
+ var fs77 = __toESM(require("fs"));
48183
+ var os61 = __toESM(require("os"));
48184
+ var path91 = __toESM(require("path"));
48039
48185
  function codeamBinDir() {
48040
- return process.env.CODEAM_BIN_DIR ?? path90.join(os60.homedir(), ".codeam", "bin");
48186
+ return process.env.CODEAM_BIN_DIR ?? path91.join(os61.homedir(), ".codeam", "bin");
48041
48187
  }
48042
48188
  var FALLBACK_GH_VERSION = "2.62.0";
48043
48189
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -48069,7 +48215,7 @@ async function download(url2, dest) {
48069
48215
  const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
48070
48216
  if (!res.ok || !res.body) return false;
48071
48217
  const buf = Buffer.from(await res.arrayBuffer());
48072
- fs76.writeFileSync(dest, buf);
48218
+ fs77.writeFileSync(dest, buf);
48073
48219
  return true;
48074
48220
  } catch {
48075
48221
  return false;
@@ -48092,8 +48238,8 @@ async function ensureGhCli(runner, token, deps = {}) {
48092
48238
  const version3 = await resolveVersionFn(token);
48093
48239
  const asset = `gh_${version3}_${osToken}_${arch2}`;
48094
48240
  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}`);
48241
+ const tmpRoot = fs77.mkdtempSync(path91.join(os61.tmpdir(), "codeam-gh-"));
48242
+ const archive = path91.join(tmpRoot, `${asset}.${ext}`);
48097
48243
  if (!await downloadFn(url2, archive)) {
48098
48244
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
48099
48245
  return null;
@@ -48103,16 +48249,16 @@ async function ensureGhCli(runner, token, deps = {}) {
48103
48249
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
48104
48250
  return null;
48105
48251
  }
48106
- const extractedBin = path90.join(tmpRoot, asset, "bin", binaryName);
48107
- if (!fs76.existsSync(extractedBin)) {
48252
+ const extractedBin = path91.join(tmpRoot, asset, "bin", binaryName);
48253
+ if (!fs77.existsSync(extractedBin)) {
48108
48254
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
48109
48255
  return null;
48110
48256
  }
48111
48257
  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);
48258
+ fs77.mkdirSync(binDir, { recursive: true });
48259
+ const target = path91.join(binDir, binaryName);
48260
+ fs77.copyFileSync(extractedBin, target);
48261
+ fs77.chmodSync(target, 493);
48116
48262
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
48117
48263
  return target;
48118
48264
  } catch (e) {
@@ -48149,19 +48295,19 @@ async function ensureGhAuth(runner, ghCmd, token) {
48149
48295
  }
48150
48296
  function ghConfigDir() {
48151
48297
  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");
48298
+ if (process.env.XDG_CONFIG_HOME) return path91.join(process.env.XDG_CONFIG_HOME, "gh");
48153
48299
  if (process.platform === "win32" && process.env.APPDATA) {
48154
- return path90.join(process.env.APPDATA, "GitHub CLI");
48300
+ return path91.join(process.env.APPDATA, "GitHub CLI");
48155
48301
  }
48156
- return path90.join(os60.homedir(), ".config", "gh");
48302
+ return path91.join(os61.homedir(), ".config", "gh");
48157
48303
  }
48158
48304
  function writeGhHostsToken(token) {
48159
48305
  try {
48160
48306
  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(
48307
+ const file = path91.join(dir, "hosts.yml");
48308
+ if (fs77.existsSync(file)) return false;
48309
+ fs77.mkdirSync(dir, { recursive: true, mode: 448 });
48310
+ fs77.writeFileSync(
48165
48311
  file,
48166
48312
  `github.com:
48167
48313
  oauth_token: ${token}
@@ -48204,8 +48350,8 @@ async function ensureGlabCli(runner, deps = {}) {
48204
48350
  const version3 = await resolveLatestGlabVersion();
48205
48351
  const asset = `glab_${version3}_${osToken}_${arch2}`;
48206
48352
  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}`);
48353
+ const tmpRoot = fs77.mkdtempSync(path91.join(os61.tmpdir(), "codeam-glab-"));
48354
+ const archive = path91.join(tmpRoot, `${asset}.${ext}`);
48209
48355
  if (!await downloadFn(url2, archive)) {
48210
48356
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
48211
48357
  return null;
@@ -48216,20 +48362,20 @@ async function ensureGlabCli(runner, deps = {}) {
48216
48362
  return null;
48217
48363
  }
48218
48364
  const candidates = [
48219
- path90.join(tmpRoot, "bin", binaryName),
48220
- path90.join(tmpRoot, asset, "bin", binaryName),
48221
- path90.join(tmpRoot, binaryName)
48365
+ path91.join(tmpRoot, "bin", binaryName),
48366
+ path91.join(tmpRoot, asset, "bin", binaryName),
48367
+ path91.join(tmpRoot, binaryName)
48222
48368
  ];
48223
- const extractedBin = candidates.find((c2) => fs76.existsSync(c2));
48369
+ const extractedBin = candidates.find((c2) => fs77.existsSync(c2));
48224
48370
  if (!extractedBin) {
48225
48371
  log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
48226
48372
  return null;
48227
48373
  }
48228
48374
  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);
48375
+ fs77.mkdirSync(binDir, { recursive: true });
48376
+ const target = path91.join(binDir, binaryName);
48377
+ fs77.copyFileSync(extractedBin, target);
48378
+ fs77.chmodSync(target, 493);
48233
48379
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
48234
48380
  return target;
48235
48381
  } catch (e) {
@@ -48311,9 +48457,9 @@ var defaultGitToolingRunner = {
48311
48457
  var import_node_child_process28 = require("child_process");
48312
48458
 
48313
48459
  // src/lib/updateNotifier.ts
48314
- var fs77 = __toESM(require("fs"));
48315
- var os61 = __toESM(require("os"));
48316
- var path91 = __toESM(require("path"));
48460
+ var fs78 = __toESM(require("fs"));
48461
+ var os62 = __toESM(require("os"));
48462
+ var path92 = __toESM(require("path"));
48317
48463
  var https8 = __toESM(require("https"));
48318
48464
  var import_node_child_process27 = require("child_process");
48319
48465
  var import_picocolors12 = __toESM(require("picocolors"));
@@ -48322,12 +48468,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
48322
48468
  var TTL_MS = 24 * 60 * 60 * 1e3;
48323
48469
  var REQUEST_TIMEOUT_MS = 1500;
48324
48470
  function cachePath() {
48325
- const dir = path91.join(os61.homedir(), ".codeam");
48326
- return path91.join(dir, "update-check.json");
48471
+ const dir = path92.join(os62.homedir(), ".codeam");
48472
+ return path92.join(dir, "update-check.json");
48327
48473
  }
48328
48474
  function readCache() {
48329
48475
  try {
48330
- const raw = fs77.readFileSync(cachePath(), "utf8");
48476
+ const raw = fs78.readFileSync(cachePath(), "utf8");
48331
48477
  const parsed = JSON.parse(raw);
48332
48478
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
48333
48479
  return parsed;
@@ -48338,10 +48484,10 @@ function readCache() {
48338
48484
  function writeCache(cache) {
48339
48485
  try {
48340
48486
  const file = cachePath();
48341
- fs77.mkdirSync(path91.dirname(file), { recursive: true });
48487
+ fs78.mkdirSync(path92.dirname(file), { recursive: true });
48342
48488
  const tmp = `${file}.${process.pid}.tmp`;
48343
- fs77.writeFileSync(tmp, JSON.stringify(cache));
48344
- fs77.renameSync(tmp, file);
48489
+ fs78.writeFileSync(tmp, JSON.stringify(cache));
48490
+ fs78.renameSync(tmp, file);
48345
48491
  } catch {
48346
48492
  }
48347
48493
  }
@@ -48415,8 +48561,8 @@ function isLinkedInstall() {
48415
48561
  timeout: 2e3
48416
48562
  }).trim();
48417
48563
  if (!root) return false;
48418
- const pkgPath = path91.join(root, PKG_NAME);
48419
- return fs77.lstatSync(pkgPath).isSymbolicLink();
48564
+ const pkgPath = path92.join(root, PKG_NAME);
48565
+ return fs78.lstatSync(pkgPath).isSymbolicLink();
48420
48566
  } catch {
48421
48567
  return false;
48422
48568
  }
@@ -48452,7 +48598,7 @@ function maybeAutoUpdate(currentVersion, latest) {
48452
48598
  return;
48453
48599
  }
48454
48600
  try {
48455
- fs77.unlinkSync(cachePath());
48601
+ fs78.unlinkSync(cachePath());
48456
48602
  } catch {
48457
48603
  }
48458
48604
  process.stderr.write(` ${import_picocolors12.default.green("\u2713")} Updated. Resuming session...
@@ -48468,7 +48614,7 @@ async function autoUpgradeBeforeCriticalCommand() {
48468
48614
  if (process.env.NODE_ENV === "test") return;
48469
48615
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
48470
48616
  if (process.env.CI) return;
48471
- const current2 = true ? "2.75.26" : null;
48617
+ const current2 = true ? "2.75.28" : null;
48472
48618
  if (!current2) return;
48473
48619
  const cache = readCache();
48474
48620
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -48485,7 +48631,7 @@ function checkForUpdates() {
48485
48631
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
48486
48632
  if (process.env.CI) return;
48487
48633
  if (!process.stdout.isTTY) return;
48488
- const current2 = true ? "2.75.26" : null;
48634
+ const current2 = true ? "2.75.28" : null;
48489
48635
  if (!current2) return;
48490
48636
  const cache = readCache();
48491
48637
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -48508,7 +48654,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
48508
48654
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
48509
48655
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
48510
48656
  function currentCliVersion() {
48511
- return true ? "2.75.26" : null;
48657
+ return true ? "2.75.28" : null;
48512
48658
  }
48513
48659
  async function installedVersion(deps) {
48514
48660
  const ls = await deps.run(
@@ -48657,6 +48803,9 @@ function isDeployPayload(p2) {
48657
48803
  function isStopPayload(p2) {
48658
48804
  return typeof p2.sessionId === "string";
48659
48805
  }
48806
+ function isResumePayload(p2) {
48807
+ return typeof p2.sessionId === "string" && p2.sessionId.length > 0;
48808
+ }
48660
48809
  function isCleanupPayload(p2) {
48661
48810
  return typeof p2.deployId === "string" && p2.deployId.length > 0;
48662
48811
  }
@@ -48945,10 +49094,7 @@ var HostAgentSupervisor = class {
48945
49094
  this.heartbeatTimer = setInterval(() => void this.beat(), HEARTBEAT_INTERVAL_MS);
48946
49095
  this.heartbeatTimer.unref?.();
48947
49096
  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));
49097
+ this.reportLiveSet("boot");
48952
49098
  const updateMs = this.selfUpdateIntervalMs();
48953
49099
  if (updateMs > 0) {
48954
49100
  this.selfUpdateTimer = setInterval(() => void this.selfUpdateTick(), updateMs);
@@ -49194,6 +49340,14 @@ var HostAgentSupervisor = class {
49194
49340
  this.stopChild(cmd.payload.sessionId);
49195
49341
  return;
49196
49342
  }
49343
+ if (cmd.type === "self_hosted_resume") {
49344
+ if (!isResumePayload(cmd.payload)) {
49345
+ log.warn("host-agent", `ignoring malformed self_hosted_resume id=${cmd.id}`);
49346
+ return;
49347
+ }
49348
+ this.resumeSavedSession(cmd.payload.sessionId);
49349
+ return;
49350
+ }
49197
49351
  if (cmd.type === "self_hosted_cleanup") {
49198
49352
  if (!isCleanupPayload(cmd.payload)) {
49199
49353
  log.warn("host-agent", `ignoring malformed self_hosted_cleanup id=${cmd.id}`);
@@ -49241,13 +49395,13 @@ var HostAgentSupervisor = class {
49241
49395
  const relay = this.relay;
49242
49396
  if (!relay) return;
49243
49397
  const raw = cmd.payload?.path;
49244
- const target = typeof raw === "string" && raw.trim() ? path92.resolve(raw.trim()) : os62.homedir();
49398
+ const target = typeof raw === "string" && raw.trim() ? path93.resolve(raw.trim()) : os63.homedir();
49245
49399
  try {
49246
- const dirents = await fs78.promises.readdir(target, { withFileTypes: true });
49400
+ const dirents = await fs79.promises.readdir(target, { withFileTypes: true });
49247
49401
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
49248
49402
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
49249
49403
  );
49250
- const parent = path92.dirname(target);
49404
+ const parent = path93.dirname(target);
49251
49405
  await relay.sendResult(cmd.id, "completed", {
49252
49406
  path: target,
49253
49407
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -49594,14 +49748,14 @@ var HostAgentSupervisor = class {
49594
49748
  ...buildHouseProxyChildEnv({ baseUrl, token, openRouter: openRouter === true }),
49595
49749
  CODEAM_AUTO_TOKEN: payload.autoPairToken
49596
49750
  };
49597
- const houseConfigDir = path92.join(
49598
- os62.homedir(),
49751
+ const houseConfigDir = path93.join(
49752
+ os63.homedir(),
49599
49753
  ".codeam",
49600
49754
  "house-claude",
49601
49755
  payload.deployId
49602
49756
  );
49603
49757
  try {
49604
- fs78.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
49758
+ fs79.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
49605
49759
  } catch {
49606
49760
  }
49607
49761
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -49611,7 +49765,7 @@ var HostAgentSupervisor = class {
49611
49765
  token,
49612
49766
  openRouter: !!openRouter,
49613
49767
  claudeConfigDir: houseConfigDir
49614
- });
49768
+ }, payload.deployId);
49615
49769
  } else {
49616
49770
  const auth = await this.resolveAgentAuth(this.identity, payload.sealedAgentAuth);
49617
49771
  const credEnv = provisionAgentCredentials(payload.agentId, auth, void 0);
@@ -49619,7 +49773,7 @@ var HostAgentSupervisor = class {
49619
49773
  ...credEnv,
49620
49774
  CODEAM_AUTO_TOKEN: payload.autoPairToken
49621
49775
  };
49622
- clearHouseProxyConfig();
49776
+ clearHouseProxyConfig(payload.deployId);
49623
49777
  }
49624
49778
  childEnv = { ...childEnv, CODEAM_AUTO_APPROVE: "1" };
49625
49779
  childEnv = { ...childEnv, CODEAM_HOST_AGENT_CHILD: "1" };
@@ -49627,7 +49781,7 @@ var HostAgentSupervisor = class {
49627
49781
  report("installing", "installing agent CLI");
49628
49782
  await this.runAgentInstall(payload.agentInstallScript);
49629
49783
  }
49630
- const home = process.env.HOME || os62.homedir();
49784
+ const home = process.env.HOME || os63.homedir();
49631
49785
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
49632
49786
  if (payload.cloneToken) {
49633
49787
  try {
@@ -49635,13 +49789,13 @@ var HostAgentSupervisor = class {
49635
49789
  if ((payload.repoProvider ?? "github") === "gitlab") {
49636
49790
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
49637
49791
  if (glabCmd) {
49638
- childEnv.PATH = `${codeamBinDir()}${path92.delimiter}${childEnv.PATH}`;
49792
+ childEnv.PATH = `${codeamBinDir()}${path93.delimiter}${childEnv.PATH}`;
49639
49793
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
49640
49794
  }
49641
49795
  } else {
49642
49796
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
49643
49797
  if (ghCmd) {
49644
- childEnv.PATH = `${codeamBinDir()}${path92.delimiter}${childEnv.PATH}`;
49798
+ childEnv.PATH = `${codeamBinDir()}${path93.delimiter}${childEnv.PATH}`;
49645
49799
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
49646
49800
  }
49647
49801
  }
@@ -49669,9 +49823,9 @@ var HostAgentSupervisor = class {
49669
49823
  );
49670
49824
  if (!payload.suppressOnboardingWelcome) {
49671
49825
  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"));
49826
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path93.join(os63.homedir(), ".claude");
49827
+ const projectDir = path93.join(cfgDir, "projects", encodeCwd(cwd));
49828
+ const hasPriorConversation = fs79.existsSync(projectDir) && fs79.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
49675
49829
  if (hasPriorConversation) {
49676
49830
  childEnv.CODEAM_RESUME_LATEST = "1";
49677
49831
  log.info(
@@ -49799,7 +49953,7 @@ var HostAgentSupervisor = class {
49799
49953
  );
49800
49954
  continue;
49801
49955
  }
49802
- this.resumeOne({ deployId: rec.deployId, cwd: rec.cwd, session });
49956
+ this.resumeOne({ deployId: rec.deployId, cwd: rec.cwd, session, agent: rec.agent });
49803
49957
  resumed += 1;
49804
49958
  }
49805
49959
  log.info(
@@ -49822,7 +49976,7 @@ var HostAgentSupervisor = class {
49822
49976
  fallbackResumeTarget() {
49823
49977
  const session = getActiveSession();
49824
49978
  if (!session || !session.pluginId || !session.pollSecret || !session.agent) return null;
49825
- const cwd = session.cwd && fs78.existsSync(session.cwd) ? session.cwd : process.cwd();
49979
+ const cwd = session.cwd && fs79.existsSync(session.cwd) ? session.cwd : process.cwd();
49826
49980
  const deployId = deployIdFromWorkspace(session.cwd) ?? session.id;
49827
49981
  return { deployId, cwd, session };
49828
49982
  }
@@ -49836,23 +49990,94 @@ var HostAgentSupervisor = class {
49836
49990
  }
49837
49991
  return st3;
49838
49992
  }
49993
+ /**
49994
+ * `self_hosted_resume` — the user opened (or reconnected) a session this box
49995
+ * is not running. A boot resumes only the children that were LIVE when the
49996
+ * box went down, so any other saved session was a dead card: the app said
49997
+ * "waking up — your message is queued", the box woke, and the session never
49998
+ * came back (codeagent-o7lm, QA box 2026-09-25: 4 saved sessions, 2 resumed).
49999
+ *
50000
+ * Resumes it through the same `resumeOne` a boot uses (bounded retries,
50001
+ * house-proxy env, persisted into the live set), then re-reports the live
50002
+ * set so the backend restores the session's host link. No-op when the
50003
+ * session is unknown, lacks its pairing, or its workspace is gone — the app
50004
+ * then keeps its offline state instead of a phantom "waking".
50005
+ */
50006
+ resumeSavedSession(sessionId) {
50007
+ const session = this.listSavedSessions().find((s) => s.id === sessionId);
50008
+ if (!session || !session.pluginId || !session.pollSecret || !session.agent) {
50009
+ log.warn("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: no saved pairing on this box`);
50010
+ return;
50011
+ }
50012
+ if (!session.cwd || !fs79.existsSync(session.cwd)) {
50013
+ log.warn("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: workspace is gone`);
50014
+ return;
50015
+ }
50016
+ const deployId = deployIdFromWorkspace(session.cwd) ?? session.id;
50017
+ if (this.children.has(deployId)) {
50018
+ log.info("host-agent", `self_hosted_resume ${sessionId.slice(0, 8)}: already live`);
50019
+ return;
50020
+ }
50021
+ this.resumeOne({ deployId, cwd: session.cwd, session });
50022
+ this.reportLiveSet("resume");
50023
+ }
50024
+ /**
50025
+ * Tell the backend exactly which sessions this host runs. `activeSessions`
50026
+ * (additive) carries the PairedSession id of every child that knows it, so a
50027
+ * link lost to host-identity churn is rebuilt instead of the session
50028
+ * rendering as LOCAL with a reconnect the user cannot perform.
50029
+ */
50030
+ reportLiveSet(why) {
50031
+ const children = [...this.children.values()];
50032
+ void reportSessionEvent(
50033
+ { hostId: this.identity.hostId, hostToken: this.identity.hostToken },
50034
+ {
50035
+ event: "reconcile",
50036
+ activeDeployIds: children.map((c2) => c2.deployId),
50037
+ activeSessions: children.filter((c2) => typeof c2.sessionId === "string").map((c2) => ({ deployId: c2.deployId, sessionId: c2.sessionId, agent: c2.agent })),
50038
+ knownSessions: this.knownSavedSessions()
50039
+ }
50040
+ ).catch((err) => log.trace("host-agent", `${why} reconcile failed (best-effort)`, err));
50041
+ }
50042
+ /**
50043
+ * Every saved session this host could resume — a pairing whose deploy
50044
+ * workspace is still on disk — live or not. The backend links the non-live
50045
+ * ones too, so the app knows they belong to THIS box and wakes + resumes it
50046
+ * when the user opens one, instead of showing a LOCAL session with a
50047
+ * "run codeam in your terminal" the user cannot do (codeagent-bbou).
50048
+ */
50049
+ knownSavedSessions() {
50050
+ try {
50051
+ const persisted = new Map(this.sessionStore.load().map((r) => [r.deployId, r.agent]));
50052
+ for (const c2 of this.children.values()) persisted.set(c2.deployId, c2.agent);
50053
+ return this.listSavedSessions().map((s) => ({ s, deployId: deployIdFromWorkspace(s.cwd) })).filter(
50054
+ (x) => x.deployId !== null && !!x.s.cwd && fs79.existsSync(x.s.cwd)
50055
+ ).map(({ s, deployId }) => {
50056
+ const agent = persisted.get(deployId);
50057
+ return { deployId, sessionId: s.id, ...agent ? { agent } : {} };
50058
+ });
50059
+ } catch {
50060
+ return [];
50061
+ }
50062
+ }
49839
50063
  /** Spawn ONE resume child for `target` (boot, retry, or re-probe). */
49840
50064
  resumeOne(target) {
49841
50065
  const { session, deployId } = target;
49842
50066
  if (this.children.has(deployId)) return;
49843
50067
  const st3 = this.resumeStateFor(target);
49844
50068
  try {
49845
- const cwd = fs78.existsSync(target.cwd) ? target.cwd : process.cwd();
50069
+ const cwd = fs79.existsSync(target.cwd) ? target.cwd : process.cwd();
49846
50070
  const proc = this.resumeSpawner(
49847
- { ...readHouseProxyChildEnv(), CODEAM_RESUME_SESSION_ID: session.id },
50071
+ { ...readHouseProxyChildEnv(deployId), CODEAM_RESUME_SESSION_ID: session.id },
49848
50072
  cwd
49849
50073
  );
49850
50074
  const child = {
49851
50075
  deployId,
49852
50076
  proc,
49853
50077
  cwd,
49854
- agent: session.agent,
49855
- startedAt: Date.now()
50078
+ agent: target.agent ?? session.agent,
50079
+ startedAt: Date.now(),
50080
+ sessionId: session.id
49856
50081
  };
49857
50082
  this.trackChild(child);
49858
50083
  let tail = "";
@@ -49868,7 +50093,7 @@ var HostAgentSupervisor = class {
49868
50093
  return;
49869
50094
  }
49870
50095
  if (tracked && signal) {
49871
- this.onResumeChildExit(target, 128 + (os62.constants.signals[signal] ?? 9), `signal ${signal}`);
50096
+ this.onResumeChildExit(target, 128 + (os63.constants.signals[signal] ?? 9), `signal ${signal}`);
49872
50097
  return;
49873
50098
  }
49874
50099
  log.warn(
@@ -49911,7 +50136,7 @@ var HostAgentSupervisor = class {
49911
50136
  if (Date.now() - child.startedAt < CRASH_RESPAWN_MIN_UPTIME_MS) return false;
49912
50137
  const session = pickSavedSessionForWorkspace(this.listSavedSessions(), child.cwd);
49913
50138
  if (!session) return false;
49914
- const exitCode = typeof code === "number" ? code : 128 + (signal ? os62.constants.signals[signal] ?? 9 : 9);
50139
+ const exitCode = typeof code === "number" ? code : 128 + (signal ? os63.constants.signals[signal] ?? 9 : 9);
49915
50140
  log.warn(
49916
50141
  "host-agent",
49917
50142
  `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 +50285,12 @@ var HostAgentSupervisor = class {
50060
50285
  this.untrackChild(deployId);
50061
50286
  }
50062
50287
  const dirs = [
50063
- path92.join(selfHostedWorkspaceRoot(), deployId),
50064
- path92.join(os62.homedir(), ".codeam", "house-claude", deployId)
50288
+ path93.join(selfHostedWorkspaceRoot(), deployId),
50289
+ path93.join(os63.homedir(), ".codeam", "house-claude", deployId)
50065
50290
  ];
50066
50291
  for (const dir of dirs) {
50067
50292
  try {
50068
- fs78.rmSync(dir, { recursive: true, force: true });
50293
+ fs79.rmSync(dir, { recursive: true, force: true });
50069
50294
  } catch (err) {
50070
50295
  log.warn(
50071
50296
  "host-agent",
@@ -50225,8 +50450,8 @@ async function invite() {
50225
50450
  var import_node_dns = require("dns");
50226
50451
  var import_node_util6 = require("util");
50227
50452
  var import_node_crypto13 = require("crypto");
50228
- var fs79 = __toESM(require("fs"));
50229
- var path93 = __toESM(require("path"));
50453
+ var fs80 = __toESM(require("fs"));
50454
+ var path94 = __toESM(require("path"));
50230
50455
  var import_picocolors14 = __toESM(require("picocolors"));
50231
50456
  var dnsResolveP = (0, import_node_util6.promisify)(import_node_dns.resolve);
50232
50457
  async function checkDns(apiBase2) {
@@ -50282,13 +50507,13 @@ async function checkHealth(apiBase2) {
50282
50507
  }
50283
50508
  }
50284
50509
  function checkConfigDir() {
50285
- const dir = path93.join(require("os").homedir(), ".codeam");
50510
+ const dir = path94.join(require("os").homedir(), ".codeam");
50286
50511
  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);
50512
+ fs80.mkdirSync(dir, { recursive: true, mode: 448 });
50513
+ const probe = path94.join(dir, ".doctor-probe");
50514
+ fs80.writeFileSync(probe, "ok", { mode: 384 });
50515
+ const read = fs80.readFileSync(probe, "utf8");
50516
+ fs80.unlinkSync(probe);
50292
50517
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
50293
50518
  return {
50294
50519
  id: "config-dir",
@@ -50328,9 +50553,9 @@ function checkSessions() {
50328
50553
  }
50329
50554
  }
50330
50555
  function checkAgentBinaries() {
50331
- const os65 = createOsStrategy();
50556
+ const os66 = createOsStrategy();
50332
50557
  return getEnabledAgents().map((meta) => {
50333
- const found = os65.findInPath(meta.binaryName);
50558
+ const found = os66.findInPath(meta.binaryName);
50334
50559
  return {
50335
50560
  id: `agent-${meta.id}`,
50336
50561
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -50352,7 +50577,7 @@ function checkNodePty() {
50352
50577
  detail: "not required on this platform"
50353
50578
  };
50354
50579
  }
50355
- const vendoredPath = path93.join(__dirname, "vendor", "node-pty");
50580
+ const vendoredPath = path94.join(__dirname, "vendor", "node-pty");
50356
50581
  for (const target of [vendoredPath, "node-pty"]) {
50357
50582
  try {
50358
50583
  require(target);
@@ -50394,7 +50619,7 @@ function checkChokidar() {
50394
50619
  }
50395
50620
  async function doctor(args2 = []) {
50396
50621
  const json = args2.includes("--json");
50397
- const cliVersion = true ? "2.75.26" : "0.0.0-dev";
50622
+ const cliVersion = true ? "2.75.28" : "0.0.0-dev";
50398
50623
  const apiBase2 = resolveApiBaseUrl();
50399
50624
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
50400
50625
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -50918,7 +51143,7 @@ async function mcpWarm(argv = [], opts = {}) {
50918
51143
  // src/commands/version.ts
50919
51144
  var import_picocolors15 = __toESM(require("picocolors"));
50920
51145
  function version2() {
50921
- const v = true ? "2.75.26" : "unknown";
51146
+ const v = true ? "2.75.28" : "unknown";
50922
51147
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
50923
51148
  }
50924
51149
 
@@ -51067,10 +51292,10 @@ var EXIT_CODE_NAMES = {
51067
51292
  };
51068
51293
 
51069
51294
  // src/index.ts
51070
- var os64 = __toESM(require("os"));
51295
+ var os65 = __toESM(require("os"));
51071
51296
  if (!process.env.HOME) {
51072
51297
  try {
51073
- const home = os64.homedir();
51298
+ const home = os65.homedir();
51074
51299
  if (home) process.env.HOME = home;
51075
51300
  } catch {
51076
51301
  }
@@ -51116,6 +51341,9 @@ async function main() {
51116
51341
  await commands[command]();
51117
51342
  return;
51118
51343
  }
51344
+ if (command === "mcp-run" || command === "mcp-router" || command === "preview-mcp") {
51345
+ loadMcpSecrets();
51346
+ }
51119
51347
  if (command === "mcp-run") {
51120
51348
  return mcpRun(args);
51121
51349
  }