codeam-cli 2.75.6 → 2.75.8

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 +18 -0
  2. package/dist/index.js +408 -250
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -357,8 +357,8 @@ function defaultSpawn(timeoutMs) {
357
357
  });
358
358
  }
359
359
  function resolveConvexBin(cwd) {
360
- const local = path89.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
361
- if (fs76.existsSync(local)) return { cmd: local, args: [] };
360
+ const local = path90.join(cwd, "node_modules", ".bin", process.platform === "win32" ? "convex.cmd" : "convex");
361
+ if (fs77.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, fs76, path89, TOOLS;
492
+ var import_node_child_process32, fs77, path90, 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
- fs76 = __toESM(require("fs"));
498
- path89 = __toESM(require("path"));
497
+ fs77 = __toESM(require("fs"));
498
+ path90 = __toESM(require("path"));
499
499
  TOOLS = [
500
500
  {
501
501
  name: "tables",
@@ -3360,11 +3360,11 @@ function quiet(fn) {
3360
3360
  log.debug(TAG, "ignored sync error", err);
3361
3361
  }
3362
3362
  }
3363
- function rmIfExistsQuiet(path91) {
3363
+ function rmIfExistsQuiet(path92) {
3364
3364
  try {
3365
- fs2.rmSync(path91, { force: true });
3365
+ fs2.rmSync(path92, { force: true });
3366
3366
  } catch (err) {
3367
- log.debug(TAG, `rmIfExists failed for ${path91}`, err);
3367
+ log.debug(TAG, `rmIfExists failed for ${path92}`, err);
3368
3368
  }
3369
3369
  }
3370
3370
  function killQuiet(target, signal = "SIGTERM") {
@@ -3568,8 +3568,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
3568
3568
  return decodedFile;
3569
3569
  };
3570
3570
  }
3571
- function normalizeWindowsPath(path91) {
3572
- return path91.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3571
+ function normalizeWindowsPath(path92) {
3572
+ return path92.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3573
3573
  }
3574
3574
 
3575
3575
  // ../../node_modules/@posthog/core/dist/error-tracking/index.mjs
@@ -6302,13 +6302,13 @@ var PostHogCoreStateless = class {
6302
6302
  sentFromRoute += batchMessages.length;
6303
6303
  }
6304
6304
  }
6305
- async _sendOtlpBatch({ path: path91, payload }) {
6305
+ async _sendOtlpBatch({ path: path92, payload }) {
6306
6306
  if (this.disabled) return {
6307
6307
  kind: "fatal",
6308
6308
  error: new Error("The client is disabled")
6309
6309
  };
6310
6310
  const serialized = JSON.stringify(payload);
6311
- const url2 = `${this.host}/i/v1/${path91}?token=${encodeURIComponent(this.apiKey)}`;
6311
+ const url2 = `${this.host}/i/v1/${path92}?token=${encodeURIComponent(this.apiKey)}`;
6312
6312
  const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
6313
6313
  const fetchOptions = {
6314
6314
  method: "POST",
@@ -7548,14 +7548,14 @@ async function addSourceContext(frames, openSourceFile = import_promises.open, l
7548
7548
  LRU_FILE_CONTENTS_CACHE.reduce();
7549
7549
  return frames;
7550
7550
  }
7551
- async function openRegularSourceFile(path91, openSourceFile, logger) {
7551
+ async function openRegularSourceFile(path92, openSourceFile, logger) {
7552
7552
  let fileHandle;
7553
7553
  let isValid = false;
7554
7554
  try {
7555
- fileHandle = await openSourceFile(path91, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
7555
+ fileHandle = await openSourceFile(path92, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
7556
7556
  const fileStat = await fileHandle.stat();
7557
7557
  if (!fileStat.isFile()) return;
7558
- if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path91}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
7558
+ if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE) return void logger?.debug(`Skipping source context for oversized file ${path92}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
7559
7559
  isValid = true;
7560
7560
  return fileHandle;
7561
7561
  } catch {
@@ -7565,8 +7565,8 @@ async function openRegularSourceFile(path91, openSourceFile, logger) {
7565
7565
  });
7566
7566
  }
7567
7567
  }
7568
- async function getContextLinesFromFile(path91, ranges, output, cacheKey, openSourceFile, logger) {
7569
- const fileHandle = await openRegularSourceFile(path91, openSourceFile, logger);
7568
+ async function getContextLinesFromFile(path92, ranges, output, cacheKey, openSourceFile, logger) {
7569
+ const fileHandle = await openRegularSourceFile(path92, openSourceFile, logger);
7570
7570
  if (void 0 === fileHandle) return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
7571
7571
  const openedFileHandle = fileHandle;
7572
7572
  return new Promise((resolve11) => {
@@ -7668,22 +7668,22 @@ function clearLineContext(frame) {
7668
7668
  delete frame.context_line;
7669
7669
  delete frame.post_context;
7670
7670
  }
7671
- function shouldSkipContextLinesForFile(path91) {
7672
- return path91.startsWith("node:") || path91.endsWith(".min.js") || path91.endsWith(".min.cjs") || path91.endsWith(".min.mjs") || path91.startsWith("data:");
7671
+ function shouldSkipContextLinesForFile(path92) {
7672
+ return path92.startsWith("node:") || path92.endsWith(".min.js") || path92.endsWith(".min.cjs") || path92.endsWith(".min.mjs") || path92.startsWith("data:");
7673
7673
  }
7674
7674
  function shouldSkipContextLinesForFrame(frame) {
7675
7675
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
7676
7676
  if (void 0 !== frame.colno && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
7677
7677
  return false;
7678
7678
  }
7679
- function makeSourceCacheKey(path91, basePath) {
7680
- if ((0, import_node_path.isAbsolute)(path91)) return JSON.stringify([
7679
+ function makeSourceCacheKey(path92, basePath) {
7680
+ if ((0, import_node_path.isAbsolute)(path92)) return JSON.stringify([
7681
7681
  null,
7682
- path91
7682
+ path92
7683
7683
  ]);
7684
7684
  return void 0 === basePath ? void 0 : JSON.stringify([
7685
7685
  basePath,
7686
- path91
7686
+ path92
7687
7687
  ]);
7688
7688
  }
7689
7689
  function rangeExistsInContentCache(cacheKey, range) {
@@ -10344,7 +10344,7 @@ function readAnonId() {
10344
10344
  }
10345
10345
  function superProperties() {
10346
10346
  return {
10347
- cliVersion: true ? "2.75.6" : "0.0.0-dev",
10347
+ cliVersion: true ? "2.75.8" : "0.0.0-dev",
10348
10348
  nodeVersion: process.version,
10349
10349
  platform: process.platform,
10350
10350
  arch: process.arch,
@@ -10586,7 +10586,7 @@ var http = __toESM(require("http"));
10586
10586
  // package.json
10587
10587
  var package_default = {
10588
10588
  name: "codeam-cli",
10589
- version: "2.75.6",
10589
+ version: "2.75.8",
10590
10590
  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.",
10591
10591
  type: "commonjs",
10592
10592
  main: "dist/index.js",
@@ -11384,6 +11384,9 @@ var streamHost = new StreamHostSelector(
11384
11384
  );
11385
11385
 
11386
11386
  // src/services/command-relay.service.ts
11387
+ function isRecord2(v) {
11388
+ return typeof v === "object" && v !== null;
11389
+ }
11387
11390
  function httpStatusOf(err) {
11388
11391
  if (typeof err === "object" && err !== null && "statusCode" in err) {
11389
11392
  const status2 = err.statusCode;
@@ -11394,6 +11397,8 @@ function httpStatusOf(err) {
11394
11397
  var API_BASE2 = resolveApiBaseUrl();
11395
11398
  var PENDING_STREAM_PATH = "/api/commands/pending/stream";
11396
11399
  var SSE_LIVENESS_TIMEOUT_MS = 45e3;
11400
+ var HEARTBEAT_RETRY_MS = 3e3;
11401
+ var HEARTBEAT_WARN_INTERVAL_MS = 6e4;
11397
11402
  var SSE_WATCHDOG_INTERVAL_MS = 1e4;
11398
11403
  var CommandRelayService = class _CommandRelayService {
11399
11404
  constructor(pluginId, onCommand, agentMeta, agentsOverride, explicitPollSecret, onHeartbeat) {
@@ -11412,6 +11417,18 @@ var CommandRelayService = class _CommandRelayService {
11412
11417
  onHeartbeat;
11413
11418
  _running = false;
11414
11419
  pairingInvalid = false;
11420
+ /**
11421
+ * Heartbeat health. Before 2026-09-23 a failed heartbeat was a `log.trace`,
11422
+ * i.e. INVISIBLE in a normal `~/.codeam/debug-*.log` — a user whose beats
11423
+ * never reached the origin (every other request did) spent a day on "Server
11424
+ * Failed to Start" with nothing in his log to show for it. Failures are now
11425
+ * WARN (rate-limited per streak) + a PostHog event, and the process exits
11426
+ * when the backend answers `paired:false`.
11427
+ */
11428
+ heartbeatFailStreak = 0;
11429
+ heartbeatLastWarnAt = 0;
11430
+ sessionGone = false;
11431
+ onSessionGone;
11415
11432
  heartbeatTimer = null;
11416
11433
  agentsTimer = null;
11417
11434
  /** Injectable for tests; defaults to real fs/fetch/spawn wiring. */
@@ -11530,6 +11547,17 @@ var CommandRelayService = class _CommandRelayService {
11530
11547
  stop() {
11531
11548
  void this.stopAndFlush();
11532
11549
  }
11550
+ /**
11551
+ * Called ONCE when a heartbeat answers `paired:false` — the backend no longer
11552
+ * has a live session for this pluginId (deleted / disconnected from the
11553
+ * app). The relay has already stopped itself by then; the owner should exit
11554
+ * the process like a Ctrl-C would. Backstop for a process whose
11555
+ * `session_terminated` command was consumed by a sibling on the same
11556
+ * pluginId (two `codeam start` on one saved session, 2026-09-23).
11557
+ */
11558
+ setOnSessionGone(cb) {
11559
+ this.onSessionGone = cb;
11560
+ }
11533
11561
  /**
11534
11562
  * Same teardown as {@link stop}, but resolves only once the `online:false`
11535
11563
  * heartbeat POST has settled — so a caller can `await` it before exiting.
@@ -11877,8 +11905,9 @@ var CommandRelayService = class _CommandRelayService {
11877
11905
  });
11878
11906
  }
11879
11907
  // ─── Heartbeat + agents ──────────────────────────────────────────
11880
- async sendHeartbeat(online) {
11881
- await _postJson(`${API_BASE2}/api/plugin/heartbeat`, {
11908
+ async sendHeartbeat(online, attempt = 0) {
11909
+ if (this.sessionGone && online) return;
11910
+ const body = {
11882
11911
  pluginId: this.pluginId,
11883
11912
  online,
11884
11913
  agentId: this.agentMeta.id,
@@ -11887,8 +11916,58 @@ var CommandRelayService = class _CommandRelayService {
11887
11916
  // fresh + clear the "CLI update available" banner after a self-update
11888
11917
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
11889
11918
  // pair/reconnect). Older backends ignore the extra field.
11890
- ..."2.75.6" ? { ideVersion: "2.75.6" } : {}
11891
- }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
11919
+ ..."2.75.8" ? { ideVersion: "2.75.8" } : {}
11920
+ };
11921
+ try {
11922
+ const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body);
11923
+ this.heartbeatFailStreak = 0;
11924
+ log.trace("relay", `heartbeat ok online=${online}`);
11925
+ const data = res?.data;
11926
+ if (online && isRecord2(data) && data.paired === false) this.handleSessionGone();
11927
+ } catch (err) {
11928
+ if (!online) {
11929
+ log.trace("relay", "goodbye heartbeat failed", err);
11930
+ return;
11931
+ }
11932
+ this.heartbeatFailStreak += 1;
11933
+ this.noteHeartbeatFailure(err);
11934
+ if (attempt === 0 && this._running) {
11935
+ const t2 = setTimeout(() => {
11936
+ void this.sendHeartbeat(true, 1);
11937
+ }, HEARTBEAT_RETRY_MS);
11938
+ t2.unref?.();
11939
+ }
11940
+ }
11941
+ }
11942
+ noteHeartbeatFailure(err) {
11943
+ const status2 = httpStatusOf(err);
11944
+ const code = err?.code;
11945
+ const reason = status2 ? `status_${status2}` : typeof code === "string" ? code : (err instanceof Error ? err.message : String(err)).slice(0, 80);
11946
+ const now = Date.now();
11947
+ const firstOfStreak = this.heartbeatFailStreak === 1;
11948
+ if (!firstOfStreak && now - this.heartbeatLastWarnAt < HEARTBEAT_WARN_INTERVAL_MS) return;
11949
+ this.heartbeatLastWarnAt = now;
11950
+ log.warn(
11951
+ "relay",
11952
+ `heartbeat failed (${reason}, streak=${this.heartbeatFailStreak}) \u2014 two misses in a row and the app shows this session OFFLINE even though it is running`
11953
+ );
11954
+ capture("heartbeat_failed", {
11955
+ pluginId: this.pluginId,
11956
+ agentId: this.agentMeta.id,
11957
+ reason,
11958
+ streak: this.heartbeatFailStreak
11959
+ });
11960
+ }
11961
+ handleSessionGone() {
11962
+ if (this.sessionGone) return;
11963
+ log.warn("relay", "backend reports this session no longer exists (paired:false) \u2014 stopping");
11964
+ capture("session_gone_detected", { pluginId: this.pluginId, agentId: this.agentMeta.id });
11965
+ process.stderr.write(
11966
+ "[codeam] This session was deleted or disconnected from the app \u2014 exiting. Run `codeam pair` to start a new one.\n"
11967
+ );
11968
+ this.stop();
11969
+ this.sessionGone = true;
11970
+ this.onSessionGone?.();
11892
11971
  }
11893
11972
  /**
11894
11973
  * Refresh {@link cachedBranch} without blocking the event loop.
@@ -12143,10 +12222,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
12143
12222
  /[\\/]Start Menu([\\/]|$)/i,
12144
12223
  /[\\/]Templates([\\/]|$)/i
12145
12224
  ];
12146
- function isUnsafeWindowsWatchRoot(dir, homedir48) {
12225
+ function isUnsafeWindowsWatchRoot(dir, homedir49) {
12147
12226
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
12148
12227
  const cwd = norm(dir);
12149
- const home = norm(homedir48);
12228
+ const home = norm(homedir49);
12150
12229
  if (cwd === home) return true;
12151
12230
  if (/^[a-z]:$/.test(cwd)) return true;
12152
12231
  const sysRoots = [
@@ -16825,10 +16904,10 @@ function buildForPlatform(platform3) {
16825
16904
  var import_node_crypto4 = require("crypto");
16826
16905
 
16827
16906
  // src/agents/claude/resolver.ts
16828
- function buildClaudeLaunch(extraArgs = [], os62 = createOsStrategy()) {
16829
- const found = os62.findInPath("claude") ?? os62.findInPath("claude-code");
16907
+ function buildClaudeLaunch(extraArgs = [], os63 = createOsStrategy()) {
16908
+ const found = os63.findInPath("claude") ?? os63.findInPath("claude-code");
16830
16909
  if (!found) return null;
16831
- return os62.buildLaunch(found, extraArgs);
16910
+ return os63.buildLaunch(found, extraArgs);
16832
16911
  }
16833
16912
 
16834
16913
  // src/agents/claude/installer.ts
@@ -17590,8 +17669,8 @@ var ClaudeRuntimeStrategy = class {
17590
17669
  meta = getAgent("claude");
17591
17670
  mode = "interactive";
17592
17671
  os;
17593
- constructor(os62) {
17594
- this.os = os62;
17672
+ constructor(os63) {
17673
+ this.os = os63;
17595
17674
  }
17596
17675
  /**
17597
17676
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -18679,8 +18758,8 @@ function codexCredentialLocator() {
18679
18758
  function codexLoginLauncher() {
18680
18759
  return {
18681
18760
  async ensureInstalled() {
18682
- const os62 = createOsStrategy();
18683
- return os62.findInPath("codex") !== null;
18761
+ const os63 = createOsStrategy();
18762
+ return os63.findInPath("codex") !== null;
18684
18763
  },
18685
18764
  launch() {
18686
18765
  return (0, import_node_child_process3.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -18703,8 +18782,8 @@ var CodexRuntimeStrategy = class {
18703
18782
  meta = getAgent("codex");
18704
18783
  mode = "interactive";
18705
18784
  os;
18706
- constructor(os62) {
18707
- this.os = os62;
18785
+ constructor(os63) {
18786
+ this.os = os63;
18708
18787
  }
18709
18788
  async prepareLaunch() {
18710
18789
  let binary = this.os.findInPath("codex");
@@ -18813,12 +18892,12 @@ var CodexRuntimeStrategy = class {
18813
18892
  });
18814
18893
  }
18815
18894
  };
18816
- function resolveNpm(os62) {
18817
- return os62.id === "win32" ? "npm.cmd" : "npm";
18895
+ function resolveNpm(os63) {
18896
+ return os63.id === "win32" ? "npm.cmd" : "npm";
18818
18897
  }
18819
- async function installCodexViaNpm(os62) {
18898
+ async function installCodexViaNpm(os63) {
18820
18899
  return new Promise((resolve11, reject) => {
18821
- const proc = (0, import_node_child_process4.spawn)(resolveNpm(os62), ["install", "-g", "@openai/codex"], {
18900
+ const proc = (0, import_node_child_process4.spawn)(resolveNpm(os63), ["install", "-g", "@openai/codex"], {
18822
18901
  stdio: "inherit"
18823
18902
  });
18824
18903
  proc.on("close", (code) => {
@@ -18835,16 +18914,16 @@ async function installCodexViaNpm(os62) {
18835
18914
  });
18836
18915
  });
18837
18916
  }
18838
- function augmentNpmGlobalBin(os62) {
18917
+ function augmentNpmGlobalBin(os63) {
18839
18918
  try {
18840
- const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os62), ["prefix", "-g"], {
18919
+ const result = (0, import_node_child_process4.spawnSync)(resolveNpm(os63), ["prefix", "-g"], {
18841
18920
  stdio: ["ignore", "pipe", "ignore"]
18842
18921
  });
18843
18922
  if (result.status !== 0) return;
18844
18923
  const prefix = result.stdout.toString().trim();
18845
18924
  if (!prefix) return;
18846
- const binDir = os62.id === "win32" ? prefix : path24.join(prefix, "bin");
18847
- os62.augmentPath([binDir]);
18925
+ const binDir = os63.id === "win32" ? prefix : path24.join(prefix, "bin");
18926
+ os63.augmentPath([binDir]);
18848
18927
  } catch {
18849
18928
  }
18850
18929
  }
@@ -19038,10 +19117,10 @@ function manualInstallHint(runner, tools) {
19038
19117
  const argv = osPackageInstallArgv(detectPackageManager(runner), [...tools]);
19039
19118
  return argv ? `\`sudo ${argv.join(" ")}\`` : `your package manager (e.g. \`${pkgs}\`)`;
19040
19119
  }
19041
- function writeUnzipShim(os62, runner) {
19120
+ function writeUnzipShim(os63, runner) {
19042
19121
  const python = ["python3", "python"].find((p2) => runner.which(p2));
19043
19122
  if (!python) return null;
19044
- const dir = os62.scratchPath("codeam-cr-prereq");
19123
+ const dir = os63.scratchPath("codeam-cr-prereq");
19045
19124
  const shim = path26.join(dir, "unzip");
19046
19125
  const script = `#!/bin/sh
19047
19126
  set -e
@@ -19063,9 +19142,9 @@ exec ${python} -m zipfile -e "$archive" "$dest"
19063
19142
  (0, import_node_fs5.chmodSync)(shim, 448);
19064
19143
  return dir;
19065
19144
  }
19066
- async function ensureInstallPrerequisites(os62, deps = {}) {
19145
+ async function ensureInstallPrerequisites(os63, deps = {}) {
19067
19146
  const runner = deps.runner ?? defaultOsRunner;
19068
- const missing = REQUIRED_TOOLS.filter((t2) => os62.findInPath(t2) === null);
19147
+ const missing = REQUIRED_TOOLS.filter((t2) => os63.findInPath(t2) === null);
19069
19148
  if (missing.length === 0) return { ok: true, extraPath: [] };
19070
19149
  log.info(
19071
19150
  "coderabbit",
@@ -19084,10 +19163,10 @@ async function ensureInstallPrerequisites(os62, deps = {}) {
19084
19163
  );
19085
19164
  }
19086
19165
  }
19087
- const stillMissing = REQUIRED_TOOLS.filter((t2) => os62.findInPath(t2) === null);
19166
+ const stillMissing = REQUIRED_TOOLS.filter((t2) => os63.findInPath(t2) === null);
19088
19167
  if (stillMissing.length === 0) return { ok: true, extraPath: [] };
19089
19168
  if (stillMissing.length === 1 && stillMissing[0] === "unzip") {
19090
- const shimDir = writeUnzipShim(os62, runner);
19169
+ const shimDir = writeUnzipShim(os63, runner);
19091
19170
  if (shimDir) {
19092
19171
  log.info("coderabbit", "unzip is unavailable \u2014 using a scoped python zipfile shim");
19093
19172
  return { ok: true, extraPath: [shimDir] };
@@ -19150,15 +19229,15 @@ function summarizeInstallFailure(output) {
19150
19229
  }
19151
19230
  return lines.length > 0 ? lines[lines.length - 1] : null;
19152
19231
  }
19153
- async function ensureCoderabbitInstalled(os62, deps = {}) {
19154
- if (os62.findInPath("coderabbit")) return { ok: true };
19155
- if (os62.id === "win32") {
19232
+ async function ensureCoderabbitInstalled(os63, deps = {}) {
19233
+ if (os63.findInPath("coderabbit")) return { ok: true };
19234
+ if (os63.id === "win32") {
19156
19235
  return {
19157
19236
  ok: false,
19158
19237
  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."
19159
19238
  };
19160
19239
  }
19161
- const prereq = await ensureInstallPrerequisites(os62, deps);
19240
+ const prereq = await ensureInstallPrerequisites(os63, deps);
19162
19241
  if (!prereq.ok) return { ok: false, error: prereq.error };
19163
19242
  const env = { ...process.env };
19164
19243
  if (prereq.extraPath.length > 0) {
@@ -19167,8 +19246,8 @@ async function ensureCoderabbitInstalled(os62, deps = {}) {
19167
19246
  log.info("coderabbit", "CodeRabbit CLI not found \u2014 installing via the official script");
19168
19247
  const run = deps.runInstallScript ?? defaultRunInstallScript;
19169
19248
  const { code, output } = await run(env);
19170
- os62.augmentPath([`${os62.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
19171
- const binary = os62.findInPath("coderabbit");
19249
+ os63.augmentPath([`${os63.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
19250
+ const binary = os63.findInPath("coderabbit");
19172
19251
  const detail = summarizeInstallFailure(output);
19173
19252
  if (binary !== null) {
19174
19253
  if (code === 0) return { ok: true };
@@ -19222,10 +19301,10 @@ function coderabbitCredentialLocator() {
19222
19301
  validate: validateNonEmptyCredential
19223
19302
  };
19224
19303
  }
19225
- function coderabbitLoginLauncher(os62) {
19304
+ function coderabbitLoginLauncher(os63) {
19226
19305
  return {
19227
19306
  async ensureInstalled() {
19228
- const result = await ensureCoderabbitInstalled(os62);
19307
+ const result = await ensureCoderabbitInstalled(os63);
19229
19308
  if (!result.ok && result.error) console.error(`
19230
19309
  \u2717 ${result.error}
19231
19310
  `);
@@ -19285,8 +19364,8 @@ function pickLine(obj) {
19285
19364
  function toHunk(raw, groupSeverity) {
19286
19365
  if (!raw || typeof raw !== "object") return null;
19287
19366
  const o = raw;
19288
- const path91 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
19289
- if (!path91) return null;
19367
+ const path92 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
19368
+ if (!path92) return null;
19290
19369
  const message = asString(
19291
19370
  pick(o, [
19292
19371
  "comment",
@@ -19303,7 +19382,7 @@ function toHunk(raw, groupSeverity) {
19303
19382
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
19304
19383
  const locObj = pick(o, ["location"]) ?? o;
19305
19384
  return {
19306
- path: path91.trim(),
19385
+ path: path92.trim(),
19307
19386
  line: pickLine(o) ?? pickLine(locObj),
19308
19387
  severity,
19309
19388
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -19386,10 +19465,10 @@ function parsePlain(stdout) {
19386
19465
  for (const line of stdout.split(/\r?\n/)) {
19387
19466
  const m = line.match(HUNK_LINE_RE);
19388
19467
  if (!m) continue;
19389
- const [, path91, lineNo, sevToken, message] = m;
19390
- if (!path91 || !lineNo || !message) continue;
19468
+ const [, path92, lineNo, sevToken, message] = m;
19469
+ if (!path92 || !lineNo || !message) continue;
19391
19470
  hunks.push({
19392
- path: path91.trim(),
19471
+ path: path92.trim(),
19393
19472
  line: Number(lineNo),
19394
19473
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
19395
19474
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -19449,8 +19528,8 @@ var CoderabbitRuntimeStrategy = class {
19449
19528
  meta = getAgent("coderabbit");
19450
19529
  mode = "batch";
19451
19530
  os;
19452
- constructor(os62) {
19453
- this.os = os62;
19531
+ constructor(os63) {
19532
+ this.os = os63;
19454
19533
  }
19455
19534
  getDefaultArgs() {
19456
19535
  return ["review", "--agent"];
@@ -19721,10 +19800,10 @@ function cursorCredentialLocator() {
19721
19800
  validate: validateNonEmptyCredential
19722
19801
  };
19723
19802
  }
19724
- function cursorLoginLauncher(os62) {
19803
+ function cursorLoginLauncher(os63) {
19725
19804
  return {
19726
19805
  async ensureInstalled() {
19727
- if (os62.findInPath("cursor-agent")) return true;
19806
+ if (os63.findInPath("cursor-agent")) return true;
19728
19807
  console.error(
19729
19808
  "\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"
19730
19809
  );
@@ -19788,8 +19867,8 @@ var CursorRuntimeStrategy = class {
19788
19867
  meta = getAgent("cursor");
19789
19868
  mode = "interactive";
19790
19869
  os;
19791
- constructor(os62) {
19792
- this.os = os62;
19870
+ constructor(os63) {
19871
+ this.os = os63;
19793
19872
  }
19794
19873
  async prepareLaunch() {
19795
19874
  const binary = this.os.findInPath("cursor-agent");
@@ -20005,10 +20084,10 @@ function aiderCredentialLocator() {
20005
20084
  validate: validateNonEmptyCredential
20006
20085
  };
20007
20086
  }
20008
- function aiderLoginLauncher(os62) {
20087
+ function aiderLoginLauncher(os63) {
20009
20088
  return {
20010
20089
  async ensureInstalled() {
20011
- if (os62.findInPath("aider")) return true;
20090
+ if (os63.findInPath("aider")) return true;
20012
20091
  console.error(
20013
20092
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
20014
20093
  );
@@ -20018,7 +20097,7 @@ function aiderLoginLauncher(os62) {
20018
20097
  console.error(
20019
20098
  "\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"
20020
20099
  );
20021
- return (0, import_node_child_process11.spawn)(os62.id === "win32" ? "cmd.exe" : "sh", os62.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
20100
+ return (0, import_node_child_process11.spawn)(os63.id === "win32" ? "cmd.exe" : "sh", os63.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
20022
20101
  stdio: "ignore"
20023
20102
  });
20024
20103
  }
@@ -20293,8 +20372,8 @@ var AiderRuntimeStrategy = class {
20293
20372
  meta = getAgent("aider");
20294
20373
  mode = "interactive";
20295
20374
  os;
20296
- constructor(os62) {
20297
- this.os = os62;
20375
+ constructor(os63) {
20376
+ this.os = os63;
20298
20377
  }
20299
20378
  async prepareLaunch() {
20300
20379
  augmentUserLocalBinPaths();
@@ -20427,8 +20506,8 @@ function geminiCredentialLocator() {
20427
20506
  function geminiLoginLauncher() {
20428
20507
  return {
20429
20508
  async ensureInstalled() {
20430
- const os62 = createOsStrategy();
20431
- return os62.findInPath("gemini") !== null;
20509
+ const os63 = createOsStrategy();
20510
+ return os63.findInPath("gemini") !== null;
20432
20511
  },
20433
20512
  launch() {
20434
20513
  return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -20618,8 +20697,8 @@ var GeminiRuntimeStrategy = class {
20618
20697
  meta = getAgent("gemini");
20619
20698
  mode = "interactive";
20620
20699
  os;
20621
- constructor(os62) {
20622
- this.os = os62;
20700
+ constructor(os63) {
20701
+ this.os = os63;
20623
20702
  }
20624
20703
  async prepareLaunch() {
20625
20704
  const binary = this.os.findInPath("gemini");
@@ -20910,8 +20989,8 @@ var KimiRuntimeStrategy = class {
20910
20989
  meta = getAgent("kimi");
20911
20990
  mode = "interactive";
20912
20991
  os;
20913
- constructor(os62) {
20914
- this.os = os62;
20992
+ constructor(os63) {
20993
+ this.os = os63;
20915
20994
  }
20916
20995
  async prepareLaunch() {
20917
20996
  const binary = this.os.findInPath("kimi");
@@ -21053,8 +21132,8 @@ var OpencodeRuntimeStrategy = class {
21053
21132
  meta = getAgent("opencode");
21054
21133
  mode = "interactive";
21055
21134
  os;
21056
- constructor(os62) {
21057
- this.os = os62;
21135
+ constructor(os63) {
21136
+ this.os = os63;
21058
21137
  }
21059
21138
  async prepareLaunch() {
21060
21139
  const binary = this.os.findInPath("opencode");
@@ -21138,20 +21217,20 @@ var OpencodeRuntimeStrategy = class {
21138
21217
 
21139
21218
  // src/agents/registry.ts
21140
21219
  var runtimeBuilders = {
21141
- claude: (os62) => new ClaudeRuntimeStrategy(os62),
21142
- codex: (os62) => new CodexRuntimeStrategy(os62),
21143
- coderabbit: (os62) => new CoderabbitRuntimeStrategy(os62),
21144
- cursor: (os62) => new CursorRuntimeStrategy(os62),
21145
- aider: (os62) => new AiderRuntimeStrategy(os62),
21146
- gemini: (os62) => new GeminiRuntimeStrategy(os62),
21147
- kimi: (os62) => new KimiRuntimeStrategy(os62),
21148
- opencode: (os62) => new OpencodeRuntimeStrategy(os62)
21220
+ claude: (os63) => new ClaudeRuntimeStrategy(os63),
21221
+ codex: (os63) => new CodexRuntimeStrategy(os63),
21222
+ coderabbit: (os63) => new CoderabbitRuntimeStrategy(os63),
21223
+ cursor: (os63) => new CursorRuntimeStrategy(os63),
21224
+ aider: (os63) => new AiderRuntimeStrategy(os63),
21225
+ gemini: (os63) => new GeminiRuntimeStrategy(os63),
21226
+ kimi: (os63) => new KimiRuntimeStrategy(os63),
21227
+ opencode: (os63) => new OpencodeRuntimeStrategy(os63)
21149
21228
  };
21150
21229
  var deployBuilders = {
21151
21230
  claude: () => new ClaudeDeployStrategy(),
21152
21231
  codex: () => new CodexDeployStrategy()
21153
21232
  };
21154
- function createAgentStrategy(agent, os62 = createOsStrategy()) {
21233
+ function createAgentStrategy(agent, os63 = createOsStrategy()) {
21155
21234
  if (!AGENT_REGISTRY[agent]?.enabled) {
21156
21235
  throw new Error(
21157
21236
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -21161,10 +21240,10 @@ function createAgentStrategy(agent, os62 = createOsStrategy()) {
21161
21240
  if (!build) {
21162
21241
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
21163
21242
  }
21164
- return build(os62);
21243
+ return build(os63);
21165
21244
  }
21166
- function createInteractiveAgentStrategy(agent, os62 = createOsStrategy()) {
21167
- const s = createAgentStrategy(agent, os62);
21245
+ function createInteractiveAgentStrategy(agent, os63 = createOsStrategy()) {
21246
+ const s = createAgentStrategy(agent, os63);
21168
21247
  if (s.mode !== "interactive") {
21169
21248
  throw new Error(
21170
21249
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -21874,8 +21953,8 @@ function collectChangedFiles(cwd) {
21874
21953
  }
21875
21954
  return [...byPath.values()];
21876
21955
  }
21877
- function restoreCoderabbitOauthBlob(os62, value) {
21878
- const dir = path38.join(os62.homeDir(), ".coderabbit");
21956
+ function restoreCoderabbitOauthBlob(os63, value) {
21957
+ const dir = path38.join(os63.homeDir(), ".coderabbit");
21879
21958
  (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
21880
21959
  let file = "auth.json";
21881
21960
  let contents = value.trim();
@@ -21895,26 +21974,26 @@ function installFailureMessage(result) {
21895
21974
  return result.error ?? "CodeRabbit CLI could not be installed";
21896
21975
  }
21897
21976
  async function configureCoderabbit(input, deps = {}) {
21898
- const os62 = deps.os ?? createOsStrategy();
21977
+ const os63 = deps.os ?? createOsStrategy();
21899
21978
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
21900
21979
  const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
21901
21980
  const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
21902
21981
  const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
21903
21982
  const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
21904
21983
  const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
21905
- const home = os62.homeDir();
21906
- os62.augmentPath(
21907
- os62.id === "win32" ? [
21984
+ const home = os63.homeDir();
21985
+ os63.augmentPath(
21986
+ os63.id === "win32" ? [
21908
21987
  path38.join(home, ".local", "bin"),
21909
21988
  path38.join(process.env.APPDATA ?? path38.join(home, "AppData", "Roaming"), "npm"),
21910
21989
  path38.join(home, "scoop", "shims")
21911
21990
  ] : [path38.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
21912
21991
  );
21913
- const installed2 = os62.findInPath("coderabbit") !== null;
21992
+ const installed2 = os63.findInPath("coderabbit") !== null;
21914
21993
  const base = () => ({
21915
21994
  action: input.action,
21916
21995
  supported: true,
21917
- installed: os62.findInPath("coderabbit") !== null,
21996
+ installed: os63.findInPath("coderabbit") !== null,
21918
21997
  loggedIn: false
21919
21998
  });
21920
21999
  if (input.action === "status") {
@@ -21928,7 +22007,7 @@ async function configureCoderabbit(input, deps = {}) {
21928
22007
  const key = (input.apiKey ?? "").trim();
21929
22008
  if (!key) return { ...res2, error: "No API key provided" };
21930
22009
  if (!res2.installed) {
21931
- const inst = await ensureInstalled(os62);
22010
+ const inst = await ensureInstalled(os63);
21932
22011
  res2.installed = inst.ok;
21933
22012
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
21934
22013
  }
@@ -21952,7 +22031,7 @@ async function configureCoderabbit(input, deps = {}) {
21952
22031
  }
21953
22032
  if (!res2.installed) {
21954
22033
  deps.onEvent?.({ kind: "installing" });
21955
- const inst = await ensureInstalled(os62);
22034
+ const inst = await ensureInstalled(os63);
21956
22035
  res2.installed = inst.ok;
21957
22036
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
21958
22037
  }
@@ -21969,7 +22048,7 @@ async function configureCoderabbit(input, deps = {}) {
21969
22048
  return { ...res2, loggedIn: true, linked: true };
21970
22049
  }
21971
22050
  try {
21972
- restoreCoderabbitOauthBlob(os62, cred.credential);
22051
+ restoreCoderabbitOauthBlob(os63, cred.credential);
21973
22052
  } catch (err) {
21974
22053
  return {
21975
22054
  ...res2,
@@ -21993,7 +22072,7 @@ async function configureCoderabbit(input, deps = {}) {
21993
22072
  const res2 = base();
21994
22073
  if (!installed2) {
21995
22074
  deps.onEvent?.({ kind: "installing" });
21996
- const inst = await ensureInstalled(os62);
22075
+ const inst = await ensureInstalled(os63);
21997
22076
  res2.installed = inst.ok;
21998
22077
  if (!inst.ok) return { ...res2, error: installFailureMessage(inst) };
21999
22078
  }
@@ -22033,7 +22112,7 @@ async function configureCoderabbit(input, deps = {}) {
22033
22112
  }
22034
22113
  const res = base();
22035
22114
  if (!res.installed) {
22036
- const inst = await ensureInstalled(os62);
22115
+ const inst = await ensureInstalled(os63);
22037
22116
  res.installed = inst.ok;
22038
22117
  if (!inst.ok) return { ...res, error: installFailureMessage(inst) };
22039
22118
  }
@@ -25062,11 +25141,11 @@ function resolveDoltInstallStrategy(platform3) {
25062
25141
  }
25063
25142
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
25064
25143
  function doltPlatformTuple(platform3, arch2) {
25065
- const os62 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25144
+ const os63 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
25066
25145
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
25067
25146
  if (!a) return null;
25068
- if (os62 === "windows" && a !== "amd64") return null;
25069
- return `${os62}-${a}`;
25147
+ if (os63 === "windows" && a !== "amd64") return null;
25148
+ return `${os63}-${a}`;
25070
25149
  }
25071
25150
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
25072
25151
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -26728,7 +26807,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
26728
26807
  });
26729
26808
  const token = ctx.pluginAuthToken;
26730
26809
  void (async () => {
26731
- const os62 = createOsStrategy();
26810
+ const os63 = createOsStrategy();
26732
26811
  try {
26733
26812
  const report = await reviewPullRequest(
26734
26813
  {
@@ -26737,7 +26816,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
26737
26816
  baseBranch: parsed.baseBranch
26738
26817
  },
26739
26818
  {
26740
- runReview: (input) => new CoderabbitRuntimeStrategy(os62).runOneShot(input),
26819
+ runReview: (input) => new CoderabbitRuntimeStrategy(os63).runOneShot(input),
26741
26820
  runGh: (args2) => defaultRunGh(args2),
26742
26821
  postReport: async (r) => {
26743
26822
  if (!token) return;
@@ -27872,11 +27951,11 @@ function resolveTokenValue(args2) {
27872
27951
  }
27873
27952
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
27874
27953
  if (fileFlag) {
27875
- const path91 = fileFlag.slice("--token-file=".length);
27954
+ const path92 = fileFlag.slice("--token-file=".length);
27876
27955
  try {
27877
- const content = fs51.readFileSync(path91, "utf8").trim();
27878
- if (content.length === 0) fail(`--token-file ${path91} is empty`);
27879
- rmIfExistsQuiet(path91);
27956
+ const content = fs51.readFileSync(path92, "utf8").trim();
27957
+ if (content.length === 0) fail(`--token-file ${path92} is empty`);
27958
+ rmIfExistsQuiet(path92);
27880
27959
  return content;
27881
27960
  } catch (err) {
27882
27961
  fail(`Could not read --token-file: ${err.message}`);
@@ -31218,14 +31297,14 @@ var zGuardCreateElicitationResponseCancel = z7.object({
31218
31297
 
31219
31298
  // ../../node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js
31220
31299
  var CANCEL_REQUEST_METHOD = "$/cancel_request";
31221
- function isRecord2(value) {
31300
+ function isRecord3(value) {
31222
31301
  return typeof value === "object" && value !== null;
31223
31302
  }
31224
31303
  function isJsonRpcId(value) {
31225
31304
  return value === null || typeof value === "string" || typeof value === "number" && Number.isFinite(value);
31226
31305
  }
31227
31306
  function cancelRequestId(params) {
31228
- if (!isRecord2(params) || !isJsonRpcId(params["requestId"])) {
31307
+ if (!isRecord3(params) || !isJsonRpcId(params["requestId"])) {
31229
31308
  return void 0;
31230
31309
  }
31231
31310
  return params["requestId"];
@@ -31657,7 +31736,7 @@ var Connection = class {
31657
31736
  if (this.abortController.signal.aborted) {
31658
31737
  return;
31659
31738
  }
31660
- if (!isRecord2(message)) {
31739
+ if (!isRecord3(message)) {
31661
31740
  console.error("Invalid message", { message });
31662
31741
  return;
31663
31742
  }
@@ -31750,7 +31829,7 @@ var Connection = class {
31750
31829
  pendingResponse.cleanup?.();
31751
31830
  if ("result" in response) {
31752
31831
  pendingResponse.resolve(response.result);
31753
- } else if ("error" in response && isRecord2(response.error)) {
31832
+ } else if ("error" in response && isRecord3(response.error)) {
31754
31833
  const { code, message, data } = response.error;
31755
31834
  pendingResponse.reject(new RequestError(code, message, data));
31756
31835
  } else {
@@ -32023,7 +32102,7 @@ function ndJsonStream(output, input) {
32023
32102
  if (trimmedLine) {
32024
32103
  try {
32025
32104
  const message = JSON.parse(trimmedLine);
32026
- if (isRecord2(message)) {
32105
+ if (isRecord3(message)) {
32027
32106
  controller.enqueue(message);
32028
32107
  } else {
32029
32108
  console.warn("Skipping JSON line that is not an object:", trimmedLine);
@@ -36583,7 +36662,7 @@ function defaultRunGit(cwd, args2) {
36583
36662
  });
36584
36663
  }
36585
36664
  async function discoverRepos(workingDir, maxDepth = 4) {
36586
- const fs77 = await import("fs/promises");
36665
+ const fs78 = await import("fs/promises");
36587
36666
  const out2 = [];
36588
36667
  await walk(workingDir, 0);
36589
36668
  return out2;
@@ -36591,7 +36670,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
36591
36670
  if (depth > maxDepth) return;
36592
36671
  let entries = [];
36593
36672
  try {
36594
- const dirents = await fs77.readdir(dir, { withFileTypes: true });
36673
+ const dirents = await fs78.readdir(dir, { withFileTypes: true });
36595
36674
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
36596
36675
  } catch {
36597
36676
  return;
@@ -40600,6 +40679,7 @@ async function runAcpSession(opts) {
40600
40679
  };
40601
40680
  process.once("SIGINT", () => void shutdown("SIGINT"));
40602
40681
  process.once("SIGTERM", () => void shutdown("SIGTERM"));
40682
+ relay.setOnSessionGone(() => void shutdown("SIGTERM"));
40603
40683
  process.once("SIGHUP", () => void shutdown("SIGHUP"));
40604
40684
  await new Promise(() => {
40605
40685
  });
@@ -41750,6 +41830,74 @@ ${BEADS_HINT}
41750
41830
  }
41751
41831
  }
41752
41832
 
41833
+ // src/agents/retired-proxy-cleanup.ts
41834
+ var fs68 = __toESM(require("fs"));
41835
+ var path78 = __toESM(require("path"));
41836
+ var os53 = __toESM(require("os"));
41837
+ var RETIRED_PROXY_RE = /^https?:\/\/(?:127\.0\.0\.1|localhost|\[::1\]):8787(?:[/?#]|$)/i;
41838
+ var HEADROOM_CMD_RE = /(^|[\s/"'])headroom(\s|$)/i;
41839
+ var MARKETPLACE_KEY = "headroom-marketplace";
41840
+ function isHeadroomHook(group) {
41841
+ return (group.hooks ?? []).some(
41842
+ (h) => typeof h?.command === "string" && HEADROOM_CMD_RE.test(h.command)
41843
+ );
41844
+ }
41845
+ function sanitizeRetiredProxyConfig(homeDir2 = os53.homedir()) {
41846
+ const out2 = { inspected: false, changed: false, removed: [] };
41847
+ const file = path78.join(homeDir2, ".claude", "settings.json");
41848
+ let parsed;
41849
+ try {
41850
+ parsed = JSON.parse(fs68.readFileSync(file, "utf8"));
41851
+ } catch {
41852
+ return out2;
41853
+ }
41854
+ if (!parsed || typeof parsed !== "object") return out2;
41855
+ out2.inspected = true;
41856
+ const env = parsed.env;
41857
+ if (env && typeof env === "object") {
41858
+ const envRec = env;
41859
+ const base = envRec.ANTHROPIC_BASE_URL;
41860
+ if (typeof base === "string" && RETIRED_PROXY_RE.test(base.trim())) {
41861
+ delete envRec.ANTHROPIC_BASE_URL;
41862
+ out2.removed.push("env.ANTHROPIC_BASE_URL");
41863
+ out2.changed = true;
41864
+ if (Object.keys(envRec).length === 0) delete parsed.env;
41865
+ }
41866
+ }
41867
+ const mkts = parsed.extraKnownMarketplaces;
41868
+ if (mkts && typeof mkts === "object" && MARKETPLACE_KEY in mkts) {
41869
+ delete mkts[MARKETPLACE_KEY];
41870
+ out2.removed.push(`extraKnownMarketplaces.${MARKETPLACE_KEY}`);
41871
+ out2.changed = true;
41872
+ if (Object.keys(mkts).length === 0) delete parsed.extraKnownMarketplaces;
41873
+ }
41874
+ const hooks = parsed.hooks;
41875
+ if (hooks && typeof hooks === "object") {
41876
+ const hookRec = hooks;
41877
+ for (const [event, groups] of Object.entries(hookRec)) {
41878
+ if (!Array.isArray(groups)) continue;
41879
+ const kept = groups.filter((g) => !isHeadroomHook(g));
41880
+ if (kept.length !== groups.length) {
41881
+ out2.removed.push(`hooks.${event}`);
41882
+ out2.changed = true;
41883
+ if (kept.length) hookRec[event] = kept;
41884
+ else delete hookRec[event];
41885
+ }
41886
+ }
41887
+ if (Object.keys(hookRec).length === 0) delete parsed.hooks;
41888
+ }
41889
+ if (!out2.changed) return out2;
41890
+ try {
41891
+ const tmp = `${file}.codeam.tmp`;
41892
+ fs68.writeFileSync(tmp, `${JSON.stringify(parsed, null, 2)}
41893
+ `, { mode: 384 });
41894
+ fs68.renameSync(tmp, file);
41895
+ } catch {
41896
+ out2.changed = false;
41897
+ }
41898
+ return out2;
41899
+ }
41900
+
41753
41901
  // src/integrations/refresh-manifest.ts
41754
41902
  function fingerprint(m) {
41755
41903
  const norm = [...m.integrations].map((e) => ({ id: e.id, delivery: e.delivery })).sort((a, b) => a.id.localeCompare(b.id));
@@ -42275,7 +42423,7 @@ var AcpDriver = class {
42275
42423
  };
42276
42424
 
42277
42425
  // src/baton/transcript-mirror.ts
42278
- var fs68 = __toESM(require("fs"));
42426
+ var fs69 = __toESM(require("fs"));
42279
42427
  var TranscriptMirror = class {
42280
42428
  constructor(deps) {
42281
42429
  this.deps = deps;
@@ -42369,7 +42517,7 @@ var TranscriptMirror = class {
42369
42517
  }
42370
42518
  };
42371
42519
  function defaultWatch(file, onChange) {
42372
- const w3 = fs68.watch(file, { persistent: false }, () => onChange());
42520
+ const w3 = fs69.watch(file, { persistent: false }, () => onChange());
42373
42521
  return () => w3.close();
42374
42522
  }
42375
42523
 
@@ -42662,6 +42810,7 @@ async function runBatonSession(opts) {
42662
42810
  process.once("SIGINT", onSignal);
42663
42811
  process.once("SIGTERM", onSignal);
42664
42812
  process.once("SIGHUP", onSignal);
42813
+ relay.setOnSessionGone(onSignal);
42665
42814
  showInfo(`Starting ${opts.agent} baton (local) \u2014 native TUI + mobile take-control\u2026`);
42666
42815
  await controller.begin();
42667
42816
  relay.start();
@@ -42714,16 +42863,16 @@ function keepDeviceAwake(deps = {}) {
42714
42863
  }
42715
42864
 
42716
42865
  // src/agents/claude/onboarding.ts
42717
- var fs69 = __toESM(require("fs"));
42718
- var os54 = __toESM(require("os"));
42719
- var path78 = __toESM(require("path"));
42866
+ var fs70 = __toESM(require("fs"));
42867
+ var os55 = __toESM(require("os"));
42868
+ var path79 = __toESM(require("path"));
42720
42869
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
42721
42870
  function ensureClaudeOnboarded(cwd) {
42722
42871
  try {
42723
- const file = path78.join(os54.homedir(), ".claude.json");
42872
+ const file = path79.join(os55.homedir(), ".claude.json");
42724
42873
  let config = {};
42725
42874
  try {
42726
- config = JSON.parse(fs69.readFileSync(file, "utf8"));
42875
+ config = JSON.parse(fs70.readFileSync(file, "utf8"));
42727
42876
  } catch {
42728
42877
  }
42729
42878
  let changed = false;
@@ -42748,8 +42897,8 @@ function ensureClaudeOnboarded(cwd) {
42748
42897
  }
42749
42898
  }
42750
42899
  if (!changed) return;
42751
- fs69.mkdirSync(path78.dirname(file), { recursive: true });
42752
- fs69.writeFileSync(file, JSON.stringify(config, null, 2));
42900
+ fs70.mkdirSync(path79.dirname(file), { recursive: true });
42901
+ fs70.writeFileSync(file, JSON.stringify(config, null, 2));
42753
42902
  log.info(
42754
42903
  "claude",
42755
42904
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -42838,6 +42987,12 @@ async function start(requestedAgent, presetSession) {
42838
42987
  if (!isLocalSession() && session.agent === "claude") {
42839
42988
  ensureAgentStandard();
42840
42989
  }
42990
+ if (!isLocalSession()) {
42991
+ const cleaned = sanitizeRetiredProxyConfig();
42992
+ if (cleaned.changed) {
42993
+ log.info("claude", `removed retired Headroom config: ${cleaned.removed.join(", ")}`);
42994
+ }
42995
+ }
42841
42996
  const beadsReady = provisionBeadsForStart({
42842
42997
  sessionId: session.id,
42843
42998
  pluginId,
@@ -43096,6 +43251,9 @@ async function start(requestedAgent, presetSession) {
43096
43251
  })
43097
43252
  );
43098
43253
  ctx.relay = relay;
43254
+ relay.setOnSessionGone(() => {
43255
+ void sigintHandler();
43256
+ });
43099
43257
  void beadsReady.then((started) => {
43100
43258
  ctx.beads = started;
43101
43259
  });
@@ -43495,7 +43653,7 @@ var import_picocolors10 = __toESM(require("picocolors"));
43495
43653
  var import_child_process30 = require("child_process");
43496
43654
  var import_util4 = require("util");
43497
43655
  var import_picocolors8 = __toESM(require("picocolors"));
43498
- var path79 = __toESM(require("path"));
43656
+ var path80 = __toESM(require("path"));
43499
43657
  var execFileP5 = (0, import_util4.promisify)(import_child_process30.execFile);
43500
43658
  var MAX_BUFFER = 8 * 1024 * 1024;
43501
43659
  function resetStdinForChild() {
@@ -43984,7 +44142,7 @@ var GitHubCodespacesProvider = class {
43984
44142
  });
43985
44143
  }
43986
44144
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
43987
- const remoteDir = path79.posix.dirname(remotePath);
44145
+ const remoteDir = path80.posix.dirname(remotePath);
43988
44146
  const parts = [
43989
44147
  `mkdir -p ${shellQuote(remoteDir)}`,
43990
44148
  `cat > ${shellQuote(remotePath)}`
@@ -44054,7 +44212,7 @@ function shellQuote(s) {
44054
44212
  // src/services/providers/gitpod.ts
44055
44213
  var import_child_process31 = require("child_process");
44056
44214
  var import_util5 = require("util");
44057
- var path80 = __toESM(require("path"));
44215
+ var path81 = __toESM(require("path"));
44058
44216
  var import_picocolors9 = __toESM(require("picocolors"));
44059
44217
  var execFileP6 = (0, import_util5.promisify)(import_child_process31.execFile);
44060
44218
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -44294,7 +44452,7 @@ var GitpodProvider = class {
44294
44452
  });
44295
44453
  }
44296
44454
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
44297
- const remoteDir = path80.posix.dirname(remotePath);
44455
+ const remoteDir = path81.posix.dirname(remotePath);
44298
44456
  const parts = [
44299
44457
  `mkdir -p ${shellQuote2(remoteDir)}`,
44300
44458
  `cat > ${shellQuote2(remotePath)}`
@@ -44330,7 +44488,7 @@ function shellQuote2(s) {
44330
44488
  // src/services/providers/gitlab-workspaces.ts
44331
44489
  var import_child_process32 = require("child_process");
44332
44490
  var import_util6 = require("util");
44333
- var path81 = __toESM(require("path"));
44491
+ var path82 = __toESM(require("path"));
44334
44492
  var execFileP7 = (0, import_util6.promisify)(import_child_process32.execFile);
44335
44493
  var MAX_BUFFER3 = 8 * 1024 * 1024;
44336
44494
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -44590,7 +44748,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
44590
44748
  }
44591
44749
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
44592
44750
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
44593
- const remoteDir = path81.posix.dirname(remotePath);
44751
+ const remoteDir = path82.posix.dirname(remotePath);
44594
44752
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
44595
44753
  if (options.mode != null) {
44596
44754
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -44658,7 +44816,7 @@ function shellQuote3(s) {
44658
44816
  // src/services/providers/railway.ts
44659
44817
  var import_child_process33 = require("child_process");
44660
44818
  var import_util7 = require("util");
44661
- var path82 = __toESM(require("path"));
44819
+ var path83 = __toESM(require("path"));
44662
44820
  var execFileP8 = (0, import_util7.promisify)(import_child_process33.execFile);
44663
44821
  var MAX_BUFFER4 = 8 * 1024 * 1024;
44664
44822
  function resetStdinForChild4() {
@@ -44894,7 +45052,7 @@ var RailwayProvider = class {
44894
45052
  if (!projectId || !serviceId) {
44895
45053
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
44896
45054
  }
44897
- const remoteDir = path82.posix.dirname(remotePath);
45055
+ const remoteDir = path83.posix.dirname(remotePath);
44898
45056
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
44899
45057
  if (options.mode != null) {
44900
45058
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -45434,14 +45592,14 @@ async function stopWorkspaceFromLocal(target) {
45434
45592
  }
45435
45593
 
45436
45594
  // src/commands/host/host-client.ts
45437
- var fs70 = __toESM(require("fs"));
45438
- var os55 = __toESM(require("os"));
45439
- var path83 = __toESM(require("path"));
45595
+ var fs71 = __toESM(require("fs"));
45596
+ var os56 = __toESM(require("os"));
45597
+ var path84 = __toESM(require("path"));
45440
45598
  var import_node_crypto11 = require("crypto");
45441
45599
  function sampleCpuTimes() {
45442
45600
  let idle = 0;
45443
45601
  let total = 0;
45444
- for (const cpu of os55.cpus()) {
45602
+ for (const cpu of os56.cpus()) {
45445
45603
  const t2 = cpu.times;
45446
45604
  idle += t2.idle;
45447
45605
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -45460,8 +45618,8 @@ var MetricsCollector = class {
45460
45618
  const prev = this.prevCpu;
45461
45619
  this.prevCpu = current2;
45462
45620
  if (!prev) {
45463
- const cores = os55.cpus().length || 1;
45464
- const proxy = os55.loadavg()[0] / cores * 100;
45621
+ const cores = os56.cpus().length || 1;
45622
+ const proxy = os56.loadavg()[0] / cores * 100;
45465
45623
  return Math.min(100, Math.max(0, Math.round(proxy)));
45466
45624
  }
45467
45625
  const idleDelta = current2.idle - prev.idle;
@@ -45474,8 +45632,8 @@ var MetricsCollector = class {
45474
45632
  collect() {
45475
45633
  return {
45476
45634
  cpuPct: this.cpuPct(),
45477
- ramUsedMb: Math.round((os55.totalmem() - os55.freemem()) / 1048576),
45478
- ramTotalMb: Math.round(os55.totalmem() / 1048576),
45635
+ ramUsedMb: Math.round((os56.totalmem() - os56.freemem()) / 1048576),
45636
+ ramTotalMb: Math.round(os56.totalmem() / 1048576),
45479
45637
  latencyMs: this.lastLatencyMs
45480
45638
  };
45481
45639
  }
@@ -45484,19 +45642,19 @@ function apiBase() {
45484
45642
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
45485
45643
  }
45486
45644
  function hostIdentityPath() {
45487
- return path83.join(os55.homedir(), ".codeam", "host-agent.json");
45645
+ return path84.join(os56.homedir(), ".codeam", "host-agent.json");
45488
45646
  }
45489
45647
  function collectOsInfo() {
45490
45648
  return {
45491
- distro: os55.platform(),
45492
- arch: os55.arch(),
45493
- kernel: os55.release(),
45649
+ distro: os56.platform(),
45650
+ arch: os56.arch(),
45651
+ kernel: os56.release(),
45494
45652
  nodeVersion: process.versions.node
45495
45653
  };
45496
45654
  }
45497
45655
  function loadHostIdentity() {
45498
45656
  try {
45499
- const raw = fs70.readFileSync(hostIdentityPath(), "utf8");
45657
+ const raw = fs71.readFileSync(hostIdentityPath(), "utf8");
45500
45658
  const parsed = JSON.parse(raw);
45501
45659
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
45502
45660
  const p2 = parsed;
@@ -45515,8 +45673,8 @@ function loadHostIdentity() {
45515
45673
  }
45516
45674
  function saveHostIdentity(identity) {
45517
45675
  const file = hostIdentityPath();
45518
- fs70.mkdirSync(path83.dirname(file), { recursive: true, mode: 448 });
45519
- fs70.writeFileSync(file, JSON.stringify(identity, null, 2), {
45676
+ fs71.mkdirSync(path84.dirname(file), { recursive: true, mode: 448 });
45677
+ fs71.writeFileSync(file, JSON.stringify(identity, null, 2), {
45520
45678
  encoding: "utf8",
45521
45679
  mode: 384
45522
45680
  });
@@ -45561,7 +45719,7 @@ function isTerminalEnrollError(err) {
45561
45719
  }
45562
45720
  function deleteHostIdentity() {
45563
45721
  try {
45564
- fs70.rmSync(hostIdentityPath(), { force: true });
45722
+ fs71.rmSync(hostIdentityPath(), { force: true });
45565
45723
  } catch {
45566
45724
  }
45567
45725
  }
@@ -45585,7 +45743,7 @@ async function postJson(pathname, body) {
45585
45743
  function resolveHostLabel(label) {
45586
45744
  const explicit = label?.trim();
45587
45745
  const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
45588
- const resolved = explicit || envLabel || os55.hostname();
45746
+ const resolved = explicit || envLabel || os56.hostname();
45589
45747
  return resolved.slice(0, 80);
45590
45748
  }
45591
45749
  async function redeemEnrollToken(token, label) {
@@ -45774,9 +45932,9 @@ async function host(args2) {
45774
45932
 
45775
45933
  // src/commands/host-agent.ts
45776
45934
  var import_node_child_process30 = require("child_process");
45777
- var os59 = __toESM(require("os"));
45778
- var fs74 = __toESM(require("fs"));
45779
- var path87 = __toESM(require("path"));
45935
+ var os60 = __toESM(require("os"));
45936
+ var fs75 = __toESM(require("fs"));
45937
+ var path88 = __toESM(require("path"));
45780
45938
 
45781
45939
  // src/skills/persist-from-payload.ts
45782
45940
  function persistOrClearSkillsFromPayload(skills) {
@@ -45785,25 +45943,25 @@ function persistOrClearSkillsFromPayload(skills) {
45785
45943
  }
45786
45944
 
45787
45945
  // src/commands/host/workspace.ts
45788
- var fs71 = __toESM(require("fs"));
45789
- var os56 = __toESM(require("os"));
45790
- var path84 = __toESM(require("path"));
45946
+ var fs72 = __toESM(require("fs"));
45947
+ var os57 = __toESM(require("os"));
45948
+ var path85 = __toESM(require("path"));
45791
45949
  var import_node_child_process25 = require("child_process");
45792
45950
  var import_node_util5 = require("util");
45793
45951
  var execFileP9 = (0, import_node_util5.promisify)(import_node_child_process25.execFile);
45794
45952
  function isAbsolutePathTarget(target) {
45795
- return path84.isAbsolute(target);
45953
+ return path85.isAbsolute(target);
45796
45954
  }
45797
45955
  function selfHostedWorkspaceRoot() {
45798
- return path84.join(os56.homedir(), ".codeam", "self-hosted");
45956
+ return path85.join(os57.homedir(), ".codeam", "self-hosted");
45799
45957
  }
45800
45958
  function deployIdFromWorkspace(cwd) {
45801
45959
  if (!cwd) return null;
45802
45960
  const root = selfHostedWorkspaceRoot();
45803
- const resolved = path84.resolve(cwd);
45804
- const rel = path84.relative(root, resolved);
45805
- if (!rel || rel.startsWith("..") || path84.isAbsolute(rel)) return null;
45806
- const parts = rel.split(path84.sep).filter(Boolean);
45961
+ const resolved = path85.resolve(cwd);
45962
+ const rel = path85.relative(root, resolved);
45963
+ if (!rel || rel.startsWith("..") || path85.isAbsolute(rel)) return null;
45964
+ const parts = rel.split(path85.sep).filter(Boolean);
45807
45965
  if (parts.length !== 1) return null;
45808
45966
  return parts[0];
45809
45967
  }
@@ -45875,15 +46033,15 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
45875
46033
  const isGitlab = provider === "gitlab";
45876
46034
  if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
45877
46035
  if (!cloneToken) return;
45878
- const credFile = path84.join(dest, ".git", "codeam-credentials");
46036
+ const credFile = path85.join(dest, ".git", "codeam-credentials");
45879
46037
  const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
45880
46038
  ` : `https://x-access-token:${cloneToken}@github.com
45881
46039
  `;
45882
- fs71.writeFileSync(credFile, credLine, { mode: 384 });
46040
+ fs72.writeFileSync(credFile, credLine, { mode: 384 });
45883
46041
  restrictToOwner(credFile);
45884
46042
  const env = nonInteractiveGitEnv();
45885
46043
  const git2 = (args2) => execFileP9("git", ["-C", dest, ...args2], { timeout: 3e4, env });
45886
- const credFilePosix = credFile.split(path84.sep).join("/");
46044
+ const credFilePosix = credFile.split(path85.sep).join("/");
45887
46045
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
45888
46046
  });
45889
46047
  await git2([
@@ -45916,17 +46074,17 @@ function maskToken(text, cloneToken) {
45916
46074
  }
45917
46075
  async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
45918
46076
  if (isAbsolutePathTarget(repoOrPath)) {
45919
- if (!fs71.existsSync(repoOrPath)) {
46077
+ if (!fs72.existsSync(repoOrPath)) {
45920
46078
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
45921
46079
  }
45922
46080
  return repoOrPath;
45923
46081
  }
45924
- const dest = path84.join(selfHostedWorkspaceRoot(), deployId);
45925
- if (fs71.existsSync(path84.join(dest, ".git"))) {
46082
+ const dest = path85.join(selfHostedWorkspaceRoot(), deployId);
46083
+ if (fs72.existsSync(path85.join(dest, ".git"))) {
45926
46084
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
45927
46085
  return dest;
45928
46086
  }
45929
- fs71.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
46087
+ fs72.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
45930
46088
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
45931
46089
  const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
45932
46090
  try {
@@ -45945,11 +46103,11 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
45945
46103
 
45946
46104
  // src/commands/host/git-tooling.ts
45947
46105
  var import_node_child_process26 = require("child_process");
45948
- var fs72 = __toESM(require("fs"));
45949
- var os57 = __toESM(require("os"));
45950
- var path85 = __toESM(require("path"));
46106
+ var fs73 = __toESM(require("fs"));
46107
+ var os58 = __toESM(require("os"));
46108
+ var path86 = __toESM(require("path"));
45951
46109
  function codeamBinDir() {
45952
- return process.env.CODEAM_BIN_DIR ?? path85.join(os57.homedir(), ".codeam", "bin");
46110
+ return process.env.CODEAM_BIN_DIR ?? path86.join(os58.homedir(), ".codeam", "bin");
45953
46111
  }
45954
46112
  var FALLBACK_GH_VERSION = "2.62.0";
45955
46113
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -45981,7 +46139,7 @@ async function download(url2, dest) {
45981
46139
  const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
45982
46140
  if (!res.ok || !res.body) return false;
45983
46141
  const buf = Buffer.from(await res.arrayBuffer());
45984
- fs72.writeFileSync(dest, buf);
46142
+ fs73.writeFileSync(dest, buf);
45985
46143
  return true;
45986
46144
  } catch {
45987
46145
  return false;
@@ -46004,8 +46162,8 @@ async function ensureGhCli(runner, token, deps = {}) {
46004
46162
  const version3 = await resolveVersionFn(token);
46005
46163
  const asset = `gh_${version3}_${osToken}_${arch2}`;
46006
46164
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
46007
- const tmpRoot = fs72.mkdtempSync(path85.join(os57.tmpdir(), "codeam-gh-"));
46008
- const archive = path85.join(tmpRoot, `${asset}.${ext}`);
46165
+ const tmpRoot = fs73.mkdtempSync(path86.join(os58.tmpdir(), "codeam-gh-"));
46166
+ const archive = path86.join(tmpRoot, `${asset}.${ext}`);
46009
46167
  if (!await downloadFn(url2, archive)) {
46010
46168
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
46011
46169
  return null;
@@ -46015,16 +46173,16 @@ async function ensureGhCli(runner, token, deps = {}) {
46015
46173
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
46016
46174
  return null;
46017
46175
  }
46018
- const extractedBin = path85.join(tmpRoot, asset, "bin", binaryName);
46019
- if (!fs72.existsSync(extractedBin)) {
46176
+ const extractedBin = path86.join(tmpRoot, asset, "bin", binaryName);
46177
+ if (!fs73.existsSync(extractedBin)) {
46020
46178
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
46021
46179
  return null;
46022
46180
  }
46023
46181
  const binDir = codeamBinDir();
46024
- fs72.mkdirSync(binDir, { recursive: true });
46025
- const target = path85.join(binDir, binaryName);
46026
- fs72.copyFileSync(extractedBin, target);
46027
- fs72.chmodSync(target, 493);
46182
+ fs73.mkdirSync(binDir, { recursive: true });
46183
+ const target = path86.join(binDir, binaryName);
46184
+ fs73.copyFileSync(extractedBin, target);
46185
+ fs73.chmodSync(target, 493);
46028
46186
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
46029
46187
  return target;
46030
46188
  } catch (e) {
@@ -46084,8 +46242,8 @@ async function ensureGlabCli(runner, deps = {}) {
46084
46242
  const version3 = await resolveLatestGlabVersion();
46085
46243
  const asset = `glab_${version3}_${osToken}_${arch2}`;
46086
46244
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
46087
- const tmpRoot = fs72.mkdtempSync(path85.join(os57.tmpdir(), "codeam-glab-"));
46088
- const archive = path85.join(tmpRoot, `${asset}.${ext}`);
46245
+ const tmpRoot = fs73.mkdtempSync(path86.join(os58.tmpdir(), "codeam-glab-"));
46246
+ const archive = path86.join(tmpRoot, `${asset}.${ext}`);
46089
46247
  if (!await downloadFn(url2, archive)) {
46090
46248
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
46091
46249
  return null;
@@ -46096,20 +46254,20 @@ async function ensureGlabCli(runner, deps = {}) {
46096
46254
  return null;
46097
46255
  }
46098
46256
  const candidates = [
46099
- path85.join(tmpRoot, "bin", binaryName),
46100
- path85.join(tmpRoot, asset, "bin", binaryName),
46101
- path85.join(tmpRoot, binaryName)
46257
+ path86.join(tmpRoot, "bin", binaryName),
46258
+ path86.join(tmpRoot, asset, "bin", binaryName),
46259
+ path86.join(tmpRoot, binaryName)
46102
46260
  ];
46103
- const extractedBin = candidates.find((c2) => fs72.existsSync(c2));
46261
+ const extractedBin = candidates.find((c2) => fs73.existsSync(c2));
46104
46262
  if (!extractedBin) {
46105
46263
  log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
46106
46264
  return null;
46107
46265
  }
46108
46266
  const binDir = codeamBinDir();
46109
- fs72.mkdirSync(binDir, { recursive: true });
46110
- const target = path85.join(binDir, binaryName);
46111
- fs72.copyFileSync(extractedBin, target);
46112
- fs72.chmodSync(target, 493);
46267
+ fs73.mkdirSync(binDir, { recursive: true });
46268
+ const target = path86.join(binDir, binaryName);
46269
+ fs73.copyFileSync(extractedBin, target);
46270
+ fs73.chmodSync(target, 493);
46113
46271
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
46114
46272
  return target;
46115
46273
  } catch (e) {
@@ -46191,9 +46349,9 @@ var defaultGitToolingRunner = {
46191
46349
  var import_node_child_process28 = require("child_process");
46192
46350
 
46193
46351
  // src/lib/updateNotifier.ts
46194
- var fs73 = __toESM(require("fs"));
46195
- var os58 = __toESM(require("os"));
46196
- var path86 = __toESM(require("path"));
46352
+ var fs74 = __toESM(require("fs"));
46353
+ var os59 = __toESM(require("os"));
46354
+ var path87 = __toESM(require("path"));
46197
46355
  var https8 = __toESM(require("https"));
46198
46356
  var import_node_child_process27 = require("child_process");
46199
46357
  var import_picocolors12 = __toESM(require("picocolors"));
@@ -46202,12 +46360,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
46202
46360
  var TTL_MS = 24 * 60 * 60 * 1e3;
46203
46361
  var REQUEST_TIMEOUT_MS = 1500;
46204
46362
  function cachePath() {
46205
- const dir = path86.join(os58.homedir(), ".codeam");
46206
- return path86.join(dir, "update-check.json");
46363
+ const dir = path87.join(os59.homedir(), ".codeam");
46364
+ return path87.join(dir, "update-check.json");
46207
46365
  }
46208
46366
  function readCache() {
46209
46367
  try {
46210
- const raw = fs73.readFileSync(cachePath(), "utf8");
46368
+ const raw = fs74.readFileSync(cachePath(), "utf8");
46211
46369
  const parsed = JSON.parse(raw);
46212
46370
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
46213
46371
  return parsed;
@@ -46218,10 +46376,10 @@ function readCache() {
46218
46376
  function writeCache(cache) {
46219
46377
  try {
46220
46378
  const file = cachePath();
46221
- fs73.mkdirSync(path86.dirname(file), { recursive: true });
46379
+ fs74.mkdirSync(path87.dirname(file), { recursive: true });
46222
46380
  const tmp = `${file}.${process.pid}.tmp`;
46223
- fs73.writeFileSync(tmp, JSON.stringify(cache));
46224
- fs73.renameSync(tmp, file);
46381
+ fs74.writeFileSync(tmp, JSON.stringify(cache));
46382
+ fs74.renameSync(tmp, file);
46225
46383
  } catch {
46226
46384
  }
46227
46385
  }
@@ -46295,8 +46453,8 @@ function isLinkedInstall() {
46295
46453
  timeout: 2e3
46296
46454
  }).trim();
46297
46455
  if (!root) return false;
46298
- const pkgPath = path86.join(root, PKG_NAME);
46299
- return fs73.lstatSync(pkgPath).isSymbolicLink();
46456
+ const pkgPath = path87.join(root, PKG_NAME);
46457
+ return fs74.lstatSync(pkgPath).isSymbolicLink();
46300
46458
  } catch {
46301
46459
  return false;
46302
46460
  }
@@ -46332,7 +46490,7 @@ function maybeAutoUpdate(currentVersion, latest) {
46332
46490
  return;
46333
46491
  }
46334
46492
  try {
46335
- fs73.unlinkSync(cachePath());
46493
+ fs74.unlinkSync(cachePath());
46336
46494
  } catch {
46337
46495
  }
46338
46496
  process.stderr.write(` ${import_picocolors12.default.green("\u2713")} Updated. Resuming session...
@@ -46348,7 +46506,7 @@ async function autoUpgradeBeforeCriticalCommand() {
46348
46506
  if (process.env.NODE_ENV === "test") return;
46349
46507
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
46350
46508
  if (process.env.CI) return;
46351
- const current2 = true ? "2.75.6" : null;
46509
+ const current2 = true ? "2.75.8" : null;
46352
46510
  if (!current2) return;
46353
46511
  const cache = readCache();
46354
46512
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -46365,7 +46523,7 @@ function checkForUpdates() {
46365
46523
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
46366
46524
  if (process.env.CI) return;
46367
46525
  if (!process.stdout.isTTY) return;
46368
- const current2 = true ? "2.75.6" : null;
46526
+ const current2 = true ? "2.75.8" : null;
46369
46527
  if (!current2) return;
46370
46528
  const cache = readCache();
46371
46529
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -46388,7 +46546,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
46388
46546
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
46389
46547
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
46390
46548
  function currentCliVersion() {
46391
- return true ? "2.75.6" : null;
46549
+ return true ? "2.75.8" : null;
46392
46550
  }
46393
46551
  async function installedVersion(deps) {
46394
46552
  const ls = await deps.run(
@@ -47085,13 +47243,13 @@ var HostAgentSupervisor = class {
47085
47243
  const relay = this.relay;
47086
47244
  if (!relay) return;
47087
47245
  const raw = cmd.payload?.path;
47088
- const target = typeof raw === "string" && raw.trim() ? path87.resolve(raw.trim()) : os59.homedir();
47246
+ const target = typeof raw === "string" && raw.trim() ? path88.resolve(raw.trim()) : os60.homedir();
47089
47247
  try {
47090
- const dirents = await fs74.promises.readdir(target, { withFileTypes: true });
47248
+ const dirents = await fs75.promises.readdir(target, { withFileTypes: true });
47091
47249
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
47092
47250
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
47093
47251
  );
47094
- const parent = path87.dirname(target);
47252
+ const parent = path88.dirname(target);
47095
47253
  await relay.sendResult(cmd.id, "completed", {
47096
47254
  path: target,
47097
47255
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -47438,14 +47596,14 @@ var HostAgentSupervisor = class {
47438
47596
  ...buildHouseProxyChildEnv({ baseUrl, token, openRouter: openRouter === true }),
47439
47597
  CODEAM_AUTO_TOKEN: payload.autoPairToken
47440
47598
  };
47441
- const houseConfigDir = path87.join(
47442
- os59.homedir(),
47599
+ const houseConfigDir = path88.join(
47600
+ os60.homedir(),
47443
47601
  ".codeam",
47444
47602
  "house-claude",
47445
47603
  payload.deployId
47446
47604
  );
47447
47605
  try {
47448
- fs74.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
47606
+ fs75.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
47449
47607
  } catch {
47450
47608
  }
47451
47609
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -47471,7 +47629,7 @@ var HostAgentSupervisor = class {
47471
47629
  report("installing", "installing agent CLI");
47472
47630
  await this.runAgentInstall(payload.agentInstallScript);
47473
47631
  }
47474
- const home = process.env.HOME || os59.homedir();
47632
+ const home = process.env.HOME || os60.homedir();
47475
47633
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
47476
47634
  if (payload.cloneToken) {
47477
47635
  try {
@@ -47479,13 +47637,13 @@ var HostAgentSupervisor = class {
47479
47637
  if ((payload.repoProvider ?? "github") === "gitlab") {
47480
47638
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
47481
47639
  if (glabCmd) {
47482
- childEnv.PATH = `${codeamBinDir()}${path87.delimiter}${childEnv.PATH}`;
47640
+ childEnv.PATH = `${codeamBinDir()}${path88.delimiter}${childEnv.PATH}`;
47483
47641
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
47484
47642
  }
47485
47643
  } else {
47486
47644
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
47487
47645
  if (ghCmd) {
47488
- childEnv.PATH = `${codeamBinDir()}${path87.delimiter}${childEnv.PATH}`;
47646
+ childEnv.PATH = `${codeamBinDir()}${path88.delimiter}${childEnv.PATH}`;
47489
47647
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
47490
47648
  }
47491
47649
  }
@@ -47513,9 +47671,9 @@ var HostAgentSupervisor = class {
47513
47671
  );
47514
47672
  if (!payload.suppressOnboardingWelcome) {
47515
47673
  try {
47516
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path87.join(os59.homedir(), ".claude");
47517
- const projectDir = path87.join(cfgDir, "projects", encodeCwd(cwd));
47518
- const hasPriorConversation = fs74.existsSync(projectDir) && fs74.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
47674
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path88.join(os60.homedir(), ".claude");
47675
+ const projectDir = path88.join(cfgDir, "projects", encodeCwd(cwd));
47676
+ const hasPriorConversation = fs75.existsSync(projectDir) && fs75.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
47519
47677
  if (hasPriorConversation) {
47520
47678
  childEnv.CODEAM_RESUME_LATEST = "1";
47521
47679
  log.info(
@@ -47608,7 +47766,7 @@ var HostAgentSupervisor = class {
47608
47766
  if (this.children.size > 0) return;
47609
47767
  const session = getActiveSession();
47610
47768
  if (!session || !session.pluginId || !session.pollSecret || !session.agent) return;
47611
- const cwd = session.cwd && fs74.existsSync(session.cwd) ? session.cwd : process.cwd();
47769
+ const cwd = session.cwd && fs75.existsSync(session.cwd) ? session.cwd : process.cwd();
47612
47770
  const proc = this.resumeSpawner(
47613
47771
  readHouseProxyChildEnv(),
47614
47772
  cwd
@@ -47794,12 +47952,12 @@ var HostAgentSupervisor = class {
47794
47952
  this.children.delete(deployId);
47795
47953
  }
47796
47954
  const dirs = [
47797
- path87.join(selfHostedWorkspaceRoot(), deployId),
47798
- path87.join(os59.homedir(), ".codeam", "house-claude", deployId)
47955
+ path88.join(selfHostedWorkspaceRoot(), deployId),
47956
+ path88.join(os60.homedir(), ".codeam", "house-claude", deployId)
47799
47957
  ];
47800
47958
  for (const dir of dirs) {
47801
47959
  try {
47802
- fs74.rmSync(dir, { recursive: true, force: true });
47960
+ fs75.rmSync(dir, { recursive: true, force: true });
47803
47961
  } catch (err) {
47804
47962
  log.warn(
47805
47963
  "host-agent",
@@ -47959,8 +48117,8 @@ async function invite() {
47959
48117
  var import_node_dns = require("dns");
47960
48118
  var import_node_util6 = require("util");
47961
48119
  var import_node_crypto12 = require("crypto");
47962
- var fs75 = __toESM(require("fs"));
47963
- var path88 = __toESM(require("path"));
48120
+ var fs76 = __toESM(require("fs"));
48121
+ var path89 = __toESM(require("path"));
47964
48122
  var import_picocolors14 = __toESM(require("picocolors"));
47965
48123
  var dnsResolveP = (0, import_node_util6.promisify)(import_node_dns.resolve);
47966
48124
  async function checkDns(apiBase2) {
@@ -48016,13 +48174,13 @@ async function checkHealth(apiBase2) {
48016
48174
  }
48017
48175
  }
48018
48176
  function checkConfigDir() {
48019
- const dir = path88.join(require("os").homedir(), ".codeam");
48177
+ const dir = path89.join(require("os").homedir(), ".codeam");
48020
48178
  try {
48021
- fs75.mkdirSync(dir, { recursive: true, mode: 448 });
48022
- const probe = path88.join(dir, ".doctor-probe");
48023
- fs75.writeFileSync(probe, "ok", { mode: 384 });
48024
- const read = fs75.readFileSync(probe, "utf8");
48025
- fs75.unlinkSync(probe);
48179
+ fs76.mkdirSync(dir, { recursive: true, mode: 448 });
48180
+ const probe = path89.join(dir, ".doctor-probe");
48181
+ fs76.writeFileSync(probe, "ok", { mode: 384 });
48182
+ const read = fs76.readFileSync(probe, "utf8");
48183
+ fs76.unlinkSync(probe);
48026
48184
  if (read !== "ok") throw new Error("write/read round-trip mismatch");
48027
48185
  return {
48028
48186
  id: "config-dir",
@@ -48062,9 +48220,9 @@ function checkSessions() {
48062
48220
  }
48063
48221
  }
48064
48222
  function checkAgentBinaries() {
48065
- const os62 = createOsStrategy();
48223
+ const os63 = createOsStrategy();
48066
48224
  return getEnabledAgents().map((meta) => {
48067
- const found = os62.findInPath(meta.binaryName);
48225
+ const found = os63.findInPath(meta.binaryName);
48068
48226
  return {
48069
48227
  id: `agent-${meta.id}`,
48070
48228
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -48086,7 +48244,7 @@ function checkNodePty() {
48086
48244
  detail: "not required on this platform"
48087
48245
  };
48088
48246
  }
48089
- const vendoredPath = path88.join(__dirname, "vendor", "node-pty");
48247
+ const vendoredPath = path89.join(__dirname, "vendor", "node-pty");
48090
48248
  for (const target of [vendoredPath, "node-pty"]) {
48091
48249
  try {
48092
48250
  require(target);
@@ -48128,7 +48286,7 @@ function checkChokidar() {
48128
48286
  }
48129
48287
  async function doctor(args2 = []) {
48130
48288
  const json = args2.includes("--json");
48131
- const cliVersion = true ? "2.75.6" : "0.0.0-dev";
48289
+ const cliVersion = true ? "2.75.8" : "0.0.0-dev";
48132
48290
  const apiBase2 = resolveApiBaseUrl();
48133
48291
  const diagnosticId = (0, import_node_crypto12.randomUUID)();
48134
48292
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -48652,7 +48810,7 @@ async function mcpWarm(argv = [], opts = {}) {
48652
48810
  // src/commands/version.ts
48653
48811
  var import_picocolors15 = __toESM(require("picocolors"));
48654
48812
  function version2() {
48655
- const v = true ? "2.75.6" : "unknown";
48813
+ const v = true ? "2.75.8" : "unknown";
48656
48814
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
48657
48815
  }
48658
48816
 
@@ -48801,10 +48959,10 @@ var EXIT_CODE_NAMES = {
48801
48959
  };
48802
48960
 
48803
48961
  // src/index.ts
48804
- var os61 = __toESM(require("os"));
48962
+ var os62 = __toESM(require("os"));
48805
48963
  if (!process.env.HOME) {
48806
48964
  try {
48807
- const home = os61.homedir();
48965
+ const home = os62.homedir();
48808
48966
  if (home) process.env.HOME = home;
48809
48967
  } catch {
48810
48968
  }