codeam-cli 2.65.15 → 2.65.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.js +341 -218
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -948,6 +948,8 @@ function isKnownAgentId(id) {
948
948
 
949
949
  // ../../packages/shared/src/agents/identity.ts
950
950
  var HOUSE_AGENT_ID = "house-codeagent-cloud";
951
+ var HOUSE_AGENT_NAME = "CodeAgent Cloud";
952
+ var HOUSE_AGENT_SUBTITLE = "Included \u2014 no setup";
951
953
  var PUBLIC_TO_INTERNAL = {
952
954
  claude_code: "claude",
953
955
  // CLI-side extra: self-hosted deploy payloads may carry the internal id.
@@ -3154,11 +3156,11 @@ function quiet(fn) {
3154
3156
  log.debug(TAG, "ignored sync error", err);
3155
3157
  }
3156
3158
  }
3157
- function rmIfExistsQuiet(path93) {
3159
+ function rmIfExistsQuiet(path94) {
3158
3160
  try {
3159
- fs2.rmSync(path93, { force: true });
3161
+ fs2.rmSync(path94, { force: true });
3160
3162
  } catch (err) {
3161
- log.debug(TAG, `rmIfExists failed for ${path93}`, err);
3163
+ log.debug(TAG, `rmIfExists failed for ${path94}`, err);
3162
3164
  }
3163
3165
  }
3164
3166
  function killQuiet(target, signal = "SIGTERM") {
@@ -3365,8 +3367,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
3365
3367
  return decodedFile;
3366
3368
  };
3367
3369
  }
3368
- function normalizeWindowsPath(path93) {
3369
- return path93.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3370
+ function normalizeWindowsPath(path94) {
3371
+ return path94.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3370
3372
  }
3371
3373
 
3372
3374
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -5846,9 +5848,9 @@ async function addSourceContext(frames) {
5846
5848
  LRU_FILE_CONTENTS_CACHE.reduce();
5847
5849
  return frames;
5848
5850
  }
5849
- function getContextLinesFromFile(path93, ranges, output) {
5851
+ function getContextLinesFromFile(path94, ranges, output) {
5850
5852
  return new Promise((resolve10) => {
5851
- const stream = (0, import_node_fs.createReadStream)(path93);
5853
+ const stream = (0, import_node_fs.createReadStream)(path94);
5852
5854
  const lineReaded = (0, import_node_readline.createInterface)({
5853
5855
  input: stream
5854
5856
  });
@@ -5863,7 +5865,7 @@ function getContextLinesFromFile(path93, ranges, output) {
5863
5865
  let rangeStart = range[0];
5864
5866
  let rangeEnd = range[1];
5865
5867
  function onStreamError() {
5866
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path93, 1);
5868
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path94, 1);
5867
5869
  lineReaded.close();
5868
5870
  lineReaded.removeAllListeners();
5869
5871
  destroyStreamAndResolve();
@@ -5924,8 +5926,8 @@ function clearLineContext(frame) {
5924
5926
  delete frame.context_line;
5925
5927
  delete frame.post_context;
5926
5928
  }
5927
- function shouldSkipContextLinesForFile(path93) {
5928
- return path93.startsWith("node:") || path93.endsWith(".min.js") || path93.endsWith(".min.cjs") || path93.endsWith(".min.mjs") || path93.startsWith("data:");
5929
+ function shouldSkipContextLinesForFile(path94) {
5930
+ return path94.startsWith("node:") || path94.endsWith(".min.js") || path94.endsWith(".min.cjs") || path94.endsWith(".min.mjs") || path94.startsWith("data:");
5929
5931
  }
5930
5932
  function shouldSkipContextLinesForFrame(frame) {
5931
5933
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -8079,7 +8081,7 @@ function readAnonId() {
8079
8081
  }
8080
8082
  function superProperties() {
8081
8083
  return {
8082
- cliVersion: true ? "2.65.15" : "0.0.0-dev",
8084
+ cliVersion: true ? "2.65.17" : "0.0.0-dev",
8083
8085
  nodeVersion: process.version,
8084
8086
  platform: process.platform,
8085
8087
  arch: process.arch,
@@ -8321,7 +8323,7 @@ var http = __toESM(require("http"));
8321
8323
  // package.json
8322
8324
  var package_default = {
8323
8325
  name: "codeam-cli",
8324
- version: "2.65.15",
8326
+ version: "2.65.17",
8325
8327
  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.",
8326
8328
  type: "commonjs",
8327
8329
  main: "dist/index.js",
@@ -8719,11 +8721,12 @@ async function fetchProvisionCredentialDetailed(input) {
8719
8721
  input.pluginAuthToken
8720
8722
  );
8721
8723
  const data = res?.data;
8722
- if (data && (data.method === "api_key" || data.method === "oauth") && typeof data.credential === "string" && data.credential.length > 0) {
8724
+ if (data && (data.method === "api_key" || data.method === "oauth" || data.method === "house_proxy") && typeof data.credential === "string" && data.credential.length > 0) {
8723
8725
  return {
8724
8726
  ok: true,
8725
8727
  method: data.method,
8726
8728
  credential: data.credential,
8729
+ ...typeof data.baseUrl === "string" && data.baseUrl.length > 0 ? { baseUrl: data.baseUrl } : {},
8727
8730
  ...typeof data.installScript === "string" && data.installScript.length > 0 ? { installScript: data.installScript } : {}
8728
8731
  };
8729
8732
  }
@@ -8737,7 +8740,7 @@ async function fetchProvisionCredentialDetailed(input) {
8737
8740
  }
8738
8741
  async function fetchProvisionCredential(input) {
8739
8742
  const res = await fetchProvisionCredentialDetailed(input);
8740
- if (!res.ok) return null;
8743
+ if (!res.ok || res.method === "house_proxy") return null;
8741
8744
  return {
8742
8745
  method: res.method,
8743
8746
  credential: res.credential,
@@ -9842,7 +9845,7 @@ var CommandRelayService = class _CommandRelayService {
9842
9845
  // fresh + clear the "CLI update available" banner after a self-update
9843
9846
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9844
9847
  // pair/reconnect). Older backends ignore the extra field.
9845
- ..."2.65.15" ? { ideVersion: "2.65.15" } : {}
9848
+ ..."2.65.17" ? { ideVersion: "2.65.17" } : {}
9846
9849
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9847
9850
  }
9848
9851
  /**
@@ -10102,10 +10105,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
10102
10105
  /[\\/]Start Menu([\\/]|$)/i,
10103
10106
  /[\\/]Templates([\\/]|$)/i
10104
10107
  ];
10105
- function isUnsafeWindowsWatchRoot(dir, homedir53) {
10108
+ function isUnsafeWindowsWatchRoot(dir, homedir54) {
10106
10109
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
10107
10110
  const cwd = norm(dir);
10108
- const home = norm(homedir53);
10111
+ const home = norm(homedir54);
10109
10112
  if (cwd === home) return true;
10110
10113
  if (/^[a-z]:$/.test(cwd)) return true;
10111
10114
  const sysRoots = [
@@ -14761,10 +14764,10 @@ function buildForPlatform(platform3) {
14761
14764
  var import_node_crypto4 = require("crypto");
14762
14765
 
14763
14766
  // src/agents/claude/resolver.ts
14764
- function buildClaudeLaunch(extraArgs = [], os67 = createOsStrategy()) {
14765
- const found = os67.findInPath("claude") ?? os67.findInPath("claude-code");
14767
+ function buildClaudeLaunch(extraArgs = [], os68 = createOsStrategy()) {
14768
+ const found = os68.findInPath("claude") ?? os68.findInPath("claude-code");
14766
14769
  if (!found) return null;
14767
- return os67.buildLaunch(found, extraArgs);
14770
+ return os68.buildLaunch(found, extraArgs);
14768
14771
  }
14769
14772
 
14770
14773
  // src/agents/claude/installer.ts
@@ -15524,8 +15527,8 @@ var ClaudeRuntimeStrategy = class {
15524
15527
  meta = getAgent("claude");
15525
15528
  mode = "interactive";
15526
15529
  os;
15527
- constructor(os67) {
15528
- this.os = os67;
15530
+ constructor(os68) {
15531
+ this.os = os68;
15529
15532
  }
15530
15533
  /**
15531
15534
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -16613,8 +16616,8 @@ function codexCredentialLocator() {
16613
16616
  function codexLoginLauncher() {
16614
16617
  return {
16615
16618
  async ensureInstalled() {
16616
- const os67 = createOsStrategy();
16617
- return os67.findInPath("codex") !== null;
16619
+ const os68 = createOsStrategy();
16620
+ return os68.findInPath("codex") !== null;
16618
16621
  },
16619
16622
  launch() {
16620
16623
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -16637,8 +16640,8 @@ var CodexRuntimeStrategy = class {
16637
16640
  meta = getAgent("codex");
16638
16641
  mode = "interactive";
16639
16642
  os;
16640
- constructor(os67) {
16641
- this.os = os67;
16643
+ constructor(os68) {
16644
+ this.os = os68;
16642
16645
  }
16643
16646
  async prepareLaunch() {
16644
16647
  let binary = this.os.findInPath("codex");
@@ -16747,12 +16750,12 @@ var CodexRuntimeStrategy = class {
16747
16750
  });
16748
16751
  }
16749
16752
  };
16750
- function resolveNpm(os67) {
16751
- return os67.id === "win32" ? "npm.cmd" : "npm";
16753
+ function resolveNpm(os68) {
16754
+ return os68.id === "win32" ? "npm.cmd" : "npm";
16752
16755
  }
16753
- async function installCodexViaNpm(os67) {
16756
+ async function installCodexViaNpm(os68) {
16754
16757
  return new Promise((resolve10, reject) => {
16755
- const proc = (0, import_node_child_process5.spawn)(resolveNpm(os67), ["install", "-g", "@openai/codex"], {
16758
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os68), ["install", "-g", "@openai/codex"], {
16756
16759
  stdio: "inherit"
16757
16760
  });
16758
16761
  proc.on("close", (code) => {
@@ -16769,16 +16772,16 @@ async function installCodexViaNpm(os67) {
16769
16772
  });
16770
16773
  });
16771
16774
  }
16772
- function augmentNpmGlobalBin(os67) {
16775
+ function augmentNpmGlobalBin(os68) {
16773
16776
  try {
16774
- const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os67), ["prefix", "-g"], {
16777
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os68), ["prefix", "-g"], {
16775
16778
  stdio: ["ignore", "pipe", "ignore"]
16776
16779
  });
16777
16780
  if (result.status !== 0) return;
16778
16781
  const prefix = result.stdout.toString().trim();
16779
16782
  if (!prefix) return;
16780
- const binDir = os67.id === "win32" ? prefix : path27.join(prefix, "bin");
16781
- os67.augmentPath([binDir]);
16783
+ const binDir = os68.id === "win32" ? prefix : path27.join(prefix, "bin");
16784
+ os68.augmentPath([binDir]);
16782
16785
  } catch {
16783
16786
  }
16784
16787
  }
@@ -16992,19 +16995,31 @@ function escalateCommand(argv) {
16992
16995
  const isRoot = process.getuid?.() === 0;
16993
16996
  return isRoot ? { cmd: argv[0], args: argv.slice(1) } : { cmd: "sudo", args: argv };
16994
16997
  }
16995
- async function ensurePip(runner) {
16998
+ async function ensurePythonInstaller(runner) {
16996
16999
  if (runner.which("pip") || runner.which("pip3")) {
16997
- return true;
17000
+ return { ok: true, installer: { kind: "pip" } };
17001
+ }
17002
+ if (runner.which("uv")) {
17003
+ log.info("host-agent", "pip absent but uv is available \u2014 installing without root");
17004
+ return { ok: true, installer: { kind: "uv", bin: "uv" } };
16998
17005
  }
16999
17006
  const pm = detectPackageManager(runner);
17000
17007
  if (!pm) {
17001
- log.warn(
17002
- "host-agent",
17003
- "pip is absent and no known package manager (apt-get/apk/dnf/yum/pacman/zypper) found \u2014 skipping Headroom"
17004
- );
17005
- return false;
17008
+ return {
17009
+ ok: false,
17010
+ reason: "Python pip is not installed and no supported package manager (apt-get/apk/dnf/yum/pacman/zypper) was found. Install pip \u2014 or uv \u2014 on this machine, then retry."
17011
+ };
17006
17012
  }
17007
17013
  const escalate = escalateCommand;
17014
+ if (process.getuid?.() !== 0) {
17015
+ const probe = await runner.run("sudo", ["-n", "true"], { timeoutMs: 1e4 });
17016
+ if (probe.code !== 0) {
17017
+ return {
17018
+ ok: false,
17019
+ reason: "Python pip is not installed here and this session cannot install it: it runs as a non-root user and sudo requires a password (there is no terminal to type it into). Install python3-pip \u2014 or uv \u2014 on the machine, then retry."
17020
+ };
17021
+ }
17022
+ }
17008
17023
  const recipe = PROVISION_RECIPES[pm];
17009
17024
  log.info(
17010
17025
  "host-agent",
@@ -17024,21 +17039,23 @@ async function ensurePip(runner) {
17024
17039
  const { cmd, args: args2 } = escalate(recipe.install);
17025
17040
  const installResult = await runner.run(cmd, args2, { timeoutMs: PM_INSTALL_TIMEOUT_MS });
17026
17041
  if (installResult.code !== 0) {
17042
+ const detail = installResult.stderr.trim().split("\n").slice(-1)[0] ?? "";
17027
17043
  log.warn(
17028
17044
  "host-agent",
17029
17045
  `${pm} bare-box provision failed (code=${String(installResult.code)}) \u2014 skipping Headroom`
17030
17046
  );
17031
- return false;
17047
+ return {
17048
+ ok: false,
17049
+ reason: `Installing python3-pip via ${pm} failed (exit ${String(installResult.code)})${detail ? `: ${detail}` : ""}.`
17050
+ };
17032
17051
  }
17033
17052
  } catch (e) {
17034
- log.warn(
17035
- "host-agent",
17036
- `bare-box provision threw unexpectedly: ${e instanceof Error ? e.message : String(e)} \u2014 skipping Headroom`
17037
- );
17038
- return false;
17053
+ const msg = e instanceof Error ? e.message : String(e);
17054
+ log.warn("host-agent", `bare-box provision threw unexpectedly: ${msg} \u2014 skipping Headroom`);
17055
+ return { ok: false, reason: `Installing python3-pip via ${pm} threw: ${msg}` };
17039
17056
  }
17040
17057
  log.info("host-agent", `bare box provisioned via ${pm} (python3+pip+ca-certificates+curl)`);
17041
- return true;
17058
+ return { ok: true, installer: { kind: "pip" } };
17042
17059
  }
17043
17060
  async function resolveHeadroomPython(runner) {
17044
17061
  const PROBE_TIMEOUT_MS = 5e3;
@@ -17189,10 +17206,10 @@ function manualInstallHint(runner, tools) {
17189
17206
  const argv = osPackageInstallArgv(detectPackageManager(runner), [...tools]);
17190
17207
  return argv ? `\`sudo ${argv.join(" ")}\`` : `your package manager (e.g. \`${pkgs}\`)`;
17191
17208
  }
17192
- function writeUnzipShim(os67, runner) {
17209
+ function writeUnzipShim(os68, runner) {
17193
17210
  const python = ["python3", "python"].find((p2) => runner.which(p2));
17194
17211
  if (!python) return null;
17195
- const dir = os67.scratchPath("codeam-cr-prereq");
17212
+ const dir = os68.scratchPath("codeam-cr-prereq");
17196
17213
  const shim = path29.join(dir, "unzip");
17197
17214
  const script = `#!/bin/sh
17198
17215
  set -e
@@ -17214,9 +17231,9 @@ exec ${python} -m zipfile -e "$archive" "$dest"
17214
17231
  (0, import_node_fs5.chmodSync)(shim, 448);
17215
17232
  return dir;
17216
17233
  }
17217
- async function ensureInstallPrerequisites(os67, deps = {}) {
17234
+ async function ensureInstallPrerequisites(os68, deps = {}) {
17218
17235
  const runner = deps.runner ?? defaultHeadroomRunner;
17219
- const missing = REQUIRED_TOOLS.filter((t2) => os67.findInPath(t2) === null);
17236
+ const missing = REQUIRED_TOOLS.filter((t2) => os68.findInPath(t2) === null);
17220
17237
  if (missing.length === 0) return { ok: true, extraPath: [] };
17221
17238
  log.info(
17222
17239
  "coderabbit",
@@ -17235,10 +17252,10 @@ async function ensureInstallPrerequisites(os67, deps = {}) {
17235
17252
  );
17236
17253
  }
17237
17254
  }
17238
- const stillMissing = REQUIRED_TOOLS.filter((t2) => os67.findInPath(t2) === null);
17255
+ const stillMissing = REQUIRED_TOOLS.filter((t2) => os68.findInPath(t2) === null);
17239
17256
  if (stillMissing.length === 0) return { ok: true, extraPath: [] };
17240
17257
  if (stillMissing.length === 1 && stillMissing[0] === "unzip") {
17241
- const shimDir = writeUnzipShim(os67, runner);
17258
+ const shimDir = writeUnzipShim(os68, runner);
17242
17259
  if (shimDir) {
17243
17260
  log.info("coderabbit", "unzip is unavailable \u2014 using a scoped python zipfile shim");
17244
17261
  return { ok: true, extraPath: [shimDir] };
@@ -17301,15 +17318,15 @@ function summarizeInstallFailure(output) {
17301
17318
  }
17302
17319
  return lines.length > 0 ? lines[lines.length - 1] : null;
17303
17320
  }
17304
- async function ensureCoderabbitInstalled(os67, deps = {}) {
17305
- if (os67.findInPath("coderabbit")) return { ok: true };
17306
- if (os67.id === "win32") {
17321
+ async function ensureCoderabbitInstalled(os68, deps = {}) {
17322
+ if (os68.findInPath("coderabbit")) return { ok: true };
17323
+ if (os68.id === "win32") {
17307
17324
  return {
17308
17325
  ok: false,
17309
17326
  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."
17310
17327
  };
17311
17328
  }
17312
- const prereq = await ensureInstallPrerequisites(os67, deps);
17329
+ const prereq = await ensureInstallPrerequisites(os68, deps);
17313
17330
  if (!prereq.ok) return { ok: false, error: prereq.error };
17314
17331
  const env = { ...process.env };
17315
17332
  if (prereq.extraPath.length > 0) {
@@ -17318,8 +17335,8 @@ async function ensureCoderabbitInstalled(os67, deps = {}) {
17318
17335
  log.info("coderabbit", "CodeRabbit CLI not found \u2014 installing via the official script");
17319
17336
  const run = deps.runInstallScript ?? defaultRunInstallScript;
17320
17337
  const { code, output } = await run(env);
17321
- os67.augmentPath([`${os67.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
17322
- const binary = os67.findInPath("coderabbit");
17338
+ os68.augmentPath([`${os68.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
17339
+ const binary = os68.findInPath("coderabbit");
17323
17340
  const detail = summarizeInstallFailure(output);
17324
17341
  if (binary !== null) {
17325
17342
  if (code === 0) return { ok: true };
@@ -17373,10 +17390,10 @@ function coderabbitCredentialLocator() {
17373
17390
  validate: validateNonEmptyCredential
17374
17391
  };
17375
17392
  }
17376
- function coderabbitLoginLauncher(os67) {
17393
+ function coderabbitLoginLauncher(os68) {
17377
17394
  return {
17378
17395
  async ensureInstalled() {
17379
- const result = await ensureCoderabbitInstalled(os67);
17396
+ const result = await ensureCoderabbitInstalled(os68);
17380
17397
  if (!result.ok && result.error) console.error(`
17381
17398
  \u2717 ${result.error}
17382
17399
  `);
@@ -17436,8 +17453,8 @@ function pickLine(obj) {
17436
17453
  function toHunk(raw, groupSeverity) {
17437
17454
  if (!raw || typeof raw !== "object") return null;
17438
17455
  const o = raw;
17439
- const path93 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
17440
- if (!path93) return null;
17456
+ const path94 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
17457
+ if (!path94) return null;
17441
17458
  const message = asString(
17442
17459
  pick(o, [
17443
17460
  "comment",
@@ -17454,7 +17471,7 @@ function toHunk(raw, groupSeverity) {
17454
17471
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
17455
17472
  const locObj = pick(o, ["location"]) ?? o;
17456
17473
  return {
17457
- path: path93.trim(),
17474
+ path: path94.trim(),
17458
17475
  line: pickLine(o) ?? pickLine(locObj),
17459
17476
  severity,
17460
17477
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -17537,10 +17554,10 @@ function parsePlain(stdout) {
17537
17554
  for (const line of stdout.split(/\r?\n/)) {
17538
17555
  const m = line.match(HUNK_LINE_RE);
17539
17556
  if (!m) continue;
17540
- const [, path93, lineNo, sevToken, message] = m;
17541
- if (!path93 || !lineNo || !message) continue;
17557
+ const [, path94, lineNo, sevToken, message] = m;
17558
+ if (!path94 || !lineNo || !message) continue;
17542
17559
  hunks.push({
17543
- path: path93.trim(),
17560
+ path: path94.trim(),
17544
17561
  line: Number(lineNo),
17545
17562
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
17546
17563
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -17600,8 +17617,8 @@ var CoderabbitRuntimeStrategy = class {
17600
17617
  meta = getAgent("coderabbit");
17601
17618
  mode = "batch";
17602
17619
  os;
17603
- constructor(os67) {
17604
- this.os = os67;
17620
+ constructor(os68) {
17621
+ this.os = os68;
17605
17622
  }
17606
17623
  getDefaultArgs() {
17607
17624
  return ["review", "--agent"];
@@ -17872,10 +17889,10 @@ function cursorCredentialLocator() {
17872
17889
  validate: validateNonEmptyCredential
17873
17890
  };
17874
17891
  }
17875
- function cursorLoginLauncher(os67) {
17892
+ function cursorLoginLauncher(os68) {
17876
17893
  return {
17877
17894
  async ensureInstalled() {
17878
- if (os67.findInPath("cursor-agent")) return true;
17895
+ if (os68.findInPath("cursor-agent")) return true;
17879
17896
  console.error(
17880
17897
  "\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"
17881
17898
  );
@@ -17939,8 +17956,8 @@ var CursorRuntimeStrategy = class {
17939
17956
  meta = getAgent("cursor");
17940
17957
  mode = "interactive";
17941
17958
  os;
17942
- constructor(os67) {
17943
- this.os = os67;
17959
+ constructor(os68) {
17960
+ this.os = os68;
17944
17961
  }
17945
17962
  async prepareLaunch() {
17946
17963
  const binary = this.os.findInPath("cursor-agent");
@@ -18156,10 +18173,10 @@ function aiderCredentialLocator() {
18156
18173
  validate: validateNonEmptyCredential
18157
18174
  };
18158
18175
  }
18159
- function aiderLoginLauncher(os67) {
18176
+ function aiderLoginLauncher(os68) {
18160
18177
  return {
18161
18178
  async ensureInstalled() {
18162
- if (os67.findInPath("aider")) return true;
18179
+ if (os68.findInPath("aider")) return true;
18163
18180
  console.error(
18164
18181
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
18165
18182
  );
@@ -18169,7 +18186,7 @@ function aiderLoginLauncher(os67) {
18169
18186
  console.error(
18170
18187
  "\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"
18171
18188
  );
18172
- return (0, import_node_child_process12.spawn)(os67.id === "win32" ? "cmd.exe" : "sh", os67.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
18189
+ return (0, import_node_child_process12.spawn)(os68.id === "win32" ? "cmd.exe" : "sh", os68.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
18173
18190
  stdio: "ignore"
18174
18191
  });
18175
18192
  }
@@ -18444,8 +18461,8 @@ var AiderRuntimeStrategy = class {
18444
18461
  meta = getAgent("aider");
18445
18462
  mode = "interactive";
18446
18463
  os;
18447
- constructor(os67) {
18448
- this.os = os67;
18464
+ constructor(os68) {
18465
+ this.os = os68;
18449
18466
  }
18450
18467
  async prepareLaunch() {
18451
18468
  augmentUserLocalBinPaths();
@@ -18578,8 +18595,8 @@ function geminiCredentialLocator() {
18578
18595
  function geminiLoginLauncher() {
18579
18596
  return {
18580
18597
  async ensureInstalled() {
18581
- const os67 = createOsStrategy();
18582
- return os67.findInPath("gemini") !== null;
18598
+ const os68 = createOsStrategy();
18599
+ return os68.findInPath("gemini") !== null;
18583
18600
  },
18584
18601
  launch() {
18585
18602
  return (0, import_node_child_process13.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -18769,8 +18786,8 @@ var GeminiRuntimeStrategy = class {
18769
18786
  meta = getAgent("gemini");
18770
18787
  mode = "interactive";
18771
18788
  os;
18772
- constructor(os67) {
18773
- this.os = os67;
18789
+ constructor(os68) {
18790
+ this.os = os68;
18774
18791
  }
18775
18792
  async prepareLaunch() {
18776
18793
  const binary = this.os.findInPath("gemini");
@@ -19061,8 +19078,8 @@ var KimiRuntimeStrategy = class {
19061
19078
  meta = getAgent("kimi");
19062
19079
  mode = "interactive";
19063
19080
  os;
19064
- constructor(os67) {
19065
- this.os = os67;
19081
+ constructor(os68) {
19082
+ this.os = os68;
19066
19083
  }
19067
19084
  async prepareLaunch() {
19068
19085
  const binary = this.os.findInPath("kimi");
@@ -19204,8 +19221,8 @@ var OpencodeRuntimeStrategy = class {
19204
19221
  meta = getAgent("opencode");
19205
19222
  mode = "interactive";
19206
19223
  os;
19207
- constructor(os67) {
19208
- this.os = os67;
19224
+ constructor(os68) {
19225
+ this.os = os68;
19209
19226
  }
19210
19227
  async prepareLaunch() {
19211
19228
  const binary = this.os.findInPath("opencode");
@@ -19289,20 +19306,20 @@ var OpencodeRuntimeStrategy = class {
19289
19306
 
19290
19307
  // src/agents/registry.ts
19291
19308
  var runtimeBuilders = {
19292
- claude: (os67) => new ClaudeRuntimeStrategy(os67),
19293
- codex: (os67) => new CodexRuntimeStrategy(os67),
19294
- coderabbit: (os67) => new CoderabbitRuntimeStrategy(os67),
19295
- cursor: (os67) => new CursorRuntimeStrategy(os67),
19296
- aider: (os67) => new AiderRuntimeStrategy(os67),
19297
- gemini: (os67) => new GeminiRuntimeStrategy(os67),
19298
- kimi: (os67) => new KimiRuntimeStrategy(os67),
19299
- opencode: (os67) => new OpencodeRuntimeStrategy(os67)
19309
+ claude: (os68) => new ClaudeRuntimeStrategy(os68),
19310
+ codex: (os68) => new CodexRuntimeStrategy(os68),
19311
+ coderabbit: (os68) => new CoderabbitRuntimeStrategy(os68),
19312
+ cursor: (os68) => new CursorRuntimeStrategy(os68),
19313
+ aider: (os68) => new AiderRuntimeStrategy(os68),
19314
+ gemini: (os68) => new GeminiRuntimeStrategy(os68),
19315
+ kimi: (os68) => new KimiRuntimeStrategy(os68),
19316
+ opencode: (os68) => new OpencodeRuntimeStrategy(os68)
19300
19317
  };
19301
19318
  var deployBuilders = {
19302
19319
  claude: () => new ClaudeDeployStrategy(),
19303
19320
  codex: () => new CodexDeployStrategy()
19304
19321
  };
19305
- function createAgentStrategy(agent, os67 = createOsStrategy()) {
19322
+ function createAgentStrategy(agent, os68 = createOsStrategy()) {
19306
19323
  if (!AGENT_REGISTRY[agent]?.enabled) {
19307
19324
  throw new Error(
19308
19325
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -19312,10 +19329,10 @@ function createAgentStrategy(agent, os67 = createOsStrategy()) {
19312
19329
  if (!build) {
19313
19330
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
19314
19331
  }
19315
- return build(os67);
19332
+ return build(os68);
19316
19333
  }
19317
- function createInteractiveAgentStrategy(agent, os67 = createOsStrategy()) {
19318
- const s = createAgentStrategy(agent, os67);
19334
+ function createInteractiveAgentStrategy(agent, os68 = createOsStrategy()) {
19335
+ const s = createAgentStrategy(agent, os68);
19319
19336
  if (s.mode !== "interactive") {
19320
19337
  throw new Error(
19321
19338
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -19993,8 +20010,8 @@ function collectChangedFiles(cwd) {
19993
20010
  }
19994
20011
  return [...byPath.values()];
19995
20012
  }
19996
- function restoreCoderabbitOauthBlob(os67, value) {
19997
- const dir = path41.join(os67.homeDir(), ".coderabbit");
20013
+ function restoreCoderabbitOauthBlob(os68, value) {
20014
+ const dir = path41.join(os68.homeDir(), ".coderabbit");
19998
20015
  (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
19999
20016
  let file = "auth.json";
20000
20017
  let contents = value.trim();
@@ -20014,26 +20031,26 @@ function installFailureMessage(result) {
20014
20031
  return result.error ?? "CodeRabbit CLI could not be installed";
20015
20032
  }
20016
20033
  async function configureCoderabbit(input, deps = {}) {
20017
- const os67 = deps.os ?? createOsStrategy();
20034
+ const os68 = deps.os ?? createOsStrategy();
20018
20035
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
20019
20036
  const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
20020
20037
  const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
20021
20038
  const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
20022
20039
  const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
20023
20040
  const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
20024
- const home = os67.homeDir();
20025
- os67.augmentPath(
20026
- os67.id === "win32" ? [
20041
+ const home = os68.homeDir();
20042
+ os68.augmentPath(
20043
+ os68.id === "win32" ? [
20027
20044
  path41.join(home, ".local", "bin"),
20028
20045
  path41.join(process.env.APPDATA ?? path41.join(home, "AppData", "Roaming"), "npm"),
20029
20046
  path41.join(home, "scoop", "shims")
20030
20047
  ] : [path41.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
20031
20048
  );
20032
- const installed2 = os67.findInPath("coderabbit") !== null;
20049
+ const installed2 = os68.findInPath("coderabbit") !== null;
20033
20050
  const base = () => ({
20034
20051
  action: input.action,
20035
20052
  supported: true,
20036
- installed: os67.findInPath("coderabbit") !== null,
20053
+ installed: os68.findInPath("coderabbit") !== null,
20037
20054
  loggedIn: false
20038
20055
  });
20039
20056
  if (input.action === "status") {
@@ -20047,7 +20064,7 @@ async function configureCoderabbit(input, deps = {}) {
20047
20064
  const key = (input.apiKey ?? "").trim();
20048
20065
  if (!key) return { ...res2, error: "No API key provided" };
20049
20066
  if (!res2.installed) {
20050
- const inst = await ensureInstalled(os67);
20067
+ const inst = await ensureInstalled(os68);
20051
20068
  res2.installed = inst.ok;
20052
20069
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
20053
20070
  }
@@ -20071,7 +20088,7 @@ async function configureCoderabbit(input, deps = {}) {
20071
20088
  }
20072
20089
  if (!res2.installed) {
20073
20090
  deps.onEvent?.({ kind: "installing" });
20074
- const inst = await ensureInstalled(os67);
20091
+ const inst = await ensureInstalled(os68);
20075
20092
  res2.installed = inst.ok;
20076
20093
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
20077
20094
  }
@@ -20088,7 +20105,7 @@ async function configureCoderabbit(input, deps = {}) {
20088
20105
  return { ...res2, loggedIn: true, linked: true };
20089
20106
  }
20090
20107
  try {
20091
- restoreCoderabbitOauthBlob(os67, cred.credential);
20108
+ restoreCoderabbitOauthBlob(os68, cred.credential);
20092
20109
  } catch (err) {
20093
20110
  return {
20094
20111
  ...res2,
@@ -20112,7 +20129,7 @@ async function configureCoderabbit(input, deps = {}) {
20112
20129
  const res2 = base();
20113
20130
  if (!installed2) {
20114
20131
  deps.onEvent?.({ kind: "installing" });
20115
- const inst = await ensureInstalled(os67);
20132
+ const inst = await ensureInstalled(os68);
20116
20133
  res2.installed = inst.ok;
20117
20134
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
20118
20135
  }
@@ -20152,7 +20169,7 @@ async function configureCoderabbit(input, deps = {}) {
20152
20169
  }
20153
20170
  const res = base();
20154
20171
  if (!res.installed) {
20155
- const inst = await ensureInstalled(os67);
20172
+ const inst = await ensureInstalled(os68);
20156
20173
  res.installed = inst.ok;
20157
20174
  if (!inst.ok) return { ...res, error: installFailureMessage(inst) };
20158
20175
  }
@@ -21690,10 +21707,12 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
21690
21707
  const onProgress = opts.onProgress ?? (() => {
21691
21708
  });
21692
21709
  const SERVER_DEPS = HEADROOM_PIP_COMPANIONS;
21693
- const pipAvailable = await ensurePip(runner);
21694
- if (!pipAvailable) {
21710
+ const installerResult = await ensurePythonInstaller(runner);
21711
+ if (!installerResult.ok) {
21712
+ log.warn("host-agent", `Headroom: ${installerResult.reason}`);
21695
21713
  return false;
21696
21714
  }
21715
+ const installer = installerResult.installer;
21697
21716
  const py = await ensureModernPython(runner);
21698
21717
  if (py === null) {
21699
21718
  log.warn(
@@ -21704,6 +21723,14 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
21704
21723
  }
21705
21724
  log.info("host-agent", `Headroom will use interpreter: ${py}`);
21706
21725
  const pipInstall = async (pkgs, extraArgs, timeoutMs) => {
21726
+ if (installer.kind === "uv") {
21727
+ const r2 = await runner.run(
21728
+ installer.bin,
21729
+ ["pip", "install", "--quiet", "--python", py, "--break-system-packages", ...extraArgs, ...pkgs],
21730
+ { timeoutMs }
21731
+ );
21732
+ return r2.code === 0;
21733
+ }
21707
21734
  const base = ["-m", "pip", "install", "--quiet", ...extraArgs, ...pkgs];
21708
21735
  const r = await runner.run(py, base, { timeoutMs });
21709
21736
  if (r.code === 0) return true;
@@ -21823,28 +21850,64 @@ function readHouseProxyChildEnv() {
21823
21850
  const o = parsed;
21824
21851
  if (typeof o.baseUrl !== "string" || !o.baseUrl) return {};
21825
21852
  if (typeof o.token !== "string" || !o.token) return {};
21826
- const env = {
21827
- ANTHROPIC_BASE_URL: o.baseUrl,
21828
- ANTHROPIC_AUTH_TOKEN: o.token,
21829
- CLAUDE_CODE_AUTO_COMPACT_WINDOW: "512000",
21830
- API_TIMEOUT_MS: "3000000"
21831
- };
21832
- if (o.openRouter === true) {
21833
- env.ANTHROPIC_API_KEY = "";
21834
- } else {
21835
- env.ANTHROPIC_MODEL = "MiniMax-M3";
21836
- env.ANTHROPIC_DEFAULT_SONNET_MODEL = "MiniMax-M3";
21837
- env.ANTHROPIC_DEFAULT_OPUS_MODEL = "MiniMax-M3";
21838
- env.ANTHROPIC_DEFAULT_HAIKU_MODEL = "MiniMax-M3";
21839
- }
21840
- if (typeof o.claudeConfigDir === "string" && o.claudeConfigDir) {
21841
- env.CLAUDE_CONFIG_DIR = o.claudeConfigDir;
21842
- }
21843
- return env;
21853
+ return buildHouseProxyChildEnv({
21854
+ baseUrl: o.baseUrl,
21855
+ token: o.token,
21856
+ openRouter: o.openRouter === true,
21857
+ ...typeof o.claudeConfigDir === "string" && o.claudeConfigDir ? { claudeConfigDir: o.claudeConfigDir } : {}
21858
+ });
21844
21859
  } catch {
21845
21860
  return {};
21846
21861
  }
21847
21862
  }
21863
+ function buildHouseProxyChildEnv(cfg) {
21864
+ const env = {
21865
+ ANTHROPIC_BASE_URL: cfg.baseUrl,
21866
+ ANTHROPIC_AUTH_TOKEN: cfg.token,
21867
+ CLAUDE_CODE_AUTO_COMPACT_WINDOW: "512000",
21868
+ API_TIMEOUT_MS: "3000000"
21869
+ };
21870
+ if (cfg.openRouter === true) {
21871
+ env.ANTHROPIC_API_KEY = "";
21872
+ } else {
21873
+ env.ANTHROPIC_MODEL = "MiniMax-M3";
21874
+ env.ANTHROPIC_DEFAULT_SONNET_MODEL = "MiniMax-M3";
21875
+ env.ANTHROPIC_DEFAULT_OPUS_MODEL = "MiniMax-M3";
21876
+ env.ANTHROPIC_DEFAULT_HAIKU_MODEL = "MiniMax-M3";
21877
+ }
21878
+ if (typeof cfg.claudeConfigDir === "string" && cfg.claudeConfigDir) {
21879
+ env.CLAUDE_CONFIG_DIR = cfg.claudeConfigDir;
21880
+ }
21881
+ return env;
21882
+ }
21883
+ var HOUSE_PROXY_ENV_KEYS = [
21884
+ "ANTHROPIC_BASE_URL",
21885
+ "ANTHROPIC_AUTH_TOKEN",
21886
+ "ANTHROPIC_API_KEY",
21887
+ "ANTHROPIC_MODEL",
21888
+ "ANTHROPIC_DEFAULT_SONNET_MODEL",
21889
+ "ANTHROPIC_DEFAULT_OPUS_MODEL",
21890
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL",
21891
+ "CLAUDE_CODE_AUTO_COMPACT_WINDOW",
21892
+ "API_TIMEOUT_MS",
21893
+ "CLAUDE_CONFIG_DIR"
21894
+ ];
21895
+ function clearHouseProxyEnvOverrides() {
21896
+ const out2 = {};
21897
+ for (const key of HOUSE_PROXY_ENV_KEYS) out2[key] = void 0;
21898
+ return out2;
21899
+ }
21900
+ function isHouseProxyEnv(env) {
21901
+ return typeof env.ANTHROPIC_AUTH_TOKEN === "string" && env.ANTHROPIC_AUTH_TOKEN.length > 0 && (env.ANTHROPIC_BASE_URL ?? "").includes("/api/v1/agent-proxy");
21902
+ }
21903
+ function pickHouseProxyEnv(env) {
21904
+ const out2 = {};
21905
+ for (const key of HOUSE_PROXY_ENV_KEYS) {
21906
+ const v = env[key];
21907
+ if (typeof v === "string") out2[key] = v;
21908
+ }
21909
+ return out2;
21910
+ }
21848
21911
 
21849
21912
  // src/commands/host/self-update.ts
21850
21913
  var import_node_child_process23 = require("child_process");
@@ -22007,7 +22070,7 @@ async function autoUpgradeBeforeCriticalCommand() {
22007
22070
  if (process.env.NODE_ENV === "test") return;
22008
22071
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22009
22072
  if (process.env.CI) return;
22010
- const current2 = true ? "2.65.15" : null;
22073
+ const current2 = true ? "2.65.17" : null;
22011
22074
  if (!current2) return;
22012
22075
  const cache = readCache();
22013
22076
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22024,7 +22087,7 @@ function checkForUpdates() {
22024
22087
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22025
22088
  if (process.env.CI) return;
22026
22089
  if (!process.stdout.isTTY) return;
22027
- const current2 = true ? "2.65.15" : null;
22090
+ const current2 = true ? "2.65.17" : null;
22028
22091
  if (!current2) return;
22029
22092
  const cache = readCache();
22030
22093
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22044,7 +22107,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
22044
22107
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
22045
22108
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
22046
22109
  function currentCliVersion() {
22047
- return true ? "2.65.15" : null;
22110
+ return true ? "2.65.17" : null;
22048
22111
  }
22049
22112
  function runCmd(cmd, args2, timeoutMs) {
22050
22113
  return new Promise((resolve10) => {
@@ -23820,7 +23883,7 @@ async function defaultFetchJson(url2) {
23820
23883
  async function readUsageReport(deps = {}) {
23821
23884
  const port = deps.port ?? HEADROOM_PROXY_PORT;
23822
23885
  const base = `http://127.0.0.1:${port}`;
23823
- const get2 = deps.fetchJson ?? ((path93) => defaultFetchJson(`${base}${path93}`));
23886
+ const get2 = deps.fetchJson ?? ((path94) => defaultFetchJson(`${base}${path94}`));
23824
23887
  let history;
23825
23888
  try {
23826
23889
  history = await get2("/stats-history");
@@ -25737,11 +25800,11 @@ function resolveDoltInstallStrategy(platform3) {
25737
25800
  }
25738
25801
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
25739
25802
  function doltPlatformTuple(platform3, arch2) {
25740
- const os67 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25803
+ const os68 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25741
25804
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
25742
25805
  if (!a) return null;
25743
- if (os67 === "windows" && a !== "amd64") return null;
25744
- return `${os67}-${a}`;
25806
+ if (os68 === "windows" && a !== "amd64") return null;
25807
+ return `${os68}-${a}`;
25745
25808
  }
25746
25809
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
25747
25810
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -27393,7 +27456,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
27393
27456
  });
27394
27457
  const token = ctx.pluginAuthToken;
27395
27458
  void (async () => {
27396
- const os67 = createOsStrategy();
27459
+ const os68 = createOsStrategy();
27397
27460
  try {
27398
27461
  const report = await reviewPullRequest(
27399
27462
  {
@@ -27402,7 +27465,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
27402
27465
  baseBranch: parsed.baseBranch
27403
27466
  },
27404
27467
  {
27405
- runReview: (input) => new CoderabbitRuntimeStrategy(os67).runOneShot(input),
27468
+ runReview: (input) => new CoderabbitRuntimeStrategy(os68).runOneShot(input),
27406
27469
  runGh: (args2) => defaultRunGh(args2),
27407
27470
  postReport: async (r) => {
27408
27471
  if (!token) return;
@@ -28505,11 +28568,11 @@ function resolveTokenValue(args2) {
28505
28568
  }
28506
28569
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
28507
28570
  if (fileFlag) {
28508
- const path93 = fileFlag.slice("--token-file=".length);
28571
+ const path94 = fileFlag.slice("--token-file=".length);
28509
28572
  try {
28510
- const content = fs65.readFileSync(path93, "utf8").trim();
28511
- if (content.length === 0) fail(`--token-file ${path93} is empty`);
28512
- rmIfExistsQuiet(path93);
28573
+ const content = fs65.readFileSync(path94, "utf8").trim();
28574
+ if (content.length === 0) fail(`--token-file ${path94} is empty`);
28575
+ rmIfExistsQuiet(path94);
28513
28576
  return content;
28514
28577
  } catch (err) {
28515
28578
  fail(`Could not read --token-file: ${err.message}`);
@@ -29429,6 +29492,9 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
29429
29492
 
29430
29493
  // src/agents/acp/runner.ts
29431
29494
  var import_node_crypto11 = require("crypto");
29495
+ var fs77 = __toESM(require("fs"));
29496
+ var os62 = __toESM(require("os"));
29497
+ var path85 = __toESM(require("path"));
29432
29498
 
29433
29499
  // src/services/history.service.ts
29434
29500
  var fs66 = __toESM(require("fs"));
@@ -35274,16 +35340,23 @@ var NON_SWITCHABLE = /* @__PURE__ */ new Set([
35274
35340
  "coderabbit"
35275
35341
  ]);
35276
35342
  function displayName(id) {
35343
+ if (id === HOUSE_AGENT_ID) return HOUSE_AGENT_NAME;
35277
35344
  return isKnownAgentId(id) ? AGENT_REGISTRY[id]?.displayName ?? id : id;
35278
35345
  }
35279
35346
  function credentialFailureMessage(agentId, failure) {
35280
35347
  if (failure.message) return failure.message;
35281
35348
  return `No linked credential for ${displayName(agentId)}. Link it in Profile \u203A Agents first.`;
35282
35349
  }
35283
- function resolveSwitchTarget(raw, currentAgent) {
35350
+ function resolveSwitchTarget(raw, currentAgent, currentIsHouse = false) {
35284
35351
  if (typeof raw !== "string" || raw.length === 0) {
35285
35352
  return { ok: false, error: "switch_agent: missing agentId" };
35286
35353
  }
35354
+ if (raw === HOUSE_AGENT_ID) {
35355
+ if (currentIsHouse) {
35356
+ return { ok: false, error: `${HOUSE_AGENT_NAME} is already this session's agent.` };
35357
+ }
35358
+ return { ok: true, agentId: "claude", wireId: HOUSE_AGENT_ID, house: true };
35359
+ }
35287
35360
  if (!isKnownAgentId(raw)) {
35288
35361
  return { ok: false, error: `Unknown agent "${raw}".` };
35289
35362
  }
@@ -35296,10 +35369,10 @@ function resolveSwitchTarget(raw, currentAgent) {
35296
35369
  error: `${displayName(raw)} can't be switched to in a live session yet.`
35297
35370
  };
35298
35371
  }
35299
- if (raw === currentAgent) {
35372
+ if (raw === currentAgent && !currentIsHouse) {
35300
35373
  return { ok: false, error: `${displayName(raw)} is already this session's agent.` };
35301
35374
  }
35302
- return { ok: true, agentId: raw };
35375
+ return { ok: true, agentId: raw, wireId: raw, house: false };
35303
35376
  }
35304
35377
  function toAgentAuth(method, credential) {
35305
35378
  return { kind: method === "api_key" ? "api_key" : "oauth_token", value: credential };
@@ -35374,7 +35447,8 @@ function makeSerializedSwitchEmitter(post2) {
35374
35447
  }
35375
35448
  async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
35376
35449
  const from = deps.currentAgent();
35377
- const target = resolveSwitchTarget(rawAgentId, from);
35450
+ const fromIsHouse = deps.currentIsHouse();
35451
+ const target = resolveSwitchTarget(rawAgentId, from, fromIsHouse);
35378
35452
  if (!target.ok) {
35379
35453
  return {
35380
35454
  ok: false,
@@ -35383,27 +35457,45 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
35383
35457
  };
35384
35458
  }
35385
35459
  const agentId = target.agentId;
35460
+ const wireId = target.wireId;
35461
+ const fromWireId = fromIsHouse ? HOUSE_AGENT_ID : from;
35462
+ const targetName = displayName(wireId);
35386
35463
  const emitStatus = (status2) => deps.postEvent("switch_agent_status", { ...status2 });
35387
- const emitStep = (step) => deps.postEvent("switch_agent_progress", { step, agentId });
35464
+ const emitStep = (step) => deps.postEvent("switch_agent_progress", { step, agentId: wireId });
35388
35465
  const fail2 = (error) => {
35389
- log.warn("switchAgent", `switch ${from} \u2192 ${agentId} failed: ${error}`);
35390
- void emitStatus({ state: "error", agentId, fromAgentId: from, error });
35391
- return { ok: false, agentId, error };
35466
+ log.warn("switchAgent", `switch ${fromWireId} \u2192 ${wireId} failed: ${error}`);
35467
+ void emitStatus({ state: "error", agentId: wireId, fromAgentId: fromWireId, error });
35468
+ return { ok: false, agentId: wireId, error };
35392
35469
  };
35393
- log.info("switchAgent", `switch requested ${from} \u2192 ${agentId}`);
35394
- void emitStatus({ state: "switching", agentId, fromAgentId: from });
35470
+ log.info("switchAgent", `switch requested ${fromWireId} \u2192 ${wireId}`);
35471
+ void emitStatus({ state: "switching", agentId: wireId, fromAgentId: fromWireId });
35395
35472
  let installScript;
35396
35473
  if (!fastPath.skipProvision) {
35397
35474
  void emitStep("credential");
35398
- const cred = await deps.fetchCredential(agentId);
35475
+ const cred = await deps.fetchCredential(wireId);
35399
35476
  if (!cred.ok) {
35400
- return fail2(credentialFailureMessage(agentId, cred));
35477
+ return fail2(credentialFailureMessage(wireId, cred));
35401
35478
  }
35402
- try {
35403
- deps.provisionCredential(agentId, toAgentAuth(cred.method, cred.credential));
35404
- } catch (err) {
35405
- log.warn("switchAgent", `credential provisioning failed: ${err.message}`);
35406
- return fail2(`Couldn't write the ${displayName(agentId)} credential on this machine.`);
35479
+ if (target.house) {
35480
+ if (cred.method !== "house_proxy" || !cred.baseUrl) {
35481
+ return fail2(`${targetName} isn't available on this backend yet.`);
35482
+ }
35483
+ try {
35484
+ deps.provisionHouseProxy({ baseUrl: cred.baseUrl, token: cred.credential });
35485
+ } catch (err) {
35486
+ log.warn("switchAgent", `house proxy provisioning failed: ${err.message}`);
35487
+ return fail2(`Couldn't configure ${targetName} on this machine.`);
35488
+ }
35489
+ } else {
35490
+ if (cred.method === "house_proxy") {
35491
+ return fail2(`Couldn't fetch the ${targetName} credential.`);
35492
+ }
35493
+ try {
35494
+ deps.provisionCredential(agentId, toAgentAuth(cred.method, cred.credential));
35495
+ } catch (err) {
35496
+ log.warn("switchAgent", `credential provisioning failed: ${err.message}`);
35497
+ return fail2(`Couldn't write the ${targetName} credential on this machine.`);
35498
+ }
35407
35499
  }
35408
35500
  installScript = cred.installScript;
35409
35501
  }
@@ -35416,19 +35508,19 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
35416
35508
  }
35417
35509
  void emitStep("restart");
35418
35510
  try {
35419
- await deps.swapRuntime(agentId);
35511
+ await deps.swapRuntime(agentId, { house: target.house });
35420
35512
  } catch (err) {
35421
- log.warn("switchAgent", `swap failed, reverting to ${from}: ${err.message}`);
35513
+ log.warn("switchAgent", `swap failed, reverting to ${fromWireId}: ${err.message}`);
35422
35514
  try {
35423
- await deps.revertRuntime(from);
35515
+ await deps.revertRuntime(from, { house: fromIsHouse });
35424
35516
  } catch (revertErr) {
35425
35517
  log.warn("switchAgent", `revert failed: ${revertErr.message}`);
35426
35518
  return fail2(
35427
- `Switching to ${displayName(agentId)} failed and ${displayName(from)} couldn't be restored \u2014 restart the session.`
35519
+ `Switching to ${targetName} failed and ${displayName(fromWireId)} couldn't be restored \u2014 restart the session.`
35428
35520
  );
35429
35521
  }
35430
35522
  return fail2(
35431
- `Couldn't start ${displayName(agentId)} \u2014 the session stays on ${displayName(from)}.`
35523
+ `Couldn't start ${targetName} \u2014 the session stays on ${displayName(fromWireId)}.`
35432
35524
  );
35433
35525
  }
35434
35526
  try {
@@ -35437,9 +35529,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
35437
35529
  log.warn("switchAgent", `persist failed (non-fatal): ${err.message}`);
35438
35530
  }
35439
35531
  deps.reannounce(agentId);
35440
- await emitStatus({ state: "ready", agentId, fromAgentId: from });
35441
- log.info("switchAgent", `switch complete ${from} \u2192 ${agentId}`);
35442
- return { ok: true, agentId };
35532
+ await emitStatus({ state: "ready", agentId: wireId, fromAgentId: fromWireId });
35533
+ log.info("switchAgent", `switch complete ${fromWireId} \u2192 ${wireId}`);
35534
+ return { ok: true, agentId: wireId };
35443
35535
  }
35444
35536
 
35445
35537
  // src/services/streaming/transport.ts
@@ -36716,7 +36808,7 @@ function defaultRunGit(cwd, args2) {
36716
36808
  });
36717
36809
  }
36718
36810
  async function discoverRepos(workingDir, maxDepth = 4) {
36719
- const fs81 = await import("fs/promises");
36811
+ const fs82 = await import("fs/promises");
36720
36812
  const out2 = [];
36721
36813
  await walk(workingDir, 0);
36722
36814
  return out2;
@@ -36724,7 +36816,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
36724
36816
  if (depth > maxDepth) return;
36725
36817
  let entries = [];
36726
36818
  try {
36727
- const dirents = await fs81.readdir(dir, { withFileTypes: true });
36819
+ const dirents = await fs82.readdir(dir, { withFileTypes: true });
36728
36820
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
36729
36821
  } catch {
36730
36822
  return;
@@ -40273,7 +40365,10 @@ async function runAcpSession(opts) {
40273
40365
  refreshSquadRoster();
40274
40366
  const pendingProposal = { current: null };
40275
40367
  let switchCredentialEnv = {};
40276
- const relaunchWith = async (nextAgent) => {
40368
+ let houseActive = isHouseProxyEnv(process.env);
40369
+ let houseEnv = houseActive ? pickHouseProxyEnv(process.env) : {};
40370
+ let pendingHouseConfig = null;
40371
+ const relaunchWith = async (nextAgent, swapOpts = { house: false }) => {
40277
40372
  try {
40278
40373
  await client3.cancel();
40279
40374
  } catch {
@@ -40287,13 +40382,15 @@ async function runAcpSession(opts) {
40287
40382
  if (!adapter) throw new Error(`no ACP adapter available for ${nextAgent}`);
40288
40383
  const disable1m = loadCliConfig().sessions.find((s) => s.pluginId === opts.pluginId)?.disable1mContext === true;
40289
40384
  clientOptions.adapter = adapter;
40385
+ const leavingHouseEnv = !swapOpts.house && (houseActive || isHouseProxyEnv(process.env) || Object.keys(houseEnv).length > 0) ? clearHouseProxyEnvOverrides() : {};
40290
40386
  clientOptions.extraEnv = {
40291
40387
  ...computeAdapterExtraEnv({
40292
40388
  agent: nextAgent,
40293
40389
  autoApprovePermissions: opts.autoApprovePermissions,
40294
40390
  disable1mContext: disable1m
40295
40391
  }),
40296
- ...switchCredentialEnv
40392
+ ...leavingHouseEnv,
40393
+ ...swapOpts.house ? houseEnv : switchCredentialEnv
40297
40394
  };
40298
40395
  const next = new AcpClient(clientOptions);
40299
40396
  const hs = await next.start();
@@ -40313,13 +40410,23 @@ async function runAcpSession(opts) {
40313
40410
  });
40314
40411
  budgetRecovery = makeBudgetRecovery();
40315
40412
  pendingHandoff.current = buildHandoffPreamble(prevAgent, nextAgent, transcript);
40413
+ const wasHouse = houseActive;
40414
+ houseActive = swapOpts.house;
40415
+ if (swapOpts.house) {
40416
+ if (pendingHouseConfig) {
40417
+ persistHouseProxyConfig(pendingHouseConfig);
40418
+ pendingHouseConfig = null;
40419
+ }
40420
+ } else if (wasHouse) {
40421
+ clearHouseProxyConfig();
40422
+ }
40316
40423
  void publisher.publishOutput({
40317
40424
  type: "agent_banner",
40318
- agentId: nextAgent,
40425
+ agentId: swapOpts.house ? HOUSE_AGENT_ID : nextAgent,
40319
40426
  // A switch starts a FRESH conversation with the new agent — never "back".
40320
- title: bannerTitle(false),
40321
- subtitle: buildBannerSubtitle(nextAgent, hs.sessionId, hs.model, hs.tier),
40322
- path: bannerLocation(opts.cwd),
40427
+ title: swapOpts.house ? HOUSE_AGENT_NAME : bannerTitle(false),
40428
+ subtitle: swapOpts.house ? HOUSE_AGENT_SUBTITLE : buildBannerSubtitle(nextAgent, hs.sessionId, hs.model, hs.tier),
40429
+ path: swapOpts.house ? "" : bannerLocation(opts.cwd),
40323
40430
  done: true
40324
40431
  });
40325
40432
  };
@@ -40334,6 +40441,7 @@ async function runAcpSession(opts) {
40334
40441
  );
40335
40442
  const switchDeps = {
40336
40443
  currentAgent: () => opts.agent,
40444
+ currentIsHouse: () => houseActive,
40337
40445
  postEvent: emitSwitchEvent,
40338
40446
  fetchCredential: (agentId) => fetchProvisionCredentialDetailed({
40339
40447
  agentId,
@@ -40345,6 +40453,21 @@ async function runAcpSession(opts) {
40345
40453
  provisionCredential: (agentId, auth) => {
40346
40454
  switchCredentialEnv = provisionAgentCredentials(agentId, auth);
40347
40455
  },
40456
+ provisionHouseProxy: ({ baseUrl, token }) => {
40457
+ const claudeConfigDir = path85.join(
40458
+ os62.homedir(),
40459
+ ".codeam",
40460
+ "house-claude",
40461
+ `switch-${opts.pluginId}`
40462
+ );
40463
+ try {
40464
+ fs77.mkdirSync(claudeConfigDir, { recursive: true, mode: 448 });
40465
+ } catch {
40466
+ }
40467
+ houseEnv = buildHouseProxyChildEnv({ baseUrl, token, claudeConfigDir });
40468
+ pendingHouseConfig = { baseUrl, token, claudeConfigDir };
40469
+ switchCredentialEnv = {};
40470
+ },
40348
40471
  ensureBinary: (agentId, installScript, onRetry) => ensureAgentBinaryForSwitch(agentId, installScript, { onRetry }),
40349
40472
  swapRuntime: relaunchWith,
40350
40473
  revertRuntime: relaunchWith,
@@ -41540,9 +41663,9 @@ function startClaudeCredentialSync(opts) {
41540
41663
  }
41541
41664
 
41542
41665
  // src/beads/workflow-hint.ts
41543
- var fs77 = __toESM(require("fs"));
41544
- var path85 = __toESM(require("path"));
41545
- var os62 = __toESM(require("os"));
41666
+ var fs78 = __toESM(require("fs"));
41667
+ var path86 = __toESM(require("path"));
41668
+ var os63 = __toESM(require("os"));
41546
41669
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
41547
41670
  var BEADS_HINT = `${BEADS_HINT_MARKER}
41548
41671
  # Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
@@ -41556,22 +41679,22 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
41556
41679
  - \`bd ready\` (available work) \xB7 \`bd show <id>\` \xB7 \`bd update <id> --claim\` \xB7 \`bd close <id>\`.
41557
41680
  - Use \`bd remember "..."\` for persistent knowledge \u2014 do NOT use MEMORY.md files.
41558
41681
  ${BEADS_HINT_MARKER}`;
41559
- function ensureBeadsWorkflowHint(homeDir2 = os62.homedir()) {
41682
+ function ensureBeadsWorkflowHint(homeDir2 = os63.homedir()) {
41560
41683
  try {
41561
- const file = path85.join(homeDir2, ".claude", "CLAUDE.md");
41684
+ const file = path86.join(homeDir2, ".claude", "CLAUDE.md");
41562
41685
  let existing = "";
41563
41686
  try {
41564
- existing = fs77.readFileSync(file, "utf8");
41687
+ existing = fs78.readFileSync(file, "utf8");
41565
41688
  } catch {
41566
41689
  }
41567
41690
  if (existing.includes(BEADS_HINT_MARKER)) return;
41568
- fs77.mkdirSync(path85.dirname(file), { recursive: true });
41691
+ fs78.mkdirSync(path86.dirname(file), { recursive: true });
41569
41692
  const next = existing.trim() ? `${existing.trimEnd()}
41570
41693
 
41571
41694
  ${BEADS_HINT}
41572
41695
  ` : `${BEADS_HINT}
41573
41696
  `;
41574
- fs77.writeFileSync(file, next);
41697
+ fs78.writeFileSync(file, next);
41575
41698
  } catch {
41576
41699
  }
41577
41700
  }
@@ -42082,7 +42205,7 @@ var AcpDriver = class {
42082
42205
  };
42083
42206
 
42084
42207
  // src/baton/transcript-mirror.ts
42085
- var fs78 = __toESM(require("fs"));
42208
+ var fs79 = __toESM(require("fs"));
42086
42209
  var TranscriptMirror = class {
42087
42210
  constructor(deps) {
42088
42211
  this.deps = deps;
@@ -42149,7 +42272,7 @@ var TranscriptMirror = class {
42149
42272
  }
42150
42273
  };
42151
42274
  function defaultWatch(file, onChange) {
42152
- const w3 = fs78.watch(file, { persistent: false }, () => onChange());
42275
+ const w3 = fs79.watch(file, { persistent: false }, () => onChange());
42153
42276
  return () => w3.close();
42154
42277
  }
42155
42278
 
@@ -42479,16 +42602,16 @@ function keepDeviceAwake(deps = {}) {
42479
42602
  }
42480
42603
 
42481
42604
  // src/agents/claude/onboarding.ts
42482
- var fs79 = __toESM(require("fs"));
42483
- var os64 = __toESM(require("os"));
42484
- var path86 = __toESM(require("path"));
42605
+ var fs80 = __toESM(require("fs"));
42606
+ var os65 = __toESM(require("os"));
42607
+ var path87 = __toESM(require("path"));
42485
42608
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
42486
42609
  function ensureClaudeOnboarded(cwd) {
42487
42610
  try {
42488
- const file = path86.join(os64.homedir(), ".claude.json");
42611
+ const file = path87.join(os65.homedir(), ".claude.json");
42489
42612
  let config = {};
42490
42613
  try {
42491
- config = JSON.parse(fs79.readFileSync(file, "utf8"));
42614
+ config = JSON.parse(fs80.readFileSync(file, "utf8"));
42492
42615
  } catch {
42493
42616
  }
42494
42617
  let changed = false;
@@ -42513,8 +42636,8 @@ function ensureClaudeOnboarded(cwd) {
42513
42636
  }
42514
42637
  }
42515
42638
  if (!changed) return;
42516
- fs79.mkdirSync(path86.dirname(file), { recursive: true });
42517
- fs79.writeFileSync(file, JSON.stringify(config, null, 2));
42639
+ fs80.mkdirSync(path87.dirname(file), { recursive: true });
42640
+ fs80.writeFileSync(file, JSON.stringify(config, null, 2));
42518
42641
  log.info(
42519
42642
  "claude",
42520
42643
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -43251,7 +43374,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
43251
43374
  var import_child_process31 = require("child_process");
43252
43375
  var import_util4 = require("util");
43253
43376
  var import_picocolors9 = __toESM(require("picocolors"));
43254
- var path87 = __toESM(require("path"));
43377
+ var path88 = __toESM(require("path"));
43255
43378
  var execFileP6 = (0, import_util4.promisify)(import_child_process31.execFile);
43256
43379
  var MAX_BUFFER = 8 * 1024 * 1024;
43257
43380
  function resetStdinForChild() {
@@ -43740,7 +43863,7 @@ var GitHubCodespacesProvider = class {
43740
43863
  });
43741
43864
  }
43742
43865
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
43743
- const remoteDir = path87.posix.dirname(remotePath);
43866
+ const remoteDir = path88.posix.dirname(remotePath);
43744
43867
  const parts = [
43745
43868
  `mkdir -p ${shellQuote(remoteDir)}`,
43746
43869
  `cat > ${shellQuote(remotePath)}`
@@ -43810,7 +43933,7 @@ function shellQuote(s) {
43810
43933
  // src/services/providers/gitpod.ts
43811
43934
  var import_child_process32 = require("child_process");
43812
43935
  var import_util5 = require("util");
43813
- var path88 = __toESM(require("path"));
43936
+ var path89 = __toESM(require("path"));
43814
43937
  var import_picocolors10 = __toESM(require("picocolors"));
43815
43938
  var execFileP7 = (0, import_util5.promisify)(import_child_process32.execFile);
43816
43939
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -44050,7 +44173,7 @@ var GitpodProvider = class {
44050
44173
  });
44051
44174
  }
44052
44175
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
44053
- const remoteDir = path88.posix.dirname(remotePath);
44176
+ const remoteDir = path89.posix.dirname(remotePath);
44054
44177
  const parts = [
44055
44178
  `mkdir -p ${shellQuote2(remoteDir)}`,
44056
44179
  `cat > ${shellQuote2(remotePath)}`
@@ -44086,7 +44209,7 @@ function shellQuote2(s) {
44086
44209
  // src/services/providers/gitlab-workspaces.ts
44087
44210
  var import_child_process33 = require("child_process");
44088
44211
  var import_util6 = require("util");
44089
- var path89 = __toESM(require("path"));
44212
+ var path90 = __toESM(require("path"));
44090
44213
  var execFileP8 = (0, import_util6.promisify)(import_child_process33.execFile);
44091
44214
  var MAX_BUFFER3 = 8 * 1024 * 1024;
44092
44215
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -44346,7 +44469,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
44346
44469
  }
44347
44470
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
44348
44471
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
44349
- const remoteDir = path89.posix.dirname(remotePath);
44472
+ const remoteDir = path90.posix.dirname(remotePath);
44350
44473
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
44351
44474
  if (options.mode != null) {
44352
44475
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -44414,7 +44537,7 @@ function shellQuote3(s) {
44414
44537
  // src/services/providers/railway.ts
44415
44538
  var import_child_process34 = require("child_process");
44416
44539
  var import_util7 = require("util");
44417
- var path90 = __toESM(require("path"));
44540
+ var path91 = __toESM(require("path"));
44418
44541
  var execFileP9 = (0, import_util7.promisify)(import_child_process34.execFile);
44419
44542
  var MAX_BUFFER4 = 8 * 1024 * 1024;
44420
44543
  function resetStdinForChild4() {
@@ -44650,7 +44773,7 @@ var RailwayProvider = class {
44650
44773
  if (!projectId || !serviceId) {
44651
44774
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
44652
44775
  }
44653
- const remoteDir = path90.posix.dirname(remotePath);
44776
+ const remoteDir = path91.posix.dirname(remotePath);
44654
44777
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
44655
44778
  if (options.mode != null) {
44656
44779
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -45296,8 +45419,8 @@ async function invite() {
45296
45419
  var import_node_dns = require("dns");
45297
45420
  var import_node_util5 = require("util");
45298
45421
  var import_node_crypto13 = require("crypto");
45299
- var fs80 = __toESM(require("fs"));
45300
- var path91 = __toESM(require("path"));
45422
+ var fs81 = __toESM(require("fs"));
45423
+ var path92 = __toESM(require("path"));
45301
45424
  var import_picocolors14 = __toESM(require("picocolors"));
45302
45425
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
45303
45426
  async function checkDns(apiBase2) {
@@ -45353,13 +45476,13 @@ async function checkHealth(apiBase2) {
45353
45476
  }
45354
45477
  }
45355
45478
  function checkConfigDir() {
45356
- const dir = path91.join(require("os").homedir(), ".codeam");
45479
+ const dir = path92.join(require("os").homedir(), ".codeam");
45357
45480
  try {
45358
- fs80.mkdirSync(dir, { recursive: true, mode: 448 });
45359
- const probe = path91.join(dir, ".doctor-probe");
45360
- fs80.writeFileSync(probe, "ok", { mode: 384 });
45361
- const read2 = fs80.readFileSync(probe, "utf8");
45362
- fs80.unlinkSync(probe);
45481
+ fs81.mkdirSync(dir, { recursive: true, mode: 448 });
45482
+ const probe = path92.join(dir, ".doctor-probe");
45483
+ fs81.writeFileSync(probe, "ok", { mode: 384 });
45484
+ const read2 = fs81.readFileSync(probe, "utf8");
45485
+ fs81.unlinkSync(probe);
45363
45486
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
45364
45487
  return {
45365
45488
  id: "config-dir",
@@ -45399,9 +45522,9 @@ function checkSessions() {
45399
45522
  }
45400
45523
  }
45401
45524
  function checkAgentBinaries() {
45402
- const os67 = createOsStrategy();
45525
+ const os68 = createOsStrategy();
45403
45526
  return getEnabledAgents().map((meta) => {
45404
- const found = os67.findInPath(meta.binaryName);
45527
+ const found = os68.findInPath(meta.binaryName);
45405
45528
  return {
45406
45529
  id: `agent-${meta.id}`,
45407
45530
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -45423,7 +45546,7 @@ function checkNodePty() {
45423
45546
  detail: "not required on this platform"
45424
45547
  };
45425
45548
  }
45426
- const vendoredPath = path91.join(__dirname, "vendor", "node-pty");
45549
+ const vendoredPath = path92.join(__dirname, "vendor", "node-pty");
45427
45550
  for (const target of [vendoredPath, "node-pty"]) {
45428
45551
  try {
45429
45552
  require(target);
@@ -45465,7 +45588,7 @@ function checkChokidar() {
45465
45588
  }
45466
45589
  async function doctor(args2 = []) {
45467
45590
  const json = args2.includes("--json");
45468
- const cliVersion = true ? "2.65.15" : "0.0.0-dev";
45591
+ const cliVersion = true ? "2.65.17" : "0.0.0-dev";
45469
45592
  const apiBase2 = resolveApiBaseUrl();
45470
45593
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
45471
45594
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -45856,7 +45979,7 @@ async function mcpRun(args2) {
45856
45979
  // src/commands/version.ts
45857
45980
  var import_picocolors15 = __toESM(require("picocolors"));
45858
45981
  function version2() {
45859
- const v = true ? "2.65.15" : "unknown";
45982
+ const v = true ? "2.65.17" : "unknown";
45860
45983
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
45861
45984
  }
45862
45985
 
@@ -46005,10 +46128,10 @@ var EXIT_CODE_NAMES = {
46005
46128
  };
46006
46129
 
46007
46130
  // src/index.ts
46008
- var os66 = __toESM(require("os"));
46131
+ var os67 = __toESM(require("os"));
46009
46132
  if (!process.env.HOME) {
46010
46133
  try {
46011
- const home = os66.homedir();
46134
+ const home = os67.homedir();
46012
46135
  if (home) process.env.HOME = home;
46013
46136
  } catch {
46014
46137
  }