codeam-cli 2.74.8 → 2.74.9

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 +10 -0
  2. package/dist/index.js +272 -279
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3211,11 +3211,11 @@ function quiet(fn) {
3211
3211
  log.debug(TAG, "ignored sync error", err);
3212
3212
  }
3213
3213
  }
3214
- function rmIfExistsQuiet(path95) {
3214
+ function rmIfExistsQuiet(path96) {
3215
3215
  try {
3216
- fs2.rmSync(path95, { force: true });
3216
+ fs2.rmSync(path96, { force: true });
3217
3217
  } catch (err) {
3218
- log.debug(TAG, `rmIfExists failed for ${path95}`, err);
3218
+ log.debug(TAG, `rmIfExists failed for ${path96}`, err);
3219
3219
  }
3220
3220
  }
3221
3221
  function killQuiet(target, signal = "SIGTERM") {
@@ -3386,7 +3386,7 @@ var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, ge
3386
3386
  // src/commands/pair-auto.ts
3387
3387
  var fs66 = __toESM(require("fs"));
3388
3388
  var os55 = __toESM(require("os"));
3389
- var path72 = __toESM(require("path"));
3389
+ var path73 = __toESM(require("path"));
3390
3390
  var import_crypto4 = require("crypto");
3391
3391
 
3392
3392
  // src/services/telemetry.service.ts
@@ -3422,8 +3422,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
3422
3422
  return decodedFile;
3423
3423
  };
3424
3424
  }
3425
- function normalizeWindowsPath(path95) {
3426
- return path95.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3425
+ function normalizeWindowsPath(path96) {
3426
+ return path96.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3427
3427
  }
3428
3428
 
3429
3429
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -5903,9 +5903,9 @@ async function addSourceContext(frames) {
5903
5903
  LRU_FILE_CONTENTS_CACHE.reduce();
5904
5904
  return frames;
5905
5905
  }
5906
- function getContextLinesFromFile(path95, ranges, output) {
5906
+ function getContextLinesFromFile(path96, ranges, output) {
5907
5907
  return new Promise((resolve11) => {
5908
- const stream = (0, import_node_fs.createReadStream)(path95);
5908
+ const stream = (0, import_node_fs.createReadStream)(path96);
5909
5909
  const lineReaded = (0, import_node_readline.createInterface)({
5910
5910
  input: stream
5911
5911
  });
@@ -5920,7 +5920,7 @@ function getContextLinesFromFile(path95, ranges, output) {
5920
5920
  let rangeStart = range[0];
5921
5921
  let rangeEnd = range[1];
5922
5922
  function onStreamError() {
5923
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path95, 1);
5923
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path96, 1);
5924
5924
  lineReaded.close();
5925
5925
  lineReaded.removeAllListeners();
5926
5926
  destroyStreamAndResolve();
@@ -5981,8 +5981,8 @@ function clearLineContext(frame) {
5981
5981
  delete frame.context_line;
5982
5982
  delete frame.post_context;
5983
5983
  }
5984
- function shouldSkipContextLinesForFile(path95) {
5985
- return path95.startsWith("node:") || path95.endsWith(".min.js") || path95.endsWith(".min.cjs") || path95.endsWith(".min.mjs") || path95.startsWith("data:");
5984
+ function shouldSkipContextLinesForFile(path96) {
5985
+ return path96.startsWith("node:") || path96.endsWith(".min.js") || path96.endsWith(".min.cjs") || path96.endsWith(".min.mjs") || path96.startsWith("data:");
5986
5986
  }
5987
5987
  function shouldSkipContextLinesForFrame(frame) {
5988
5988
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -8136,7 +8136,7 @@ function readAnonId() {
8136
8136
  }
8137
8137
  function superProperties() {
8138
8138
  return {
8139
- cliVersion: true ? "2.74.8" : "0.0.0-dev",
8139
+ cliVersion: true ? "2.74.9" : "0.0.0-dev",
8140
8140
  nodeVersion: process.version,
8141
8141
  platform: process.platform,
8142
8142
  arch: process.arch,
@@ -8378,7 +8378,7 @@ var http = __toESM(require("http"));
8378
8378
  // package.json
8379
8379
  var package_default = {
8380
8380
  name: "codeam-cli",
8381
- version: "2.74.8",
8381
+ version: "2.74.9",
8382
8382
  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.",
8383
8383
  type: "commonjs",
8384
8384
  main: "dist/index.js",
@@ -9971,7 +9971,7 @@ var CommandRelayService = class _CommandRelayService {
9971
9971
  // fresh + clear the "CLI update available" banner after a self-update
9972
9972
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9973
9973
  // pair/reconnect). Older backends ignore the extra field.
9974
- ..."2.74.8" ? { ideVersion: "2.74.8" } : {}
9974
+ ..."2.74.9" ? { ideVersion: "2.74.9" } : {}
9975
9975
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9976
9976
  }
9977
9977
  /**
@@ -11380,7 +11380,7 @@ function closeAllTerminals() {
11380
11380
  // src/commands/start/handlers.ts
11381
11381
  var fs65 = __toESM(require("fs"));
11382
11382
  var os54 = __toESM(require("os"));
11383
- var path71 = __toESM(require("path"));
11383
+ var path72 = __toESM(require("path"));
11384
11384
  var import_crypto3 = require("crypto");
11385
11385
  var import_child_process28 = require("child_process");
11386
11386
 
@@ -17588,8 +17588,8 @@ function pickLine(obj) {
17588
17588
  function toHunk(raw, groupSeverity) {
17589
17589
  if (!raw || typeof raw !== "object") return null;
17590
17590
  const o = raw;
17591
- const path95 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
17592
- if (!path95) return null;
17591
+ const path96 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
17592
+ if (!path96) return null;
17593
17593
  const message = asString(
17594
17594
  pick(o, [
17595
17595
  "comment",
@@ -17606,7 +17606,7 @@ function toHunk(raw, groupSeverity) {
17606
17606
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
17607
17607
  const locObj = pick(o, ["location"]) ?? o;
17608
17608
  return {
17609
- path: path95.trim(),
17609
+ path: path96.trim(),
17610
17610
  line: pickLine(o) ?? pickLine(locObj),
17611
17611
  severity,
17612
17612
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -17689,10 +17689,10 @@ function parsePlain(stdout) {
17689
17689
  for (const line of stdout.split(/\r?\n/)) {
17690
17690
  const m = line.match(HUNK_LINE_RE);
17691
17691
  if (!m) continue;
17692
- const [, path95, lineNo, sevToken, message] = m;
17693
- if (!path95 || !lineNo || !message) continue;
17692
+ const [, path96, lineNo, sevToken, message] = m;
17693
+ if (!path96 || !lineNo || !message) continue;
17694
17694
  hunks.push({
17695
- path: path95.trim(),
17695
+ path: path96.trim(),
17696
17696
  line: Number(lineNo),
17697
17697
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
17698
17698
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -22272,7 +22272,7 @@ async function autoUpgradeBeforeCriticalCommand() {
22272
22272
  if (process.env.NODE_ENV === "test") return;
22273
22273
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22274
22274
  if (process.env.CI) return;
22275
- const current2 = true ? "2.74.8" : null;
22275
+ const current2 = true ? "2.74.9" : null;
22276
22276
  if (!current2) return;
22277
22277
  const cache = readCache();
22278
22278
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22289,7 +22289,7 @@ function checkForUpdates() {
22289
22289
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
22290
22290
  if (process.env.CI) return;
22291
22291
  if (!process.stdout.isTTY) return;
22292
- const current2 = true ? "2.74.8" : null;
22292
+ const current2 = true ? "2.74.9" : null;
22293
22293
  if (!current2) return;
22294
22294
  const cache = readCache();
22295
22295
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -22312,7 +22312,7 @@ var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
22312
22312
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
22313
22313
  var SUDO_PREFLIGHT_TIMEOUT_MS = 5e3;
22314
22314
  function currentCliVersion() {
22315
- return true ? "2.74.8" : null;
22315
+ return true ? "2.74.9" : null;
22316
22316
  }
22317
22317
  async function installedVersion(deps) {
22318
22318
  const ls = await deps.run(
@@ -24289,17 +24289,17 @@ async function defaultFetchJson(url2) {
24289
24289
  async function readUsageReport(deps = {}) {
24290
24290
  const port = deps.port ?? HEADROOM_PROXY_PORT;
24291
24291
  const base = `http://127.0.0.1:${port}`;
24292
- const get3 = deps.fetchJson ?? ((path95) => defaultFetchJson(`${base}${path95}`));
24292
+ const get4 = deps.fetchJson ?? ((path96) => defaultFetchJson(`${base}${path96}`));
24293
24293
  let history;
24294
24294
  try {
24295
- history = await get3("/stats-history");
24295
+ history = await get4("/stats-history");
24296
24296
  } catch (err) {
24297
24297
  log.info("headroomUsage", `stats-history unavailable: ${err.message}`);
24298
24298
  return null;
24299
24299
  }
24300
24300
  let proxyVersion;
24301
24301
  try {
24302
- const health = await get3("/health");
24302
+ const health = await get4("/health");
24303
24303
  if (health && typeof health.version === "string") proxyVersion = health.version;
24304
24304
  } catch {
24305
24305
  }
@@ -24959,6 +24959,51 @@ function quoteIfNeeded(value) {
24959
24959
  return value;
24960
24960
  }
24961
24961
 
24962
+ // src/services/preview/expo.ts
24963
+ var http6 = __toESM(require("http"));
24964
+ var path60 = __toESM(require("path"));
24965
+ var EXPO_PACKAGER_PROXY_URL_ENV = "EXPO_PACKAGER_PROXY_URL";
24966
+ function stripExpoTunnelFlag(args2) {
24967
+ return args2.filter((a) => a !== "--tunnel" && !a.startsWith("--tunnel="));
24968
+ }
24969
+ function ensureExpoPortArg(command2, args2, port) {
24970
+ const hasPort = args2.some((a) => a === "--port" || a.startsWith("--port="));
24971
+ if (hasPort) return [...args2];
24972
+ const out2 = [...args2];
24973
+ if (path60.basename(command2) === "npm" && !out2.includes("--")) out2.push("--");
24974
+ out2.push("--port", String(port));
24975
+ return out2;
24976
+ }
24977
+ function expoSpawnArgs(command2, args2, port) {
24978
+ return ensureExpoPortArg(command2, stripExpoTunnelFlag(args2), port);
24979
+ }
24980
+ function expoGoDeepLink(publicUrl) {
24981
+ return `exps://${new URL(publicUrl).host}`;
24982
+ }
24983
+ function isExpoManifestServed(port, host2 = "127.0.0.1") {
24984
+ return new Promise((resolve11) => {
24985
+ const req = http6.get(
24986
+ { host: host2, port, path: "/", headers: { "expo-platform": "ios" }, timeout: 1500 },
24987
+ (res) => {
24988
+ const ok = res.statusCode !== void 0 && res.statusCode >= 200 && res.statusCode < 300;
24989
+ res.resume();
24990
+ resolve11(ok);
24991
+ }
24992
+ );
24993
+ req.once("timeout", () => req.destroy());
24994
+ req.once("error", () => resolve11(false));
24995
+ });
24996
+ }
24997
+ async function waitForExpoManifest(port, opts) {
24998
+ const interval = opts.intervalMs ?? 500;
24999
+ const deadline = Date.now() + opts.timeoutMs;
25000
+ for (; ; ) {
25001
+ if (await isExpoManifestServed(port)) return true;
25002
+ if (Date.now() >= deadline) return false;
25003
+ await new Promise((r) => setTimeout(r, interval));
25004
+ }
25005
+ }
25006
+
24962
25007
  // src/services/preview/parser.ts
24963
25008
  var REQUIRED_FIELDS2 = [
24964
25009
  "framework",
@@ -25047,21 +25092,6 @@ function parseCloudflaredUrl(stderr) {
25047
25092
  const match = stderr.match(CLOUDFLARED_URL_RE);
25048
25093
  return match ? match[0] : null;
25049
25094
  }
25050
- var EXPO_DEEP_LINK_RE = /exp:\/\/[^\s"'`)]+\.exp\.(?:direct|host)(?::\d+)?/;
25051
- var EXPO_DEBUG_TUNNEL_RE = /Tunnel URL:\s*(https?:\/\/([^\s"'`)]+\.exp\.(?:direct|host)))/;
25052
- function parseExpoUrl(output) {
25053
- const direct = output.match(EXPO_DEEP_LINK_RE);
25054
- if (direct) return direct[0];
25055
- const dbg = output.match(EXPO_DEBUG_TUNNEL_RE);
25056
- if (dbg) return `exp://${dbg[2]}`;
25057
- return null;
25058
- }
25059
- var EXPO_TUNNEL_DEBUG_CHANNEL = "expo:start:server:ngrok";
25060
- function expoTunnelDebugEnv(existing) {
25061
- const cur = (existing ?? "").split(",").map((s) => s.trim()).filter(Boolean);
25062
- if (!cur.includes(EXPO_TUNNEL_DEBUG_CHANNEL)) cur.push(EXPO_TUNNEL_DEBUG_CHANNEL);
25063
- return { DEBUG: cur.join(",") };
25064
- }
25065
25095
  var RAW_EXCERPT_LIMIT = 1e3;
25066
25096
  function describeDetectionFailure(raw) {
25067
25097
  const text = raw?.trim() ?? "";
@@ -25545,25 +25575,6 @@ async function ensureYarnInstalled(deps) {
25545
25575
  if (!res.ok) return res;
25546
25576
  return await deps.hasYarn() ? { ok: true, code: 0 } : { ok: false, code: res.code };
25547
25577
  }
25548
- function isExpoTunnelCommand(command2, args2) {
25549
- const flat = [import_path8.default.basename(command2), ...args2];
25550
- return flat.includes("expo") && flat.includes("--tunnel");
25551
- }
25552
- var EXPO_NGROK_SPEC = "@expo/ngrok@^4.1.0";
25553
- async function ensureExpoTunnelDeps(deps) {
25554
- if (await deps.hasNgrok()) return { ok: true, code: 0, installed: false };
25555
- const res = await deps.installNgrok();
25556
- if (!res.ok) return { ...res, installed: false };
25557
- return await deps.hasNgrok() ? { ok: true, code: 0, installed: true } : { ok: false, code: res.code, installed: false };
25558
- }
25559
- function ngrokResolvesFrom(cwd) {
25560
- try {
25561
- require.resolve("@expo/ngrok/package.json", { paths: [cwd] });
25562
- return true;
25563
- } catch {
25564
- return false;
25565
- }
25566
- }
25567
25578
  function isJsInstallCommand(cmd, args2) {
25568
25579
  const known = ["npm", "pnpm", "yarn", "bun"];
25569
25580
  if (!known.includes(cmd)) return false;
@@ -25612,7 +25623,7 @@ async function awaitTunnelRegistered(candidate, hostname3, deadlineMs) {
25612
25623
  }
25613
25624
 
25614
25625
  // src/services/preview/adopt-port.ts
25615
- var http6 = __toESM(require("http"));
25626
+ var http7 = __toESM(require("http"));
25616
25627
  var DIRECTORY_LISTING_RE = /<title>\s*(?:Directory listing for|Index of)/i;
25617
25628
  var PROBE_TIMEOUT_MS = 2e3;
25618
25629
  var PROBE_BODY_LIMIT = 4 * 1024;
@@ -25627,7 +25638,7 @@ function verdictFor(res) {
25627
25638
  return { adopt: true };
25628
25639
  }
25629
25640
  var probePort = (port) => new Promise((resolve11) => {
25630
- const req = http6.get(
25641
+ const req = http7.get(
25631
25642
  { host: "127.0.0.1", port, path: "/", timeout: PROBE_TIMEOUT_MS },
25632
25643
  (res) => {
25633
25644
  let body = "";
@@ -25709,18 +25720,18 @@ function activePreviewSessionIds() {
25709
25720
  // src/services/preview/start-orchestrator.ts
25710
25721
  var import_child_process23 = require("child_process");
25711
25722
  var fs59 = __toESM(require("fs"));
25712
- var path64 = __toESM(require("path"));
25723
+ var path65 = __toESM(require("path"));
25713
25724
  var import_which2 = __toESM(require("which"));
25714
25725
 
25715
25726
  // src/services/project-env/index.ts
25716
25727
  var import_fs6 = require("fs");
25717
- var path63 = __toESM(require("path"));
25728
+ var path64 = __toESM(require("path"));
25718
25729
 
25719
25730
  // src/beads/project-key.ts
25720
25731
  var import_child_process22 = require("child_process");
25721
25732
  var crypto2 = __toESM(require("crypto"));
25722
25733
  var fs57 = __toESM(require("fs"));
25723
- var path62 = __toESM(require("path"));
25734
+ var path63 = __toESM(require("path"));
25724
25735
  function normalizeOrigin(raw) {
25725
25736
  const trimmed = raw.trim();
25726
25737
  if (!trimmed) return null;
@@ -25746,17 +25757,17 @@ function normalizeOrigin(raw) {
25746
25757
  return `${host2}/${pathPart}`;
25747
25758
  }
25748
25759
  function findRepoRoot(cwd) {
25749
- let dir = path62.resolve(cwd);
25760
+ let dir = path63.resolve(cwd);
25750
25761
  const seen = /* @__PURE__ */ new Set();
25751
25762
  for (let i = 0; i < 256; i++) {
25752
25763
  if (seen.has(dir)) return null;
25753
25764
  seen.add(dir);
25754
25765
  try {
25755
- const stat3 = fs57.statSync(path62.join(dir, ".git"), { throwIfNoEntry: false });
25766
+ const stat3 = fs57.statSync(path63.join(dir, ".git"), { throwIfNoEntry: false });
25756
25767
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
25757
25768
  } catch {
25758
25769
  }
25759
- const parent = path62.dirname(dir);
25770
+ const parent = path63.dirname(dir);
25760
25771
  if (parent === dir) return null;
25761
25772
  dir = parent;
25762
25773
  }
@@ -25796,7 +25807,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
25796
25807
  } catch {
25797
25808
  }
25798
25809
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
25799
- return { projectKey: `path:${hash}`, projectLabel: path62.basename(real) || "project" };
25810
+ return { projectKey: `path:${hash}`, projectLabel: path63.basename(real) || "project" };
25800
25811
  }
25801
25812
 
25802
25813
  // src/services/project-env/index.ts
@@ -25809,7 +25820,7 @@ async function readIfExists(p2) {
25809
25820
  }
25810
25821
  async function syncProjectEnvUp(cwd, ctx) {
25811
25822
  if (!ctx.pluginAuthToken) return;
25812
- const content = await readIfExists(path63.join(cwd, ".env"));
25823
+ const content = await readIfExists(path64.join(cwd, ".env"));
25813
25824
  if (content == null) return;
25814
25825
  try {
25815
25826
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -25831,7 +25842,7 @@ async function syncProjectEnvUp(cwd, ctx) {
25831
25842
  }
25832
25843
  async function restoreProjectEnvIfMissing(cwd, ctx) {
25833
25844
  if (!ctx.pluginAuthToken) return false;
25834
- const envPath = path63.join(cwd, ".env");
25845
+ const envPath = path64.join(cwd, ".env");
25835
25846
  if (await readIfExists(envPath) != null) return false;
25836
25847
  try {
25837
25848
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -25842,7 +25853,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
25842
25853
  projectKey
25843
25854
  });
25844
25855
  if (!stored) return false;
25845
- const tmp = path63.join(cwd, ".env.codeam-restore.tmp");
25856
+ const tmp = path64.join(cwd, ".env.codeam-restore.tmp");
25846
25857
  await import_fs6.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
25847
25858
  await import_fs6.promises.rename(tmp, envPath);
25848
25859
  log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
@@ -25874,7 +25885,7 @@ async function resolveNamedTunnel(ctx, fetchTunnel) {
25874
25885
  }
25875
25886
 
25876
25887
  // src/services/preview/inspector-proxy.ts
25877
- var http7 = __toESM(require("http"));
25888
+ var http8 = __toESM(require("http"));
25878
25889
  var net4 = __toESM(require("net"));
25879
25890
  var INJECTION_SCAN_BUDGET_BYTES = 64 * 1024;
25880
25891
  var INJECTION_ANCHORS = ["</head>", "<body>", "</body>"];
@@ -25900,7 +25911,7 @@ function injectAt(html, script) {
25900
25911
  async function startInspectorProxy(opts) {
25901
25912
  const targetHost = opts.targetHost ?? "127.0.0.1";
25902
25913
  const upgraded = /* @__PURE__ */ new Set();
25903
- const server = http7.createServer((req, res) => {
25914
+ const server = http8.createServer((req, res) => {
25904
25915
  const one = (v) => Array.isArray(v) ? v[0] : v;
25905
25916
  const inject = isNavigation({
25906
25917
  accept: one(req.headers.accept),
@@ -25909,7 +25920,7 @@ async function startInspectorProxy(opts) {
25909
25920
  });
25910
25921
  const headers = { ...req.headers };
25911
25922
  if (inject) delete headers["accept-encoding"];
25912
- const upstream = http7.request(
25923
+ const upstream = http8.request(
25913
25924
  { host: targetHost, port: opts.targetPort, method: req.method, path: req.url, headers },
25914
25925
  (originRes) => {
25915
25926
  const outHeaders = { ...originRes.headers };
@@ -26422,7 +26433,7 @@ function normalizeDetectionForSpawn(detection, cwd) {
26422
26433
  if (args2.length === 0) return detection;
26423
26434
  const binName = args2[0];
26424
26435
  if (binName.startsWith("-")) return detection;
26425
- const binPath = path64.join(cwd, "node_modules", ".bin", binName);
26436
+ const binPath = path65.join(cwd, "node_modules", ".bin", binName);
26426
26437
  if (!fs59.existsSync(binPath)) return detection;
26427
26438
  return {
26428
26439
  ...detection,
@@ -26455,10 +26466,38 @@ async function runPreviewStart(args2) {
26455
26466
  });
26456
26467
  ctx.emitProgress("ENV_DETECTED", `${detection.framework}`);
26457
26468
  if (!await provisionDeps(ctx)) return;
26469
+ if (detection.framework === "Expo") {
26470
+ await runExpoBringUp(ctx);
26471
+ return;
26472
+ }
26458
26473
  const dev = await startDevServer(ctx);
26459
26474
  if (!dev) return;
26460
26475
  const tun = await establishTunnel(ctx, dev);
26461
26476
  if (!tun) return;
26477
+ announceReady(ctx, dev, tun);
26478
+ }
26479
+ async function runExpoBringUp(ctx) {
26480
+ const { detection, emit: emit2, emitProgress } = ctx;
26481
+ emitProgress("TUNNEL_STARTING", `cloudflared quick tunnel \u2192 Expo :${detection.port}`);
26482
+ const pub = await bringUpPublicUrl(ctx, detection.port);
26483
+ if (!pub.ok) {
26484
+ emit2(USER_EVENTS.PREVIEW_ERROR, { stage: "tunnel", message: pub.message });
26485
+ return;
26486
+ }
26487
+ const dev = await startDevServer(ctx, { [EXPO_PACKAGER_PROXY_URL_ENV]: pub.url });
26488
+ if (!dev) {
26489
+ killQuiet(pub.tunnel);
26490
+ return;
26491
+ }
26492
+ announceReady(ctx, dev, {
26493
+ url: expoGoDeepLink(pub.url),
26494
+ tunnel: pub.tunnel,
26495
+ // No inspector: a DOM inspector means nothing against a native app.
26496
+ inspector: null
26497
+ });
26498
+ }
26499
+ function announceReady(ctx, dev, tun) {
26500
+ const { sessionId, detection, emit: emit2 } = ctx;
26462
26501
  ctx.emitProgress("TUNNEL_READY", tun.url);
26463
26502
  registerPreview(sessionId, {
26464
26503
  sessionId,
@@ -26489,7 +26528,6 @@ async function provisionDeps(ctx) {
26489
26528
  pluginAuthToken: ctx.projectEnvAuth.pluginAuthToken
26490
26529
  });
26491
26530
  }
26492
- const needsExpoNgrok = isExpoTunnelCommand(detection.command, detection.args ?? []);
26493
26531
  const missingDeps = detectMissingNodeDeps(cwd);
26494
26532
  let preflightRan = false;
26495
26533
  if (missingDeps) {
@@ -26543,32 +26581,6 @@ async function provisionDeps(ctx) {
26543
26581
  }
26544
26582
  preflightRan = true;
26545
26583
  }
26546
- if (needsExpoNgrok) {
26547
- const ensured = await ensureExpoTunnelDeps({
26548
- hasNgrok: async () => ngrokResolvesFrom(cwd),
26549
- installNgrok: async () => {
26550
- emitProgress(
26551
- "SETUP_RUN",
26552
- `npm install --no-save ${EXPO_NGROK_SPEC} (Expo tunnel needs ngrok; not found)`
26553
- );
26554
- const r = await runSetupCommand(
26555
- "npm",
26556
- ["install", "--no-save", "--no-audit", "--no-fund", EXPO_NGROK_SPEC],
26557
- cwd,
26558
- detection.env,
26559
- { timeoutMs: INSTALL_TIMEOUT_MS2 }
26560
- );
26561
- return { ok: r.status === "ok", code: r.code };
26562
- }
26563
- });
26564
- if (!ensured.ok) {
26565
- emit2(USER_EVENTS.PREVIEW_ERROR, {
26566
- stage: "spawn",
26567
- message: `Expo's tunnel needs @expo/ngrok and installing it automatically failed (npm install --no-save ${EXPO_NGROK_SPEC}, exit ${ensured.code}). Install it in the project and try the preview again.`
26568
- });
26569
- return false;
26570
- }
26571
- }
26572
26584
  const normalizedSetup = (detection.setup_commands ?? []).map((entry) => {
26573
26585
  if (typeof entry === "string") {
26574
26586
  const parts = entry.trim().split(/\s+/).filter(Boolean);
@@ -26604,7 +26616,7 @@ async function provisionDeps(ctx) {
26604
26616
  }
26605
26617
  return true;
26606
26618
  }
26607
- async function startDevServer(ctx) {
26619
+ async function startDevServer(ctx, extraEnv = {}) {
26608
26620
  const { sessionId, detection, cwd, emit: emit2, emitProgress } = ctx;
26609
26621
  if (await isPortListening(detection.port)) {
26610
26622
  const raceExisting = activePreviews.get(sessionId);
@@ -26656,7 +26668,7 @@ async function startDevServer(ctx) {
26656
26668
  if (verdict.adopt) {
26657
26669
  log.info("preview", `adopting the dev server already serving on port ${detection.port}`);
26658
26670
  emitProgress("READY_DETECTED", `adopted the server already on port ${detection.port}`);
26659
- return { devServer: null, expoUrlRef: { current: null } };
26671
+ return { devServer: null };
26660
26672
  }
26661
26673
  emit2(USER_EVENTS.PREVIEW_ERROR, {
26662
26674
  stage: "spawn",
@@ -26666,13 +26678,16 @@ async function startDevServer(ctx) {
26666
26678
  }
26667
26679
  }
26668
26680
  await applyPreviewHostAllow(cwd);
26669
- const spawnable = normalizeDetectionForSpawn(detection, cwd);
26670
- emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
26671
26681
  const isExpo = detection.framework === "Expo";
26672
- const expoDebugEnv = isExpo && isExpoTunnelCommand(detection.command, detection.args ?? []) ? expoTunnelDebugEnv(spawnable.env?.DEBUG ?? process.env.DEBUG) : {};
26682
+ const normalized = normalizeDetectionForSpawn(detection, cwd);
26683
+ const spawnable = isExpo ? {
26684
+ ...normalized,
26685
+ args: expoSpawnArgs(normalized.command, normalized.args, detection.port)
26686
+ } : normalized;
26687
+ emitProgress("BOOT_SEQUENCE", `${spawnable.command} ${spawnable.args.join(" ")}`);
26673
26688
  const devServer = (0, import_child_process23.spawn)(spawnable.command, spawnable.args, {
26674
26689
  cwd,
26675
- env: { ...process.env, ...spawnable.env ?? {}, ...expoDebugEnv },
26690
+ env: { ...process.env, ...spawnable.env ?? {}, ...extraEnv },
26676
26691
  stdio: ["ignore", "pipe", "pipe"],
26677
26692
  // POSIX: lead a new process group so teardown can SIGTERM the whole
26678
26693
  // tree. Dev servers fork worker children that bind the port; killing
@@ -26684,22 +26699,19 @@ async function startDevServer(ctx) {
26684
26699
  });
26685
26700
  emitProgress("BIND_PORT", String(detection.port));
26686
26701
  emitProgress("WAITING_FOR_READY", detection.ready_pattern);
26687
- const expoUrlRef = { current: null };
26688
26702
  let outputTail = "";
26689
26703
  const readyRe = isExpo ? new RegExp(
26690
- `(?:${compileReadyPattern(detection.ready_pattern).source})|exp:\\/\\/[^\\s]+\\.exp\\.(?:direct|host)|Tunnel URL:`,
26704
+ `(?:${compileReadyPattern(detection.ready_pattern).source})|Waiting on http:\\/\\/localhost:${detection.port}|Logs for your project will appear below`,
26691
26705
  "i"
26692
26706
  ) : compileReadyPattern(detection.ready_pattern);
26693
26707
  const isNextJs = /next/i.test(detection.framework);
26708
+ const portProbe = isExpo ? () => waitForExpoManifest(detection.port, { timeoutMs: 1e3, intervalMs: 250 }) : isNextJs ? () => waitForPortListening(detection.port, { timeoutMs: 1e3, intervalMs: 250 }) : void 0;
26694
26709
  const outcome = await waitForDevServerReady(devServer, readyRe, {
26695
26710
  timeoutMs: 12e4,
26696
26711
  onChunk: (s) => {
26697
26712
  outputTail = (outputTail + s).slice(-16e3);
26698
- if (!expoUrlRef.current && isExpo) {
26699
- expoUrlRef.current = parseExpoUrl(outputTail);
26700
- }
26701
26713
  },
26702
- portProbe: isNextJs ? () => waitForPortListening(detection.port, { timeoutMs: 1e3, intervalMs: 250 }) : void 0
26714
+ portProbe
26703
26715
  });
26704
26716
  if (outcome.kind === "exited") {
26705
26717
  killProcessTree(devServer, "SIGTERM");
@@ -26720,48 +26732,31 @@ async function startDevServer(ctx) {
26720
26732
  return null;
26721
26733
  }
26722
26734
  emitProgress("READY_DETECTED", `port ${detection.port}`);
26723
- return { devServer, expoUrlRef };
26735
+ return { devServer };
26724
26736
  }
26725
26737
  var MAX_TUNNEL_ATTEMPTS = 3;
26726
26738
  async function establishTunnel(ctx, dev) {
26727
26739
  const { detection, emit: emit2, emitProgress } = ctx;
26728
26740
  const { devServer } = dev;
26729
- emitProgress(
26730
- "TUNNEL_STARTING",
26731
- detection.framework === "Expo" ? "Expo (self-tunnelled)" : "cloudflared quick tunnel"
26732
- );
26733
- if (detection.framework === "Expo") {
26734
- if (!dev.expoUrlRef.current) {
26735
- const expoDeadline = Date.now() + 15e3;
26736
- while (!dev.expoUrlRef.current && Date.now() < expoDeadline) {
26737
- await new Promise((r) => setTimeout(r, 250));
26738
- }
26739
- }
26740
- const expoUrl = dev.expoUrlRef.current;
26741
- if (!expoUrl) {
26742
- if (devServer) killProcessTree(devServer, "SIGTERM");
26743
- emit2(USER_EVENTS.PREVIEW_ERROR, {
26744
- stage: "tunnel",
26745
- message: "Expo did not report a tunnel URL."
26746
- });
26747
- return null;
26748
- }
26749
- return { url: expoUrl, tunnel: null, inspector: null };
26750
- }
26741
+ emitProgress("TUNNEL_STARTING", "cloudflared quick tunnel");
26751
26742
  const inspection = await bringUpInspector(detection.port, {
26752
26743
  log: (m) => log.info("preview", m)
26753
26744
  });
26754
- const tunnelPort = inspection.port;
26745
+ const pub = await bringUpPublicUrl(ctx, inspection.port);
26746
+ if (!pub.ok) {
26747
+ if (devServer) killProcessTree(devServer, "SIGTERM");
26748
+ emit2(USER_EVENTS.PREVIEW_ERROR, { stage: "tunnel", message: pub.message });
26749
+ return null;
26750
+ }
26751
+ return { url: pub.url, tunnel: pub.tunnel, inspector: inspection.proxy };
26752
+ }
26753
+ async function bringUpPublicUrl(ctx, tunnelPort) {
26754
+ const { emitProgress } = ctx;
26755
26755
  let bin;
26756
26756
  try {
26757
26757
  bin = await resolveCloudflared();
26758
26758
  } catch (e) {
26759
- if (devServer) killProcessTree(devServer, "SIGTERM");
26760
- emit2(USER_EVENTS.PREVIEW_ERROR, {
26761
- stage: "tunnel",
26762
- message: e.message
26763
- });
26764
- return null;
26759
+ return { ok: false, message: e.message };
26765
26760
  }
26766
26761
  let tunnel = null;
26767
26762
  let parsedUrl = null;
@@ -26827,22 +26822,20 @@ async function establishTunnel(ctx, dev) {
26827
26822
  killQuiet(candidate);
26828
26823
  }
26829
26824
  }
26830
- if (!parsedUrl) {
26831
- if (devServer) killProcessTree(devServer, "SIGTERM");
26832
- emit2(USER_EVENTS.PREVIEW_ERROR, {
26833
- stage: "tunnel",
26825
+ if (!parsedUrl || !tunnel) {
26826
+ return {
26827
+ ok: false,
26834
26828
  message: `Tunnel did not become reachable after ${MAX_TUNNEL_ATTEMPTS} attempts (${lastTunnelErr}). Cloudflare Quick Tunnels occasionally fail to register \u2014 please retry.`
26835
- });
26836
- return null;
26829
+ };
26837
26830
  }
26838
- return { url: parsedUrl, tunnel, inspector: inspection.proxy };
26831
+ return { ok: true, url: parsedUrl, tunnel };
26839
26832
  }
26840
26833
 
26841
26834
  // src/beads/bd-adapter.ts
26842
26835
  var import_child_process24 = require("child_process");
26843
26836
  var fs60 = __toESM(require("fs"));
26844
26837
  var os48 = __toESM(require("os"));
26845
- var path65 = __toESM(require("path"));
26838
+ var path66 = __toESM(require("path"));
26846
26839
  var BD_PACKAGE = "@beads/bd";
26847
26840
  function resolveBundledBdBinary() {
26848
26841
  return _resolveSeam.resolveBundled();
@@ -26854,9 +26847,9 @@ function _defaultResolveBundled() {
26854
26847
  } catch {
26855
26848
  return null;
26856
26849
  }
26857
- const binDir = path65.join(path65.dirname(pkgJsonPath), "bin");
26850
+ const binDir = path66.join(path66.dirname(pkgJsonPath), "bin");
26858
26851
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
26859
- const binaryPath = path65.join(binDir, binaryName);
26852
+ const binaryPath = path66.join(binDir, binaryName);
26860
26853
  try {
26861
26854
  fs60.accessSync(binaryPath, fs60.constants.F_OK);
26862
26855
  return binaryPath;
@@ -26868,11 +26861,11 @@ function resolveBdOnPath() {
26868
26861
  return _resolveSeam.resolveOnPath();
26869
26862
  }
26870
26863
  function _defaultResolveOnPath() {
26871
- const dirs = (process.env.PATH ?? "").split(path65.delimiter).filter(Boolean);
26864
+ const dirs = (process.env.PATH ?? "").split(path66.delimiter).filter(Boolean);
26872
26865
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
26873
26866
  for (const dir of dirs) {
26874
26867
  for (const candidate of candidates) {
26875
- const full = path65.join(dir, candidate);
26868
+ const full = path66.join(dir, candidate);
26876
26869
  try {
26877
26870
  fs60.accessSync(full, fs60.constants.F_OK);
26878
26871
  return full;
@@ -27053,7 +27046,7 @@ function coerceIssue(row, projectKey) {
27053
27046
  var import_child_process27 = require("child_process");
27054
27047
  var fs62 = __toESM(require("fs"));
27055
27048
  var os50 = __toESM(require("os"));
27056
- var path67 = __toESM(require("path"));
27049
+ var path68 = __toESM(require("path"));
27057
27050
 
27058
27051
  // src/beads/install-bd.ts
27059
27052
  var import_child_process25 = require("child_process");
@@ -27120,7 +27113,7 @@ async function installBd(platform3 = process.platform) {
27120
27113
  var import_child_process26 = require("child_process");
27121
27114
  var fs61 = __toESM(require("fs"));
27122
27115
  var os49 = __toESM(require("os"));
27123
- var path66 = __toESM(require("path"));
27116
+ var path67 = __toESM(require("path"));
27124
27117
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
27125
27118
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
27126
27119
  function resolveDoltInstallStrategy(platform3) {
@@ -27227,7 +27220,7 @@ function doltBinaryNames(platform3) {
27227
27220
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
27228
27221
  }
27229
27222
  function knownDoltDirs(platform3) {
27230
- const P3 = platform3 === "win32" ? path66.win32 : path66.posix;
27223
+ const P3 = platform3 === "win32" ? path67.win32 : path67.posix;
27231
27224
  const home = _doltPathSeam.homedir();
27232
27225
  if (platform3 === "win32") {
27233
27226
  return [
@@ -27243,7 +27236,7 @@ function knownDoltDirs(platform3) {
27243
27236
  ].filter(Boolean);
27244
27237
  }
27245
27238
  function ensureDoltResolvable(platform3 = process.platform) {
27246
- const P3 = platform3 === "win32" ? path66.win32 : path66.posix;
27239
+ const P3 = platform3 === "win32" ? path67.win32 : path67.posix;
27247
27240
  const delim = platform3 === "win32" ? ";" : ":";
27248
27241
  const names = doltBinaryNames(platform3);
27249
27242
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -27451,9 +27444,9 @@ var _linkSeam = {
27451
27444
  * which `linkBdOntoPath` creates if missing.
27452
27445
  */
27453
27446
  cliBinDir: () => {
27454
- const pathDirs = (process.env.PATH ?? "").split(path67.delimiter).filter(Boolean);
27447
+ const pathDirs = (process.env.PATH ?? "").split(path68.delimiter).filter(Boolean);
27455
27448
  const home = _linkSeam.homedir();
27456
- const localBin = home ? path67.join(home, ".local", "bin") : null;
27449
+ const localBin = home ? path68.join(home, ".local", "bin") : null;
27457
27450
  if (localBin) {
27458
27451
  try {
27459
27452
  _linkSeam.ensureDir(localBin);
@@ -27463,16 +27456,16 @@ var _linkSeam = {
27463
27456
  const candidates = [];
27464
27457
  if (localBin) candidates.push(localBin);
27465
27458
  try {
27466
- candidates.push(path67.dirname(process.execPath));
27459
+ candidates.push(path68.dirname(process.execPath));
27467
27460
  } catch {
27468
27461
  }
27469
27462
  candidates.push("/usr/local/bin");
27470
27463
  const entry = process.argv[1];
27471
27464
  if (entry) {
27472
27465
  try {
27473
- candidates.push(path67.dirname(fs62.realpathSync(entry)));
27466
+ candidates.push(path68.dirname(fs62.realpathSync(entry)));
27474
27467
  } catch {
27475
- candidates.push(path67.dirname(entry));
27468
+ candidates.push(path68.dirname(entry));
27476
27469
  }
27477
27470
  }
27478
27471
  const onPathWritable = candidates.find(
@@ -27497,7 +27490,7 @@ function linkBdOntoPath(binaryPath) {
27497
27490
  const binDir = _linkSeam.cliBinDir();
27498
27491
  if (!binDir) return;
27499
27492
  _linkSeam.ensureDir(binDir);
27500
- const linkPath = path67.join(binDir, "bd");
27493
+ const linkPath = path68.join(binDir, "bd");
27501
27494
  if (linkPath === binaryPath) return;
27502
27495
  const current2 = _linkSeam.readlink(linkPath);
27503
27496
  if (current2 === binaryPath) return;
@@ -27692,7 +27685,7 @@ function dedupeRecipes(agents) {
27692
27685
 
27693
27686
  // src/beads/watcher.ts
27694
27687
  var crypto4 = __toESM(require("crypto"));
27695
- var path68 = __toESM(require("path"));
27688
+ var path69 = __toESM(require("path"));
27696
27689
  var API_BASE6 = resolveApiBaseUrl();
27697
27690
  var DEBOUNCE_MS2 = 400;
27698
27691
  var ZERO_SUMMARY = {
@@ -27716,7 +27709,7 @@ var BeadsWatcher = class {
27716
27709
  constructor(opts) {
27717
27710
  this.opts = opts;
27718
27711
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
27719
- this.feedPath = opts.feedPath ?? path68.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
27712
+ this.feedPath = opts.feedPath ?? path69.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
27720
27713
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
27721
27714
  }
27722
27715
  opts;
@@ -28215,7 +28208,7 @@ function cleanupAttachmentTempFiles() {
28215
28208
  function saveFilesTemp(files) {
28216
28209
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
28217
28210
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
28218
- const tmpPath = path71.join(os54.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
28211
+ const tmpPath = path72.join(os54.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
28219
28212
  fs65.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
28220
28213
  pendingAttachmentFiles.add(tmpPath);
28221
28214
  return tmpPath;
@@ -28451,7 +28444,7 @@ var listFiles = async (ctx, cmd, parsed) => {
28451
28444
  await ctx.relay.sendResult(cmd.id, "completed", result);
28452
28445
  };
28453
28446
  var envReadH = async (ctx, cmd) => {
28454
- const envPath = path71.join(process.cwd(), ".env");
28447
+ const envPath = path72.join(process.cwd(), ".env");
28455
28448
  await restoreProjectEnvIfMissing(process.cwd(), ctx);
28456
28449
  try {
28457
28450
  const raw = await fs65.promises.readFile(envPath, "utf8");
@@ -28483,7 +28476,7 @@ var envParseH = async (ctx, cmd, parsed) => {
28483
28476
  const existing = /* @__PURE__ */ new Map();
28484
28477
  if (!replace) {
28485
28478
  try {
28486
- const raw = await fs65.promises.readFile(path71.join(process.cwd(), ".env"), "utf8");
28479
+ const raw = await fs65.promises.readFile(path72.join(process.cwd(), ".env"), "utf8");
28487
28480
  for (const v of parseDotenv(raw)) existing.set(v.key, v.value);
28488
28481
  } catch {
28489
28482
  }
@@ -28523,8 +28516,8 @@ var envWriteH = async (ctx, cmd, parsed) => {
28523
28516
  }
28524
28517
  seen.add(v.key);
28525
28518
  }
28526
- const envPath = path71.join(process.cwd(), ".env");
28527
- const tmpPath = path71.join(process.cwd(), ".env.codeam.tmp");
28519
+ const envPath = path72.join(process.cwd(), ".env");
28520
+ const tmpPath = path72.join(process.cwd(), ".env.codeam.tmp");
28528
28521
  try {
28529
28522
  await fs65.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
28530
28523
  await fs65.promises.rename(tmpPath, envPath);
@@ -29061,7 +29054,7 @@ function buildNpmInstallInvocation(opts) {
29061
29054
  const execPath = opts?.execPath ?? process.execPath;
29062
29055
  const exists2 = opts?.existsSync ?? fs65.existsSync;
29063
29056
  const platform3 = opts?.platform ?? process.platform;
29064
- const p2 = platform3 === "win32" ? path71.win32 : path71.posix;
29057
+ const p2 = platform3 === "win32" ? path72.win32 : path72.posix;
29065
29058
  const normalized = entryScript.split(/[\\/]/).join("/");
29066
29059
  const marker = "/lib/node_modules/codeam-cli/";
29067
29060
  const markerIdx = normalized.indexOf(marker);
@@ -29083,7 +29076,7 @@ function isPermissionError(stderr) {
29083
29076
  function resolveGlobalNodeModulesDir(opts) {
29084
29077
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
29085
29078
  const platform3 = opts?.platform ?? process.platform;
29086
- const p2 = platform3 === "win32" ? path71.win32 : path71.posix;
29079
+ const p2 = platform3 === "win32" ? path72.win32 : path72.posix;
29087
29080
  const marker = "/lib/node_modules/codeam-cli/";
29088
29081
  const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
29089
29082
  if (markerIdx <= 0) return null;
@@ -29105,7 +29098,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
29105
29098
  }
29106
29099
  for (const name of entries) {
29107
29100
  if (!/^\.codeam-cli-/.test(name)) continue;
29108
- const full = path71.join(nodeModulesDir, name);
29101
+ const full = path72.join(nodeModulesDir, name);
29109
29102
  try {
29110
29103
  const st3 = statSync17(full);
29111
29104
  if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
@@ -30070,11 +30063,11 @@ function resolveTokenValue(args2) {
30070
30063
  }
30071
30064
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
30072
30065
  if (fileFlag) {
30073
- const path95 = fileFlag.slice("--token-file=".length);
30066
+ const path96 = fileFlag.slice("--token-file=".length);
30074
30067
  try {
30075
- const content = fs66.readFileSync(path95, "utf8").trim();
30076
- if (content.length === 0) fail(`--token-file ${path95} is empty`);
30077
- rmIfExistsQuiet(path95);
30068
+ const content = fs66.readFileSync(path96, "utf8").trim();
30069
+ if (content.length === 0) fail(`--token-file ${path96} is empty`);
30070
+ rmIfExistsQuiet(path96);
30078
30071
  return content;
30079
30072
  } catch (err) {
30080
30073
  fail(`Could not read --token-file: ${err.message}`);
@@ -30166,12 +30159,12 @@ async function claim(token, pluginId, pluginSecretHash) {
30166
30159
  }
30167
30160
  }
30168
30161
  function pairAutoLockPath() {
30169
- return path72.join(os55.homedir(), ".codeam", "pair-auto.lock");
30162
+ return path73.join(os55.homedir(), ".codeam", "pair-auto.lock");
30170
30163
  }
30171
30164
  var procRoot = "/proc";
30172
30165
  function readProcFile(rel) {
30173
30166
  try {
30174
- return fs66.readFileSync(path72.join(procRoot, rel), "utf8");
30167
+ return fs66.readFileSync(path73.join(procRoot, rel), "utf8");
30175
30168
  } catch {
30176
30169
  return void 0;
30177
30170
  }
@@ -30247,12 +30240,12 @@ function releaseOwnLock(lockPath) {
30247
30240
  }
30248
30241
  function daemonLockPath(sessionId) {
30249
30242
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
30250
- return path72.join(os55.homedir(), ".codeam", `daemon-${safe}.lock`);
30243
+ return path73.join(os55.homedir(), ".codeam", `daemon-${safe}.lock`);
30251
30244
  }
30252
30245
  function acquireDaemonLock(sessionId) {
30253
30246
  const lockPath = daemonLockPath(sessionId);
30254
30247
  try {
30255
- fs66.mkdirSync(path72.dirname(lockPath), { recursive: true });
30248
+ fs66.mkdirSync(path73.dirname(lockPath), { recursive: true });
30256
30249
  try {
30257
30250
  fs66.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
30258
30251
  } catch (e) {
@@ -30278,7 +30271,7 @@ function acquireDaemonLock(sessionId) {
30278
30271
  function acquireSingletonLock() {
30279
30272
  const lockPath = pairAutoLockPath();
30280
30273
  try {
30281
- fs66.mkdirSync(path72.dirname(lockPath), { recursive: true });
30274
+ fs66.mkdirSync(path73.dirname(lockPath), { recursive: true });
30282
30275
  try {
30283
30276
  fs66.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
30284
30277
  } catch (e) {
@@ -30732,7 +30725,7 @@ var AgentService = class _AgentService {
30732
30725
  };
30733
30726
 
30734
30727
  // src/agents/acp/adapters.ts
30735
- var path73 = __toESM(require("path"));
30728
+ var path74 = __toESM(require("path"));
30736
30729
 
30737
30730
  // src/agents/kimi/installer.ts
30738
30731
  var import_node_child_process27 = require("child_process");
@@ -30852,13 +30845,13 @@ function resolveBin(pkgName, binName) {
30852
30845
  try {
30853
30846
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
30854
30847
  const manifest = require_(`${pkgName}/package.json`);
30855
- const pkgDir = path73.dirname(manifestPath);
30848
+ const pkgDir = path74.dirname(manifestPath);
30856
30849
  const bin = manifest.bin;
30857
30850
  if (!bin) return null;
30858
- if (typeof bin === "string") return path73.resolve(pkgDir, bin);
30851
+ if (typeof bin === "string") return path74.resolve(pkgDir, bin);
30859
30852
  const target = binName ?? Object.keys(bin)[0];
30860
30853
  if (!target || !bin[target]) return null;
30861
- return path73.resolve(pkgDir, bin[target]);
30854
+ return path74.resolve(pkgDir, bin[target]);
30862
30855
  } catch {
30863
30856
  return null;
30864
30857
  }
@@ -31041,14 +31034,14 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
31041
31034
  var import_node_crypto11 = require("crypto");
31042
31035
  var fs78 = __toESM(require("fs"));
31043
31036
  var os62 = __toESM(require("os"));
31044
- var path86 = __toESM(require("path"));
31037
+ var path87 = __toESM(require("path"));
31045
31038
 
31046
31039
  // src/services/history.service.ts
31047
31040
  var fs67 = __toESM(require("fs"));
31048
- var path74 = __toESM(require("path"));
31041
+ var path75 = __toESM(require("path"));
31049
31042
  var os56 = __toESM(require("os"));
31050
31043
  var https7 = __toESM(require("https"));
31051
- var http8 = __toESM(require("http"));
31044
+ var http9 = __toESM(require("http"));
31052
31045
  var import_zod2 = require("zod");
31053
31046
  var historyRecordSchema = import_zod2.z.object({
31054
31047
  type: import_zod2.z.string().optional(),
@@ -31151,7 +31144,7 @@ function postWithStatus(endpoint, body, pluginAuthToken) {
31151
31144
  return new Promise((resolve11) => {
31152
31145
  const payload = JSON.stringify(body);
31153
31146
  const u2 = new URL(`${API_BASE8}${endpoint}`);
31154
- const transport = u2.protocol === "https:" ? https7 : http8;
31147
+ const transport = u2.protocol === "https:" ? https7 : http9;
31155
31148
  const req = transport.request(
31156
31149
  {
31157
31150
  hostname: u2.hostname,
@@ -31261,7 +31254,7 @@ var HistoryService = class _HistoryService {
31261
31254
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
31262
31255
  }
31263
31256
  get projectDir() {
31264
- return this.runtime.resolveHistoryDir(this.cwd) ?? path74.join(os56.homedir(), ".claude", "projects", encodeCwd(this.cwd));
31257
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path75.join(os56.homedir(), ".claude", "projects", encodeCwd(this.cwd));
31265
31258
  }
31266
31259
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
31267
31260
  setCurrentConversationId(id) {
@@ -31273,7 +31266,7 @@ var HistoryService = class _HistoryService {
31273
31266
  /** Return the current message count in the active conversation. */
31274
31267
  getCurrentMessageCount() {
31275
31268
  if (!this.currentConversationId) return 0;
31276
- const filePath = path74.join(this.projectDir, `${this.currentConversationId}.jsonl`);
31269
+ const filePath = path75.join(this.projectDir, `${this.currentConversationId}.jsonl`);
31277
31270
  return parseJsonl(filePath).length;
31278
31271
  }
31279
31272
  /**
@@ -31284,7 +31277,7 @@ var HistoryService = class _HistoryService {
31284
31277
  const deadline = Date.now() + timeoutMs;
31285
31278
  while (Date.now() < deadline) {
31286
31279
  if (!this.currentConversationId) return null;
31287
- const filePath = path74.join(this.projectDir, `${this.currentConversationId}.jsonl`);
31280
+ const filePath = path75.join(this.projectDir, `${this.currentConversationId}.jsonl`);
31288
31281
  const messages = parseJsonl(filePath);
31289
31282
  if (messages.length > previousCount) {
31290
31283
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -31312,14 +31305,14 @@ var HistoryService = class _HistoryService {
31312
31305
  try {
31313
31306
  const files = fs67.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
31314
31307
  try {
31315
- const stat3 = fs67.statSync(path74.join(dir, e.name));
31308
+ const stat3 = fs67.statSync(path75.join(dir, e.name));
31316
31309
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
31317
31310
  } catch {
31318
31311
  return { name: e.name, mtime: 0, birthtime: 0 };
31319
31312
  }
31320
31313
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
31321
31314
  if (files.length > 0) {
31322
- this.currentConversationId = path74.basename(files[0].name, ".jsonl");
31315
+ this.currentConversationId = path75.basename(files[0].name, ".jsonl");
31323
31316
  }
31324
31317
  } catch {
31325
31318
  }
@@ -31359,7 +31352,7 @@ var HistoryService = class _HistoryService {
31359
31352
  }
31360
31353
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
31361
31354
  try {
31362
- const stat3 = fs67.statSync(path74.join(dir, e.name));
31355
+ const stat3 = fs67.statSync(path75.join(dir, e.name));
31363
31356
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
31364
31357
  } catch {
31365
31358
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -31368,7 +31361,7 @@ var HistoryService = class _HistoryService {
31368
31361
  if (files.length === 0) return null;
31369
31362
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
31370
31363
  if (!files.some((f) => f.name === targetFile)) return null;
31371
- return this.extractUsageFromFile(path74.join(dir, targetFile));
31364
+ return this.extractUsageFromFile(path75.join(dir, targetFile));
31372
31365
  }
31373
31366
  extractUsageFromFile(filePath) {
31374
31367
  let raw;
@@ -31427,7 +31420,7 @@ var HistoryService = class _HistoryService {
31427
31420
  try {
31428
31421
  files = fs67.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
31429
31422
  try {
31430
- return fs67.statSync(path74.join(projectDir, f)).mtimeMs >= monthStartMs;
31423
+ return fs67.statSync(path75.join(projectDir, f)).mtimeMs >= monthStartMs;
31431
31424
  } catch {
31432
31425
  return false;
31433
31426
  }
@@ -31438,7 +31431,7 @@ var HistoryService = class _HistoryService {
31438
31431
  for (const file of files) {
31439
31432
  let raw;
31440
31433
  try {
31441
- raw = fs67.readFileSync(path74.join(projectDir, file), "utf8");
31434
+ raw = fs67.readFileSync(path75.join(projectDir, file), "utf8");
31442
31435
  } catch {
31443
31436
  continue;
31444
31437
  }
@@ -31517,7 +31510,7 @@ var HistoryService = class _HistoryService {
31517
31510
  if (this.runtime.resolveHistoryFile) {
31518
31511
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
31519
31512
  }
31520
- return path74.join(this.projectDir, `${sessionId}.jsonl`);
31513
+ return path75.join(this.projectDir, `${sessionId}.jsonl`);
31521
31514
  }
31522
31515
  /**
31523
31516
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -31555,7 +31548,7 @@ var HistoryService = class _HistoryService {
31555
31548
  };
31556
31549
  });
31557
31550
  }
31558
- return parseJsonl(path74.join(this.projectDir, `${sessionId}.jsonl`));
31551
+ return parseJsonl(path75.join(this.projectDir, `${sessionId}.jsonl`));
31559
31552
  }
31560
31553
  /** One in-flight full upload per conversation — the baton mirror and a
31561
31554
  * `get_conversation` used to upload the same transcript concurrently. */
@@ -31715,7 +31708,7 @@ var import_node_child_process29 = require("child_process");
31715
31708
  var fs68 = __toESM(require("fs/promises"));
31716
31709
  var fsSync = __toESM(require("fs"));
31717
31710
  var os58 = __toESM(require("os"));
31718
- var path76 = __toESM(require("path"));
31711
+ var path77 = __toESM(require("path"));
31719
31712
  var import_node_stream = require("stream");
31720
31713
 
31721
31714
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -35741,7 +35734,7 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
35741
35734
  }
35742
35735
 
35743
35736
  // src/agents/acp/internal-paths.ts
35744
- var path75 = __toESM(require("path"));
35737
+ var path76 = __toESM(require("path"));
35745
35738
  var os57 = __toESM(require("os"));
35746
35739
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
35747
35740
  var PROSE_ONLY_TOOL_KINDS = /* @__PURE__ */ new Set(["think", "switch_mode"]);
@@ -35756,11 +35749,11 @@ function textReferencesInternal(text) {
35756
35749
  }
35757
35750
  function pathIsInternal(p2, homeDir2 = os57.homedir()) {
35758
35751
  if (!p2) return false;
35759
- const abs = path75.resolve(p2);
35760
- const home = path75.resolve(homeDir2);
35761
- const within = (root) => abs === root || abs.startsWith(root + path75.sep);
35762
- if (within(path75.join(home, ".codeam", "self-hosted"))) return false;
35763
- return within(path75.join(home, ".codeam")) || within(path75.join(home, ".beads")) || abs === path75.join(home, ".codeam-host.log") || abs.includes(`${path75.sep}house-claude${path75.sep}`) || abs.endsWith(`${path75.sep}house-claude`);
35752
+ const abs = path76.resolve(p2);
35753
+ const home = path76.resolve(homeDir2);
35754
+ const within = (root) => abs === root || abs.startsWith(root + path76.sep);
35755
+ if (within(path76.join(home, ".codeam", "self-hosted"))) return false;
35756
+ return within(path76.join(home, ".codeam")) || within(path76.join(home, ".beads")) || abs === path76.join(home, ".codeam-host.log") || abs.includes(`${path76.sep}house-claude${path76.sep}`) || abs.endsWith(`${path76.sep}house-claude`);
35764
35757
  }
35765
35758
  function toolCallReferencesInternal(call, homeDir2) {
35766
35759
  if (call.locations?.some((l) => pathIsInternal(l.path, homeDir2))) return true;
@@ -36958,25 +36951,25 @@ function knownAgentBinaryDirs() {
36958
36951
  out2.push("/tmp/codeam-node20/bin");
36959
36952
  for (const root of [
36960
36953
  "/usr/local/share/nvm/versions/node",
36961
- path76.join(home, ".nvm/versions/node")
36954
+ path77.join(home, ".nvm/versions/node")
36962
36955
  ]) {
36963
36956
  try {
36964
36957
  for (const child of fsSync.readdirSync(root)) {
36965
- out2.push(path76.join(root, child, "bin"));
36958
+ out2.push(path77.join(root, child, "bin"));
36966
36959
  }
36967
36960
  } catch {
36968
36961
  }
36969
36962
  }
36970
- out2.push(path76.join(home, ".volta/bin"));
36963
+ out2.push(path77.join(home, ".volta/bin"));
36971
36964
  out2.push("/usr/local/bin");
36972
36965
  out2.push("/usr/bin");
36973
- out2.push(path76.join(home, ".local/bin"));
36974
- out2.push(path76.join(home, "bin"));
36966
+ out2.push(path77.join(home, ".local/bin"));
36967
+ out2.push(path77.join(home, "bin"));
36975
36968
  out2.push(...agentInstallBinDirs());
36976
36969
  if (process.platform === "win32") {
36977
36970
  const { LOCALAPPDATA, APPDATA } = process.env;
36978
- if (LOCALAPPDATA) out2.push(path76.join(LOCALAPPDATA, "cursor-agent"));
36979
- if (APPDATA) out2.push(path76.join(APPDATA, "npm"));
36971
+ if (LOCALAPPDATA) out2.push(path77.join(LOCALAPPDATA, "cursor-agent"));
36972
+ if (APPDATA) out2.push(path77.join(APPDATA, "npm"));
36980
36973
  }
36981
36974
  return out2.filter((p2) => {
36982
36975
  try {
@@ -36987,7 +36980,7 @@ function knownAgentBinaryDirs() {
36987
36980
  });
36988
36981
  }
36989
36982
  function expandPathForAgentBinaries(existingPath) {
36990
- const existing = new Set(existingPath.split(path76.delimiter).filter((p2) => p2.length > 0));
36983
+ const existing = new Set(existingPath.split(path77.delimiter).filter((p2) => p2.length > 0));
36991
36984
  const additions = [];
36992
36985
  for (const dir of knownAgentBinaryDirs()) {
36993
36986
  if (!existing.has(dir)) {
@@ -36996,7 +36989,7 @@ function expandPathForAgentBinaries(existingPath) {
36996
36989
  }
36997
36990
  }
36998
36991
  if (additions.length === 0) return existingPath;
36999
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path76.delimiter);
36992
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path77.delimiter);
37000
36993
  }
37001
36994
 
37002
36995
  // src/agents/acp/headroom-budget-proxy.ts
@@ -37232,7 +37225,7 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
37232
37225
  }
37233
37226
 
37234
37227
  // src/services/streaming/transport.ts
37235
- var http9 = __toESM(require("http"));
37228
+ var http10 = __toESM(require("http"));
37236
37229
  var https8 = __toESM(require("https"));
37237
37230
  var _transport4 = {
37238
37231
  post: _post3,
@@ -37242,7 +37235,7 @@ function _post3(url2, headers, payload) {
37242
37235
  return new Promise((resolve11, reject) => {
37243
37236
  let settled = false;
37244
37237
  const u2 = new URL(url2);
37245
- const lib = u2.protocol === "https:" ? https8 : http9;
37238
+ const lib = u2.protocol === "https:" ? https8 : http10;
37246
37239
  const req = lib.request(
37247
37240
  {
37248
37241
  hostname: u2.hostname,
@@ -37284,7 +37277,7 @@ function _get(url2, headers) {
37284
37277
  return new Promise((resolve11, reject) => {
37285
37278
  let settled = false;
37286
37279
  const u2 = new URL(url2);
37287
- const lib = u2.protocol === "https:" ? https8 : http9;
37280
+ const lib = u2.protocol === "https:" ? https8 : http10;
37288
37281
  const req = lib.request(
37289
37282
  {
37290
37283
  hostname: u2.hostname,
@@ -37921,12 +37914,12 @@ function withholdTrailingPartialFenceMarker(text) {
37921
37914
  var import_child_process30 = require("child_process");
37922
37915
  var fs69 = __toESM(require("fs"));
37923
37916
  var os59 = __toESM(require("os"));
37924
- var path77 = __toESM(require("path"));
37917
+ var path78 = __toESM(require("path"));
37925
37918
  var _onboardingSeam = {
37926
- markerPath: (sessionId) => path77.join(os59.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
37919
+ markerPath: (sessionId) => path78.join(os59.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
37927
37920
  exists: (p2) => fs69.existsSync(p2),
37928
37921
  write: (p2) => {
37929
- fs69.mkdirSync(path77.dirname(p2), { recursive: true });
37922
+ fs69.mkdirSync(path78.dirname(p2), { recursive: true });
37930
37923
  fs69.writeFileSync(p2, "");
37931
37924
  },
37932
37925
  disabled: () => {
@@ -37964,7 +37957,7 @@ function resolveRepoName(cwd) {
37964
37957
  if (name) return name;
37965
37958
  }
37966
37959
  }
37967
- const base = path77.basename(cwd || "");
37960
+ const base = path78.basename(cwd || "");
37968
37961
  if (base && !isUuid(base)) return base;
37969
37962
  return "this project";
37970
37963
  }
@@ -38297,12 +38290,12 @@ var import_crypto5 = require("crypto");
38297
38290
  // src/services/turn-files/git-changeset.ts
38298
38291
  var import_child_process31 = require("child_process");
38299
38292
  var fs71 = __toESM(require("fs/promises"));
38300
- var path79 = __toESM(require("path"));
38293
+ var path80 = __toESM(require("path"));
38301
38294
 
38302
38295
  // src/services/turn-files/review-ignore.ts
38303
38296
  var import_ignore2 = __toESM(require("ignore"));
38304
38297
  var fs70 = __toESM(require("fs"));
38305
- var path78 = __toESM(require("path"));
38298
+ var path79 = __toESM(require("path"));
38306
38299
  var CURATED_REVIEW_IGNORE = [
38307
38300
  // Google Cloud SDK (the incident) — installs a huge python tree.
38308
38301
  "google-cloud-sdk/",
@@ -38341,7 +38334,7 @@ var CURATED_REVIEW_IGNORE = [
38341
38334
  function makeReviewIgnore(repoRoot) {
38342
38335
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
38343
38336
  try {
38344
- const custom = fs70.readFileSync(path78.join(repoRoot, ".codeam", "reviewignore"), "utf8");
38337
+ const custom = fs70.readFileSync(path79.join(repoRoot, ".codeam", "reviewignore"), "utf8");
38345
38338
  ig.add(custom);
38346
38339
  } catch {
38347
38340
  }
@@ -38386,7 +38379,7 @@ async function collectRepoChangeset(opts) {
38386
38379
  let stats;
38387
38380
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
38388
38381
  const lineCount = await readUntrackedLineCount(
38389
- path79.join(opts.repoRoot, row.filePath)
38382
+ path80.join(opts.repoRoot, row.filePath)
38390
38383
  );
38391
38384
  stats = { added: lineCount, removed: 0 };
38392
38385
  } else {
@@ -38528,8 +38521,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
38528
38521
  if (hasGit) {
38529
38522
  out2.push({
38530
38523
  repoRoot: dir,
38531
- repoPath: path79.relative(workingDir, dir),
38532
- repoName: path79.basename(dir)
38524
+ repoPath: path80.relative(workingDir, dir),
38525
+ repoName: path80.basename(dir)
38533
38526
  });
38534
38527
  return;
38535
38528
  }
@@ -38537,14 +38530,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
38537
38530
  if (!entry.isDirectory) continue;
38538
38531
  if (entry.name === "node_modules") continue;
38539
38532
  if (entry.name === "dist" || entry.name === "build") continue;
38540
- await walk(path79.join(dir, entry.name), depth + 1);
38533
+ await walk(path80.join(dir, entry.name), depth + 1);
38541
38534
  }
38542
38535
  }
38543
38536
  }
38544
38537
 
38545
38538
  // src/services/turn-files/files-outbox.ts
38546
38539
  var fs72 = __toESM(require("fs/promises"));
38547
- var path80 = __toESM(require("path"));
38540
+ var path81 = __toESM(require("path"));
38548
38541
  var import_os12 = require("os");
38549
38542
  var HOME_OUTBOX_DIR = ".codeam/outbox";
38550
38543
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -38577,15 +38570,15 @@ var FilesOutbox = class {
38577
38570
  backoffIndex = 0;
38578
38571
  stopped = false;
38579
38572
  constructor(opts) {
38580
- const base = opts.baseDir ?? path80.join(homeDir(), HOME_OUTBOX_DIR);
38581
- this.filePath = path80.join(base, `${opts.sessionId}.jsonl`);
38573
+ const base = opts.baseDir ?? path81.join(homeDir(), HOME_OUTBOX_DIR);
38574
+ this.filePath = path81.join(base, `${opts.sessionId}.jsonl`);
38582
38575
  this.post = opts.post;
38583
38576
  this.autoSchedule = opts.autoSchedule !== false;
38584
38577
  }
38585
38578
  /** Persist the entry to disk and trigger a flush. Returns once the
38586
38579
  * line is durable on disk (not once the POST succeeds). */
38587
38580
  async enqueue(entry) {
38588
- await fs72.mkdir(path80.dirname(this.filePath), { recursive: true });
38581
+ await fs72.mkdir(path81.dirname(this.filePath), { recursive: true });
38589
38582
  await fs72.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
38590
38583
  this.backoffIndex = 0;
38591
38584
  if (this.autoSchedule) this.scheduleFlush(0);
@@ -39224,7 +39217,7 @@ async function postBudgetReached(opts, fetchImpl = fetch) {
39224
39217
  // src/packs/gates.ts
39225
39218
  var import_node_child_process30 = require("child_process");
39226
39219
  var fs73 = __toESM(require("fs"));
39227
- var path81 = __toESM(require("path"));
39220
+ var path82 = __toESM(require("path"));
39228
39221
  var defaultCommandRunner = (file, args2, cwd, timeoutMs) => new Promise((resolve11) => {
39229
39222
  (0, import_node_child_process30.execFile)(
39230
39223
  file,
@@ -39261,14 +39254,14 @@ var NO_TEST_PLACEHOLDER = 'echo "Error: no test specified"';
39261
39254
  var CHECKS_TIMEOUT_MS = 5 * 6e4;
39262
39255
  function detectChecksCommand(cwd) {
39263
39256
  try {
39264
- const cfg = JSON.parse(fs73.readFileSync(path81.join(cwd, ".codeam", "pack.json"), "utf8"));
39257
+ const cfg = JSON.parse(fs73.readFileSync(path82.join(cwd, ".codeam", "pack.json"), "utf8"));
39265
39258
  if (typeof cfg.checksCommand === "string" && cfg.checksCommand.trim().length > 0) {
39266
39259
  return cfg.checksCommand.trim();
39267
39260
  }
39268
39261
  } catch {
39269
39262
  }
39270
39263
  try {
39271
- const pkg = JSON.parse(fs73.readFileSync(path81.join(cwd, "package.json"), "utf8"));
39264
+ const pkg = JSON.parse(fs73.readFileSync(path82.join(cwd, "package.json"), "utf8"));
39272
39265
  const test = pkg.scripts?.test;
39273
39266
  if (typeof test === "string" && test.trim().length > 0 && !test.includes(NO_TEST_PLACEHOLDER)) {
39274
39267
  return "npm test";
@@ -39287,36 +39280,36 @@ ${res.stderr}`.trim();
39287
39280
 
39288
39281
  // src/packs/run-store.ts
39289
39282
  var fs74 = __toESM(require("fs"));
39290
- var path82 = __toESM(require("path"));
39283
+ var path83 = __toESM(require("path"));
39291
39284
  var crypto5 = __toESM(require("crypto"));
39292
39285
  function packsDir(cwd) {
39293
- return path82.join(cwd, ".codeam", "packs");
39286
+ return path83.join(cwd, ".codeam", "packs");
39294
39287
  }
39295
39288
  function runDir(cwd, runId) {
39296
- return path82.join(packsDir(cwd), runId);
39289
+ return path83.join(packsDir(cwd), runId);
39297
39290
  }
39298
39291
  function newRunId() {
39299
39292
  return `pk_${Date.now().toString(36)}_${crypto5.randomBytes(4).toString("hex")}`;
39300
39293
  }
39301
39294
  function writeJsonAtomic(file, value) {
39302
- fs74.mkdirSync(path82.dirname(file), { recursive: true });
39295
+ fs74.mkdirSync(path83.dirname(file), { recursive: true });
39303
39296
  const tmp = `${file}.tmp`;
39304
39297
  fs74.writeFileSync(tmp, JSON.stringify(value, null, 2));
39305
39298
  fs74.renameSync(tmp, file);
39306
39299
  }
39307
39300
  function saveRun(cwd, state) {
39308
- writeJsonAtomic(path82.join(runDir(cwd, state.runId), "run.json"), state);
39301
+ writeJsonAtomic(path83.join(runDir(cwd, state.runId), "run.json"), state);
39309
39302
  }
39310
39303
  function saveStageHandoff(cwd, runId, stageIndex, role, handoff) {
39311
39304
  const name = `${String(stageIndex + 1).padStart(2, "0")}-${role}.json`;
39312
- writeJsonAtomic(path82.join(runDir(cwd, runId), name), handoff);
39305
+ writeJsonAtomic(path83.join(runDir(cwd, runId), name), handoff);
39313
39306
  }
39314
39307
  function loadLatestRun(cwd) {
39315
39308
  try {
39316
39309
  const dir = packsDir(cwd);
39317
39310
  const entries = fs74.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
39318
39311
  for (let i = entries.length - 1; i >= 0; i--) {
39319
- const file = path82.join(dir, entries[i], "run.json");
39312
+ const file = path83.join(dir, entries[i], "run.json");
39320
39313
  try {
39321
39314
  const parsed = JSON.parse(fs74.readFileSync(file, "utf8"));
39322
39315
  if (parsed && typeof parsed.runId === "string") return parsed;
@@ -39329,16 +39322,16 @@ function loadLatestRun(cwd) {
39329
39322
  }
39330
39323
  function ensureLedgerIgnored(cwd) {
39331
39324
  try {
39332
- const gitDir = path82.join(cwd, ".git");
39325
+ const gitDir = path83.join(cwd, ".git");
39333
39326
  if (!fs74.existsSync(gitDir)) return;
39334
- const exclude = path82.join(gitDir, "info", "exclude");
39327
+ const exclude = path83.join(gitDir, "info", "exclude");
39335
39328
  let existing = "";
39336
39329
  try {
39337
39330
  existing = fs74.readFileSync(exclude, "utf8");
39338
39331
  } catch {
39339
39332
  }
39340
39333
  if (existing.includes(".codeam/packs/")) return;
39341
- fs74.mkdirSync(path82.dirname(exclude), { recursive: true });
39334
+ fs74.mkdirSync(path83.dirname(exclude), { recursive: true });
39342
39335
  fs74.writeFileSync(exclude, `${existing.trimEnd()}
39343
39336
  .codeam/packs/
39344
39337
  `.trimStart());
@@ -40283,18 +40276,18 @@ function buildAcpPromptBlocks(payload) {
40283
40276
 
40284
40277
  // src/agents/agent-standard.ts
40285
40278
  var fs77 = __toESM(require("fs"));
40286
- var path85 = __toESM(require("path"));
40279
+ var path86 = __toESM(require("path"));
40287
40280
  var os61 = __toESM(require("os"));
40288
40281
  function ensureAgentStandard(homeDir2 = os61.homedir()) {
40289
40282
  try {
40290
- const file = path85.join(homeDir2, ".claude", "CLAUDE.md");
40283
+ const file = path86.join(homeDir2, ".claude", "CLAUDE.md");
40291
40284
  let existing = "";
40292
40285
  try {
40293
40286
  existing = fs77.readFileSync(file, "utf8");
40294
40287
  } catch {
40295
40288
  }
40296
40289
  if (existing.includes(AGENT_STANDARD_MARKER)) return;
40297
- fs77.mkdirSync(path85.dirname(file), { recursive: true });
40290
+ fs77.mkdirSync(path86.dirname(file), { recursive: true });
40298
40291
  const next = existing.trim() ? `${existing.trimEnd()}
40299
40292
 
40300
40293
  ${AGENT_STANDARD_BLOCK}
@@ -40306,10 +40299,10 @@ ${AGENT_STANDARD_BLOCK}
40306
40299
  }
40307
40300
  var _agentStandardSeam = {
40308
40301
  isLocalSession: () => isLocalSession(),
40309
- markerPath: (sessionId) => path85.join(os61.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
40302
+ markerPath: (sessionId) => path86.join(os61.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
40310
40303
  exists: (p2) => fs77.existsSync(p2),
40311
40304
  write: (p2) => {
40312
- fs77.mkdirSync(path85.dirname(p2), { recursive: true });
40305
+ fs77.mkdirSync(path86.dirname(p2), { recursive: true });
40313
40306
  fs77.writeFileSync(p2, "");
40314
40307
  }
40315
40308
  };
@@ -42388,7 +42381,7 @@ async function runAcpSession(opts) {
42388
42381
  switchCredentialEnv = provisionAgentCredentials(agentId, auth);
42389
42382
  },
42390
42383
  provisionHouseProxy: ({ baseUrl, token }) => {
42391
- const claudeConfigDir = path86.join(
42384
+ const claudeConfigDir = path87.join(
42392
42385
  os62.homedir(),
42393
42386
  ".codeam",
42394
42387
  "house-claude",
@@ -43598,7 +43591,7 @@ function startClaudeCredentialSync(opts) {
43598
43591
 
43599
43592
  // src/beads/workflow-hint.ts
43600
43593
  var fs79 = __toESM(require("fs"));
43601
- var path87 = __toESM(require("path"));
43594
+ var path88 = __toESM(require("path"));
43602
43595
  var os63 = __toESM(require("os"));
43603
43596
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
43604
43597
  var BEADS_HINT = `${BEADS_HINT_MARKER}
@@ -43615,14 +43608,14 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
43615
43608
  ${BEADS_HINT_MARKER}`;
43616
43609
  function ensureBeadsWorkflowHint(homeDir2 = os63.homedir()) {
43617
43610
  try {
43618
- const file = path87.join(homeDir2, ".claude", "CLAUDE.md");
43611
+ const file = path88.join(homeDir2, ".claude", "CLAUDE.md");
43619
43612
  let existing = "";
43620
43613
  try {
43621
43614
  existing = fs79.readFileSync(file, "utf8");
43622
43615
  } catch {
43623
43616
  }
43624
43617
  if (existing.includes(BEADS_HINT_MARKER)) return;
43625
- fs79.mkdirSync(path87.dirname(file), { recursive: true });
43618
+ fs79.mkdirSync(path88.dirname(file), { recursive: true });
43626
43619
  const next = existing.trim() ? `${existing.trimEnd()}
43627
43620
 
43628
43621
  ${BEADS_HINT}
@@ -44590,11 +44583,11 @@ function keepDeviceAwake(deps = {}) {
44590
44583
  // src/agents/claude/onboarding.ts
44591
44584
  var fs81 = __toESM(require("fs"));
44592
44585
  var os65 = __toESM(require("os"));
44593
- var path88 = __toESM(require("path"));
44586
+ var path89 = __toESM(require("path"));
44594
44587
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
44595
44588
  function ensureClaudeOnboarded(cwd) {
44596
44589
  try {
44597
- const file = path88.join(os65.homedir(), ".claude.json");
44590
+ const file = path89.join(os65.homedir(), ".claude.json");
44598
44591
  let config = {};
44599
44592
  try {
44600
44593
  config = JSON.parse(fs81.readFileSync(file, "utf8"));
@@ -44622,7 +44615,7 @@ function ensureClaudeOnboarded(cwd) {
44622
44615
  }
44623
44616
  }
44624
44617
  if (!changed) return;
44625
- fs81.mkdirSync(path88.dirname(file), { recursive: true });
44618
+ fs81.mkdirSync(path89.dirname(file), { recursive: true });
44626
44619
  fs81.writeFileSync(file, JSON.stringify(config, null, 2));
44627
44620
  log.info(
44628
44621
  "claude",
@@ -45386,7 +45379,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
45386
45379
  var import_child_process32 = require("child_process");
45387
45380
  var import_util4 = require("util");
45388
45381
  var import_picocolors9 = __toESM(require("picocolors"));
45389
- var path89 = __toESM(require("path"));
45382
+ var path90 = __toESM(require("path"));
45390
45383
  var execFileP6 = (0, import_util4.promisify)(import_child_process32.execFile);
45391
45384
  var MAX_BUFFER = 8 * 1024 * 1024;
45392
45385
  function resetStdinForChild() {
@@ -45875,7 +45868,7 @@ var GitHubCodespacesProvider = class {
45875
45868
  });
45876
45869
  }
45877
45870
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
45878
- const remoteDir = path89.posix.dirname(remotePath);
45871
+ const remoteDir = path90.posix.dirname(remotePath);
45879
45872
  const parts = [
45880
45873
  `mkdir -p ${shellQuote(remoteDir)}`,
45881
45874
  `cat > ${shellQuote(remotePath)}`
@@ -45945,7 +45938,7 @@ function shellQuote(s) {
45945
45938
  // src/services/providers/gitpod.ts
45946
45939
  var import_child_process33 = require("child_process");
45947
45940
  var import_util5 = require("util");
45948
- var path90 = __toESM(require("path"));
45941
+ var path91 = __toESM(require("path"));
45949
45942
  var import_picocolors10 = __toESM(require("picocolors"));
45950
45943
  var execFileP7 = (0, import_util5.promisify)(import_child_process33.execFile);
45951
45944
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -46185,7 +46178,7 @@ var GitpodProvider = class {
46185
46178
  });
46186
46179
  }
46187
46180
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46188
- const remoteDir = path90.posix.dirname(remotePath);
46181
+ const remoteDir = path91.posix.dirname(remotePath);
46189
46182
  const parts = [
46190
46183
  `mkdir -p ${shellQuote2(remoteDir)}`,
46191
46184
  `cat > ${shellQuote2(remotePath)}`
@@ -46221,7 +46214,7 @@ function shellQuote2(s) {
46221
46214
  // src/services/providers/gitlab-workspaces.ts
46222
46215
  var import_child_process34 = require("child_process");
46223
46216
  var import_util6 = require("util");
46224
- var path91 = __toESM(require("path"));
46217
+ var path92 = __toESM(require("path"));
46225
46218
  var execFileP8 = (0, import_util6.promisify)(import_child_process34.execFile);
46226
46219
  var MAX_BUFFER3 = 8 * 1024 * 1024;
46227
46220
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -46481,7 +46474,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
46481
46474
  }
46482
46475
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
46483
46476
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
46484
- const remoteDir = path91.posix.dirname(remotePath);
46477
+ const remoteDir = path92.posix.dirname(remotePath);
46485
46478
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
46486
46479
  if (options.mode != null) {
46487
46480
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -46549,7 +46542,7 @@ function shellQuote3(s) {
46549
46542
  // src/services/providers/railway.ts
46550
46543
  var import_child_process35 = require("child_process");
46551
46544
  var import_util7 = require("util");
46552
- var path92 = __toESM(require("path"));
46545
+ var path93 = __toESM(require("path"));
46553
46546
  var execFileP9 = (0, import_util7.promisify)(import_child_process35.execFile);
46554
46547
  var MAX_BUFFER4 = 8 * 1024 * 1024;
46555
46548
  function resetStdinForChild4() {
@@ -46785,7 +46778,7 @@ var RailwayProvider = class {
46785
46778
  if (!projectId || !serviceId) {
46786
46779
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
46787
46780
  }
46788
- const remoteDir = path92.posix.dirname(remotePath);
46781
+ const remoteDir = path93.posix.dirname(remotePath);
46789
46782
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
46790
46783
  if (options.mode != null) {
46791
46784
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -47432,7 +47425,7 @@ var import_node_dns = require("dns");
47432
47425
  var import_node_util5 = require("util");
47433
47426
  var import_node_crypto13 = require("crypto");
47434
47427
  var fs82 = __toESM(require("fs"));
47435
- var path93 = __toESM(require("path"));
47428
+ var path94 = __toESM(require("path"));
47436
47429
  var import_picocolors14 = __toESM(require("picocolors"));
47437
47430
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
47438
47431
  async function checkDns(apiBase2) {
@@ -47488,10 +47481,10 @@ async function checkHealth(apiBase2) {
47488
47481
  }
47489
47482
  }
47490
47483
  function checkConfigDir() {
47491
- const dir = path93.join(require("os").homedir(), ".codeam");
47484
+ const dir = path94.join(require("os").homedir(), ".codeam");
47492
47485
  try {
47493
47486
  fs82.mkdirSync(dir, { recursive: true, mode: 448 });
47494
- const probe = path93.join(dir, ".doctor-probe");
47487
+ const probe = path94.join(dir, ".doctor-probe");
47495
47488
  fs82.writeFileSync(probe, "ok", { mode: 384 });
47496
47489
  const read2 = fs82.readFileSync(probe, "utf8");
47497
47490
  fs82.unlinkSync(probe);
@@ -47558,7 +47551,7 @@ function checkNodePty() {
47558
47551
  detail: "not required on this platform"
47559
47552
  };
47560
47553
  }
47561
- const vendoredPath = path93.join(__dirname, "vendor", "node-pty");
47554
+ const vendoredPath = path94.join(__dirname, "vendor", "node-pty");
47562
47555
  for (const target of [vendoredPath, "node-pty"]) {
47563
47556
  try {
47564
47557
  require(target);
@@ -47600,7 +47593,7 @@ function checkChokidar() {
47600
47593
  }
47601
47594
  async function doctor(args2 = []) {
47602
47595
  const json = args2.includes("--json");
47603
- const cliVersion = true ? "2.74.8" : "0.0.0-dev";
47596
+ const cliVersion = true ? "2.74.9" : "0.0.0-dev";
47604
47597
  const apiBase2 = resolveApiBaseUrl();
47605
47598
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
47606
47599
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -48124,7 +48117,7 @@ async function mcpWarm(argv = [], opts = {}) {
48124
48117
  // src/commands/version.ts
48125
48118
  var import_picocolors15 = __toESM(require("picocolors"));
48126
48119
  function version2() {
48127
- const v = true ? "2.74.8" : "unknown";
48120
+ const v = true ? "2.74.9" : "unknown";
48128
48121
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
48129
48122
  }
48130
48123