codeam-cli 2.76.21 → 2.76.23

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 +21 -0
  2. package/dist/index.js +753 -691
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3802,9 +3802,9 @@ var _default = makeConfig();
3802
3802
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, setSessionAgent, setSquadAuto, getSquadAuto, clearAll, saveCliConfig, loadCliConfig } = _default;
3803
3803
 
3804
3804
  // src/commands/pair-auto.ts
3805
- var fs66 = __toESM(require("fs"));
3806
- var os48 = __toESM(require("os"));
3807
- var path74 = __toESM(require("path"));
3805
+ var fs67 = __toESM(require("fs"));
3806
+ var os49 = __toESM(require("os"));
3807
+ var path75 = __toESM(require("path"));
3808
3808
  var import_crypto4 = require("crypto");
3809
3809
 
3810
3810
  // src/services/telemetry.service.ts
@@ -10617,7 +10617,7 @@ function readAnonId() {
10617
10617
  }
10618
10618
  function superProperties() {
10619
10619
  return {
10620
- cliVersion: true ? "2.76.21" : "0.0.0-dev",
10620
+ cliVersion: true ? "2.76.23" : "0.0.0-dev",
10621
10621
  nodeVersion: process.version,
10622
10622
  platform: process.platform,
10623
10623
  arch: process.arch,
@@ -10866,7 +10866,7 @@ var http = __toESM(require("http"));
10866
10866
  // package.json
10867
10867
  var package_default = {
10868
10868
  name: "codeam-cli",
10869
- version: "2.76.21",
10869
+ version: "2.76.23",
10870
10870
  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.",
10871
10871
  type: "commonjs",
10872
10872
  main: "dist/index.js",
@@ -11145,7 +11145,7 @@ async function postAiResult(input) {
11145
11145
  async function fetchNamedPreviewTunnel(input) {
11146
11146
  const res = await _transport.postJsonAuthed(
11147
11147
  `${API_BASE}/api/preview/tunnel`,
11148
- { pluginId: input.pluginId },
11148
+ { sessionId: input.sessionId, pluginId: input.pluginId },
11149
11149
  input.pluginAuthToken
11150
11150
  );
11151
11151
  const body = res;
@@ -12229,7 +12229,7 @@ var CommandRelayService = class _CommandRelayService {
12229
12229
  // fresh + clear the "CLI update available" banner after a self-update
12230
12230
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
12231
12231
  // pair/reconnect). Older backends ignore the extra field.
12232
- ..."2.76.21" ? { ideVersion: "2.76.21" } : {}
12232
+ ..."2.76.23" ? { ideVersion: "2.76.23" } : {}
12233
12233
  };
12234
12234
  try {
12235
12235
  const res = await _postJson(`${API_BASE2}/api/plugin/heartbeat`, body, this.pollSecretHeader());
@@ -13710,12 +13710,54 @@ function closeAllTerminals() {
13710
13710
  }
13711
13711
 
13712
13712
  // src/commands/start/handlers.ts
13713
- var fs65 = __toESM(require("fs"));
13714
- var os47 = __toESM(require("os"));
13715
- var path73 = __toESM(require("path"));
13713
+ var fs66 = __toESM(require("fs"));
13714
+ var os48 = __toESM(require("os"));
13715
+ var path74 = __toESM(require("path"));
13716
13716
  var import_crypto3 = require("crypto");
13717
13717
  var import_child_process25 = require("child_process");
13718
13718
 
13719
+ // src/services/turn-marker.ts
13720
+ var fs6 = __toESM(require("fs"));
13721
+ var os6 = __toESM(require("os"));
13722
+ var path7 = __toESM(require("path"));
13723
+ var depth = 0;
13724
+ function codeamHome() {
13725
+ return path7.join(os6.homedir(), ".codeam");
13726
+ }
13727
+ function turnMarkerPath(pid = process.pid, home = codeamHome()) {
13728
+ return path7.join(home, "turns", String(pid));
13729
+ }
13730
+ function mark() {
13731
+ try {
13732
+ const file = turnMarkerPath();
13733
+ fs6.mkdirSync(path7.dirname(file), { recursive: true });
13734
+ fs6.writeFileSync(file, String(Date.now()));
13735
+ } catch {
13736
+ }
13737
+ }
13738
+ function clear() {
13739
+ try {
13740
+ fs6.rmSync(turnMarkerPath(), { force: true });
13741
+ } catch {
13742
+ }
13743
+ }
13744
+ async function withTurnMarker(fn) {
13745
+ if (depth++ === 0) mark();
13746
+ try {
13747
+ return await fn();
13748
+ } finally {
13749
+ if (--depth === 0) clear();
13750
+ }
13751
+ }
13752
+ function isProcessMidTurn(pid, home) {
13753
+ if (!pid) return false;
13754
+ try {
13755
+ return fs6.existsSync(turnMarkerPath(pid, home));
13756
+ } catch {
13757
+ return false;
13758
+ }
13759
+ }
13760
+
13719
13761
  // src/lib/payload.ts
13720
13762
  var import_zod2 = require("zod");
13721
13763
  var fileEntrySchema = import_zod2.z.object({
@@ -13933,8 +13975,8 @@ function parsePayload2(schema, raw) {
13933
13975
  }
13934
13976
 
13935
13977
  // src/services/file-ops.service.ts
13936
- var fs6 = __toESM(require("fs/promises"));
13937
- var path7 = __toESM(require("path"));
13978
+ var fs7 = __toESM(require("fs/promises"));
13979
+ var path8 = __toESM(require("path"));
13938
13980
  var MAX_FILE_BYTES = 5 * 1024 * 1024;
13939
13981
  var MAX_WALK_DEPTH = 6;
13940
13982
  var MAX_VISITED_DIRS = 5e3;
@@ -13969,12 +14011,12 @@ var SUBDIR_IGNORE = /* @__PURE__ */ new Set([
13969
14011
  "__pycache__"
13970
14012
  ]);
13971
14013
  function isUnder(parent, candidate) {
13972
- const rel = path7.relative(parent, candidate);
13973
- return rel === "" || !rel.startsWith("..") && !path7.isAbsolute(rel);
14014
+ const rel = path8.relative(parent, candidate);
14015
+ return rel === "" || !rel.startsWith("..") && !path8.isAbsolute(rel);
13974
14016
  }
13975
14017
  async function isExistingFile(absPath) {
13976
14018
  try {
13977
- const stat3 = await fs6.stat(absPath);
14019
+ const stat3 = await fs7.stat(absPath);
13978
14020
  return stat3.isFile();
13979
14021
  } catch {
13980
14022
  return false;
@@ -13987,13 +14029,13 @@ async function walkForSuffix(dir, needleVariants, depth2, ctx) {
13987
14029
  ctx.visited++;
13988
14030
  let entries2 = [];
13989
14031
  try {
13990
- entries2 = await fs6.readdir(dir, { withFileTypes: true });
14032
+ entries2 = await fs7.readdir(dir, { withFileTypes: true });
13991
14033
  } catch {
13992
14034
  return;
13993
14035
  }
13994
14036
  for (const e of entries2) {
13995
14037
  if (!e.isFile()) continue;
13996
- const full = path7.join(dir, e.name);
14038
+ const full = path8.join(dir, e.name);
13997
14039
  if (needleVariants.some((needle) => full.endsWith(needle))) {
13998
14040
  ctx.matches.push(full);
13999
14041
  if (ctx.matches.length >= ctx.cap) return;
@@ -14003,21 +14045,21 @@ async function walkForSuffix(dir, needleVariants, depth2, ctx) {
14003
14045
  if (!e.isDirectory()) continue;
14004
14046
  if (SUBDIR_IGNORE.has(e.name)) continue;
14005
14047
  if (e.name.startsWith(".") && SUBDIR_IGNORE.has(e.name)) continue;
14006
- await walkForSuffix(path7.join(dir, e.name), needleVariants, depth2 + 1, ctx);
14048
+ await walkForSuffix(path8.join(dir, e.name), needleVariants, depth2 + 1, ctx);
14007
14049
  if (ctx.matches.length >= ctx.cap) return;
14008
14050
  }
14009
14051
  }
14010
14052
  async function findFile(rawPath) {
14011
14053
  const cwd = process.cwd();
14012
- if (path7.isAbsolute(rawPath)) {
14013
- const abs = path7.normalize(rawPath);
14054
+ if (path8.isAbsolute(rawPath)) {
14055
+ const abs = path8.normalize(rawPath);
14014
14056
  if (isUnder(cwd, abs) && await isExistingFile(abs)) return abs;
14015
14057
  }
14016
- const direct = path7.resolve(cwd, rawPath);
14058
+ const direct = path8.resolve(cwd, rawPath);
14017
14059
  if (isUnder(cwd, direct) && await isExistingFile(direct)) return direct;
14018
- const normalized = path7.normalize(rawPath).replace(/^[./\\]+/, "");
14060
+ const normalized = path8.normalize(rawPath).replace(/^[./\\]+/, "");
14019
14061
  const needles = [
14020
- `${path7.sep}${normalized}`,
14062
+ `${path8.sep}${normalized}`,
14021
14063
  `/${normalized}`
14022
14064
  ].filter((v, i, a) => a.indexOf(v) === i);
14023
14065
  const ctx = { visited: 0, matches: [], cap: 16 };
@@ -14031,7 +14073,7 @@ async function findWriteTarget(rawPath) {
14031
14073
  const found = await findFile(rawPath);
14032
14074
  if (found) return found;
14033
14075
  const cwd = process.cwd();
14034
- const fallback = path7.isAbsolute(rawPath) ? path7.normalize(rawPath) : path7.resolve(cwd, rawPath);
14076
+ const fallback = path8.isAbsolute(rawPath) ? path8.normalize(rawPath) : path8.resolve(cwd, rawPath);
14035
14077
  if (!isUnder(cwd, fallback)) return null;
14036
14078
  return fallback;
14037
14079
  }
@@ -14048,11 +14090,11 @@ async function readProjectFile(rawPath) {
14048
14090
  if (!abs) {
14049
14091
  return { error: `File not found in the project tree: ${rawPath}` };
14050
14092
  }
14051
- const stat3 = await fs6.stat(abs);
14093
+ const stat3 = await fs7.stat(abs);
14052
14094
  if (stat3.size > MAX_FILE_BYTES) {
14053
14095
  return { error: `File too large (${(stat3.size / 1024 / 1024).toFixed(1)} MB > ${MAX_FILE_BYTES / 1024 / 1024} MB).` };
14054
14096
  }
14055
- const buf = await fs6.readFile(abs);
14097
+ const buf = await fs7.readFile(abs);
14056
14098
  if (looksBinary(buf)) {
14057
14099
  return { error: "Binary file \u2014 refusing to open in a code editor." };
14058
14100
  }
@@ -14071,8 +14113,8 @@ async function writeProjectFile(rawPath, content) {
14071
14113
  if (Buffer.byteLength(content, "utf-8") > MAX_FILE_BYTES) {
14072
14114
  return { error: "Content too large." };
14073
14115
  }
14074
- await fs6.mkdir(path7.dirname(abs), { recursive: true });
14075
- await fs6.writeFile(abs, content, "utf-8");
14116
+ await fs7.mkdir(path8.dirname(abs), { recursive: true });
14117
+ await fs7.writeFile(abs, content, "utf-8");
14076
14118
  return { ok: true };
14077
14119
  } catch (e) {
14078
14120
  const msg = e instanceof Error ? e.message : "Write failed";
@@ -14083,8 +14125,8 @@ async function writeProjectFile(rawPath, content) {
14083
14125
  // src/services/project-ops.service.ts
14084
14126
  var import_child_process5 = require("child_process");
14085
14127
  var import_util = require("util");
14086
- var fs7 = __toESM(require("fs/promises"));
14087
- var path8 = __toESM(require("path"));
14128
+ var fs8 = __toESM(require("fs/promises"));
14129
+ var path9 = __toESM(require("path"));
14088
14130
  var execFileP = (0, import_util.promisify)(import_child_process5.execFile);
14089
14131
  var PROJECT_IGNORE = /* @__PURE__ */ new Set([
14090
14132
  "node_modules",
@@ -14138,7 +14180,7 @@ async function listProjectFiles(opts = {}) {
14138
14180
  }
14139
14181
  let entries2 = [];
14140
14182
  try {
14141
- entries2 = await fs7.readdir(dir, { withFileTypes: true });
14183
+ entries2 = await fs8.readdir(dir, { withFileTypes: true });
14142
14184
  } catch {
14143
14185
  return;
14144
14186
  }
@@ -14148,18 +14190,18 @@ async function listProjectFiles(opts = {}) {
14148
14190
  return;
14149
14191
  }
14150
14192
  if (isProjectIgnored(e.name)) continue;
14151
- const full = path8.join(dir, e.name);
14193
+ const full = path9.join(dir, e.name);
14152
14194
  if (e.isDirectory()) {
14153
14195
  if (depth2 >= 12) continue;
14154
14196
  await walk2(full, depth2 + 1);
14155
14197
  } else if (e.isFile()) {
14156
- const rel = path8.relative(root, full);
14198
+ const rel = path9.relative(root, full);
14157
14199
  if (q2 && !rel.toLowerCase().includes(q2) && !e.name.toLowerCase().includes(q2)) {
14158
14200
  continue;
14159
14201
  }
14160
14202
  let size = 0;
14161
14203
  try {
14162
- const st3 = await fs7.stat(full);
14204
+ const st3 = await fs8.stat(full);
14163
14205
  size = st3.size;
14164
14206
  } catch {
14165
14207
  }
@@ -14261,8 +14303,8 @@ async function gitStatus(cwd) {
14261
14303
  let hasMergeInProgress = false;
14262
14304
  try {
14263
14305
  const gitDir = (await git(["rev-parse", "--git-dir"], root)).stdout.trim();
14264
- const mergeHead = path8.isAbsolute(gitDir) ? path8.join(gitDir, "MERGE_HEAD") : path8.join(root, gitDir, "MERGE_HEAD");
14265
- await fs7.access(mergeHead);
14306
+ const mergeHead = path9.isAbsolute(gitDir) ? path9.join(gitDir, "MERGE_HEAD") : path9.join(root, gitDir, "MERGE_HEAD");
14307
+ await fs8.access(mergeHead);
14266
14308
  hasMergeInProgress = true;
14267
14309
  } catch {
14268
14310
  }
@@ -14408,7 +14450,7 @@ async function jsSearchFiles(opts, cwd, cap) {
14408
14450
  }
14409
14451
  let content = "";
14410
14452
  try {
14411
- content = await fs7.readFile(path8.join(cwd, f.path), "utf8");
14453
+ content = await fs8.readFile(path9.join(cwd, f.path), "utf8");
14412
14454
  } catch {
14413
14455
  continue;
14414
14456
  }
@@ -14485,14 +14527,14 @@ function formatRemaining(expiresAt) {
14485
14527
 
14486
14528
  // src/services/apply-file-review.service.ts
14487
14529
  var import_child_process6 = require("child_process");
14488
- var fs8 = __toESM(require("fs"));
14489
- var path9 = __toESM(require("path"));
14530
+ var fs9 = __toESM(require("fs"));
14531
+ var path10 = __toESM(require("path"));
14490
14532
  async function applyFileReview(workingDir, filePath, action) {
14491
- if (filePath.includes("..") || path9.isAbsolute(filePath)) {
14533
+ if (filePath.includes("..") || path10.isAbsolute(filePath)) {
14492
14534
  return { ok: false, action, filePath, error: "invalid file path" };
14493
14535
  }
14494
- const absFile = path9.resolve(workingDir, filePath);
14495
- const repoRoot = findGitRoot2(path9.dirname(absFile));
14536
+ const absFile = path10.resolve(workingDir, filePath);
14537
+ const repoRoot = findGitRoot2(path10.dirname(absFile));
14496
14538
  if (!repoRoot) {
14497
14539
  return {
14498
14540
  ok: false,
@@ -14501,7 +14543,7 @@ async function applyFileReview(workingDir, filePath, action) {
14501
14543
  error: `no enclosing git repo for ${filePath}`
14502
14544
  };
14503
14545
  }
14504
- const relInRepo = path9.relative(repoRoot, absFile);
14546
+ const relInRepo = path10.relative(repoRoot, absFile);
14505
14547
  if (!relInRepo || relInRepo.startsWith("..")) {
14506
14548
  return { ok: false, action, filePath, error: "path escapes repo root" };
14507
14549
  }
@@ -14550,17 +14592,17 @@ function runGit2(cwd, args2) {
14550
14592
  });
14551
14593
  }
14552
14594
  function findGitRoot2(startDir) {
14553
- let dir = path9.resolve(startDir);
14595
+ let dir = path10.resolve(startDir);
14554
14596
  const seen2 = /* @__PURE__ */ new Set();
14555
14597
  for (let i = 0; i < 256; i++) {
14556
14598
  if (seen2.has(dir)) return null;
14557
14599
  seen2.add(dir);
14558
14600
  try {
14559
- const stat3 = fs8.statSync(path9.join(dir, ".git"), { throwIfNoEntry: false });
14601
+ const stat3 = fs9.statSync(path10.join(dir, ".git"), { throwIfNoEntry: false });
14560
14602
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
14561
14603
  } catch {
14562
14604
  }
14563
- const parent = path9.dirname(dir);
14605
+ const parent = path10.dirname(dir);
14564
14606
  if (parent === dir) return null;
14565
14607
  dir = parent;
14566
14608
  }
@@ -14569,8 +14611,8 @@ function findGitRoot2(startDir) {
14569
14611
 
14570
14612
  // src/commands/link.ts
14571
14613
  var import_node_crypto9 = require("crypto");
14572
- var fs31 = __toESM(require("fs"));
14573
- var path38 = __toESM(require("path"));
14614
+ var fs32 = __toESM(require("fs"));
14615
+ var path39 = __toESM(require("path"));
14574
14616
  var import_chokidar = __toESM(require("chokidar"));
14575
14617
  var import_picocolors2 = __toESM(require("picocolors"));
14576
14618
 
@@ -16644,19 +16686,19 @@ function parseFrame(frame, dispatch) {
16644
16686
  }
16645
16687
 
16646
16688
  // src/os/posix.ts
16647
- var fs10 = __toESM(require("fs"));
16648
- var os7 = __toESM(require("os"));
16649
- var path12 = __toESM(require("path"));
16689
+ var fs11 = __toESM(require("fs"));
16690
+ var os8 = __toESM(require("os"));
16691
+ var path13 = __toESM(require("path"));
16650
16692
  var import_node_crypto2 = require("crypto");
16651
16693
 
16652
16694
  // src/os/strategy.ts
16653
- var path10 = __toESM(require("path"));
16695
+ var path11 = __toESM(require("path"));
16654
16696
  function findInPathFor(name, opts) {
16655
- const dirs = (process.env.PATH ?? "").split(path10.delimiter).filter(Boolean);
16697
+ const dirs = (process.env.PATH ?? "").split(path11.delimiter).filter(Boolean);
16656
16698
  const candidates = opts.candidates(name);
16657
16699
  for (const dir of dirs) {
16658
16700
  for (const candidate of candidates) {
16659
- const full = path10.join(dir, candidate);
16701
+ const full = path11.join(dir, candidate);
16660
16702
  try {
16661
16703
  opts.accessSync(full, opts.accessFlag);
16662
16704
  return full;
@@ -16669,9 +16711,9 @@ function findInPathFor(name, opts) {
16669
16711
 
16670
16712
  // src/services/pty/unix.strategy.ts
16671
16713
  var import_child_process7 = require("child_process");
16672
- var fs9 = __toESM(require("fs"));
16673
- var os6 = __toESM(require("os"));
16674
- var path11 = __toESM(require("path"));
16714
+ var fs10 = __toESM(require("fs"));
16715
+ var os7 = __toESM(require("os"));
16716
+ var path12 = __toESM(require("path"));
16675
16717
 
16676
16718
  // src/services/pty/types.ts
16677
16719
  function findInPath(name) {
@@ -16767,8 +16809,8 @@ var UnixPtyStrategy = class {
16767
16809
  }
16768
16810
  const cols = process.stdout.columns || 220;
16769
16811
  const rows = process.stdout.rows || 50;
16770
- this.helperPath = path11.join(os6.tmpdir(), "codeam-pty-helper.py");
16771
- fs9.writeFileSync(this.helperPath, PYTHON_PTY_HELPER, { mode: 420 });
16812
+ this.helperPath = path12.join(os7.tmpdir(), "codeam-pty-helper.py");
16813
+ fs10.writeFileSync(this.helperPath, PYTHON_PTY_HELPER, { mode: 420 });
16772
16814
  this.proc = (0, import_child_process7.spawn)(python, [this.helperPath, cmd, ...args2], {
16773
16815
  stdio: ["pipe", "pipe", "inherit"],
16774
16816
  cwd,
@@ -16936,11 +16978,11 @@ var UnixPtyStrategy = class {
16936
16978
  // src/os/posix.ts
16937
16979
  var PosixOsStrategy = class {
16938
16980
  homeDir() {
16939
- return os7.homedir();
16981
+ return os8.homedir();
16940
16982
  }
16941
16983
  scratchPath(prefix) {
16942
16984
  const tag = `${process.pid}-${(0, import_node_crypto2.randomBytes)(4).toString("hex")}`;
16943
- return path12.join(os7.tmpdir(), `${prefix}-${tag}`);
16985
+ return path13.join(os8.tmpdir(), `${prefix}-${tag}`);
16944
16986
  }
16945
16987
  devNull() {
16946
16988
  return "/dev/null";
@@ -16948,8 +16990,8 @@ var PosixOsStrategy = class {
16948
16990
  findInPath(name) {
16949
16991
  return findInPathFor(name, {
16950
16992
  candidates: () => [name],
16951
- accessFlag: fs10.constants.X_OK,
16952
- accessSync: fs10.accessSync
16993
+ accessFlag: fs11.constants.X_OK,
16994
+ accessSync: fs11.accessSync
16953
16995
  });
16954
16996
  }
16955
16997
  augmentPath(dirs) {
@@ -16994,15 +17036,15 @@ var LinuxOsStrategy = class extends PosixOsStrategy {
16994
17036
  };
16995
17037
 
16996
17038
  // src/os/win32.ts
16997
- var fs11 = __toESM(require("fs"));
16998
- var os8 = __toESM(require("os"));
16999
- var path14 = __toESM(require("path"));
17039
+ var fs12 = __toESM(require("fs"));
17040
+ var os9 = __toESM(require("os"));
17041
+ var path15 = __toESM(require("path"));
17000
17042
  var import_node_crypto3 = require("crypto");
17001
17043
 
17002
17044
  // src/services/pty/windows-conpty.strategy.ts
17003
- var path13 = __toESM(require("path"));
17045
+ var path14 = __toESM(require("path"));
17004
17046
  function loadNodePty2() {
17005
- const vendoredPath = path13.join(__dirname, "vendor", "node-pty");
17047
+ const vendoredPath = path14.join(__dirname, "vendor", "node-pty");
17006
17048
  try {
17007
17049
  return require(vendoredPath);
17008
17050
  } catch (vendorErr) {
@@ -17194,25 +17236,25 @@ var WINDOWS_EXEC_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
17194
17236
  var Win32OsStrategy = class {
17195
17237
  id = "win32";
17196
17238
  homeDir() {
17197
- return os8.homedir();
17239
+ return os9.homedir();
17198
17240
  }
17199
17241
  scratchPath(prefix) {
17200
17242
  const tag = `${process.pid}-${(0, import_node_crypto3.randomBytes)(4).toString("hex")}`;
17201
- return path14.join(os8.tmpdir(), `${prefix}-${tag}`);
17243
+ return path15.join(os9.tmpdir(), `${prefix}-${tag}`);
17202
17244
  }
17203
17245
  devNull() {
17204
17246
  return "NUL";
17205
17247
  }
17206
17248
  findInPath(name) {
17207
- const hasExt = path14.extname(name).length > 0;
17249
+ const hasExt = path15.extname(name).length > 0;
17208
17250
  return findInPathFor(name, {
17209
17251
  candidates: (n) => hasExt ? [n] : [...WINDOWS_EXEC_EXTS.map((ext) => `${n}${ext}`), n],
17210
17252
  // Windows has no Unix execute bit; presence + matching extension
17211
17253
  // IS the executability check. X_OK on Windows is a no-op alias
17212
17254
  // for F_OK at the libuv layer anyway, but F_OK makes intent
17213
17255
  // explicit.
17214
- accessFlag: fs11.constants.F_OK,
17215
- accessSync: fs11.accessSync
17256
+ accessFlag: fs12.constants.F_OK,
17257
+ accessSync: fs12.accessSync
17216
17258
  });
17217
17259
  }
17218
17260
  augmentPath(dirs) {
@@ -17249,7 +17291,7 @@ var Win32OsStrategy = class {
17249
17291
  return `"${escaped.replace(/[&|^<>()%!]/g, "^$&")}"`;
17250
17292
  }
17251
17293
  buildLaunch(binaryPath, extraArgs = []) {
17252
- const ext = path14.extname(binaryPath).toLowerCase();
17294
+ const ext = path15.extname(binaryPath).toLowerCase();
17253
17295
  if (ext === ".cmd" || ext === ".bat") {
17254
17296
  return { cmd: "cmd.exe", args: ["/c", binaryPath, ...extraArgs] };
17255
17297
  }
@@ -17325,20 +17367,20 @@ function buildClaudeLaunch(extraArgs = [], os74 = createOsStrategy()) {
17325
17367
 
17326
17368
  // src/agents/claude/installer.ts
17327
17369
  var import_child_process9 = require("child_process");
17328
- var path15 = __toESM(require("path"));
17329
- var os9 = __toESM(require("os"));
17370
+ var path16 = __toESM(require("path"));
17371
+ var os10 = __toESM(require("os"));
17330
17372
  function probeInstallDirs() {
17331
- const home = os9.homedir();
17373
+ const home = os10.homedir();
17332
17374
  if (process.platform === "win32") {
17333
17375
  return [
17334
- path15.join(home, ".claude", "local"),
17335
- path15.join(home, "AppData", "Local", "AnthropicClaude"),
17336
- path15.join(home, "AppData", "Local", "Programs", "AnthropicClaude")
17376
+ path16.join(home, ".claude", "local"),
17377
+ path16.join(home, "AppData", "Local", "AnthropicClaude"),
17378
+ path16.join(home, "AppData", "Local", "Programs", "AnthropicClaude")
17337
17379
  ];
17338
17380
  }
17339
17381
  return [
17340
- path15.join(home, ".local", "bin"),
17341
- path15.join(home, ".claude", "local"),
17382
+ path16.join(home, ".local", "bin"),
17383
+ path16.join(home, ".claude", "local"),
17342
17384
  "/usr/local/bin"
17343
17385
  ];
17344
17386
  }
@@ -17347,7 +17389,7 @@ function isAvailable() {
17347
17389
  }
17348
17390
  function augmentPath() {
17349
17391
  const dirs = probeInstallDirs();
17350
- const sep8 = path15.delimiter;
17392
+ const sep8 = path16.delimiter;
17351
17393
  const current2 = process.env.PATH ?? "";
17352
17394
  const existing = new Set(current2.split(sep8).filter(Boolean));
17353
17395
  const additions = dirs.filter((d3) => !existing.has(d3));
@@ -17438,9 +17480,9 @@ var import_node_child_process3 = require("child_process");
17438
17480
 
17439
17481
  // src/agents/claude/local-token.ts
17440
17482
  var import_node_child_process2 = require("child_process");
17441
- var fs12 = __toESM(require("fs"));
17442
- var os10 = __toESM(require("os"));
17443
- var path16 = __toESM(require("path"));
17483
+ var fs13 = __toESM(require("fs"));
17484
+ var os11 = __toESM(require("os"));
17485
+ var path17 = __toESM(require("path"));
17444
17486
  var import_node_util4 = require("util");
17445
17487
  var execFileP2 = (0, import_node_util4.promisify)(import_node_child_process2.execFile);
17446
17488
  var KEYCHAIN_SERVICE_NAMES = [
@@ -17450,17 +17492,17 @@ var KEYCHAIN_SERVICE_NAMES = [
17450
17492
  "Anthropic Claude"
17451
17493
  ];
17452
17494
  function claudeCredentialsPaths() {
17453
- const home = os10.homedir();
17495
+ const home = os11.homedir();
17454
17496
  return [
17455
- path16.join(home, ".claude", ".credentials.json"),
17456
- path16.join(home, ".config", "claude", ".credentials.json")
17497
+ path17.join(home, ".claude", ".credentials.json"),
17498
+ path17.join(home, ".config", "claude", ".credentials.json")
17457
17499
  ];
17458
17500
  }
17459
17501
  async function extractLocalClaudeToken() {
17460
17502
  const agentState = readClaudeAgentState();
17461
17503
  for (const flat of claudeCredentialsPaths()) {
17462
- if (!fs12.existsSync(flat)) continue;
17463
- const credential = fs12.readFileSync(flat, "utf8").trim();
17504
+ if (!fs13.existsSync(flat)) continue;
17505
+ const credential = fs13.readFileSync(flat, "utf8").trim();
17464
17506
  if (credential.length > 0) {
17465
17507
  return { method: "oauth", credential, source: "flat-file", agentState };
17466
17508
  }
@@ -17485,10 +17527,10 @@ async function extractLocalClaudeToken() {
17485
17527
  }
17486
17528
  function readClaudeAgentState() {
17487
17529
  const STATE_MAX_BYTES = 256 * 1024;
17488
- const candidate = path16.join(os10.homedir(), ".claude.json");
17530
+ const candidate = path17.join(os11.homedir(), ".claude.json");
17489
17531
  try {
17490
- if (!fs12.existsSync(candidate)) return void 0;
17491
- const buf = fs12.readFileSync(candidate);
17532
+ if (!fs13.existsSync(candidate)) return void 0;
17533
+ const buf = fs13.readFileSync(candidate);
17492
17534
  if (buf.length === 0 || buf.length > STATE_MAX_BYTES) return void 0;
17493
17535
  const text = buf.toString("utf8").trim();
17494
17536
  return text.length > 0 ? text : void 0;
@@ -17577,9 +17619,9 @@ function claudeLoginLauncher() {
17577
17619
  }
17578
17620
 
17579
17621
  // src/agents/claude/quota.ts
17580
- var fs13 = __toESM(require("fs"));
17581
- var os11 = __toESM(require("os"));
17582
- var path17 = __toESM(require("path"));
17622
+ var fs14 = __toESM(require("fs"));
17623
+ var os12 = __toESM(require("os"));
17624
+ var path18 = __toESM(require("path"));
17583
17625
  var import_child_process10 = require("child_process");
17584
17626
  var HELPER_SCRIPT = `import os,pty,sys,select,signal,struct,fcntl,termios,errno
17585
17627
  m,s=pty.openpty()
@@ -17642,8 +17684,8 @@ async function fetchClaudeQuota() {
17642
17684
  resolve13(null);
17643
17685
  return;
17644
17686
  }
17645
- const helperPath = path17.join(os11.tmpdir(), "codeam-quota-helper.py");
17646
- fs13.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
17687
+ const helperPath = path18.join(os12.tmpdir(), "codeam-quota-helper.py");
17688
+ fs14.writeFileSync(helperPath, HELPER_SCRIPT, { mode: 420 });
17647
17689
  const python = findInPath("python3") ?? findInPath("python");
17648
17690
  if (!python) {
17649
17691
  resolve13(null);
@@ -17670,7 +17712,7 @@ async function fetchClaudeQuota() {
17670
17712
  } catch {
17671
17713
  }
17672
17714
  try {
17673
- fs13.unlinkSync(helperPath);
17715
+ fs14.unlinkSync(helperPath);
17674
17716
  } catch {
17675
17717
  }
17676
17718
  resolve13(result);
@@ -17805,37 +17847,37 @@ function readOneShotConversations(cwd, homeDir2) {
17805
17847
  }
17806
17848
 
17807
17849
  // src/agents/claude/history.ts
17808
- var fs15 = __toESM(require("fs"));
17850
+ var fs16 = __toESM(require("fs"));
17809
17851
 
17810
17852
  // src/agents/claude-memory-file.ts
17811
- var os13 = __toESM(require("os"));
17812
- var path19 = __toESM(require("path"));
17853
+ var os14 = __toESM(require("os"));
17854
+ var path20 = __toESM(require("path"));
17813
17855
  function claudeMemoryFile(homeDir2, env = process.env) {
17814
- if (homeDir2) return path19.join(homeDir2, ".claude", "CLAUDE.md");
17815
- return path19.join(claudeConfigDir(env), "CLAUDE.md");
17856
+ if (homeDir2) return path20.join(homeDir2, ".claude", "CLAUDE.md");
17857
+ return path20.join(claudeConfigDir(env), "CLAUDE.md");
17816
17858
  }
17817
17859
  function claudeConfigDir(env = currentAgentEnv()) {
17818
17860
  const configDir = env.CLAUDE_CONFIG_DIR?.trim();
17819
- return configDir ? configDir : path19.join(os13.homedir(), ".claude");
17861
+ return configDir ? configDir : path20.join(os14.homedir(), ".claude");
17820
17862
  }
17821
17863
 
17822
17864
  // src/agents/claude/history.ts
17823
- var path20 = __toESM(require("path"));
17865
+ var path21 = __toESM(require("path"));
17824
17866
  function encodeCwd(cwd) {
17825
17867
  return cwd.replace(/[\\/:_.]/g, "-");
17826
17868
  }
17827
17869
  function resolveHistoryDir(cwd, projectsRoot) {
17828
- const root = projectsRoot ?? path20.join(claudeConfigDir(), "projects");
17829
- const primary = path20.join(root, encodeCwd(cwd));
17830
- if (fs15.existsSync(primary)) return primary;
17870
+ const root = projectsRoot ?? path21.join(claudeConfigDir(), "projects");
17871
+ const primary = path21.join(root, encodeCwd(cwd));
17872
+ if (fs16.existsSync(primary)) return primary;
17831
17873
  try {
17832
- const entries2 = fs15.readdirSync(root, { withFileTypes: true });
17874
+ const entries2 = fs16.readdirSync(root, { withFileTypes: true });
17833
17875
  const wanted = encodeCwd(cwd);
17834
17876
  for (const e of entries2) {
17835
17877
  if (!e.isDirectory()) continue;
17836
17878
  const candidate = e.name.replace(/-+/g, "-");
17837
17879
  if (candidate === wanted.replace(/-+/g, "-")) {
17838
- return path20.join(root, e.name);
17880
+ return path21.join(root, e.name);
17839
17881
  }
17840
17882
  }
17841
17883
  } catch {
@@ -17845,31 +17887,31 @@ function resolveHistoryDir(cwd, projectsRoot) {
17845
17887
  function resolveHistoryFile(cwd, sessionId, projectsRoot) {
17846
17888
  const dir = resolveHistoryDir(cwd, projectsRoot);
17847
17889
  if (!dir) return null;
17848
- const filePath = path20.join(dir, `${sessionId}.jsonl`);
17849
- return fs15.existsSync(filePath) ? filePath : null;
17890
+ const filePath = path21.join(dir, `${sessionId}.jsonl`);
17891
+ return fs16.existsSync(filePath) ? filePath : null;
17850
17892
  }
17851
17893
  function getCurrentUsage(historyDir, bootTimeMs = 0) {
17852
17894
  const GRACE_MS = 5e3;
17853
17895
  const cutoff = bootTimeMs > 0 ? bootTimeMs - GRACE_MS : 0;
17854
17896
  let entries2;
17855
17897
  try {
17856
- entries2 = fs15.readdirSync(historyDir, { withFileTypes: true });
17898
+ entries2 = fs16.readdirSync(historyDir, { withFileTypes: true });
17857
17899
  } catch {
17858
17900
  return null;
17859
17901
  }
17860
17902
  const files = entries2.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
17861
17903
  try {
17862
- const stat3 = fs15.statSync(path20.join(historyDir, e.name));
17904
+ const stat3 = fs16.statSync(path21.join(historyDir, e.name));
17863
17905
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
17864
17906
  } catch {
17865
17907
  return { name: e.name, mtime: 0, birthtime: 0 };
17866
17908
  }
17867
17909
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
17868
17910
  if (files.length === 0) return null;
17869
- const filePath = path20.join(historyDir, files[0].name);
17911
+ const filePath = path21.join(historyDir, files[0].name);
17870
17912
  let raw;
17871
17913
  try {
17872
- raw = fs15.readFileSync(filePath, "utf8");
17914
+ raw = fs16.readFileSync(filePath, "utf8");
17873
17915
  } catch {
17874
17916
  return null;
17875
17917
  }
@@ -17937,7 +17979,7 @@ function parseHistoryFile(filePath) {
17937
17979
  const exitPlanIds = /* @__PURE__ */ new Set();
17938
17980
  let raw;
17939
17981
  try {
17940
- raw = fs15.readFileSync(filePath, "utf8");
17982
+ raw = fs16.readFileSync(filePath, "utf8");
17941
17983
  } catch {
17942
17984
  return out2;
17943
17985
  }
@@ -17983,7 +18025,7 @@ function listResumableSessions(cwd) {
17983
18025
  if (!dir) return [];
17984
18026
  let entries2;
17985
18027
  try {
17986
- entries2 = fs15.readdirSync(dir, { withFileTypes: true });
18028
+ entries2 = fs16.readdirSync(dir, { withFileTypes: true });
17987
18029
  } catch {
17988
18030
  return [];
17989
18031
  }
@@ -17991,15 +18033,15 @@ function listResumableSessions(cwd) {
17991
18033
  for (const entry of entries2) {
17992
18034
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
17993
18035
  const id = entry.name.slice(0, -".jsonl".length);
17994
- const filePath = path20.join(dir, entry.name);
18036
+ const filePath = path21.join(dir, entry.name);
17995
18037
  let timestamp = Date.now();
17996
18038
  try {
17997
- timestamp = fs15.statSync(filePath).mtimeMs;
18039
+ timestamp = fs16.statSync(filePath).mtimeMs;
17998
18040
  } catch {
17999
18041
  }
18000
18042
  let summary = "";
18001
18043
  try {
18002
- const raw = fs15.readFileSync(filePath, "utf8");
18044
+ const raw = fs16.readFileSync(filePath, "utf8");
18003
18045
  for (const line of raw.split("\n")) {
18004
18046
  if (!line.trim()) continue;
18005
18047
  try {
@@ -18030,19 +18072,19 @@ var SWITCH_PROBE_BYTES = 256 * 1024;
18030
18072
  function isClearedConversationFile(filePath) {
18031
18073
  let fd;
18032
18074
  try {
18033
- fd = fs15.openSync(filePath, "r");
18075
+ fd = fs16.openSync(filePath, "r");
18034
18076
  } catch {
18035
18077
  return false;
18036
18078
  }
18037
18079
  let raw;
18038
18080
  try {
18039
18081
  const buf = Buffer.alloc(SWITCH_PROBE_BYTES);
18040
- const n = fs15.readSync(fd, buf, 0, SWITCH_PROBE_BYTES, 0);
18082
+ const n = fs16.readSync(fd, buf, 0, SWITCH_PROBE_BYTES, 0);
18041
18083
  raw = buf.toString("utf8", 0, n);
18042
18084
  } catch {
18043
18085
  return false;
18044
18086
  } finally {
18045
- fs15.closeSync(fd);
18087
+ fs16.closeSync(fd);
18046
18088
  }
18047
18089
  if (!raw.includes(CLEAR_COMMAND_ECHO) && !raw.includes("SessionStart:clear")) return false;
18048
18090
  for (const line of raw.split("\n")) {
@@ -18069,16 +18111,16 @@ function isClearedConversationFile(filePath) {
18069
18111
  function appendedTailHasResumeMarker(filePath, fromOffset) {
18070
18112
  let fd;
18071
18113
  try {
18072
- fd = fs15.openSync(filePath, "r");
18114
+ fd = fs16.openSync(filePath, "r");
18073
18115
  } catch {
18074
18116
  return false;
18075
18117
  }
18076
18118
  try {
18077
- const size = fs15.fstatSync(fd).size;
18119
+ const size = fs16.fstatSync(fd).size;
18078
18120
  const len = Math.min(Math.max(size - fromOffset, 0), SWITCH_PROBE_BYTES);
18079
18121
  if (len <= 0) return false;
18080
18122
  const buf = Buffer.alloc(len);
18081
- const n = fs15.readSync(fd, buf, 0, len, fromOffset);
18123
+ const n = fs16.readSync(fd, buf, 0, len, fromOffset);
18082
18124
  const raw = buf.toString("utf8", 0, n);
18083
18125
  if (!raw.includes('"last-prompt"')) return false;
18084
18126
  for (const line of raw.split("\n")) {
@@ -18092,11 +18134,11 @@ function appendedTailHasResumeMarker(filePath, fromOffset) {
18092
18134
  } catch {
18093
18135
  return false;
18094
18136
  } finally {
18095
- fs15.closeSync(fd);
18137
+ fs16.closeSync(fd);
18096
18138
  }
18097
18139
  }
18098
18140
  function watchConversationSwitch(cwd, opts, onSwitch, projectsRoot) {
18099
- const root = projectsRoot ?? path20.join(claudeConfigDir(), "projects");
18141
+ const root = projectsRoot ?? path21.join(claudeConfigDir(), "projects");
18100
18142
  let currentId = opts.currentId;
18101
18143
  const baseline = /* @__PURE__ */ new Map();
18102
18144
  const unclassified = /* @__PURE__ */ new Map();
@@ -18105,13 +18147,13 @@ function watchConversationSwitch(cwd, opts, onSwitch, projectsRoot) {
18105
18147
  let closed = false;
18106
18148
  const fileSize = (file) => {
18107
18149
  try {
18108
- return fs15.statSync(file).size;
18150
+ return fs16.statSync(file).size;
18109
18151
  } catch {
18110
18152
  return null;
18111
18153
  }
18112
18154
  };
18113
18155
  const switchTo = (dir, id, kind) => {
18114
- const leaving = fileSize(path20.join(dir, `${currentId}.jsonl`));
18156
+ const leaving = fileSize(path21.join(dir, `${currentId}.jsonl`));
18115
18157
  if (leaving !== null) baseline.set(currentId, leaving);
18116
18158
  baseline.delete(id);
18117
18159
  unclassified.delete(id);
@@ -18122,7 +18164,7 @@ function watchConversationSwitch(cwd, opts, onSwitch, projectsRoot) {
18122
18164
  if (closed) return;
18123
18165
  let entries2;
18124
18166
  try {
18125
- entries2 = fs15.readdirSync(dir);
18167
+ entries2 = fs16.readdirSync(dir);
18126
18168
  } catch {
18127
18169
  return;
18128
18170
  }
@@ -18130,7 +18172,7 @@ function watchConversationSwitch(cwd, opts, onSwitch, projectsRoot) {
18130
18172
  if (!name.endsWith(".jsonl")) continue;
18131
18173
  const id = name.slice(0, -".jsonl".length);
18132
18174
  if (id === currentId) continue;
18133
- const file = path20.join(dir, name);
18175
+ const file = path21.join(dir, name);
18134
18176
  const size = fileSize(file);
18135
18177
  if (size === null) continue;
18136
18178
  const known = baseline.get(id);
@@ -18156,18 +18198,18 @@ function watchConversationSwitch(cwd, opts, onSwitch, projectsRoot) {
18156
18198
  rootWatcher = null;
18157
18199
  if (initial) {
18158
18200
  try {
18159
- for (const name of fs15.readdirSync(dir)) {
18201
+ for (const name of fs16.readdirSync(dir)) {
18160
18202
  if (!name.endsWith(".jsonl")) continue;
18161
18203
  const id = name.slice(0, -".jsonl".length);
18162
18204
  if (id === currentId) continue;
18163
- const size = fileSize(path20.join(dir, name));
18205
+ const size = fileSize(path21.join(dir, name));
18164
18206
  if (size !== null) baseline.set(id, size);
18165
18207
  }
18166
18208
  } catch {
18167
18209
  }
18168
18210
  }
18169
18211
  try {
18170
- dirWatcher = fs15.watch(dir, { persistent: false }, () => scan(dir));
18212
+ dirWatcher = fs16.watch(dir, { persistent: false }, () => scan(dir));
18171
18213
  } catch {
18172
18214
  return false;
18173
18215
  }
@@ -18176,8 +18218,8 @@ function watchConversationSwitch(cwd, opts, onSwitch, projectsRoot) {
18176
18218
  };
18177
18219
  if (!attachDir(true)) {
18178
18220
  try {
18179
- fs15.mkdirSync(root, { recursive: true });
18180
- rootWatcher = fs15.watch(root, { persistent: false }, () => {
18221
+ fs16.mkdirSync(root, { recursive: true });
18222
+ rootWatcher = fs16.watch(root, { persistent: false }, () => {
18181
18223
  if (!closed && !dirWatcher) attachDir(false);
18182
18224
  });
18183
18225
  } catch {
@@ -18352,24 +18394,24 @@ var ClaudeRuntimeStrategy = class {
18352
18394
  };
18353
18395
 
18354
18396
  // src/agents/claude/deploy.ts
18355
- var fs17 = __toESM(require("fs"));
18356
- var os15 = __toESM(require("os"));
18357
- var path22 = __toESM(require("path"));
18397
+ var fs18 = __toESM(require("fs"));
18398
+ var os16 = __toESM(require("os"));
18399
+ var path23 = __toESM(require("path"));
18358
18400
 
18359
18401
  // src/agents/claude/credentials.ts
18360
18402
  var import_child_process12 = require("child_process");
18361
- var fs16 = __toESM(require("fs"));
18362
- var os14 = __toESM(require("os"));
18363
- var path21 = __toESM(require("path"));
18403
+ var fs17 = __toESM(require("fs"));
18404
+ var os15 = __toESM(require("os"));
18405
+ var path22 = __toESM(require("path"));
18364
18406
  var import_util2 = require("util");
18365
18407
  var execFileP3 = (0, import_util2.promisify)(import_child_process12.execFile);
18366
18408
  async function detectLocalClaudeCredentials() {
18367
- const localClaudeDir = path21.join(os14.homedir(), ".claude");
18368
- const flat = path21.join(localClaudeDir, ".credentials.json");
18369
- if (fs16.existsSync(flat)) {
18409
+ const localClaudeDir = path22.join(os15.homedir(), ".claude");
18410
+ const flat = path22.join(localClaudeDir, ".credentials.json");
18411
+ if (fs17.existsSync(flat)) {
18370
18412
  return { source: "flat-file", description: "~/.claude/.credentials.json" };
18371
18413
  }
18372
- if (os14.platform() === "darwin") {
18414
+ if (os15.platform() === "darwin") {
18373
18415
  try {
18374
18416
  await execFileP3(
18375
18417
  "security",
@@ -18384,9 +18426,9 @@ async function detectLocalClaudeCredentials() {
18384
18426
  return { source: "none", description: "" };
18385
18427
  }
18386
18428
  async function bridgeClaudeCredentials(provider, workspaceId) {
18387
- const localClaudeDir = path21.join(os14.homedir(), ".claude");
18388
- const fileBased = path21.join(localClaudeDir, ".credentials.json");
18389
- if (fs16.existsSync(fileBased)) {
18429
+ const localClaudeDir = path22.join(os15.homedir(), ".claude");
18430
+ const fileBased = path22.join(localClaudeDir, ".credentials.json");
18431
+ if (fs17.existsSync(fileBased)) {
18390
18432
  return { source: "flat-file", description: "~/.claude/.credentials.json" };
18391
18433
  }
18392
18434
  if (process.platform === "darwin") {
@@ -18478,8 +18520,8 @@ var ClaudeDeployStrategy = class {
18478
18520
  process.exit(1);
18479
18521
  }
18480
18522
  claudeStep.stop("\u2713 Claude CLI installed");
18481
- const localClaudeDir = path22.join(os15.homedir(), ".claude");
18482
- const haveLocalClaude = fs17.existsSync(localClaudeDir) && fs17.statSync(localClaudeDir).isDirectory();
18523
+ const localClaudeDir = path23.join(os16.homedir(), ".claude");
18524
+ const haveLocalClaude = fs18.existsSync(localClaudeDir) && fs18.statSync(localClaudeDir).isDirectory();
18483
18525
  if (haveLocalClaude) {
18484
18526
  const copyStep = fe();
18485
18527
  copyStep.start("Copying local Claude config to workspace\u2026");
@@ -18533,10 +18575,10 @@ var ClaudeDeployStrategy = class {
18533
18575
  }
18534
18576
  }
18535
18577
  if (opts.bridged !== "none") {
18536
- const localClaudeJson = path22.join(os15.homedir(), ".claude.json");
18537
- if (fs17.existsSync(localClaudeJson)) {
18578
+ const localClaudeJson = path23.join(os16.homedir(), ".claude.json");
18579
+ if (fs18.existsSync(localClaudeJson)) {
18538
18580
  try {
18539
- const contents = fs17.readFileSync(localClaudeJson);
18581
+ const contents = fs18.readFileSync(localClaudeJson);
18540
18582
  await provider.uploadFile(
18541
18583
  workspaceId,
18542
18584
  "/home/codespace/.claude.json",
@@ -18569,7 +18611,7 @@ var ClaudeDeployStrategy = class {
18569
18611
 
18570
18612
  // src/agents/codex/runtime.ts
18571
18613
  var import_node_child_process5 = require("child_process");
18572
- var path26 = __toESM(require("path"));
18614
+ var path27 = __toESM(require("path"));
18573
18615
 
18574
18616
  // src/agents/codex/history.ts
18575
18617
  var import_node_fs4 = __toESM(require("fs"));
@@ -18577,9 +18619,9 @@ var import_node_path4 = __toESM(require("path"));
18577
18619
  var import_node_os2 = __toESM(require("os"));
18578
18620
 
18579
18621
  // src/agents/acp/squad-roster.ts
18580
- var fs18 = __toESM(require("fs"));
18581
- var os16 = __toESM(require("os"));
18582
- var path23 = __toESM(require("path"));
18622
+ var fs19 = __toESM(require("fs"));
18623
+ var os17 = __toESM(require("os"));
18624
+ var path24 = __toESM(require("path"));
18583
18625
  var PROMPT_MAX = 500;
18584
18626
  var REPLY_SUMMARY_MAX = 1e3;
18585
18627
  var PREAMBLE_MAX = 2e3;
@@ -18598,11 +18640,11 @@ function defaultMember() {
18598
18640
  };
18599
18641
  }
18600
18642
  function journalPathFor(homeDir2, sessionId) {
18601
- return path23.join(homeDir2, ".codeam", `squad-journal-${sessionId}.json`);
18643
+ return path24.join(homeDir2, ".codeam", `squad-journal-${sessionId}.json`);
18602
18644
  }
18603
18645
  function loadJournal(journalPath) {
18604
18646
  try {
18605
- const raw = JSON.parse(fs18.readFileSync(journalPath, "utf-8"));
18647
+ const raw = JSON.parse(fs19.readFileSync(journalPath, "utf-8"));
18606
18648
  return Array.isArray(raw.turns) ? raw.turns : [];
18607
18649
  } catch {
18608
18650
  return [];
@@ -18630,7 +18672,7 @@ var SquadState = class {
18630
18672
  turns;
18631
18673
  members = /* @__PURE__ */ new Map();
18632
18674
  constructor(opts) {
18633
- this.journalPath = journalPathFor(opts.homeDir ?? os16.homedir(), opts.sessionId);
18675
+ this.journalPath = journalPathFor(opts.homeDir ?? os17.homedir(), opts.sessionId);
18634
18676
  this.turns = loadJournal(this.journalPath);
18635
18677
  if (opts.auto) this.setAuto(opts.auto);
18636
18678
  }
@@ -18717,8 +18759,8 @@ var SquadState = class {
18717
18759
  }
18718
18760
  persist() {
18719
18761
  try {
18720
- fs18.mkdirSync(path23.dirname(this.journalPath), { recursive: true, mode: 448 });
18721
- fs18.writeFileSync(this.journalPath, JSON.stringify({ turns: this.turns }), { mode: 384 });
18762
+ fs19.mkdirSync(path24.dirname(this.journalPath), { recursive: true, mode: 448 });
18763
+ fs19.writeFileSync(this.journalPath, JSON.stringify({ turns: this.turns }), { mode: 384 });
18722
18764
  } catch {
18723
18765
  }
18724
18766
  }
@@ -19234,16 +19276,16 @@ function getCurrentUsage2(historyDir) {
19234
19276
  var import_node_child_process4 = require("child_process");
19235
19277
 
19236
19278
  // src/agents/codex/local-token.ts
19237
- var fs20 = __toESM(require("fs"));
19238
- var os18 = __toESM(require("os"));
19239
- var path25 = __toESM(require("path"));
19279
+ var fs21 = __toESM(require("fs"));
19280
+ var os19 = __toESM(require("os"));
19281
+ var path26 = __toESM(require("path"));
19240
19282
  function codexCredentialsPath() {
19241
- return path25.join(os18.homedir(), ".codex", "auth.json");
19283
+ return path26.join(os19.homedir(), ".codex", "auth.json");
19242
19284
  }
19243
19285
  async function extractLocalCodexToken() {
19244
19286
  const file = codexCredentialsPath();
19245
- if (!fs20.existsSync(file)) return null;
19246
- const credential = fs20.readFileSync(file, "utf8").trim();
19287
+ if (!fs21.existsSync(file)) return null;
19288
+ const credential = fs21.readFileSync(file, "utf8").trim();
19247
19289
  if (credential.length === 0) return null;
19248
19290
  return { method: "oauth", credential, source: "flat-file" };
19249
19291
  }
@@ -19484,7 +19526,7 @@ function augmentNpmGlobalBin(os74) {
19484
19526
  if (result.status !== 0) return;
19485
19527
  const prefix = result.stdout.toString().trim();
19486
19528
  if (!prefix) return;
19487
- const binDir = os74.id === "win32" ? prefix : path26.join(prefix, "bin");
19529
+ const binDir = os74.id === "win32" ? prefix : path27.join(prefix, "bin");
19488
19530
  os74.augmentPath([binDir]);
19489
19531
  } catch {
19490
19532
  }
@@ -19569,7 +19611,7 @@ var import_node_child_process9 = require("child_process");
19569
19611
  // src/agents/coderabbit/installer.ts
19570
19612
  var import_node_child_process7 = require("child_process");
19571
19613
  var import_node_fs6 = require("fs");
19572
- var path28 = __toESM(require("path"));
19614
+ var path29 = __toESM(require("path"));
19573
19615
 
19574
19616
  // src/commands/host/os-packages.ts
19575
19617
  var import_node_child_process6 = require("child_process");
@@ -19683,7 +19725,7 @@ function writeUnzipShim(os74, runner) {
19683
19725
  const python = ["python3", "python"].find((p2) => runner.which(p2));
19684
19726
  if (!python) return null;
19685
19727
  const dir = os74.scratchPath("codeam-cr-prereq");
19686
- const shim = path28.join(dir, "unzip");
19728
+ const shim = path29.join(dir, "unzip");
19687
19729
  const script = `#!/bin/sh
19688
19730
  set -e
19689
19731
  archive=""
@@ -19833,9 +19875,9 @@ async function ensureCoderabbitInstalled(os74, deps = {}) {
19833
19875
 
19834
19876
  // src/agents/coderabbit/link.ts
19835
19877
  var import_node_child_process8 = require("child_process");
19836
- var fs22 = __toESM(require("fs"));
19837
- var os20 = __toESM(require("os"));
19838
- var path29 = __toESM(require("path"));
19878
+ var fs23 = __toESM(require("fs"));
19879
+ var os21 = __toESM(require("os"));
19880
+ var path30 = __toESM(require("path"));
19839
19881
 
19840
19882
  // src/agents/strategy.ts
19841
19883
  function validateNonEmptyCredential(token) {
@@ -19844,12 +19886,12 @@ function validateNonEmptyCredential(token) {
19844
19886
 
19845
19887
  // src/agents/coderabbit/link.ts
19846
19888
  function authPath() {
19847
- return path29.join(os20.homedir(), ".coderabbit", "auth.json");
19889
+ return path30.join(os21.homedir(), ".coderabbit", "auth.json");
19848
19890
  }
19849
19891
  async function extractLocalCoderabbitToken() {
19850
19892
  const file = authPath();
19851
- if (!fs22.existsSync(file)) return null;
19852
- const credential = fs22.readFileSync(file, "utf8").trim();
19893
+ if (!fs23.existsSync(file)) return null;
19894
+ const credential = fs23.readFileSync(file, "utf8").trim();
19853
19895
  if (credential.length === 0) return null;
19854
19896
  return { method: "oauth", credential, source: "flat-file" };
19855
19897
  }
@@ -20193,39 +20235,39 @@ CodeRabbit review timed out after ${Math.round(
20193
20235
  };
20194
20236
 
20195
20237
  // src/agents/cursor/history.ts
20196
- var fs23 = __toESM(require("fs"));
20197
- var os21 = __toESM(require("os"));
20198
- var path30 = __toESM(require("path"));
20238
+ var fs24 = __toESM(require("fs"));
20239
+ var os22 = __toESM(require("os"));
20240
+ var path31 = __toESM(require("path"));
20199
20241
  var import_node_crypto6 = require("crypto");
20200
- var HISTORY_ROOT = path30.join(os21.homedir(), ".cursor", "projects");
20201
- var CURSOR_HOME = path30.join(os21.homedir(), ".cursor");
20242
+ var HISTORY_ROOT = path31.join(os22.homedir(), ".cursor", "projects");
20243
+ var CURSOR_HOME = path31.join(os22.homedir(), ".cursor");
20202
20244
  var STORE_FILES = ["store.db", "store.db-wal", "store.db-shm"];
20203
20245
  function acpSessionDir(sessionId) {
20204
- return path30.join(CURSOR_HOME, "acp-sessions", sessionId);
20246
+ return path31.join(CURSOR_HOME, "acp-sessions", sessionId);
20205
20247
  }
20206
20248
  function nativeStoreDir(cwd, sessionId) {
20207
- const chatsRoot = path30.join(CURSOR_HOME, "chats");
20249
+ const chatsRoot = path31.join(CURSOR_HOME, "chats");
20208
20250
  let buckets = [];
20209
20251
  try {
20210
- buckets = fs23.readdirSync(chatsRoot);
20252
+ buckets = fs24.readdirSync(chatsRoot);
20211
20253
  } catch {
20212
20254
  }
20213
20255
  for (const b of buckets) {
20214
- const candidate = path30.join(chatsRoot, b, sessionId);
20215
- if (fs23.existsSync(path30.join(candidate, "store.db"))) return candidate;
20256
+ const candidate = path31.join(chatsRoot, b, sessionId);
20257
+ if (fs24.existsSync(path31.join(candidate, "store.db"))) return candidate;
20216
20258
  }
20217
- const computed = path30.join(chatsRoot, (0, import_node_crypto6.createHash)("md5").update(cwd).digest("hex"), sessionId);
20218
- return fs23.existsSync(computed) ? computed : null;
20259
+ const computed = path31.join(chatsRoot, (0, import_node_crypto6.createHash)("md5").update(cwd).digest("hex"), sessionId);
20260
+ return fs24.existsSync(computed) ? computed : null;
20219
20261
  }
20220
20262
  function copyStoreFiles(srcDir, dstDir) {
20221
- fs23.mkdirSync(dstDir, { recursive: true });
20263
+ fs24.mkdirSync(dstDir, { recursive: true });
20222
20264
  for (const f of STORE_FILES) {
20223
- const dst = path30.join(dstDir, f);
20224
- if (fs23.existsSync(dst)) fs23.rmSync(dst, { force: true });
20265
+ const dst = path31.join(dstDir, f);
20266
+ if (fs24.existsSync(dst)) fs24.rmSync(dst, { force: true });
20225
20267
  }
20226
20268
  for (const f of STORE_FILES) {
20227
- const src = path30.join(srcDir, f);
20228
- if (fs23.existsSync(src)) fs23.copyFileSync(src, path30.join(dstDir, f));
20269
+ const src = path31.join(srcDir, f);
20270
+ if (fs24.existsSync(src)) fs24.copyFileSync(src, path31.join(dstDir, f));
20229
20271
  }
20230
20272
  }
20231
20273
  function bridgeNativeToAcp(cwd, sessionId) {
@@ -20237,8 +20279,8 @@ function bridgeNativeToAcp(cwd, sessionId) {
20237
20279
  }
20238
20280
  const dst = acpSessionDir(sessionId);
20239
20281
  copyStoreFiles(src, dst);
20240
- fs23.writeFileSync(
20241
- path30.join(dst, "meta.json"),
20282
+ fs24.writeFileSync(
20283
+ path31.join(dst, "meta.json"),
20242
20284
  JSON.stringify({ schemaVersion: 1, cwd })
20243
20285
  );
20244
20286
  log.info("cursor", `baton bridge native\u2192acp ok (${sessionId.slice(0, 8)})`);
@@ -20249,11 +20291,11 @@ function bridgeNativeToAcp(cwd, sessionId) {
20249
20291
  function bridgeAcpToNative(cwd, sessionId) {
20250
20292
  try {
20251
20293
  const src = acpSessionDir(sessionId);
20252
- if (!fs23.existsSync(path30.join(src, "store.db"))) {
20294
+ if (!fs24.existsSync(path31.join(src, "store.db"))) {
20253
20295
  log.warn("cursor", `baton bridge: no acp store for ${sessionId.slice(0, 8)} \u2014 skip`);
20254
20296
  return;
20255
20297
  }
20256
- const dst = nativeStoreDir(cwd, sessionId) ?? path30.join(CURSOR_HOME, "chats", (0, import_node_crypto6.createHash)("md5").update(cwd).digest("hex"), sessionId);
20298
+ const dst = nativeStoreDir(cwd, sessionId) ?? path31.join(CURSOR_HOME, "chats", (0, import_node_crypto6.createHash)("md5").update(cwd).digest("hex"), sessionId);
20257
20299
  copyStoreFiles(src, dst);
20258
20300
  log.info("cursor", `baton bridge acp\u2192native ok (${sessionId.slice(0, 8)})`);
20259
20301
  } catch (err) {
@@ -20264,26 +20306,26 @@ function encodeCursorCwd(cwd) {
20264
20306
  return cwd.replace(/^[/\\]+/, "").replace(/[/\\:]/g, "-");
20265
20307
  }
20266
20308
  function resolveHistoryFile3(cwd, sessionId, root = HISTORY_ROOT) {
20267
- const rel = path30.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
20268
- const primary = path30.join(root, encodeCursorCwd(cwd), rel);
20269
- if (fs23.existsSync(primary)) return primary;
20309
+ const rel = path31.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
20310
+ const primary = path31.join(root, encodeCursorCwd(cwd), rel);
20311
+ if (fs24.existsSync(primary)) return primary;
20270
20312
  let entries2;
20271
20313
  try {
20272
- entries2 = fs23.readdirSync(root, { withFileTypes: true });
20314
+ entries2 = fs24.readdirSync(root, { withFileTypes: true });
20273
20315
  } catch {
20274
20316
  return null;
20275
20317
  }
20276
20318
  for (const e of entries2) {
20277
20319
  if (!e.isDirectory()) continue;
20278
- const candidate = path30.join(root, e.name, rel);
20279
- if (fs23.existsSync(candidate)) return candidate;
20320
+ const candidate = path31.join(root, e.name, rel);
20321
+ if (fs24.existsSync(candidate)) return candidate;
20280
20322
  }
20281
20323
  return null;
20282
20324
  }
20283
20325
  function resolveHistoryDir3(cwd) {
20284
- if (!fs23.existsSync(HISTORY_ROOT)) return null;
20285
- const dir = path30.join(HISTORY_ROOT, encodeCursorCwd(cwd));
20286
- return fs23.existsSync(dir) ? dir : null;
20326
+ if (!fs24.existsSync(HISTORY_ROOT)) return null;
20327
+ const dir = path31.join(HISTORY_ROOT, encodeCursorCwd(cwd));
20328
+ return fs24.existsSync(dir) ? dir : null;
20287
20329
  }
20288
20330
  function extractText2(content) {
20289
20331
  if (!Array.isArray(content)) return "";
@@ -20296,7 +20338,7 @@ function unwrapUserQuery(text) {
20296
20338
  function parseHistoryFile3(filePath) {
20297
20339
  let raw;
20298
20340
  try {
20299
- raw = fs23.readFileSync(filePath, "utf8");
20341
+ raw = fs24.readFileSync(filePath, "utf8");
20300
20342
  } catch {
20301
20343
  return [];
20302
20344
  }
@@ -20334,16 +20376,16 @@ function getCurrentUsage3(_historyDir) {
20334
20376
  var import_node_child_process10 = require("child_process");
20335
20377
 
20336
20378
  // src/agents/cursor/local-token.ts
20337
- var fs24 = __toESM(require("fs"));
20338
- var os22 = __toESM(require("os"));
20339
- var path31 = __toESM(require("path"));
20379
+ var fs25 = __toESM(require("fs"));
20380
+ var os23 = __toESM(require("os"));
20381
+ var path32 = __toESM(require("path"));
20340
20382
  function cursorCredentialsPath() {
20341
- return path31.join(os22.homedir(), ".cursor", "auth.json");
20383
+ return path32.join(os23.homedir(), ".cursor", "auth.json");
20342
20384
  }
20343
20385
  async function extractLocalCursorToken() {
20344
20386
  const file = cursorCredentialsPath();
20345
- if (!fs24.existsSync(file)) return null;
20346
- const credential = fs24.readFileSync(file, "utf8").trim();
20387
+ if (!fs25.existsSync(file)) return null;
20388
+ const credential = fs25.readFileSync(file, "utf8").trim();
20347
20389
  if (credential.length === 0) return null;
20348
20390
  return { method: "oauth", credential, source: "flat-file" };
20349
20391
  }
@@ -20588,12 +20630,12 @@ var CursorRuntimeStrategy = class {
20588
20630
  };
20589
20631
 
20590
20632
  // src/agents/aider/history.ts
20591
- var fs25 = __toESM(require("fs"));
20592
- var path32 = __toESM(require("path"));
20633
+ var fs26 = __toESM(require("fs"));
20634
+ var path33 = __toESM(require("path"));
20593
20635
  var AIDER_HISTORY_FILE = ".aider.chat.history.md";
20594
20636
  function resolveHistoryDir4(cwd) {
20595
- const candidate = path32.join(cwd, AIDER_HISTORY_FILE);
20596
- return fs25.existsSync(candidate) ? cwd : null;
20637
+ const candidate = path33.join(cwd, AIDER_HISTORY_FILE);
20638
+ return fs26.existsSync(candidate) ? cwd : null;
20597
20639
  }
20598
20640
  function parseHistoryFile4(_filePath) {
20599
20641
  return [];
@@ -20606,10 +20648,10 @@ function getCurrentUsage4(_historyDir) {
20606
20648
  var import_node_child_process12 = require("child_process");
20607
20649
 
20608
20650
  // src/agents/aider/local-token.ts
20609
- var fs26 = __toESM(require("fs"));
20610
- var os23 = __toESM(require("os"));
20611
- var path33 = __toESM(require("path"));
20612
- var AIDER_CONF_FILE = path33.join(os23.homedir(), ".aider.conf.yml");
20651
+ var fs27 = __toESM(require("fs"));
20652
+ var os24 = __toESM(require("os"));
20653
+ var path34 = __toESM(require("path"));
20654
+ var AIDER_CONF_FILE = path34.join(os24.homedir(), ".aider.conf.yml");
20613
20655
  var API_KEY_ENV_VARS = [
20614
20656
  "ANTHROPIC_API_KEY",
20615
20657
  "OPENAI_API_KEY",
@@ -20624,8 +20666,8 @@ async function extractLocalAiderToken() {
20624
20666
  return { method: "api_key", credential: value.trim(), source: "flat-file" };
20625
20667
  }
20626
20668
  }
20627
- if (fs26.existsSync(AIDER_CONF_FILE)) {
20628
- const conf = fs26.readFileSync(AIDER_CONF_FILE, "utf8");
20669
+ if (fs27.existsSync(AIDER_CONF_FILE)) {
20670
+ const conf = fs27.readFileSync(AIDER_CONF_FILE, "utf8");
20629
20671
  const match = conf.match(/^api-key:\s*['"]?([^'"\n]+)['"]?\s*$/m);
20630
20672
  if (match) {
20631
20673
  return { method: "api_key", credential: match[1].trim(), source: "flat-file" };
@@ -21021,19 +21063,19 @@ var import_node_crypto7 = require("crypto");
21021
21063
  var import_node_child_process13 = require("child_process");
21022
21064
 
21023
21065
  // src/agents/gemini/local-token.ts
21024
- var fs28 = __toESM(require("fs"));
21025
- var os25 = __toESM(require("os"));
21026
- var path35 = __toESM(require("path"));
21066
+ var fs29 = __toESM(require("fs"));
21067
+ var os26 = __toESM(require("os"));
21068
+ var path36 = __toESM(require("path"));
21027
21069
  function geminiCredentialsPath() {
21028
- return path35.join(os25.homedir(), ".gemini", "oauth_creds.json");
21070
+ return path36.join(os26.homedir(), ".gemini", "oauth_creds.json");
21029
21071
  }
21030
21072
  function geminiCredentialsPaths() {
21031
21073
  return [geminiCredentialsPath()];
21032
21074
  }
21033
21075
  async function extractLocalGeminiToken() {
21034
21076
  const file = geminiCredentialsPath();
21035
- if (!fs28.existsSync(file)) return null;
21036
- const credential = fs28.readFileSync(file, "utf8").trim();
21077
+ if (!fs29.existsSync(file)) return null;
21078
+ const credential = fs29.readFileSync(file, "utf8").trim();
21037
21079
  if (credential.length === 0) return null;
21038
21080
  return { method: "oauth", credential, source: "flat-file" };
21039
21081
  }
@@ -21089,20 +21131,20 @@ function geminiLoginLauncher() {
21089
21131
  }
21090
21132
 
21091
21133
  // src/agents/gemini/history.ts
21092
- var fs29 = __toESM(require("fs"));
21093
- var os26 = __toESM(require("os"));
21094
- var path36 = __toESM(require("path"));
21095
- var GEMINI_ROOT = path36.join(os26.homedir(), ".gemini");
21134
+ var fs30 = __toESM(require("fs"));
21135
+ var os27 = __toESM(require("os"));
21136
+ var path37 = __toESM(require("path"));
21137
+ var GEMINI_ROOT = path37.join(os27.homedir(), ".gemini");
21096
21138
  function projectNameForCwd(cwd, root) {
21097
21139
  try {
21098
21140
  const parsed = JSON.parse(
21099
- fs29.readFileSync(path36.join(root, "projects.json"), "utf8")
21141
+ fs30.readFileSync(path37.join(root, "projects.json"), "utf8")
21100
21142
  );
21101
21143
  const map = parsed.projects;
21102
21144
  if (map && typeof map === "object") {
21103
21145
  if (typeof map[cwd] === "string") return map[cwd];
21104
21146
  try {
21105
- const rp = fs29.realpathSync(cwd);
21147
+ const rp = fs30.realpathSync(cwd);
21106
21148
  if (typeof map[rp] === "string") return map[rp];
21107
21149
  } catch {
21108
21150
  }
@@ -21111,7 +21153,7 @@ function projectNameForCwd(cwd, root) {
21111
21153
  } catch (err) {
21112
21154
  log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
21113
21155
  }
21114
- return path36.basename(cwd) || null;
21156
+ return path37.basename(cwd) || null;
21115
21157
  }
21116
21158
  function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
21117
21159
  const name = projectNameForCwd(cwd, root);
@@ -21119,8 +21161,8 @@ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
21119
21161
  log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
21120
21162
  return null;
21121
21163
  }
21122
- const dir = path36.join(root, "tmp", name, "chats");
21123
- if (!fs29.existsSync(dir)) {
21164
+ const dir = path37.join(root, "tmp", name, "chats");
21165
+ if (!fs30.existsSync(dir)) {
21124
21166
  log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
21125
21167
  return null;
21126
21168
  }
@@ -21132,7 +21174,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
21132
21174
  if (!dir) return null;
21133
21175
  let files;
21134
21176
  try {
21135
- files = fs29.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
21177
+ files = fs30.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
21136
21178
  } catch (err) {
21137
21179
  log.warn("gemini", `resolveHistoryFile \u2014 cannot read chats dir ${dir} (id8=${id8})`, err);
21138
21180
  return null;
@@ -21144,12 +21186,12 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
21144
21186
  const byName = files.find((f) => id8.length > 0 && f.includes(id8));
21145
21187
  if (byName) {
21146
21188
  log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
21147
- return path36.join(dir, byName);
21189
+ return path37.join(dir, byName);
21148
21190
  }
21149
21191
  for (const f of files) {
21150
- const full = path36.join(dir, f);
21192
+ const full = path37.join(dir, f);
21151
21193
  try {
21152
- const firstLine = fs29.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
21194
+ const firstLine = fs30.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
21153
21195
  const hdr = JSON.parse(firstLine);
21154
21196
  if (hdr.sessionId === sessionId) {
21155
21197
  log.info("gemini", `resolveHistoryFile \u2014 matched by header sessionId: ${f}`);
@@ -21162,7 +21204,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
21162
21204
  let newest = null;
21163
21205
  for (const f of files) {
21164
21206
  try {
21165
- const mtime = fs29.statSync(path36.join(dir, f)).mtimeMs;
21207
+ const mtime = fs30.statSync(path37.join(dir, f)).mtimeMs;
21166
21208
  if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
21167
21209
  } catch {
21168
21210
  }
@@ -21171,7 +21213,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
21171
21213
  "gemini",
21172
21214
  `resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
21173
21215
  );
21174
- return newest ? path36.join(dir, newest.file) : null;
21216
+ return newest ? path37.join(dir, newest.file) : null;
21175
21217
  }
21176
21218
  function extractGeminiText(content) {
21177
21219
  const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
@@ -21199,7 +21241,7 @@ function isSyntheticGeminiTurn(text) {
21199
21241
  function parseHistoryFile5(filePath) {
21200
21242
  let raw;
21201
21243
  try {
21202
- raw = fs29.readFileSync(filePath, "utf8");
21244
+ raw = fs30.readFileSync(filePath, "utf8");
21203
21245
  } catch (err) {
21204
21246
  log.warn("gemini", `parseHistoryFile \u2014 cannot read ${filePath}`, err);
21205
21247
  return [];
@@ -21240,7 +21282,7 @@ function parseHistoryFile5(filePath) {
21240
21282
  }
21241
21283
  log.trace(
21242
21284
  "gemini",
21243
- `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path36.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
21285
+ `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path37.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
21244
21286
  );
21245
21287
  return out2;
21246
21288
  }
@@ -21386,42 +21428,42 @@ var import_node_os4 = require("os");
21386
21428
  var import_node_path6 = require("path");
21387
21429
 
21388
21430
  // src/agents/kimi/history.ts
21389
- var fs30 = __toESM(require("fs"));
21390
- var os27 = __toESM(require("os"));
21391
- var path37 = __toESM(require("path"));
21431
+ var fs31 = __toESM(require("fs"));
21432
+ var os28 = __toESM(require("os"));
21433
+ var path38 = __toESM(require("path"));
21392
21434
  var import_node_crypto8 = require("crypto");
21393
21435
  function kimiHome() {
21394
- return process.env.KIMI_CODE_HOME || path37.join(os27.homedir(), ".kimi-code");
21436
+ return process.env.KIMI_CODE_HOME || path38.join(os28.homedir(), ".kimi-code");
21395
21437
  }
21396
21438
  function workDirKey(cwd) {
21397
21439
  const hash = (0, import_node_crypto8.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
21398
- return `wd_${path37.basename(cwd)}_${hash}`;
21440
+ return `wd_${path38.basename(cwd)}_${hash}`;
21399
21441
  }
21400
21442
  function resolveHistoryDir6(cwd) {
21401
- const dir = path37.join(kimiHome(), "sessions", workDirKey(cwd));
21402
- if (!fs30.existsSync(dir)) {
21443
+ const dir = path38.join(kimiHome(), "sessions", workDirKey(cwd));
21444
+ if (!fs31.existsSync(dir)) {
21403
21445
  log.debug("kimi", `resolveHistoryDir \u2014 session bucket not present yet: ${dir}`);
21404
21446
  return null;
21405
21447
  }
21406
21448
  return dir;
21407
21449
  }
21408
- var WIRE_REL = path37.join("agents", "main", "wire.jsonl");
21450
+ var WIRE_REL = path38.join("agents", "main", "wire.jsonl");
21409
21451
  function resolveHistoryFile5(cwd, sessionId) {
21410
21452
  const fromIndex = sessionDirFromIndex(sessionId);
21411
21453
  if (fromIndex) {
21412
- const p2 = path37.join(fromIndex, WIRE_REL);
21413
- if (fs30.existsSync(p2)) return p2;
21454
+ const p2 = path38.join(fromIndex, WIRE_REL);
21455
+ if (fs31.existsSync(p2)) return p2;
21414
21456
  }
21415
- const bucket = path37.join(kimiHome(), "sessions", workDirKey(cwd));
21416
- const computed = path37.join(bucket, sessionId, WIRE_REL);
21417
- if (fs30.existsSync(computed)) return computed;
21457
+ const bucket = path38.join(kimiHome(), "sessions", workDirKey(cwd));
21458
+ const computed = path38.join(bucket, sessionId, WIRE_REL);
21459
+ if (fs31.existsSync(computed)) return computed;
21418
21460
  const scanned = scanBucketsForSession(sessionId);
21419
21461
  if (scanned) return scanned;
21420
21462
  return null;
21421
21463
  }
21422
21464
  function sessionDirFromIndex(sessionId) {
21423
21465
  try {
21424
- const raw = fs30.readFileSync(path37.join(kimiHome(), "session_index.jsonl"), "utf8");
21466
+ const raw = fs31.readFileSync(path38.join(kimiHome(), "session_index.jsonl"), "utf8");
21425
21467
  for (const line of raw.split("\n")) {
21426
21468
  if (!line.includes(sessionId)) continue;
21427
21469
  try {
@@ -21437,22 +21479,22 @@ function sessionDirFromIndex(sessionId) {
21437
21479
  return null;
21438
21480
  }
21439
21481
  function scanBucketsForSession(sessionId) {
21440
- const sessionsRoot = path37.join(kimiHome(), "sessions");
21482
+ const sessionsRoot = path38.join(kimiHome(), "sessions");
21441
21483
  let buckets;
21442
21484
  try {
21443
- buckets = fs30.readdirSync(sessionsRoot, { withFileTypes: true });
21485
+ buckets = fs31.readdirSync(sessionsRoot, { withFileTypes: true });
21444
21486
  } catch {
21445
21487
  return null;
21446
21488
  }
21447
21489
  for (const b of buckets) {
21448
21490
  if (!b.isDirectory()) continue;
21449
- const candidate = path37.join(sessionsRoot, b.name, sessionId, WIRE_REL);
21450
- if (fs30.existsSync(candidate)) return candidate;
21491
+ const candidate = path38.join(sessionsRoot, b.name, sessionId, WIRE_REL);
21492
+ if (fs31.existsSync(candidate)) return candidate;
21451
21493
  }
21452
21494
  return null;
21453
21495
  }
21454
21496
  async function discoverSessionId2(cwd, opts) {
21455
- const bucket = path37.join(kimiHome(), "sessions", workDirKey(cwd));
21497
+ const bucket = path38.join(kimiHome(), "sessions", workDirKey(cwd));
21456
21498
  const floor = opts.sinceMs - 2e3;
21457
21499
  const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
21458
21500
  for (; ; ) {
@@ -21465,7 +21507,7 @@ async function discoverSessionId2(cwd, opts) {
21465
21507
  function newestSessionSince(bucket, floorMs) {
21466
21508
  let entries2;
21467
21509
  try {
21468
- entries2 = fs30.readdirSync(bucket, { withFileTypes: true });
21510
+ entries2 = fs31.readdirSync(bucket, { withFileTypes: true });
21469
21511
  } catch {
21470
21512
  return null;
21471
21513
  }
@@ -21475,7 +21517,7 @@ function newestSessionSince(bucket, floorMs) {
21475
21517
  if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
21476
21518
  let mtime;
21477
21519
  try {
21478
- mtime = fs30.statSync(path37.join(bucket, e.name)).mtimeMs;
21520
+ mtime = fs31.statSync(path38.join(bucket, e.name)).mtimeMs;
21479
21521
  } catch {
21480
21522
  continue;
21481
21523
  }
@@ -21496,7 +21538,7 @@ function joinTextParts(parts) {
21496
21538
  function parseHistoryFile6(filePath) {
21497
21539
  let raw;
21498
21540
  try {
21499
- raw = fs30.readFileSync(filePath, "utf8");
21541
+ raw = fs31.readFileSync(filePath, "utf8");
21500
21542
  } catch {
21501
21543
  return [];
21502
21544
  }
@@ -21878,7 +21920,7 @@ function parseLinkArgs(args2) {
21878
21920
  if (apiKeyFileArg) {
21879
21921
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
21880
21922
  try {
21881
- apiKey = fs31.readFileSync(path38.resolve(filePath), "utf8").trim();
21923
+ apiKey = fs32.readFileSync(path39.resolve(filePath), "utf8").trim();
21882
21924
  } catch (err) {
21883
21925
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
21884
21926
  }
@@ -22005,7 +22047,7 @@ async function link(args2 = []) {
22005
22047
  return;
22006
22048
  }
22007
22049
  if (parsed.tokenFile) {
22008
- const credential = fs31.readFileSync(path38.resolve(parsed.tokenFile), "utf8").trim();
22050
+ const credential = fs32.readFileSync(path39.resolve(parsed.tokenFile), "utf8").trim();
22009
22051
  if (!credential) {
22010
22052
  showError(`--token-file ${parsed.tokenFile} is empty.`);
22011
22053
  process.exit(1);
@@ -22260,13 +22302,13 @@ function makePreviewHeartbeatReaffirm(deps) {
22260
22302
  // src/agents/coderabbit/configure.ts
22261
22303
  var import_node_child_process17 = require("child_process");
22262
22304
  var import_node_fs7 = require("fs");
22263
- var path40 = __toESM(require("path"));
22305
+ var path41 = __toESM(require("path"));
22264
22306
 
22265
22307
  // src/agents/coderabbit/oauth.ts
22266
22308
  var import_node_child_process16 = require("child_process");
22267
- var fs32 = __toESM(require("fs"));
22268
- var os28 = __toESM(require("os"));
22269
- var path39 = __toESM(require("path"));
22309
+ var fs33 = __toESM(require("fs"));
22310
+ var os29 = __toESM(require("os"));
22311
+ var path40 = __toESM(require("path"));
22270
22312
  function parseCoderabbitAuthEvent(line) {
22271
22313
  const l = line.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "").trim();
22272
22314
  if (!l || l[0] !== "{") return null;
@@ -22315,8 +22357,8 @@ function resolvePython() {
22315
22357
  function spawnCoderabbitLoginProc(cmd, args2) {
22316
22358
  const python = resolvePython();
22317
22359
  if (python) {
22318
- const helper = path39.join(os28.tmpdir(), "codeam-cr-pty.py");
22319
- fs32.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
22360
+ const helper = path40.join(os29.tmpdir(), "codeam-cr-pty.py");
22361
+ fs33.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
22320
22362
  return (0, import_node_child_process16.spawn)(python, [helper, cmd, ...args2], {
22321
22363
  stdio: ["pipe", "pipe", "pipe"],
22322
22364
  env: { ...process.env, TERM: "xterm-256color", COLUMNS: "220", LINES: "50" },
@@ -22427,7 +22469,7 @@ function runCoderabbitOAuthLogin(deps) {
22427
22469
  });
22428
22470
  }
22429
22471
  function coderabbitDir(home) {
22430
- return path39.join(home ?? os28.homedir(), ".coderabbit");
22472
+ return path40.join(home ?? os29.homedir(), ".coderabbit");
22431
22473
  }
22432
22474
  var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
22433
22475
  function snapshotCredentialDir(home) {
@@ -22435,14 +22477,14 @@ function snapshotCredentialDir(home) {
22435
22477
  const snap = {};
22436
22478
  let entries2;
22437
22479
  try {
22438
- entries2 = fs32.readdirSync(dir, { withFileTypes: true });
22480
+ entries2 = fs33.readdirSync(dir, { withFileTypes: true });
22439
22481
  } catch {
22440
22482
  return snap;
22441
22483
  }
22442
22484
  for (const e of entries2) {
22443
22485
  if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
22444
22486
  try {
22445
- const st3 = fs32.statSync(path39.join(dir, e.name));
22487
+ const st3 = fs33.statSync(path40.join(dir, e.name));
22446
22488
  snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
22447
22489
  } catch {
22448
22490
  }
@@ -22460,7 +22502,7 @@ function diffCapturedCredential(before, home) {
22460
22502
  }
22461
22503
  if (!best) return null;
22462
22504
  try {
22463
- return { file: best.file, contents: fs32.readFileSync(path39.join(dir, best.file), "utf8") };
22505
+ return { file: best.file, contents: fs33.readFileSync(path40.join(dir, best.file), "utf8") };
22464
22506
  } catch {
22465
22507
  return null;
22466
22508
  }
@@ -22537,7 +22579,7 @@ function collectChangedFiles(cwd) {
22537
22579
  return [...byPath.values()];
22538
22580
  }
22539
22581
  function restoreCoderabbitOauthBlob(os74, value) {
22540
- const dir = path40.join(os74.homeDir(), ".coderabbit");
22582
+ const dir = path41.join(os74.homeDir(), ".coderabbit");
22541
22583
  (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
22542
22584
  let file = "auth.json";
22543
22585
  let contents = value.trim();
@@ -22545,13 +22587,13 @@ function restoreCoderabbitOauthBlob(os74, value) {
22545
22587
  try {
22546
22588
  const parsed = JSON.parse(contents);
22547
22589
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
22548
- file = path40.basename(parsed.file);
22590
+ file = path41.basename(parsed.file);
22549
22591
  contents = parsed.contents;
22550
22592
  }
22551
22593
  } catch {
22552
22594
  }
22553
22595
  }
22554
- (0, import_node_fs7.writeFileSync)(path40.join(dir, file), contents, { mode: 384 });
22596
+ (0, import_node_fs7.writeFileSync)(path41.join(dir, file), contents, { mode: 384 });
22555
22597
  }
22556
22598
  function installFailureMessage(result) {
22557
22599
  return result.error ?? "CodeRabbit CLI could not be installed";
@@ -22567,10 +22609,10 @@ async function configureCoderabbit(input, deps = {}) {
22567
22609
  const home = os74.homeDir();
22568
22610
  os74.augmentPath(
22569
22611
  os74.id === "win32" ? [
22570
- path40.join(home, ".local", "bin"),
22571
- path40.join(process.env.APPDATA ?? path40.join(home, "AppData", "Roaming"), "npm"),
22572
- path40.join(home, "scoop", "shims")
22573
- ] : [path40.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
22612
+ path41.join(home, ".local", "bin"),
22613
+ path41.join(process.env.APPDATA ?? path41.join(home, "AppData", "Roaming"), "npm"),
22614
+ path41.join(home, "scoop", "shims")
22615
+ ] : [path41.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
22574
22616
  );
22575
22617
  const installed2 = os74.findInPath("coderabbit") !== null;
22576
22618
  const base = () => ({
@@ -22889,9 +22931,9 @@ var import_node_child_process22 = require("child_process");
22889
22931
  var import_node_util7 = require("util");
22890
22932
 
22891
22933
  // src/commands/host/workspace.ts
22892
- var fs34 = __toESM(require("fs"));
22893
- var os30 = __toESM(require("os"));
22894
- var path41 = __toESM(require("path"));
22934
+ var fs35 = __toESM(require("fs"));
22935
+ var os31 = __toESM(require("os"));
22936
+ var path42 = __toESM(require("path"));
22895
22937
  var import_node_child_process20 = require("child_process");
22896
22938
  var import_node_util5 = require("util");
22897
22939
 
@@ -22931,18 +22973,18 @@ function restrictToOwner(filePath) {
22931
22973
  // src/commands/host/workspace.ts
22932
22974
  var execFileP4 = (0, import_node_util5.promisify)(import_node_child_process20.execFile);
22933
22975
  function isAbsolutePathTarget(target) {
22934
- return path41.isAbsolute(target);
22976
+ return path42.isAbsolute(target);
22935
22977
  }
22936
22978
  function selfHostedWorkspaceRoot() {
22937
- return path41.join(os30.homedir(), ".codeam", "self-hosted");
22979
+ return path42.join(os31.homedir(), ".codeam", "self-hosted");
22938
22980
  }
22939
22981
  function deployIdFromWorkspace(cwd) {
22940
22982
  if (!cwd) return null;
22941
22983
  const root = selfHostedWorkspaceRoot();
22942
- const resolved = path41.resolve(cwd);
22943
- const rel = path41.relative(root, resolved);
22944
- if (!rel || rel.startsWith("..") || path41.isAbsolute(rel)) return null;
22945
- const parts = rel.split(path41.sep).filter(Boolean);
22984
+ const resolved = path42.resolve(cwd);
22985
+ const rel = path42.relative(root, resolved);
22986
+ if (!rel || rel.startsWith("..") || path42.isAbsolute(rel)) return null;
22987
+ const parts = rel.split(path42.sep).filter(Boolean);
22946
22988
  if (parts.length !== 1) return null;
22947
22989
  return parts[0];
22948
22990
  }
@@ -23014,15 +23056,15 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
23014
23056
  const isGitlab = provider === "gitlab";
23015
23057
  if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
23016
23058
  if (!cloneToken) return;
23017
- const credFile = path41.join(dest, ".git", "codeam-credentials");
23059
+ const credFile = path42.join(dest, ".git", "codeam-credentials");
23018
23060
  const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
23019
23061
  ` : `https://x-access-token:${cloneToken}@github.com
23020
23062
  `;
23021
- fs34.writeFileSync(credFile, credLine, { mode: 384 });
23063
+ fs35.writeFileSync(credFile, credLine, { mode: 384 });
23022
23064
  restrictToOwner(credFile);
23023
23065
  const env = nonInteractiveGitEnv();
23024
23066
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
23025
- const credFilePosix = credFile.split(path41.sep).join("/");
23067
+ const credFilePosix = credFile.split(path42.sep).join("/");
23026
23068
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
23027
23069
  });
23028
23070
  await git2([
@@ -23055,17 +23097,17 @@ function maskToken(text, cloneToken) {
23055
23097
  }
23056
23098
  async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
23057
23099
  if (isAbsolutePathTarget(repoOrPath)) {
23058
- if (!fs34.existsSync(repoOrPath)) {
23100
+ if (!fs35.existsSync(repoOrPath)) {
23059
23101
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
23060
23102
  }
23061
23103
  return repoOrPath;
23062
23104
  }
23063
- const dest = path41.join(selfHostedWorkspaceRoot(), deployId);
23064
- if (fs34.existsSync(path41.join(dest, ".git"))) {
23105
+ const dest = path42.join(selfHostedWorkspaceRoot(), deployId);
23106
+ if (fs35.existsSync(path42.join(dest, ".git"))) {
23065
23107
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
23066
23108
  return dest;
23067
23109
  }
23068
- fs34.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
23110
+ fs35.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
23069
23111
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
23070
23112
  const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
23071
23113
  try {
@@ -23207,21 +23249,21 @@ function buildZip(cwd, list, outFile) {
23207
23249
 
23208
23250
  // src/scratch/export-registry.ts
23209
23251
  var import_crypto2 = require("crypto");
23210
- var fs38 = __toESM(require("fs"));
23211
- var os31 = __toESM(require("os"));
23212
- var path45 = __toESM(require("path"));
23252
+ var fs39 = __toESM(require("fs"));
23253
+ var os32 = __toESM(require("os"));
23254
+ var path46 = __toESM(require("path"));
23213
23255
  var entries = /* @__PURE__ */ new Map();
23214
23256
  var EXPORT_TTL_MS = 6e5;
23215
23257
  var RETRY_WINDOW_MS = 6e4;
23216
23258
  var EXPORT_PATH_PREFIX = "/.codeam/export/";
23217
- var exportsBaseDir = () => path45.join(os31.homedir(), ".codeam", "exports");
23218
- var exportDir = () => path45.join(exportsBaseDir(), String(process.pid));
23259
+ var exportsBaseDir = () => path46.join(os32.homedir(), ".codeam", "exports");
23260
+ var exportDir = () => path46.join(exportsBaseDir(), String(process.pid));
23219
23261
  function drop(token) {
23220
23262
  const e = entries.get(token);
23221
23263
  if (!e) return;
23222
23264
  clearTimeout(e.timer);
23223
23265
  entries.delete(token);
23224
- fs38.rmSync(e.file, { force: true });
23266
+ fs39.rmSync(e.file, { force: true });
23225
23267
  }
23226
23268
  function armExpiry(token, ms) {
23227
23269
  const timer = setTimeout(() => {
@@ -23253,7 +23295,7 @@ function handleExportRequest(req, res) {
23253
23295
  if (req.method !== "GET" || !req.url?.startsWith(EXPORT_PATH_PREFIX)) return false;
23254
23296
  const token = req.url.slice(EXPORT_PATH_PREFIX.length).split("?")[0];
23255
23297
  const e = entries.get(token);
23256
- if (!e || e.inFlight || !fs38.existsSync(e.file)) {
23298
+ if (!e || e.inFlight || !fs39.existsSync(e.file)) {
23257
23299
  res.statusCode = 404;
23258
23300
  res.end();
23259
23301
  return true;
@@ -23265,7 +23307,7 @@ function handleExportRequest(req, res) {
23265
23307
  "Content-Disposition": 'attachment; filename="project.zip"',
23266
23308
  "Cache-Control": "no-store"
23267
23309
  });
23268
- const stream = fs38.createReadStream(e.file);
23310
+ const stream = fs39.createReadStream(e.file);
23269
23311
  stream.on("error", () => res.destroy());
23270
23312
  stream.pipe(res);
23271
23313
  res.on("finish", () => {
@@ -23295,16 +23337,16 @@ function purgeExports() {
23295
23337
  const base = exportsBaseDir();
23296
23338
  let names;
23297
23339
  try {
23298
- names = fs38.readdirSync(base);
23340
+ names = fs39.readdirSync(base);
23299
23341
  } catch {
23300
23342
  return;
23301
23343
  }
23302
23344
  for (const name of names) {
23303
- const abs = path45.join(base, name);
23345
+ const abs = path46.join(base, name);
23304
23346
  try {
23305
- const st3 = fs38.lstatSync(abs);
23347
+ const st3 = fs39.lstatSync(abs);
23306
23348
  const stale = st3.isDirectory() && /^\d+$/.test(name) ? Number(name) === process.pid || !isPidAlive(Number(name)) : Date.now() - st3.mtimeMs > EXPORT_TTL_MS;
23307
- if (stale) fs38.rmSync(abs, { recursive: true, force: true });
23349
+ if (stale) fs39.rmSync(abs, { recursive: true, force: true });
23308
23350
  } catch {
23309
23351
  }
23310
23352
  }
@@ -23441,16 +23483,16 @@ async function spawnNamedTunnel(bin, token, port) {
23441
23483
  }
23442
23484
 
23443
23485
  // src/services/preview/port-registry.ts
23444
- var fs40 = __toESM(require("fs"));
23445
- var os33 = __toESM(require("os"));
23446
- var path47 = __toESM(require("path"));
23486
+ var fs41 = __toESM(require("fs"));
23487
+ var os34 = __toESM(require("os"));
23488
+ var path48 = __toESM(require("path"));
23447
23489
  var import_child_process15 = require("child_process");
23448
23490
  function registryPath2() {
23449
- return path47.join(os33.homedir(), ".codeam", "preview-ports.json");
23491
+ return path48.join(os34.homedir(), ".codeam", "preview-ports.json");
23450
23492
  }
23451
23493
  function readRegistry() {
23452
23494
  try {
23453
- const raw = fs40.readFileSync(registryPath2(), "utf8");
23495
+ const raw = fs41.readFileSync(registryPath2(), "utf8");
23454
23496
  const parsed = JSON.parse(raw);
23455
23497
  if (parsed && typeof parsed === "object") return parsed;
23456
23498
  } catch {
@@ -23460,10 +23502,10 @@ function readRegistry() {
23460
23502
  function writeRegistry(reg) {
23461
23503
  try {
23462
23504
  const file = registryPath2();
23463
- fs40.mkdirSync(path47.dirname(file), { recursive: true });
23505
+ fs41.mkdirSync(path48.dirname(file), { recursive: true });
23464
23506
  const tmp = `${file}.tmp`;
23465
- fs40.writeFileSync(tmp, JSON.stringify(reg), "utf8");
23466
- fs40.renameSync(tmp, file);
23507
+ fs41.writeFileSync(tmp, JSON.stringify(reg), "utf8");
23508
+ fs41.renameSync(tmp, file);
23467
23509
  } catch (err) {
23468
23510
  log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
23469
23511
  }
@@ -23529,7 +23571,7 @@ function reclaimOwnOrphanPort(port) {
23529
23571
 
23530
23572
  // src/services/preview/host-allow.ts
23531
23573
  var import_fs3 = require("fs");
23532
- var path48 = __toESM(require("path"));
23574
+ var path49 = __toESM(require("path"));
23533
23575
  var NEXT_ALLOWED_ORIGINS = [
23534
23576
  "*.trycloudflare.com",
23535
23577
  "*.preview.codeagent-mobile.com",
@@ -23549,7 +23591,7 @@ var MARKER_DIR = ".codeam";
23549
23591
  var MARKER_FILE = "preview-host-allow.json";
23550
23592
  var ORIG_INFIX = ".codeam-orig";
23551
23593
  function markerPath(cwd) {
23552
- return path48.join(cwd, MARKER_DIR, MARKER_FILE);
23594
+ return path49.join(cwd, MARKER_DIR, MARKER_FILE);
23553
23595
  }
23554
23596
  async function fileExists(p2) {
23555
23597
  try {
@@ -23562,13 +23604,13 @@ async function fileExists(p2) {
23562
23604
  async function findConfigFile(cwd, framework) {
23563
23605
  const base = CONFIG_BASENAMES[framework];
23564
23606
  for (const ext of CONFIG_EXTS) {
23565
- if (await fileExists(path48.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
23607
+ if (await fileExists(path49.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
23566
23608
  }
23567
23609
  return null;
23568
23610
  }
23569
23611
  async function dependsOn(cwd, pkgName) {
23570
23612
  try {
23571
- const raw = await import_fs3.promises.readFile(path48.join(cwd, "package.json"), "utf8");
23613
+ const raw = await import_fs3.promises.readFile(path49.join(cwd, "package.json"), "utf8");
23572
23614
  const pkg = JSON.parse(raw);
23573
23615
  return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
23574
23616
  } catch {
@@ -23576,11 +23618,11 @@ async function dependsOn(cwd, pkgName) {
23576
23618
  }
23577
23619
  }
23578
23620
  async function isEsmConfig(cwd, configFile) {
23579
- const ext = path48.extname(configFile);
23621
+ const ext = path49.extname(configFile);
23580
23622
  if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
23581
23623
  if (ext === ".cjs") return false;
23582
23624
  try {
23583
- const raw = await import_fs3.promises.readFile(path48.join(cwd, "package.json"), "utf8");
23625
+ const raw = await import_fs3.promises.readFile(path49.join(cwd, "package.json"), "utf8");
23584
23626
  return JSON.parse(raw).type === "module";
23585
23627
  } catch {
23586
23628
  return false;
@@ -23671,7 +23713,7 @@ async function isOurShim(abs) {
23671
23713
  }
23672
23714
  }
23673
23715
  async function writeMarker(cwd, marker) {
23674
- await import_fs3.promises.mkdir(path48.join(cwd, MARKER_DIR), { recursive: true });
23716
+ await import_fs3.promises.mkdir(path49.join(cwd, MARKER_DIR), { recursive: true });
23675
23717
  await import_fs3.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
23676
23718
  }
23677
23719
  async function readMarker(cwd) {
@@ -23686,9 +23728,9 @@ async function restorePreviewHostAllow(cwd) {
23686
23728
  const marker = await readMarker(cwd);
23687
23729
  if (!marker) return;
23688
23730
  try {
23689
- const configAbs = path48.join(cwd, marker.configFile);
23731
+ const configAbs = path49.join(cwd, marker.configFile);
23690
23732
  if (marker.backupFile) {
23691
- const backupAbs = path48.join(cwd, marker.backupFile);
23733
+ const backupAbs = path49.join(cwd, marker.backupFile);
23692
23734
  if (await fileExists(backupAbs)) {
23693
23735
  await import_fs3.promises.rm(configAbs, { force: true });
23694
23736
  await import_fs3.promises.rename(backupAbs, configAbs);
@@ -23721,26 +23763,26 @@ async function applyPreviewHostAllow(cwd) {
23721
23763
  }
23722
23764
  if (!framework) return;
23723
23765
  if (existing) {
23724
- const ext = path48.extname(existing);
23766
+ const ext = path49.extname(existing);
23725
23767
  const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
23726
- if (await isOurShim(path48.join(cwd, existing))) {
23727
- const origAbs = path48.join(cwd, origBasename);
23768
+ if (await isOurShim(path49.join(cwd, existing))) {
23769
+ const origAbs = path49.join(cwd, origBasename);
23728
23770
  if (!await fileExists(origAbs) || await isOurShim(origAbs)) {
23729
23771
  log.warn("preview", `host-allow: ${existing} is a leftover shim with no original \u2014 skipped`);
23730
23772
  return;
23731
23773
  }
23732
- await import_fs3.promises.rm(path48.join(cwd, existing), { force: true });
23733
- await import_fs3.promises.rename(origAbs, path48.join(cwd, existing));
23774
+ await import_fs3.promises.rm(path49.join(cwd, existing), { force: true });
23775
+ await import_fs3.promises.rename(origAbs, path49.join(cwd, existing));
23734
23776
  log.info("preview", `host-allow: restored ${existing} from a leftover ${origBasename}`);
23735
23777
  }
23736
23778
  const esm = await isEsmConfig(cwd, existing);
23737
- await import_fs3.promises.rename(path48.join(cwd, existing), path48.join(cwd, origBasename));
23738
- await import_fs3.promises.writeFile(path48.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
23779
+ await import_fs3.promises.rename(path49.join(cwd, existing), path49.join(cwd, origBasename));
23780
+ await import_fs3.promises.writeFile(path49.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
23739
23781
  await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
23740
23782
  log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
23741
23783
  } else {
23742
23784
  const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
23743
- await import_fs3.promises.writeFile(path48.join(cwd, configFile), shimFor(framework, null, true), "utf8");
23785
+ await import_fs3.promises.writeFile(path49.join(cwd, configFile), shimFor(framework, null, true), "utf8");
23744
23786
  await writeMarker(cwd, { framework, configFile, backupFile: null });
23745
23787
  log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
23746
23788
  }
@@ -23750,8 +23792,8 @@ async function applyPreviewHostAllow(cwd) {
23750
23792
  }
23751
23793
 
23752
23794
  // src/services/preview/build-heal.ts
23753
- var fs42 = __toESM(require("fs"));
23754
- var path49 = __toESM(require("path"));
23795
+ var fs43 = __toESM(require("fs"));
23796
+ var path50 = __toESM(require("path"));
23755
23797
  var BUILD_MARKER_NAME = "BUILD_ID";
23756
23798
  var DEFAULT_DEBOUNCE_MS = 1500;
23757
23799
  var DEFAULT_MAX_RESTARTS = 3;
@@ -23760,7 +23802,7 @@ function isBuildHealSupported(framework) {
23760
23802
  }
23761
23803
  function defaultWatchDir(dir, onEvent) {
23762
23804
  try {
23763
- const w3 = fs42.watch(dir, { persistent: false }, (_eventType, filename) => onEvent(filename));
23805
+ const w3 = fs43.watch(dir, { persistent: false }, (_eventType, filename) => onEvent(filename));
23764
23806
  w3.on("error", () => {
23765
23807
  try {
23766
23808
  w3.close();
@@ -23783,7 +23825,7 @@ function resetBuildHealState(sessionId) {
23783
23825
  }
23784
23826
  function readMarker2(markerPath5) {
23785
23827
  try {
23786
- return fs42.readFileSync(markerPath5, "utf8").trim();
23828
+ return fs43.readFileSync(markerPath5, "utf8").trim();
23787
23829
  } catch {
23788
23830
  return null;
23789
23831
  }
@@ -23792,8 +23834,8 @@ function watchForBuildClobber(deps) {
23792
23834
  const watchDir = deps.watchDir ?? defaultWatchDir;
23793
23835
  const debounceMs = deps.debounceMs ?? DEFAULT_DEBOUNCE_MS;
23794
23836
  const maxRestarts = deps.maxRestarts ?? DEFAULT_MAX_RESTARTS;
23795
- const nextDir = path49.join(deps.cwd, ".next");
23796
- const markerPath5 = path49.join(nextDir, BUILD_MARKER_NAME);
23837
+ const nextDir = path50.join(deps.cwd, ".next");
23838
+ const markerPath5 = path50.join(nextDir, BUILD_MARKER_NAME);
23797
23839
  let stopped = false;
23798
23840
  let debounceTimer = null;
23799
23841
  let dirUnwatch = null;
@@ -23815,6 +23857,7 @@ function watchForBuildClobber(deps) {
23815
23857
  if (stopped) return;
23816
23858
  const current2 = readMarker2(markerPath5);
23817
23859
  if (current2 === lastKnownMarker) return;
23860
+ if (current2 === null) return;
23818
23861
  lastKnownMarker = current2;
23819
23862
  const count = (healRestartCounts.get(deps.sessionId) ?? 0) + 1;
23820
23863
  healRestartCounts.set(deps.sessionId, count);
@@ -23851,12 +23894,12 @@ function watchForBuildClobber(deps) {
23851
23894
  if (filename === null || filename === BUILD_MARKER_NAME) onMarkerTouched();
23852
23895
  });
23853
23896
  };
23854
- if (fs42.existsSync(nextDir)) {
23897
+ if (fs43.existsSync(nextDir)) {
23855
23898
  attachDirWatch();
23856
23899
  } else {
23857
23900
  cwdUnwatch = watchDir(deps.cwd, (filename) => {
23858
23901
  if (stopped || dirUnwatch) return;
23859
- if ((filename === ".next" || filename === null) && fs42.existsSync(nextDir)) {
23902
+ if ((filename === ".next" || filename === null) && fs43.existsSync(nextDir)) {
23860
23903
  cwdUnwatch?.();
23861
23904
  cwdUnwatch = null;
23862
23905
  attachDirWatch();
@@ -23956,7 +23999,7 @@ function quoteIfNeeded(value) {
23956
23999
 
23957
24000
  // src/services/preview/expo.ts
23958
24001
  var http6 = __toESM(require("http"));
23959
- var path51 = __toESM(require("path"));
24002
+ var path52 = __toESM(require("path"));
23960
24003
  var EXPO_PACKAGER_PROXY_URL_ENV = "EXPO_PACKAGER_PROXY_URL";
23961
24004
  function stripExpoTunnelFlag(args2) {
23962
24005
  return args2.filter((a) => a !== "--tunnel" && !a.startsWith("--tunnel="));
@@ -23965,7 +24008,7 @@ function ensureExpoPortArg(command2, args2, port) {
23965
24008
  const hasPort = args2.some((a) => a === "--port" || a.startsWith("--port="));
23966
24009
  if (hasPort) return [...args2];
23967
24010
  const out2 = [...args2];
23968
- if (path51.basename(command2) === "npm" && !out2.includes("--")) out2.push("--");
24011
+ if (path52.basename(command2) === "npm" && !out2.includes("--")) out2.push("--");
23969
24012
  out2.push("--port", String(port));
23970
24013
  return out2;
23971
24014
  }
@@ -24593,8 +24636,8 @@ function isJsInstallCommand(cmd, args2) {
24593
24636
  }
24594
24637
 
24595
24638
  // src/services/preview/script-candidates.ts
24596
- var fs46 = __toESM(require("fs"));
24597
- var path54 = __toESM(require("path"));
24639
+ var fs47 = __toESM(require("fs"));
24640
+ var path55 = __toESM(require("path"));
24598
24641
  var EXCLUDE_RE = /(^|:)(deploy|publish|release|build|test|e2e|lint|format|typecheck|type-check|clean|prebuild|postinstall|preinstall|prepare|install|migrate|seed|db|prisma|codegen|storybook-build)(:|$)/i;
24599
24642
  var EXCLUDE_BODY_RE = /\b(run:android|run:ios|gradlew|fastlane|xcodebuild|eas build|eas submit)\b/i;
24600
24643
  var MAX_APPS = 40;
@@ -24612,7 +24655,7 @@ function frameworkFor(pkg, body) {
24612
24655
  }
24613
24656
  function readPkg(file) {
24614
24657
  try {
24615
- return JSON.parse(fs46.readFileSync(file, "utf8"));
24658
+ return JSON.parse(fs47.readFileSync(file, "utf8"));
24616
24659
  } catch {
24617
24660
  return null;
24618
24661
  }
@@ -24622,7 +24665,7 @@ function expandGlob(root, pattern) {
24622
24665
  if (!clean.endsWith("/*")) return [clean];
24623
24666
  const base = clean.slice(0, -2);
24624
24667
  try {
24625
- return fs46.readdirSync(path54.join(root, base), { withFileTypes: true }).filter((d3) => d3.isDirectory() && !d3.name.startsWith(".") && d3.name !== "node_modules").map((d3) => path54.join(base, d3.name));
24668
+ return fs47.readdirSync(path55.join(root, base), { withFileTypes: true }).filter((d3) => d3.isDirectory() && !d3.name.startsWith(".") && d3.name !== "node_modules").map((d3) => path55.join(base, d3.name));
24626
24669
  } catch {
24627
24670
  return [];
24628
24671
  }
@@ -24631,7 +24674,7 @@ function workspaceDirs(root, rootPkg) {
24631
24674
  const ws = rootPkg?.workspaces;
24632
24675
  const patterns = Array.isArray(ws) ? ws : ws?.packages ?? [];
24633
24676
  try {
24634
- const pnpm = fs46.readFileSync(path54.join(root, "pnpm-workspace.yaml"), "utf8");
24677
+ const pnpm = fs47.readFileSync(path55.join(root, "pnpm-workspace.yaml"), "utf8");
24635
24678
  for (const m of pnpm.matchAll(/^\s*-\s*['"]?([^'"\n]+)['"]?\s*$/gm)) patterns.push(m[1]);
24636
24679
  } catch {
24637
24680
  }
@@ -24642,14 +24685,14 @@ function workspaceDirs(root, rootPkg) {
24642
24685
  }
24643
24686
  function listScriptCandidates(root) {
24644
24687
  const out2 = [];
24645
- const rootPkg = readPkg(path54.join(root, "package.json"));
24688
+ const rootPkg = readPkg(path55.join(root, "package.json"));
24646
24689
  const add = (pkg, appDir) => {
24647
24690
  for (const [script, body] of Object.entries(pkg.scripts ?? {})) {
24648
24691
  if (out2.length >= MAX_CANDIDATES) return;
24649
24692
  if (EXCLUDE_RE.test(script) || EXCLUDE_BODY_RE.test(body)) continue;
24650
24693
  const fw = frameworkFor(pkg, body);
24651
24694
  out2.push({
24652
- app: pkg.name ?? (appDir === "." ? path54.basename(root) : appDir),
24695
+ app: pkg.name ?? (appDir === "." ? path55.basename(root) : appDir),
24653
24696
  appDir,
24654
24697
  script,
24655
24698
  body,
@@ -24663,8 +24706,8 @@ function listScriptCandidates(root) {
24663
24706
  };
24664
24707
  if (rootPkg) add(rootPkg, ".");
24665
24708
  for (const dir of workspaceDirs(root, rootPkg)) {
24666
- const pkg = readPkg(path54.join(root, dir, "package.json"));
24667
- if (pkg) add(pkg, dir.split(path54.sep).join("/"));
24709
+ const pkg = readPkg(path55.join(root, dir, "package.json"));
24710
+ if (pkg) add(pkg, dir.split(path55.sep).join("/"));
24668
24711
  }
24669
24712
  return out2;
24670
24713
  }
@@ -24896,7 +24939,7 @@ function acquire(inst) {
24896
24939
  async function setupStandalone(ctx, rec) {
24897
24940
  const named = await resolveNamedTunnel(
24898
24941
  { sessionId: ctx.sessionId, pluginId: ctx.pluginId, pluginAuthToken: ctx.pluginAuthToken ?? "" },
24899
- (c2) => fetchNamedPreviewTunnel({ pluginId: c2.pluginId, pluginAuthToken: c2.pluginAuthToken })
24942
+ fetchNamedPreviewTunnel
24900
24943
  );
24901
24944
  if (!named || rec.cancelled) throw new Error("EXPORT_TUNNEL_UNAVAILABLE");
24902
24945
  const server = http8.createServer((req, res) => {
@@ -25416,31 +25459,31 @@ async function readActivePreviewMarker(cwd, homeDir2) {
25416
25459
  }
25417
25460
 
25418
25461
  // src/agents/acp/guardrail-config.ts
25419
- var fs51 = __toESM(require("fs"));
25420
- var path59 = __toESM(require("path"));
25421
- var os36 = __toESM(require("os"));
25462
+ var fs52 = __toESM(require("fs"));
25463
+ var path60 = __toESM(require("path"));
25464
+ var os37 = __toESM(require("os"));
25422
25465
  var current = null;
25423
- function guardrailConfigPath(homeDir2 = os36.homedir()) {
25424
- return path59.join(homeDir2, ".codeam", "guardrails.json");
25466
+ function guardrailConfigPath(homeDir2 = os37.homedir()) {
25467
+ return path60.join(homeDir2, ".codeam", "guardrails.json");
25425
25468
  }
25426
- function loadGuardrailPolicy(homeDir2 = os36.homedir()) {
25469
+ function loadGuardrailPolicy(homeDir2 = os37.homedir()) {
25427
25470
  try {
25428
- current = normalizeGuardrailPolicy(JSON.parse(fs51.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
25471
+ current = normalizeGuardrailPolicy(JSON.parse(fs52.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
25429
25472
  } catch {
25430
25473
  current = { ...DEFAULT_GUARDRAIL_POLICY };
25431
25474
  }
25432
25475
  return current;
25433
25476
  }
25434
- function getGuardrailPolicy(homeDir2 = os36.homedir()) {
25477
+ function getGuardrailPolicy(homeDir2 = os37.homedir()) {
25435
25478
  return current ?? loadGuardrailPolicy(homeDir2);
25436
25479
  }
25437
- function setGuardrailPolicy(raw, homeDir2 = os36.homedir()) {
25480
+ function setGuardrailPolicy(raw, homeDir2 = os37.homedir()) {
25438
25481
  const next = normalizeGuardrailPolicy(raw);
25439
25482
  current = next;
25440
25483
  try {
25441
25484
  const p2 = guardrailConfigPath(homeDir2);
25442
- fs51.mkdirSync(path59.dirname(p2), { recursive: true });
25443
- fs51.writeFileSync(p2, JSON.stringify(next, null, 2));
25485
+ fs52.mkdirSync(path60.dirname(p2), { recursive: true });
25486
+ fs52.writeFileSync(p2, JSON.stringify(next, null, 2));
25444
25487
  } catch {
25445
25488
  }
25446
25489
  return next;
@@ -25456,22 +25499,22 @@ function shouldOfferOneMRecovery(opts) {
25456
25499
  }
25457
25500
 
25458
25501
  // src/commands/host/house-proxy-config.ts
25459
- var fs52 = __toESM(require("fs"));
25460
- var os37 = __toESM(require("os"));
25461
- var path60 = __toESM(require("path"));
25502
+ var fs53 = __toESM(require("fs"));
25503
+ var os38 = __toESM(require("os"));
25504
+ var path61 = __toESM(require("path"));
25462
25505
  function houseProxyConfigPath() {
25463
- return path60.join(os37.homedir(), ".codeam", "house-proxy.json");
25506
+ return path61.join(os38.homedir(), ".codeam", "house-proxy.json");
25464
25507
  }
25465
25508
  var DEPLOY_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
25466
25509
  function deployHouseProxyConfigPath(deployId) {
25467
25510
  if (!DEPLOY_ID_RE.test(deployId) || deployId.includes("..")) return null;
25468
- return path60.join(os37.homedir(), ".codeam", "house-proxy", `${deployId}.json`);
25511
+ return path61.join(os38.homedir(), ".codeam", "house-proxy", `${deployId}.json`);
25469
25512
  }
25470
25513
  function writeJson0600(file, value) {
25471
- fs52.mkdirSync(path60.dirname(file), { recursive: true, mode: 448 });
25514
+ fs53.mkdirSync(path61.dirname(file), { recursive: true, mode: 448 });
25472
25515
  const tmp = `${file}.tmp-${process.pid}`;
25473
- fs52.writeFileSync(tmp, JSON.stringify(value, null, 2), { encoding: "utf8", mode: 384 });
25474
- fs52.renameSync(tmp, file);
25516
+ fs53.writeFileSync(tmp, JSON.stringify(value, null, 2), { encoding: "utf8", mode: 384 });
25517
+ fs53.renameSync(tmp, file);
25475
25518
  restrictToOwner(file);
25476
25519
  }
25477
25520
  function persistHouseProxyConfig(config, deployId) {
@@ -25488,7 +25531,7 @@ function persistHouseProxyConfig(config, deployId) {
25488
25531
  }
25489
25532
  function clearHouseProxyConfig(deployId) {
25490
25533
  try {
25491
- fs52.rmSync(houseProxyConfigPath(), { force: true });
25534
+ fs53.rmSync(houseProxyConfigPath(), { force: true });
25492
25535
  const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
25493
25536
  if (perDeploy) writeJson0600(perDeploy, { none: true });
25494
25537
  } catch {
@@ -25511,12 +25554,12 @@ function houseProxyTokenExpiring(token, nowSec, windowSec = HOUSE_PROXY_REFRESH_
25511
25554
  }
25512
25555
  function persistedConfigFile(deployId) {
25513
25556
  const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
25514
- const file = perDeploy && fs52.existsSync(perDeploy) ? perDeploy : houseProxyConfigPath();
25515
- return fs52.existsSync(file) ? file : null;
25557
+ const file = perDeploy && fs53.existsSync(perDeploy) ? perDeploy : houseProxyConfigPath();
25558
+ return fs53.existsSync(file) ? file : null;
25516
25559
  }
25517
25560
  function readConfigObject(file) {
25518
25561
  try {
25519
- const parsed = JSON.parse(fs52.readFileSync(file, "utf8"));
25562
+ const parsed = JSON.parse(fs53.readFileSync(file, "utf8"));
25520
25563
  return typeof parsed === "object" && parsed !== null ? parsed : null;
25521
25564
  } catch {
25522
25565
  return null;
@@ -25549,8 +25592,8 @@ function rewriteHouseProxyToken(deployId, freshToken) {
25549
25592
  function readHouseProxyChildEnv(deployId) {
25550
25593
  try {
25551
25594
  const perDeploy = deployId ? deployHouseProxyConfigPath(deployId) : null;
25552
- const file = perDeploy && fs52.existsSync(perDeploy) ? perDeploy : houseProxyConfigPath();
25553
- const raw = fs52.readFileSync(file, "utf8");
25595
+ const file = perDeploy && fs53.existsSync(perDeploy) ? perDeploy : houseProxyConfigPath();
25596
+ const raw = fs53.readFileSync(file, "utf8");
25554
25597
  const parsed = JSON.parse(raw);
25555
25598
  if (typeof parsed !== "object" || parsed === null) return {};
25556
25599
  const o = parsed;
@@ -25660,9 +25703,9 @@ function pickHouseProxyEnv(env) {
25660
25703
  }
25661
25704
 
25662
25705
  // src/lib/provider-routing.ts
25663
- var fs53 = __toESM(require("fs"));
25664
- var os38 = __toESM(require("os"));
25665
- var path61 = __toESM(require("path"));
25706
+ var fs54 = __toESM(require("fs"));
25707
+ var os39 = __toESM(require("os"));
25708
+ var path62 = __toESM(require("path"));
25666
25709
  var PROVIDER_BASE_URL_ENV_KEYS = [
25667
25710
  "ANTHROPIC_BASE_URL",
25668
25711
  "OPENAI_BASE_URL",
@@ -25684,15 +25727,15 @@ function redactUrlToOrigin(raw) {
25684
25727
  }
25685
25728
  }
25686
25729
  function readOpencodeProviderOrigins(opts = {}) {
25687
- const home = opts.homeDir ?? os38.homedir();
25688
- const readFile8 = opts.readFile ?? ((f) => fs53.readFileSync(f, "utf8"));
25730
+ const home = opts.homeDir ?? os39.homedir();
25731
+ const readFile8 = opts.readFile ?? ((f) => fs54.readFileSync(f, "utf8"));
25689
25732
  const candidates = [];
25690
25733
  if (opts.cwd) {
25691
- candidates.push(path61.join(opts.cwd, "opencode.json"), path61.join(opts.cwd, "opencode.jsonc"));
25734
+ candidates.push(path62.join(opts.cwd, "opencode.json"), path62.join(opts.cwd, "opencode.jsonc"));
25692
25735
  }
25693
25736
  candidates.push(
25694
- path61.join(home, ".config", "opencode", "opencode.json"),
25695
- path61.join(home, ".config", "opencode", "opencode.jsonc")
25737
+ path62.join(home, ".config", "opencode", "opencode.json"),
25738
+ path62.join(home, ".config", "opencode", "opencode.jsonc")
25696
25739
  );
25697
25740
  const out2 = [];
25698
25741
  const seen2 = /* @__PURE__ */ new Set();
@@ -26027,19 +26070,19 @@ function adapterExitMessage(opts) {
26027
26070
 
26028
26071
  // src/services/preview/start-orchestrator.ts
26029
26072
  var import_child_process20 = require("child_process");
26030
- var fs56 = __toESM(require("fs"));
26031
- var path64 = __toESM(require("path"));
26073
+ var fs57 = __toESM(require("fs"));
26074
+ var path65 = __toESM(require("path"));
26032
26075
  var import_which3 = __toESM(require("which"));
26033
26076
 
26034
26077
  // src/services/project-env/index.ts
26035
26078
  var import_fs6 = require("fs");
26036
- var path63 = __toESM(require("path"));
26079
+ var path64 = __toESM(require("path"));
26037
26080
 
26038
26081
  // src/beads/project-key.ts
26039
26082
  var import_child_process19 = require("child_process");
26040
26083
  var crypto2 = __toESM(require("crypto"));
26041
- var fs54 = __toESM(require("fs"));
26042
- var path62 = __toESM(require("path"));
26084
+ var fs55 = __toESM(require("fs"));
26085
+ var path63 = __toESM(require("path"));
26043
26086
  function normalizeOrigin(raw) {
26044
26087
  const trimmed = raw.trim();
26045
26088
  if (!trimmed) return null;
@@ -26065,17 +26108,17 @@ function normalizeOrigin(raw) {
26065
26108
  return `${host2}/${pathPart}`;
26066
26109
  }
26067
26110
  function findRepoRoot(cwd) {
26068
- let dir = path62.resolve(cwd);
26111
+ let dir = path63.resolve(cwd);
26069
26112
  const seen2 = /* @__PURE__ */ new Set();
26070
26113
  for (let i = 0; i < 256; i++) {
26071
26114
  if (seen2.has(dir)) return null;
26072
26115
  seen2.add(dir);
26073
26116
  try {
26074
- const stat3 = fs54.statSync(path62.join(dir, ".git"), { throwIfNoEntry: false });
26117
+ const stat3 = fs55.statSync(path63.join(dir, ".git"), { throwIfNoEntry: false });
26075
26118
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
26076
26119
  } catch {
26077
26120
  }
26078
- const parent = path62.dirname(dir);
26121
+ const parent = path63.dirname(dir);
26079
26122
  if (parent === dir) return null;
26080
26123
  dir = parent;
26081
26124
  }
@@ -26086,7 +26129,7 @@ var _execSeam3 = {
26086
26129
  const out2 = (0, import_child_process19.execFileSync)(file, args2, opts);
26087
26130
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
26088
26131
  },
26089
- realpath: (p2) => fs54.realpathSync(p2)
26132
+ realpath: (p2) => fs55.realpathSync(p2)
26090
26133
  };
26091
26134
  function readOrigin(cwd) {
26092
26135
  try {
@@ -26115,7 +26158,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
26115
26158
  } catch {
26116
26159
  }
26117
26160
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
26118
- return { projectKey: `path:${hash}`, projectLabel: path62.basename(real) || "project" };
26161
+ return { projectKey: `path:${hash}`, projectLabel: path63.basename(real) || "project" };
26119
26162
  }
26120
26163
 
26121
26164
  // src/services/project-env/index.ts
@@ -26128,7 +26171,7 @@ async function readIfExists(p2) {
26128
26171
  }
26129
26172
  async function syncProjectEnvUp(cwd, ctx) {
26130
26173
  if (!ctx.pluginAuthToken) return;
26131
- const content = await readIfExists(path63.join(cwd, ".env"));
26174
+ const content = await readIfExists(path64.join(cwd, ".env"));
26132
26175
  if (content == null) return;
26133
26176
  try {
26134
26177
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -26150,7 +26193,7 @@ async function syncProjectEnvUp(cwd, ctx) {
26150
26193
  }
26151
26194
  async function restoreProjectEnvIfMissing(cwd, ctx) {
26152
26195
  if (!ctx.pluginAuthToken) return false;
26153
- const envPath = path63.join(cwd, ".env");
26196
+ const envPath = path64.join(cwd, ".env");
26154
26197
  if (await readIfExists(envPath) != null) return false;
26155
26198
  try {
26156
26199
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -26161,7 +26204,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
26161
26204
  projectKey
26162
26205
  });
26163
26206
  if (!stored) return false;
26164
- const tmp = path63.join(cwd, ".env.codeam-restore.tmp");
26207
+ const tmp = path64.join(cwd, ".env.codeam-restore.tmp");
26165
26208
  await import_fs6.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
26166
26209
  await import_fs6.promises.rename(tmp, envPath);
26167
26210
  log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
@@ -26925,8 +26968,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
26925
26968
  if (args2.length === 0) return detection;
26926
26969
  const binName = args2[0];
26927
26970
  if (binName.startsWith("-")) return detection;
26928
- const binPath = path64.join(cwd, "node_modules", ".bin", binName);
26929
- if (!fs56.existsSync(binPath)) return detection;
26971
+ const binPath = path65.join(cwd, "node_modules", ".bin", binName);
26972
+ if (!fs57.existsSync(binPath)) return detection;
26930
26973
  return {
26931
26974
  ...detection,
26932
26975
  command: binPath,
@@ -27273,7 +27316,7 @@ async function bringUpPublicUrl(ctx, tunnelPort) {
27273
27316
  pluginId: ctx.projectEnvAuth?.pluginId ?? "",
27274
27317
  pluginAuthToken: ctx.projectEnvAuth?.pluginAuthToken ?? ""
27275
27318
  },
27276
- (c2) => fetchNamedPreviewTunnel({ pluginId: c2.pluginId, pluginAuthToken: c2.pluginAuthToken })
27319
+ fetchNamedPreviewTunnel
27277
27320
  );
27278
27321
  const namedToken = named?.token;
27279
27322
  const namedHostname = named?.hostname;
@@ -27339,9 +27382,9 @@ async function bringUpPublicUrl(ctx, tunnelPort) {
27339
27382
 
27340
27383
  // src/beads/bd-adapter.ts
27341
27384
  var import_child_process21 = require("child_process");
27342
- var fs57 = __toESM(require("fs"));
27343
- var os39 = __toESM(require("os"));
27344
- var path65 = __toESM(require("path"));
27385
+ var fs58 = __toESM(require("fs"));
27386
+ var os40 = __toESM(require("os"));
27387
+ var path66 = __toESM(require("path"));
27345
27388
  var BD_PACKAGE = "@beads/bd";
27346
27389
  function resolveBundledBdBinary() {
27347
27390
  return _resolveSeam.resolveBundled();
@@ -27353,11 +27396,11 @@ function _defaultResolveBundled() {
27353
27396
  } catch {
27354
27397
  return null;
27355
27398
  }
27356
- const binDir = path65.join(path65.dirname(pkgJsonPath), "bin");
27399
+ const binDir = path66.join(path66.dirname(pkgJsonPath), "bin");
27357
27400
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
27358
- const binaryPath = path65.join(binDir, binaryName);
27401
+ const binaryPath = path66.join(binDir, binaryName);
27359
27402
  try {
27360
- fs57.accessSync(binaryPath, fs57.constants.F_OK);
27403
+ fs58.accessSync(binaryPath, fs58.constants.F_OK);
27361
27404
  return binaryPath;
27362
27405
  } catch {
27363
27406
  return null;
@@ -27367,13 +27410,13 @@ function resolveBdOnPath() {
27367
27410
  return _resolveSeam.resolveOnPath();
27368
27411
  }
27369
27412
  function _defaultResolveOnPath() {
27370
- const dirs = (process.env.PATH ?? "").split(path65.delimiter).filter(Boolean);
27413
+ const dirs = (process.env.PATH ?? "").split(path66.delimiter).filter(Boolean);
27371
27414
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
27372
27415
  for (const dir of dirs) {
27373
27416
  for (const candidate of candidates) {
27374
- const full = path65.join(dir, candidate);
27417
+ const full = path66.join(dir, candidate);
27375
27418
  try {
27376
- fs57.accessSync(full, fs57.constants.F_OK);
27419
+ fs58.accessSync(full, fs58.constants.F_OK);
27377
27420
  return full;
27378
27421
  } catch {
27379
27422
  }
@@ -27458,7 +27501,7 @@ var BdAdapter = class {
27458
27501
  const env = { ...process.env };
27459
27502
  if (!env.HOME) {
27460
27503
  try {
27461
- const home = os39.homedir();
27504
+ const home = os40.homedir();
27462
27505
  if (home) env.HOME = home;
27463
27506
  } catch {
27464
27507
  }
@@ -27548,9 +27591,9 @@ function coerceIssue(row, projectKey) {
27548
27591
 
27549
27592
  // src/beads/provisioner.ts
27550
27593
  var import_child_process24 = require("child_process");
27551
- var fs59 = __toESM(require("fs"));
27552
- var os41 = __toESM(require("os"));
27553
- var path67 = __toESM(require("path"));
27594
+ var fs60 = __toESM(require("fs"));
27595
+ var os42 = __toESM(require("os"));
27596
+ var path68 = __toESM(require("path"));
27554
27597
 
27555
27598
  // src/beads/install-bd.ts
27556
27599
  var import_child_process22 = require("child_process");
@@ -27615,9 +27658,9 @@ async function installBd(platform3 = process.platform) {
27615
27658
 
27616
27659
  // src/beads/install-dolt.ts
27617
27660
  var import_child_process23 = require("child_process");
27618
- var fs58 = __toESM(require("fs"));
27619
- var os40 = __toESM(require("os"));
27620
- var path66 = __toESM(require("path"));
27661
+ var fs59 = __toESM(require("fs"));
27662
+ var os41 = __toESM(require("os"));
27663
+ var path67 = __toESM(require("path"));
27621
27664
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
27622
27665
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
27623
27666
  function resolveDoltInstallStrategy(platform3) {
@@ -27706,14 +27749,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
27706
27749
  return result;
27707
27750
  }
27708
27751
  var _doltPathSeam = {
27709
- homedir: () => os40.homedir(),
27752
+ homedir: () => os41.homedir(),
27710
27753
  getPath: () => process.env.PATH ?? "",
27711
27754
  setPath: (p2) => {
27712
27755
  process.env.PATH = p2;
27713
27756
  },
27714
27757
  exists: (p2) => {
27715
27758
  try {
27716
- fs58.accessSync(p2, fs58.constants.F_OK);
27759
+ fs59.accessSync(p2, fs59.constants.F_OK);
27717
27760
  return true;
27718
27761
  } catch {
27719
27762
  return false;
@@ -27724,7 +27767,7 @@ function doltBinaryNames(platform3) {
27724
27767
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
27725
27768
  }
27726
27769
  function knownDoltDirs(platform3) {
27727
- const P3 = platform3 === "win32" ? path66.win32 : path66.posix;
27770
+ const P3 = platform3 === "win32" ? path67.win32 : path67.posix;
27728
27771
  const home = _doltPathSeam.homedir();
27729
27772
  if (platform3 === "win32") {
27730
27773
  return [
@@ -27740,7 +27783,7 @@ function knownDoltDirs(platform3) {
27740
27783
  ].filter(Boolean);
27741
27784
  }
27742
27785
  function ensureDoltResolvable(platform3 = process.platform) {
27743
- const P3 = platform3 === "win32" ? path66.win32 : path66.posix;
27786
+ const P3 = platform3 === "win32" ? path67.win32 : path67.posix;
27744
27787
  const delim = platform3 === "win32" ? ";" : ":";
27745
27788
  const names = doltBinaryNames(platform3);
27746
27789
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -27917,10 +27960,10 @@ var _provisionSeam = {
27917
27960
  /** Does the project's git remote carry Dolt data (`refs/dolt/data`)? */
27918
27961
  remoteHasDoltData,
27919
27962
  /** Throwaway cwd for a user-level-only `bd setup` (see GLOBAL_ONLY_RECIPES). */
27920
- makeSetupCwd: () => fs59.mkdtempSync(path67.join(os41.tmpdir(), "codeam-bd-setup-")),
27963
+ makeSetupCwd: () => fs60.mkdtempSync(path68.join(os42.tmpdir(), "codeam-bd-setup-")),
27921
27964
  removeSetupCwd: (dir) => {
27922
27965
  try {
27923
- fs59.rmSync(dir, { recursive: true, force: true });
27966
+ fs60.rmSync(dir, { recursive: true, force: true });
27924
27967
  } catch {
27925
27968
  }
27926
27969
  }
@@ -27942,17 +27985,17 @@ function remoteHasDoltData(cwd) {
27942
27985
  }
27943
27986
  var _linkSeam = {
27944
27987
  platform: () => process.platform,
27945
- homedir: () => os41.homedir(),
27988
+ homedir: () => os42.homedir(),
27946
27989
  isWritableDir: (dir) => {
27947
27990
  try {
27948
- fs59.accessSync(dir, fs59.constants.W_OK);
27991
+ fs60.accessSync(dir, fs60.constants.W_OK);
27949
27992
  return true;
27950
27993
  } catch {
27951
27994
  return false;
27952
27995
  }
27953
27996
  },
27954
27997
  ensureDir: (dir) => {
27955
- fs59.mkdirSync(dir, { recursive: true });
27998
+ fs60.mkdirSync(dir, { recursive: true });
27956
27999
  },
27957
28000
  /**
27958
28001
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -27973,9 +28016,9 @@ var _linkSeam = {
27973
28016
  * which `linkBdOntoPath` creates if missing.
27974
28017
  */
27975
28018
  cliBinDir: () => {
27976
- const pathDirs = (process.env.PATH ?? "").split(path67.delimiter).filter(Boolean);
28019
+ const pathDirs = (process.env.PATH ?? "").split(path68.delimiter).filter(Boolean);
27977
28020
  const home = _linkSeam.homedir();
27978
- const localBin = home ? path67.join(home, ".local", "bin") : null;
28021
+ const localBin = home ? path68.join(home, ".local", "bin") : null;
27979
28022
  if (localBin) {
27980
28023
  try {
27981
28024
  _linkSeam.ensureDir(localBin);
@@ -27985,16 +28028,16 @@ var _linkSeam = {
27985
28028
  const candidates = [];
27986
28029
  if (localBin) candidates.push(localBin);
27987
28030
  try {
27988
- candidates.push(path67.dirname(process.execPath));
28031
+ candidates.push(path68.dirname(process.execPath));
27989
28032
  } catch {
27990
28033
  }
27991
28034
  candidates.push("/usr/local/bin");
27992
28035
  const entry = process.argv[1];
27993
28036
  if (entry) {
27994
28037
  try {
27995
- candidates.push(path67.dirname(fs59.realpathSync(entry)));
28038
+ candidates.push(path68.dirname(fs60.realpathSync(entry)));
27996
28039
  } catch {
27997
- candidates.push(path67.dirname(entry));
28040
+ candidates.push(path68.dirname(entry));
27998
28041
  }
27999
28042
  }
28000
28043
  const onPathWritable = candidates.find(
@@ -28006,20 +28049,20 @@ var _linkSeam = {
28006
28049
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
28007
28050
  readlink: (linkPath) => {
28008
28051
  try {
28009
- return fs59.readlinkSync(linkPath);
28052
+ return fs60.readlinkSync(linkPath);
28010
28053
  } catch {
28011
28054
  return null;
28012
28055
  }
28013
28056
  },
28014
- unlink: (linkPath) => fs59.unlinkSync(linkPath),
28015
- symlink: (target, linkPath) => fs59.symlinkSync(target, linkPath)
28057
+ unlink: (linkPath) => fs60.unlinkSync(linkPath),
28058
+ symlink: (target, linkPath) => fs60.symlinkSync(target, linkPath)
28016
28059
  };
28017
28060
  function linkBdOntoPath(binaryPath) {
28018
28061
  if (_linkSeam.platform() === "win32") return;
28019
28062
  const binDir = _linkSeam.cliBinDir();
28020
28063
  if (!binDir) return;
28021
28064
  _linkSeam.ensureDir(binDir);
28022
- const linkPath = path67.join(binDir, "bd");
28065
+ const linkPath = path68.join(binDir, "bd");
28023
28066
  if (linkPath === binaryPath) return;
28024
28067
  const current2 = _linkSeam.readlink(linkPath);
28025
28068
  if (current2 === binaryPath) return;
@@ -28238,16 +28281,16 @@ function dedupeRecipes(agents) {
28238
28281
  }
28239
28282
  function ensureLocalGitExclude(cwd, patterns) {
28240
28283
  try {
28241
- const gitDir = path67.join(cwd, ".git");
28242
- if (!fs59.statSync(gitDir).isDirectory()) return;
28243
- const file = path67.join(gitDir, "info", "exclude");
28244
- fs59.mkdirSync(path67.dirname(file), { recursive: true });
28245
- const current2 = fs59.existsSync(file) ? fs59.readFileSync(file, "utf8") : "";
28284
+ const gitDir = path68.join(cwd, ".git");
28285
+ if (!fs60.statSync(gitDir).isDirectory()) return;
28286
+ const file = path68.join(gitDir, "info", "exclude");
28287
+ fs60.mkdirSync(path68.dirname(file), { recursive: true });
28288
+ const current2 = fs60.existsSync(file) ? fs60.readFileSync(file, "utf8") : "";
28246
28289
  const have = new Set(current2.split(/\r?\n/).map((l) => l.trim()));
28247
28290
  const missing = patterns.filter((p2) => !have.has(p2));
28248
28291
  if (missing.length === 0) return;
28249
28292
  const prefix = current2.length > 0 && !current2.endsWith("\n") ? "\n" : "";
28250
- fs59.appendFileSync(file, `${prefix}# CodeAgent: beads state stays local
28293
+ fs60.appendFileSync(file, `${prefix}# CodeAgent: beads state stays local
28251
28294
  ${missing.join("\n")}
28252
28295
  `);
28253
28296
  } catch {
@@ -28256,7 +28299,7 @@ ${missing.join("\n")}
28256
28299
 
28257
28300
  // src/beads/watcher.ts
28258
28301
  var crypto4 = __toESM(require("crypto"));
28259
- var path68 = __toESM(require("path"));
28302
+ var path69 = __toESM(require("path"));
28260
28303
  var API_BASE5 = resolveApiBaseUrl();
28261
28304
  var DEBOUNCE_MS2 = 400;
28262
28305
  var ZERO_SUMMARY = {
@@ -28280,7 +28323,7 @@ var BeadsWatcher = class {
28280
28323
  constructor(opts) {
28281
28324
  this.opts = opts;
28282
28325
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
28283
- this.feedPath = opts.feedPath ?? path68.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
28326
+ this.feedPath = opts.feedPath ?? path69.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
28284
28327
  this.apiBase = opts.apiBaseUrl ?? API_BASE5;
28285
28328
  }
28286
28329
  opts;
@@ -28925,8 +28968,8 @@ function cleanupAttachmentTempFiles() {
28925
28968
  function saveFilesTemp(files) {
28926
28969
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
28927
28970
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
28928
- const tmpPath = path73.join(os47.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
28929
- fs65.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
28971
+ const tmpPath = path74.join(os48.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
28972
+ fs66.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
28930
28973
  pendingAttachmentFiles.add(tmpPath);
28931
28974
  return tmpPath;
28932
28975
  });
@@ -29172,10 +29215,10 @@ var listFiles = async (ctx, cmd, parsed) => {
29172
29215
  await ctx.relay.sendResult(cmd.id, "completed", result);
29173
29216
  };
29174
29217
  var envReadH = async (ctx, cmd) => {
29175
- const envPath = path73.join(process.cwd(), ".env");
29218
+ const envPath = path74.join(process.cwd(), ".env");
29176
29219
  await restoreProjectEnvIfMissing(process.cwd(), ctx);
29177
29220
  try {
29178
- const raw = await fs65.promises.readFile(envPath, "utf8");
29221
+ const raw = await fs66.promises.readFile(envPath, "utf8");
29179
29222
  await ctx.relay.sendResult(cmd.id, "completed", {
29180
29223
  exists: true,
29181
29224
  vars: parseDotenv(raw)
@@ -29204,7 +29247,7 @@ var envParseH = async (ctx, cmd, parsed) => {
29204
29247
  const existing = /* @__PURE__ */ new Map();
29205
29248
  if (!replace) {
29206
29249
  try {
29207
- const raw = await fs65.promises.readFile(path73.join(process.cwd(), ".env"), "utf8");
29250
+ const raw = await fs66.promises.readFile(path74.join(process.cwd(), ".env"), "utf8");
29208
29251
  for (const v of parseDotenv(raw)) existing.set(v.key, v.value);
29209
29252
  } catch {
29210
29253
  }
@@ -29244,15 +29287,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
29244
29287
  }
29245
29288
  seen2.add(v.key);
29246
29289
  }
29247
- const envPath = path73.join(process.cwd(), ".env");
29248
- const tmpPath = path73.join(process.cwd(), ".env.codeam.tmp");
29290
+ const envPath = path74.join(process.cwd(), ".env");
29291
+ const tmpPath = path74.join(process.cwd(), ".env.codeam.tmp");
29249
29292
  try {
29250
- await fs65.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
29251
- await fs65.promises.rename(tmpPath, envPath);
29293
+ await fs66.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
29294
+ await fs66.promises.rename(tmpPath, envPath);
29252
29295
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
29253
29296
  void syncProjectEnvUp(process.cwd(), ctx);
29254
29297
  } catch (err) {
29255
- await fs65.promises.rm(tmpPath, { force: true }).catch(() => void 0);
29298
+ await fs66.promises.rm(tmpPath, { force: true }).catch(() => void 0);
29256
29299
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
29257
29300
  }
29258
29301
  };
@@ -29601,9 +29644,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
29601
29644
  function buildNpmInstallInvocation(opts) {
29602
29645
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
29603
29646
  const execPath = opts?.execPath ?? process.execPath;
29604
- const exists2 = opts?.existsSync ?? fs65.existsSync;
29647
+ const exists2 = opts?.existsSync ?? fs66.existsSync;
29605
29648
  const platform3 = opts?.platform ?? process.platform;
29606
- const p2 = platform3 === "win32" ? path73.win32 : path73.posix;
29649
+ const p2 = platform3 === "win32" ? path74.win32 : path74.posix;
29607
29650
  const normalized = entryScript.split(/[\\/]/).join("/");
29608
29651
  const marker = "/lib/node_modules/codeam-cli/";
29609
29652
  const markerIdx = normalized.indexOf(marker);
@@ -29622,7 +29665,7 @@ function isPermissionError(stderr) {
29622
29665
  function resolveGlobalNodeModulesDir(opts) {
29623
29666
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
29624
29667
  const platform3 = opts?.platform ?? process.platform;
29625
- const p2 = platform3 === "win32" ? path73.win32 : path73.posix;
29668
+ const p2 = platform3 === "win32" ? path74.win32 : path74.posix;
29626
29669
  const marker = "/lib/node_modules/codeam-cli/";
29627
29670
  const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
29628
29671
  if (markerIdx <= 0) return null;
@@ -29632,9 +29675,9 @@ function resolveGlobalNodeModulesDir(opts) {
29632
29675
  var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
29633
29676
  function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
29634
29677
  if (!nodeModulesDir) return 0;
29635
- const readdirSync18 = deps?.readdirSync ?? fs65.readdirSync;
29636
- const statSync17 = deps?.statSync ?? fs65.statSync;
29637
- const rmSync15 = deps?.rmSync ?? fs65.rmSync;
29678
+ const readdirSync18 = deps?.readdirSync ?? fs66.readdirSync;
29679
+ const statSync17 = deps?.statSync ?? fs66.statSync;
29680
+ const rmSync15 = deps?.rmSync ?? fs66.rmSync;
29638
29681
  let removed = 0;
29639
29682
  let entries2;
29640
29683
  try {
@@ -29644,7 +29687,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
29644
29687
  }
29645
29688
  for (const name of entries2) {
29646
29689
  if (!/^\.codeam-cli-/.test(name)) continue;
29647
- const full = path73.join(nodeModulesDir, name);
29690
+ const full = path74.join(nodeModulesDir, name);
29648
29691
  try {
29649
29692
  const st3 = statSync17(full);
29650
29693
  if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
@@ -30049,7 +30092,7 @@ ${stdout}`);
30049
30092
  }
30050
30093
  }
30051
30094
  function originPayload(payload, origin) {
30052
- if (origin !== "agent") return payload;
30095
+ if (origin === void 0 || origin === "user") return payload;
30053
30096
  return { ...payload ?? {}, origin };
30054
30097
  }
30055
30098
  async function resolvePreviewDetection(args2) {
@@ -30271,7 +30314,7 @@ async function restorePreviewAfterRestart(ctx, pluginAuthToken, deps = {}) {
30271
30314
  `restoring the preview that was serving before the restart (${detection.framework})`
30272
30315
  );
30273
30316
  void (deps.start ?? startPreviewFromDetection)(ctx, detection, pluginAuthToken, {
30274
- origin: "user"
30317
+ origin: "auto"
30275
30318
  });
30276
30319
  return true;
30277
30320
  }
@@ -30303,17 +30346,19 @@ function startPreviewFromDetection(ctx, detection, pluginAuthToken, opts = {}) {
30303
30346
  void offerScratchSaveOnce(ctx, pluginAuthToken);
30304
30347
  }
30305
30348
  };
30306
- return runPreviewStart({
30307
- sessionId: ctx.sessionId,
30308
- detection,
30309
- cwd: process.cwd(),
30310
- emit: emit2,
30311
- // Auth for the per-repo `.env` vault restore, performed INSIDE the bring-up
30312
- // (provisionDeps stage, after the reuse short-circuit) so a fresh session of
30313
- // this repo picks up its saved `.env` before the dev server spawns. Optional
30314
- // — a caller without a token just skips the restore.
30315
- projectEnvAuth: { pluginId: ctx.pluginId, pluginAuthToken }
30316
- }).then(() => maybeAttachBuildHeal(ctx, pluginAuthToken)).catch((err) => {
30349
+ return withTurnMarker(
30350
+ () => runPreviewStart({
30351
+ sessionId: ctx.sessionId,
30352
+ detection,
30353
+ cwd: process.cwd(),
30354
+ emit: emit2,
30355
+ // Auth for the per-repo `.env` vault restore, performed INSIDE the bring-up
30356
+ // (provisionDeps stage, after the reuse short-circuit) so a fresh session of
30357
+ // this repo picks up its saved `.env` before the dev server spawns. Optional
30358
+ // — a caller without a token just skips the restore.
30359
+ projectEnvAuth: { pluginId: ctx.pluginId, pluginAuthToken }
30360
+ })
30361
+ ).then(() => maybeAttachBuildHeal(ctx, pluginAuthToken)).catch((err) => {
30317
30362
  const message = err instanceof Error ? err.message : String(err);
30318
30363
  log.warn("preview", `start crashed before ready: ${message}`);
30319
30364
  emit2(USER_EVENTS.PREVIEW_ERROR, {
@@ -30334,7 +30379,9 @@ function maybeAttachBuildHeal(ctx, pluginAuthToken) {
30334
30379
  if (!activePreviews.has(ctx.sessionId)) return;
30335
30380
  await killPreview(ctx.sessionId);
30336
30381
  await new Promise((r) => setTimeout(r, 150));
30337
- void startPreviewFromDetection(ctx, preview.detection, pluginAuthToken);
30382
+ void startPreviewFromDetection(ctx, preview.detection, pluginAuthToken, {
30383
+ origin: "auto"
30384
+ });
30338
30385
  })();
30339
30386
  },
30340
30387
  notify: (message) => {
@@ -30789,7 +30836,7 @@ function resolveTokenValue(args2) {
30789
30836
  if (fileFlag) {
30790
30837
  const path115 = fileFlag.slice("--token-file=".length);
30791
30838
  try {
30792
- const content = fs66.readFileSync(path115, "utf8").trim();
30839
+ const content = fs67.readFileSync(path115, "utf8").trim();
30793
30840
  if (content.length === 0) fail(`--token-file ${path115} is empty`);
30794
30841
  rmIfExistsQuiet(path115);
30795
30842
  return content;
@@ -30883,12 +30930,12 @@ async function claim(token, pluginId, pluginSecretHash) {
30883
30930
  }
30884
30931
  }
30885
30932
  function pairAutoLockPath() {
30886
- return path74.join(os48.homedir(), ".codeam", "pair-auto.lock");
30933
+ return path75.join(os49.homedir(), ".codeam", "pair-auto.lock");
30887
30934
  }
30888
30935
  var procRoot = "/proc";
30889
30936
  function readProcFile(rel) {
30890
30937
  try {
30891
- return fs66.readFileSync(path74.join(procRoot, rel), "utf8");
30938
+ return fs67.readFileSync(path75.join(procRoot, rel), "utf8");
30892
30939
  } catch {
30893
30940
  return void 0;
30894
30941
  }
@@ -30909,7 +30956,7 @@ function currentBootId() {
30909
30956
  function readLockRecord(lockPath) {
30910
30957
  let raw;
30911
30958
  try {
30912
- raw = fs66.readFileSync(lockPath, "utf8");
30959
+ raw = fs67.readFileSync(lockPath, "utf8");
30913
30960
  } catch {
30914
30961
  return void 0;
30915
30962
  }
@@ -30958,7 +31005,7 @@ function isLiveLockHolder(rec) {
30958
31005
  }
30959
31006
  function releaseOwnLock(lockPath) {
30960
31007
  try {
30961
- if (readLockRecord(lockPath)?.pid === process.pid) fs66.unlinkSync(lockPath);
31008
+ if (readLockRecord(lockPath)?.pid === process.pid) fs67.unlinkSync(lockPath);
30962
31009
  } catch {
30963
31010
  }
30964
31011
  }
@@ -30982,7 +31029,7 @@ function snapshotProcessTree(root) {
30982
31029
  const children = /* @__PURE__ */ new Map();
30983
31030
  let entries2 = [];
30984
31031
  try {
30985
- entries2 = fs66.readdirSync(procRoot).filter((e) => /^\d+$/.test(e));
31032
+ entries2 = fs67.readdirSync(procRoot).filter((e) => /^\d+$/.test(e));
30986
31033
  } catch {
30987
31034
  }
30988
31035
  for (const e of entries2) {
@@ -31017,18 +31064,18 @@ function signalProcessTree(refs, signal) {
31017
31064
  }
31018
31065
  function daemonLockPath(sessionId) {
31019
31066
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
31020
- return path74.join(os48.homedir(), ".codeam", `daemon-${safe}.lock`);
31067
+ return path75.join(os49.homedir(), ".codeam", `daemon-${safe}.lock`);
31021
31068
  }
31022
31069
  function acquireDaemonLock(sessionId) {
31023
31070
  const lockPath = daemonLockPath(sessionId);
31024
31071
  try {
31025
- fs66.mkdirSync(path74.dirname(lockPath), { recursive: true });
31072
+ fs67.mkdirSync(path75.dirname(lockPath), { recursive: true });
31026
31073
  try {
31027
- fs66.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
31074
+ fs67.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
31028
31075
  } catch (e) {
31029
31076
  if (e.code !== "EEXIST") throw e;
31030
31077
  if (isLiveLockHolder(readLockRecord(lockPath))) return false;
31031
- fs66.writeFileSync(lockPath, ownLockBody());
31078
+ fs67.writeFileSync(lockPath, ownLockBody());
31032
31079
  }
31033
31080
  const release3 = () => releaseOwnLock(lockPath);
31034
31081
  process.once("exit", release3);
@@ -31048,13 +31095,13 @@ function acquireDaemonLock(sessionId) {
31048
31095
  function acquireSingletonLock() {
31049
31096
  const lockPath = pairAutoLockPath();
31050
31097
  try {
31051
- fs66.mkdirSync(path74.dirname(lockPath), { recursive: true });
31098
+ fs67.mkdirSync(path75.dirname(lockPath), { recursive: true });
31052
31099
  try {
31053
- fs66.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
31100
+ fs67.writeFileSync(lockPath, ownLockBody(), { flag: "wx" });
31054
31101
  } catch (e) {
31055
31102
  if (e.code !== "EEXIST") throw e;
31056
31103
  if (isLiveLockHolder(readLockRecord(lockPath))) return false;
31057
- fs66.writeFileSync(lockPath, ownLockBody());
31104
+ fs67.writeFileSync(lockPath, ownLockBody());
31058
31105
  }
31059
31106
  process.once("exit", () => releaseOwnLock(lockPath));
31060
31107
  return true;
@@ -31480,7 +31527,7 @@ var AgentService = class _AgentService {
31480
31527
  };
31481
31528
 
31482
31529
  // src/agents/acp/adapters.ts
31483
- var path75 = __toESM(require("path"));
31530
+ var path76 = __toESM(require("path"));
31484
31531
 
31485
31532
  // src/agents/kimi/installer.ts
31486
31533
  var import_node_child_process26 = require("child_process");
@@ -31600,13 +31647,13 @@ function resolveBin(pkgName, binName) {
31600
31647
  try {
31601
31648
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
31602
31649
  const manifest = require_(`${pkgName}/package.json`);
31603
- const pkgDir = path75.dirname(manifestPath);
31650
+ const pkgDir = path76.dirname(manifestPath);
31604
31651
  const bin = manifest.bin;
31605
31652
  if (!bin) return null;
31606
- if (typeof bin === "string") return path75.resolve(pkgDir, bin);
31653
+ if (typeof bin === "string") return path76.resolve(pkgDir, bin);
31607
31654
  const target = binName ?? Object.keys(bin)[0];
31608
31655
  if (!target || !bin[target]) return null;
31609
- return path75.resolve(pkgDir, bin[target]);
31656
+ return path76.resolve(pkgDir, bin[target]);
31610
31657
  } catch {
31611
31658
  return null;
31612
31659
  }
@@ -31621,7 +31668,7 @@ function npmAdapterPackageDir(agent) {
31621
31668
  const pkg = NPM_ADAPTER_PACKAGES[agent];
31622
31669
  if (!pkg) return null;
31623
31670
  try {
31624
- return path75.dirname(require_.resolve(`${pkg}/package.json`));
31671
+ return path76.dirname(require_.resolve(`${pkg}/package.json`));
31625
31672
  } catch {
31626
31673
  return null;
31627
31674
  }
@@ -31801,8 +31848,8 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
31801
31848
  }
31802
31849
 
31803
31850
  // src/agents/acp/prefetch-module-graph.ts
31804
- var fs67 = __toESM(require("fs"));
31805
- var path76 = __toESM(require("path"));
31851
+ var fs68 = __toESM(require("fs"));
31852
+ var path77 = __toESM(require("path"));
31806
31853
  var LOADABLE_EXT = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs", ".json", ".node"]);
31807
31854
  var DEFAULT_MODULE_GRAPH_LIMITS = {
31808
31855
  maxFiles: 2e3,
@@ -31811,23 +31858,23 @@ var DEFAULT_MODULE_GRAPH_LIMITS = {
31811
31858
  concurrency: 16
31812
31859
  };
31813
31860
  var realFs = {
31814
- readdir: (dir) => fs67.promises.readdir(dir, { withFileTypes: true }),
31815
- readFile: (file) => fs67.promises.readFile(file),
31816
- stat: (file) => fs67.promises.stat(file)
31861
+ readdir: (dir) => fs68.promises.readdir(dir, { withFileTypes: true }),
31862
+ readFile: (file) => fs68.promises.readFile(file),
31863
+ stat: (file) => fs68.promises.stat(file)
31817
31864
  };
31818
31865
  function findPackageDir(dep, fromDir) {
31819
31866
  let dir = fromDir;
31820
31867
  for (; ; ) {
31821
- const candidate = path76.join(dir, "node_modules", dep);
31822
- if (fs67.existsSync(path76.join(candidate, "package.json"))) return candidate;
31823
- const parent = path76.dirname(dir);
31868
+ const candidate = path77.join(dir, "node_modules", dep);
31869
+ if (fs68.existsSync(path77.join(candidate, "package.json"))) return candidate;
31870
+ const parent = path77.dirname(dir);
31824
31871
  if (parent === dir) return null;
31825
31872
  dir = parent;
31826
31873
  }
31827
31874
  }
31828
31875
  function runtimeDependencies(pkgDir) {
31829
31876
  try {
31830
- const manifest = JSON.parse(fs67.readFileSync(path76.join(pkgDir, "package.json"), "utf8"));
31877
+ const manifest = JSON.parse(fs68.readFileSync(path77.join(pkgDir, "package.json"), "utf8"));
31831
31878
  return Object.keys(manifest.dependencies ?? {});
31832
31879
  } catch {
31833
31880
  return [];
@@ -31846,14 +31893,14 @@ async function packageFiles(pkgDir, fsd, out2, maxFiles) {
31846
31893
  for (const entry of entries2) {
31847
31894
  if (out2.length >= maxFiles) return;
31848
31895
  if (entry.name.startsWith(".")) continue;
31849
- const full = path76.join(dir, entry.name);
31896
+ const full = path77.join(dir, entry.name);
31850
31897
  if (entry.isDirectory()) {
31851
31898
  if (entry.name !== "node_modules") stack.push(full);
31852
31899
  continue;
31853
31900
  }
31854
31901
  if (!entry.isFile()) continue;
31855
31902
  if (entry.name.endsWith(".d.ts") || entry.name.endsWith(".map")) continue;
31856
- if (LOADABLE_EXT.has(path76.extname(entry.name))) out2.push(full);
31903
+ if (LOADABLE_EXT.has(path77.extname(entry.name))) out2.push(full);
31857
31904
  }
31858
31905
  }
31859
31906
  }
@@ -31863,7 +31910,7 @@ async function collectModuleGraphFiles(rootPkgDir, limits = DEFAULT_MODULE_GRAPH
31863
31910
  const queue = [rootPkgDir];
31864
31911
  while (queue.length > 0 && files.length < limits.maxFiles) {
31865
31912
  const pkgDir = queue.shift();
31866
- const key = fs67.existsSync(pkgDir) ? fs67.realpathSync(pkgDir) : pkgDir;
31913
+ const key = fs68.existsSync(pkgDir) ? fs68.realpathSync(pkgDir) : pkgDir;
31867
31914
  if (seen2.has(key)) continue;
31868
31915
  seen2.add(key);
31869
31916
  await packageFiles(pkgDir, fsd, files, limits.maxFiles);
@@ -32009,8 +32056,8 @@ function noteProviderBillingSignal(opts) {
32009
32056
  }
32010
32057
 
32011
32058
  // src/services/history.service.ts
32012
- var fs69 = __toESM(require("fs"));
32013
- var path78 = __toESM(require("path"));
32059
+ var fs70 = __toESM(require("fs"));
32060
+ var path79 = __toESM(require("path"));
32014
32061
  var https6 = __toESM(require("https"));
32015
32062
  var http10 = __toESM(require("http"));
32016
32063
  var import_zod3 = require("zod");
@@ -32071,7 +32118,7 @@ function parseJsonl(filePath) {
32071
32118
  const messages = [];
32072
32119
  let raw;
32073
32120
  try {
32074
- raw = fs69.readFileSync(filePath, "utf8");
32121
+ raw = fs70.readFileSync(filePath, "utf8");
32075
32122
  } catch (err) {
32076
32123
  if (err.code !== "ENOENT") {
32077
32124
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -32231,7 +32278,7 @@ var HistoryService = class _HistoryService {
32231
32278
  // session-start upload answered false, the active-conversation pointer was
32232
32279
  // never re-pointed after a Box wake, and the app opened an empty "New
32233
32280
  // conversation" over the resumed one (QA box, 2026-09-29).
32234
- path78.join(claudeConfigDir(), "projects", encodeCwd(this.cwd));
32281
+ path79.join(claudeConfigDir(), "projects", encodeCwd(this.cwd));
32235
32282
  }
32236
32283
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
32237
32284
  setCurrentConversationId(id) {
@@ -32243,7 +32290,7 @@ var HistoryService = class _HistoryService {
32243
32290
  /** Return the current message count in the active conversation. */
32244
32291
  getCurrentMessageCount() {
32245
32292
  if (!this.currentConversationId) return 0;
32246
- const filePath = path78.join(this.projectDir, `${this.currentConversationId}.jsonl`);
32293
+ const filePath = path79.join(this.projectDir, `${this.currentConversationId}.jsonl`);
32247
32294
  return parseJsonl(filePath).length;
32248
32295
  }
32249
32296
  /**
@@ -32254,7 +32301,7 @@ var HistoryService = class _HistoryService {
32254
32301
  const deadline = Date.now() + timeoutMs;
32255
32302
  while (Date.now() < deadline) {
32256
32303
  if (!this.currentConversationId) return null;
32257
- const filePath = path78.join(this.projectDir, `${this.currentConversationId}.jsonl`);
32304
+ const filePath = path79.join(this.projectDir, `${this.currentConversationId}.jsonl`);
32258
32305
  const messages = parseJsonl(filePath);
32259
32306
  if (messages.length > previousCount) {
32260
32307
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -32281,18 +32328,18 @@ var HistoryService = class _HistoryService {
32281
32328
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
32282
32329
  const oneShots = readOneShotConversations(this.cwd);
32283
32330
  try {
32284
- const files = fs69.readdirSync(dir, { withFileTypes: true }).filter(
32285
- (e) => e.isFile() && e.name.endsWith(".jsonl") && !oneShots.has(path78.basename(e.name, ".jsonl"))
32331
+ const files = fs70.readdirSync(dir, { withFileTypes: true }).filter(
32332
+ (e) => e.isFile() && e.name.endsWith(".jsonl") && !oneShots.has(path79.basename(e.name, ".jsonl"))
32286
32333
  ).map((e) => {
32287
32334
  try {
32288
- const stat3 = fs69.statSync(path78.join(dir, e.name));
32335
+ const stat3 = fs70.statSync(path79.join(dir, e.name));
32289
32336
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
32290
32337
  } catch {
32291
32338
  return { name: e.name, mtime: 0, birthtime: 0 };
32292
32339
  }
32293
32340
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
32294
32341
  if (files.length > 0) {
32295
- this.currentConversationId = path78.basename(files[0].name, ".jsonl");
32342
+ this.currentConversationId = path79.basename(files[0].name, ".jsonl");
32296
32343
  }
32297
32344
  } catch {
32298
32345
  }
@@ -32326,13 +32373,13 @@ var HistoryService = class _HistoryService {
32326
32373
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
32327
32374
  let entries2;
32328
32375
  try {
32329
- entries2 = fs69.readdirSync(dir, { withFileTypes: true });
32376
+ entries2 = fs70.readdirSync(dir, { withFileTypes: true });
32330
32377
  } catch {
32331
32378
  return null;
32332
32379
  }
32333
32380
  const files = entries2.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
32334
32381
  try {
32335
- const stat3 = fs69.statSync(path78.join(dir, e.name));
32382
+ const stat3 = fs70.statSync(path79.join(dir, e.name));
32336
32383
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
32337
32384
  } catch {
32338
32385
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -32341,12 +32388,12 @@ var HistoryService = class _HistoryService {
32341
32388
  if (files.length === 0) return null;
32342
32389
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
32343
32390
  if (!files.some((f) => f.name === targetFile)) return null;
32344
- return this.extractUsageFromFile(path78.join(dir, targetFile));
32391
+ return this.extractUsageFromFile(path79.join(dir, targetFile));
32345
32392
  }
32346
32393
  extractUsageFromFile(filePath) {
32347
32394
  let raw;
32348
32395
  try {
32349
- raw = fs69.readFileSync(filePath, "utf8");
32396
+ raw = fs70.readFileSync(filePath, "utf8");
32350
32397
  } catch {
32351
32398
  return null;
32352
32399
  }
@@ -32398,9 +32445,9 @@ var HistoryService = class _HistoryService {
32398
32445
  let totalCost = 0;
32399
32446
  let files;
32400
32447
  try {
32401
- files = fs69.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
32448
+ files = fs70.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
32402
32449
  try {
32403
- return fs69.statSync(path78.join(projectDir, f)).mtimeMs >= monthStartMs;
32450
+ return fs70.statSync(path79.join(projectDir, f)).mtimeMs >= monthStartMs;
32404
32451
  } catch {
32405
32452
  return false;
32406
32453
  }
@@ -32411,7 +32458,7 @@ var HistoryService = class _HistoryService {
32411
32458
  for (const file of files) {
32412
32459
  let raw;
32413
32460
  try {
32414
- raw = fs69.readFileSync(path78.join(projectDir, file), "utf8");
32461
+ raw = fs70.readFileSync(path79.join(projectDir, file), "utf8");
32415
32462
  } catch {
32416
32463
  continue;
32417
32464
  }
@@ -32490,7 +32537,7 @@ var HistoryService = class _HistoryService {
32490
32537
  if (this.runtime.resolveHistoryFile) {
32491
32538
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
32492
32539
  }
32493
- return path78.join(this.projectDir, `${sessionId}.jsonl`);
32540
+ return path79.join(this.projectDir, `${sessionId}.jsonl`);
32494
32541
  }
32495
32542
  /**
32496
32543
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -32528,7 +32575,7 @@ var HistoryService = class _HistoryService {
32528
32575
  };
32529
32576
  });
32530
32577
  }
32531
- return parseJsonl(path78.join(this.projectDir, `${sessionId}.jsonl`));
32578
+ return parseJsonl(path79.join(this.projectDir, `${sessionId}.jsonl`));
32532
32579
  }
32533
32580
  /** One in-flight full upload per conversation — the baton mirror and a
32534
32581
  * `get_conversation` used to upload the same transcript concurrently. */
@@ -32610,7 +32657,7 @@ var HistoryService = class _HistoryService {
32610
32657
  if (!filePath) return false;
32611
32658
  let mtimeMs;
32612
32659
  try {
32613
- mtimeMs = fs69.statSync(filePath).mtimeMs;
32660
+ mtimeMs = fs70.statSync(filePath).mtimeMs;
32614
32661
  } catch {
32615
32662
  return false;
32616
32663
  }
@@ -32685,10 +32732,10 @@ var HistoryService = class _HistoryService {
32685
32732
 
32686
32733
  // src/agents/acp/client.ts
32687
32734
  var import_node_child_process28 = require("child_process");
32688
- var fs70 = __toESM(require("fs/promises"));
32735
+ var fs71 = __toESM(require("fs/promises"));
32689
32736
  var fsSync = __toESM(require("fs"));
32690
- var os51 = __toESM(require("os"));
32691
- var path80 = __toESM(require("path"));
32737
+ var os52 = __toESM(require("os"));
32738
+ var path81 = __toESM(require("path"));
32692
32739
  var import_node_stream = require("stream");
32693
32740
 
32694
32741
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -36714,8 +36761,8 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
36714
36761
  }
36715
36762
 
36716
36763
  // src/agents/acp/internal-paths.ts
36717
- var path79 = __toESM(require("path"));
36718
- var os50 = __toESM(require("os"));
36764
+ var path80 = __toESM(require("path"));
36765
+ var os51 = __toESM(require("os"));
36719
36766
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
36720
36767
  var PROSE_ONLY_TOOL_KINDS = /* @__PURE__ */ new Set(["think", "switch_mode"]);
36721
36768
  function isProseOnlyToolKind(kind) {
@@ -36727,13 +36774,13 @@ function textReferencesInternal(text) {
36727
36774
  const scrubbed = text.replace(SELF_HOSTED_WORKSPACE_RE, " ");
36728
36775
  return INTERNAL_TOKENS.some((t2) => scrubbed.includes(t2));
36729
36776
  }
36730
- function pathIsInternal(p2, homeDir2 = os50.homedir()) {
36777
+ function pathIsInternal(p2, homeDir2 = os51.homedir()) {
36731
36778
  if (!p2) return false;
36732
- const abs = path79.resolve(p2);
36733
- const home = path79.resolve(homeDir2);
36734
- const within = (root) => abs === root || abs.startsWith(root + path79.sep);
36735
- if (within(path79.join(home, ".codeam", "self-hosted"))) return false;
36736
- return within(path79.join(home, ".codeam")) || within(path79.join(home, ".beads")) || abs === path79.join(home, ".codeam-host.log") || abs.includes(`${path79.sep}house-claude${path79.sep}`) || abs.endsWith(`${path79.sep}house-claude`);
36779
+ const abs = path80.resolve(p2);
36780
+ const home = path80.resolve(homeDir2);
36781
+ const within = (root) => abs === root || abs.startsWith(root + path80.sep);
36782
+ if (within(path80.join(home, ".codeam", "self-hosted"))) return false;
36783
+ return within(path80.join(home, ".codeam")) || within(path80.join(home, ".beads")) || abs === path80.join(home, ".codeam-host.log") || abs.includes(`${path80.sep}house-claude${path80.sep}`) || abs.endsWith(`${path80.sep}house-claude`);
36737
36784
  }
36738
36785
  function toolCallReferencesInternal(call, homeDir2) {
36739
36786
  if (call.locations?.some((l) => pathIsInternal(l.path, homeDir2))) return true;
@@ -36881,6 +36928,7 @@ var PROTOCOL_VERSION3 = 1;
36881
36928
  var FATAL_STARTUP_RE = /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist|Error authenticating|ProjectIdRequiredError/i;
36882
36929
  var NEWSESSION_TIMEOUT_MS = 12e4;
36883
36930
  var MCP_STARTUP_TIMEOUT_MS = NEWSESSION_TIMEOUT_MS - 3e4;
36931
+ var AGENT_ENV_WITHHELD = ["PREVIEW_TUNNEL_TOKEN", "PREVIEW_TUNNEL_HOSTNAME"];
36884
36932
  var LOADSESSION_TIMEOUT_MS = 6e4;
36885
36933
  var PROMPT_IDLE_TIMEOUT_MS = 9e4;
36886
36934
  var PROMPT_ACTIVE_IDLE_TIMEOUT_MS = 6e5;
@@ -37066,6 +37114,7 @@ var AcpClient = class {
37066
37114
  ...this.opts.extraEnv ?? {},
37067
37115
  PATH: augmentedPath
37068
37116
  };
37117
+ for (const key of AGENT_ENV_WITHHELD) delete childEnv[key];
37069
37118
  log.info(
37070
37119
  "acpClient",
37071
37120
  `provider routing ${formatProviderRouting(describeProviderRouting(childEnv, { cwd }), adapter.command)}`
@@ -37865,7 +37914,7 @@ var AcpClient = class {
37865
37914
  throw new RequestError(-32002, GUARDRAIL_SECRET_READ_BLOCK_REASON, { uri: params.path });
37866
37915
  }
37867
37916
  try {
37868
- const content = await fs70.readFile(params.path, "utf8");
37917
+ const content = await fs71.readFile(params.path, "utf8");
37869
37918
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
37870
37919
  } catch (err) {
37871
37920
  const code = err.code;
@@ -37886,7 +37935,7 @@ var AcpClient = class {
37886
37935
  throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
37887
37936
  }
37888
37937
  try {
37889
- await fs70.writeFile(params.path, params.content, "utf8");
37938
+ await fs71.writeFile(params.path, params.content, "utf8");
37890
37939
  return {};
37891
37940
  } catch (err) {
37892
37941
  const code = err.code;
@@ -37974,30 +38023,30 @@ function applyLineRange(content, line, limit) {
37974
38023
  return { content: lines.slice(start2, end).join("\n") };
37975
38024
  }
37976
38025
  function knownAgentBinaryDirs() {
37977
- const home = os51.homedir();
38026
+ const home = os52.homedir();
37978
38027
  const out2 = [];
37979
38028
  out2.push("/tmp/codeam-node20/bin");
37980
38029
  for (const root of [
37981
38030
  "/usr/local/share/nvm/versions/node",
37982
- path80.join(home, ".nvm/versions/node")
38031
+ path81.join(home, ".nvm/versions/node")
37983
38032
  ]) {
37984
38033
  try {
37985
38034
  for (const child of fsSync.readdirSync(root)) {
37986
- out2.push(path80.join(root, child, "bin"));
38035
+ out2.push(path81.join(root, child, "bin"));
37987
38036
  }
37988
38037
  } catch {
37989
38038
  }
37990
38039
  }
37991
- out2.push(path80.join(home, ".volta/bin"));
38040
+ out2.push(path81.join(home, ".volta/bin"));
37992
38041
  out2.push("/usr/local/bin");
37993
38042
  out2.push("/usr/bin");
37994
- out2.push(path80.join(home, ".local/bin"));
37995
- out2.push(path80.join(home, "bin"));
38043
+ out2.push(path81.join(home, ".local/bin"));
38044
+ out2.push(path81.join(home, "bin"));
37996
38045
  out2.push(...agentInstallBinDirs());
37997
38046
  if (process.platform === "win32") {
37998
38047
  const { LOCALAPPDATA, APPDATA } = process.env;
37999
- if (LOCALAPPDATA) out2.push(path80.join(LOCALAPPDATA, "cursor-agent"));
38000
- if (APPDATA) out2.push(path80.join(APPDATA, "npm"));
38048
+ if (LOCALAPPDATA) out2.push(path81.join(LOCALAPPDATA, "cursor-agent"));
38049
+ if (APPDATA) out2.push(path81.join(APPDATA, "npm"));
38001
38050
  }
38002
38051
  return out2.filter((p2) => {
38003
38052
  try {
@@ -38008,7 +38057,7 @@ function knownAgentBinaryDirs() {
38008
38057
  });
38009
38058
  }
38010
38059
  function expandPathForAgentBinaries(existingPath) {
38011
- const existing = new Set(existingPath.split(path80.delimiter).filter((p2) => p2.length > 0));
38060
+ const existing = new Set(existingPath.split(path81.delimiter).filter((p2) => p2.length > 0));
38012
38061
  const additions = [];
38013
38062
  for (const dir of knownAgentBinaryDirs()) {
38014
38063
  if (!existing.has(dir)) {
@@ -38017,17 +38066,17 @@ function expandPathForAgentBinaries(existingPath) {
38017
38066
  }
38018
38067
  }
38019
38068
  if (additions.length === 0) return existingPath;
38020
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path80.delimiter);
38069
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path81.delimiter);
38021
38070
  }
38022
38071
 
38023
38072
  // src/commands/host/agent-install.ts
38024
38073
  var import_child_process27 = require("child_process");
38025
- var os52 = __toESM(require("os"));
38074
+ var os53 = __toESM(require("os"));
38026
38075
  function runAgentInstallScript(script, opts = {}) {
38027
38076
  const timeoutMs = opts.timeoutMs ?? 18e4;
38028
38077
  const scope = opts.logScope ?? "agent-install";
38029
38078
  return new Promise((resolve13) => {
38030
- const home = process.env.HOME || os52.homedir();
38079
+ const home = process.env.HOME || os53.homedir();
38031
38080
  const child = (0, import_child_process27.spawn)("sh", ["-c", script], {
38032
38081
  env: { ...process.env, HOME: home },
38033
38082
  stdio: ["ignore", "pipe", "pipe"]
@@ -38289,9 +38338,9 @@ async function performAgentSwitch(deps, rawAgentId, fastPath = {}) {
38289
38338
  }
38290
38339
 
38291
38340
  // src/commands/host/agent-provisioning.ts
38292
- var fs71 = __toESM(require("fs"));
38293
- var os53 = __toESM(require("os"));
38294
- var path81 = __toESM(require("path"));
38341
+ var fs72 = __toESM(require("fs"));
38342
+ var os54 = __toESM(require("os"));
38343
+ var path82 = __toESM(require("path"));
38295
38344
  var PUBLIC_TO_INTERNAL_AGENT = {
38296
38345
  claude_code: "claude",
38297
38346
  claude: "claude",
@@ -38308,22 +38357,22 @@ function toInternalAgentId(publicAgentId) {
38308
38357
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
38309
38358
  }
38310
38359
  function ensureDir(dir) {
38311
- fs71.mkdirSync(dir, { recursive: true, mode: 448 });
38360
+ fs72.mkdirSync(dir, { recursive: true, mode: 448 });
38312
38361
  }
38313
38362
  function writeFile0600(filePath, contents) {
38314
- ensureDir(path81.dirname(filePath));
38315
- fs71.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
38363
+ ensureDir(path82.dirname(filePath));
38364
+ fs72.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
38316
38365
  restrictToOwner(filePath);
38317
38366
  }
38318
38367
  function rmIfExists(filePath) {
38319
38368
  try {
38320
- fs71.rmSync(filePath, { force: true });
38369
+ fs72.rmSync(filePath, { force: true });
38321
38370
  } catch {
38322
38371
  }
38323
38372
  }
38324
38373
  var claudeProvisioner = {
38325
38374
  write(auth, home) {
38326
- const credentialsJson = path81.join(home, ".claude", ".credentials.json");
38375
+ const credentialsJson = path82.join(home, ".claude", ".credentials.json");
38327
38376
  if (auth.kind === "api_key") {
38328
38377
  rmIfExists(credentialsJson);
38329
38378
  return { ANTHROPIC_API_KEY: auth.value };
@@ -38335,8 +38384,8 @@ var claudeProvisioner = {
38335
38384
  } else {
38336
38385
  rmIfExists(credentialsJson);
38337
38386
  }
38338
- const claudeJson = path81.join(home, ".claude.json");
38339
- if (!fs71.existsSync(claudeJson)) {
38387
+ const claudeJson = path82.join(home, ".claude.json");
38388
+ if (!fs72.existsSync(claudeJson)) {
38340
38389
  writeFile0600(
38341
38390
  claudeJson,
38342
38391
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -38347,7 +38396,7 @@ var claudeProvisioner = {
38347
38396
  };
38348
38397
  var codexProvisioner = {
38349
38398
  write(auth, home) {
38350
- const authJson = path81.join(home, ".codex", "auth.json");
38399
+ const authJson = path82.join(home, ".codex", "auth.json");
38351
38400
  if (auth.kind === "api_key") {
38352
38401
  writeFile0600(authJson, JSON.stringify({ auth_mode: "apikey", OPENAI_API_KEY: auth.value }));
38353
38402
  return { OPENAI_API_KEY: auth.value };
@@ -38370,7 +38419,7 @@ function codexLoginStamp(raw) {
38370
38419
  function keepsFresherCodexLogin(authJsonPath, incoming) {
38371
38420
  let onDisk;
38372
38421
  try {
38373
- onDisk = fs71.readFileSync(authJsonPath, "utf8");
38422
+ onDisk = fs72.readFileSync(authJsonPath, "utf8");
38374
38423
  } catch {
38375
38424
  return false;
38376
38425
  }
@@ -38381,8 +38430,8 @@ function keepsFresherCodexLogin(authJsonPath, incoming) {
38381
38430
  }
38382
38431
  var geminiProvisioner = {
38383
38432
  write(auth, home) {
38384
- const settingsJson = path81.join(home, ".gemini", "settings.json");
38385
- const oauthCreds = path81.join(home, ".gemini", "oauth_creds.json");
38433
+ const settingsJson = path82.join(home, ".gemini", "settings.json");
38434
+ const oauthCreds = path82.join(home, ".gemini", "oauth_creds.json");
38386
38435
  if (auth.kind === "api_key") {
38387
38436
  rmIfExists(oauthCreds);
38388
38437
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -38395,7 +38444,7 @@ var geminiProvisioner = {
38395
38444
  };
38396
38445
  var cursorProvisioner = {
38397
38446
  write(auth, home) {
38398
- const authJson = path81.join(home, ".config", "cursor", "auth.json");
38447
+ const authJson = path82.join(home, ".config", "cursor", "auth.json");
38399
38448
  if (auth.kind === "api_key") {
38400
38449
  rmIfExists(authJson);
38401
38450
  return { CURSOR_API_KEY: auth.value };
@@ -38437,22 +38486,22 @@ max_context_size = 262144
38437
38486
  var kimiProvisioner = {
38438
38487
  write(auth, home) {
38439
38488
  const credentialsFiles = [
38440
- path81.join(home, ".kimi", "credentials", "kimi-code.json"),
38441
- path81.join(home, ".kimi-code", "credentials", "kimi-code.json")
38489
+ path82.join(home, ".kimi", "credentials", "kimi-code.json"),
38490
+ path82.join(home, ".kimi-code", "credentials", "kimi-code.json")
38442
38491
  ];
38443
38492
  if (auth.kind === "api_key") {
38444
38493
  credentialsFiles.forEach(rmIfExists);
38445
38494
  return { KIMI_API_KEY: auth.value };
38446
38495
  }
38447
38496
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
38448
- writeFile0600(path81.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
38497
+ writeFile0600(path82.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
38449
38498
  return {};
38450
38499
  }
38451
38500
  };
38452
38501
  var coderabbitProvisioner = {
38453
38502
  write(auth, home) {
38454
- const dir = path81.join(home, ".coderabbit");
38455
- const authJson = path81.join(dir, "auth.json");
38503
+ const dir = path82.join(home, ".coderabbit");
38504
+ const authJson = path82.join(dir, "auth.json");
38456
38505
  if (auth.kind === "api_key") {
38457
38506
  rmIfExists(authJson);
38458
38507
  return { CODERABBIT_API_KEY: auth.value };
@@ -38464,13 +38513,13 @@ var coderabbitProvisioner = {
38464
38513
  try {
38465
38514
  const parsed = JSON.parse(value);
38466
38515
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
38467
- file = path81.basename(parsed.file);
38516
+ file = path82.basename(parsed.file);
38468
38517
  contents = parsed.contents;
38469
38518
  }
38470
38519
  } catch {
38471
38520
  }
38472
38521
  }
38473
- writeFile0600(path81.join(dir, file), contents);
38522
+ writeFile0600(path82.join(dir, file), contents);
38474
38523
  return {};
38475
38524
  }
38476
38525
  };
@@ -38502,7 +38551,7 @@ var UnsupportedAgentError = class extends Error {
38502
38551
  this.agentId = agentId;
38503
38552
  }
38504
38553
  };
38505
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os53.homedir()) {
38554
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os54.homedir()) {
38506
38555
  const internal = toInternalAgentId(publicAgentId);
38507
38556
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
38508
38557
  const provisioner = PROVISIONERS[internal];
@@ -38511,8 +38560,8 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os53.homedir(
38511
38560
  }
38512
38561
 
38513
38562
  // src/beads/workflow-hint.ts
38514
- var fs72 = __toESM(require("fs"));
38515
- var path82 = __toESM(require("path"));
38563
+ var fs73 = __toESM(require("fs"));
38564
+ var path83 = __toESM(require("path"));
38516
38565
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
38517
38566
  var BEADS_HINT = `${BEADS_HINT_MARKER}
38518
38567
  # Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
@@ -38539,11 +38588,11 @@ function ensureBeadsWorkflowHint(homeDir2, file = claudeMemoryFile(homeDir2)) {
38539
38588
  try {
38540
38589
  let existing = "";
38541
38590
  try {
38542
- existing = fs72.readFileSync(file, "utf8");
38591
+ existing = fs73.readFileSync(file, "utf8");
38543
38592
  } catch {
38544
38593
  }
38545
38594
  if (existing.includes(BEADS_HINT)) return;
38546
- fs72.mkdirSync(path82.dirname(file), { recursive: true });
38595
+ fs73.mkdirSync(path83.dirname(file), { recursive: true });
38547
38596
  let next;
38548
38597
  const open = existing.indexOf(BEADS_HINT_MARKER);
38549
38598
  const close = open === -1 ? -1 : existing.indexOf(BEADS_HINT_MARKER, open + BEADS_HINT_MARKER.length);
@@ -38556,40 +38605,40 @@ ${BEADS_HINT}
38556
38605
  ` : `${BEADS_HINT}
38557
38606
  `;
38558
38607
  }
38559
- fs72.writeFileSync(file, next);
38608
+ fs73.writeFileSync(file, next);
38560
38609
  } catch {
38561
38610
  }
38562
38611
  }
38563
38612
 
38564
38613
  // src/agents/agent-standard.ts
38565
- var fs73 = __toESM(require("fs"));
38566
- var path83 = __toESM(require("path"));
38567
- var os54 = __toESM(require("os"));
38614
+ var fs74 = __toESM(require("fs"));
38615
+ var path84 = __toESM(require("path"));
38616
+ var os55 = __toESM(require("os"));
38568
38617
  function ensureAgentStandard(homeDir2, file = claudeMemoryFile(homeDir2)) {
38569
38618
  try {
38570
38619
  let existing = "";
38571
38620
  try {
38572
- existing = fs73.readFileSync(file, "utf8");
38621
+ existing = fs74.readFileSync(file, "utf8");
38573
38622
  } catch {
38574
38623
  }
38575
38624
  if (existing.includes(AGENT_STANDARD_MARKER)) return;
38576
- fs73.mkdirSync(path83.dirname(file), { recursive: true });
38625
+ fs74.mkdirSync(path84.dirname(file), { recursive: true });
38577
38626
  const next = existing.trim() ? `${existing.trimEnd()}
38578
38627
 
38579
38628
  ${AGENT_STANDARD_BLOCK}
38580
38629
  ` : `${AGENT_STANDARD_BLOCK}
38581
38630
  `;
38582
- fs73.writeFileSync(file, next);
38631
+ fs74.writeFileSync(file, next);
38583
38632
  } catch {
38584
38633
  }
38585
38634
  }
38586
38635
  var _agentStandardSeam = {
38587
38636
  isLocalSession: () => isLocalSession(),
38588
- markerPath: (sessionId) => path83.join(os54.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
38589
- exists: (p2) => fs73.existsSync(p2),
38637
+ markerPath: (sessionId) => path84.join(os55.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
38638
+ exists: (p2) => fs74.existsSync(p2),
38590
38639
  write: (p2) => {
38591
- fs73.mkdirSync(path83.dirname(p2), { recursive: true });
38592
- fs73.writeFileSync(p2, "");
38640
+ fs74.mkdirSync(path84.dirname(p2), { recursive: true });
38641
+ fs74.writeFileSync(p2, "");
38593
38642
  }
38594
38643
  };
38595
38644
  function isClaude(agent) {
@@ -39324,15 +39373,15 @@ function withholdTrailingPartialFenceMarker(text) {
39324
39373
 
39325
39374
  // src/agents/acp/onboarding.ts
39326
39375
  var import_child_process28 = require("child_process");
39327
- var fs75 = __toESM(require("fs"));
39328
- var os55 = __toESM(require("os"));
39329
- var path85 = __toESM(require("path"));
39376
+ var fs76 = __toESM(require("fs"));
39377
+ var os56 = __toESM(require("os"));
39378
+ var path86 = __toESM(require("path"));
39330
39379
  var _onboardingSeam = {
39331
- markerPath: (sessionId) => path85.join(os55.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
39332
- exists: (p2) => fs75.existsSync(p2),
39380
+ markerPath: (sessionId) => path86.join(os56.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
39381
+ exists: (p2) => fs76.existsSync(p2),
39333
39382
  write: (p2) => {
39334
- fs75.mkdirSync(path85.dirname(p2), { recursive: true });
39335
- fs75.writeFileSync(p2, "");
39383
+ fs76.mkdirSync(path86.dirname(p2), { recursive: true });
39384
+ fs76.writeFileSync(p2, "");
39336
39385
  },
39337
39386
  disabled: () => {
39338
39387
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -39369,7 +39418,7 @@ function resolveRepoName(cwd) {
39369
39418
  if (name) return name;
39370
39419
  }
39371
39420
  }
39372
- const base = path85.basename(cwd || "");
39421
+ const base = path86.basename(cwd || "");
39373
39422
  if (base && !isUuid(base)) return base;
39374
39423
  return "this project";
39375
39424
  }
@@ -39383,14 +39432,11 @@ function buildOnboardingWelcome(cwd) {
39383
39432
  "- **Smart Composer** \u2014 help crafting and structuring your prompts.",
39384
39433
  "- **Team Spaces** \u2014 share this session with your team, or hand it off to someone else.",
39385
39434
  "",
39386
- "Found a bug or have feedback? Reach us at:",
39387
- // EXPLICIT markdown links, not bare URLs. Relying on the app's autolinker
39388
- // rendered the GitHub bullet as an EMPTY link (the label was consumed, the
39389
- // href never attached) — a labelled link renders correctly everywhere and
39390
- // reads better than a raw URL on a phone-width bubble.
39391
- "- [GitHub issues](https://github.com/edgar-durand/codeagent-mobile-clients/issues)",
39392
- "- [Discord community](https://discord.gg/Np2pbMrV9f)",
39393
- "",
39435
+ // ⚠️ No support links here. The first message a new user reads is the
39436
+ // invitation to start; "Found a bug? GitHub issues / Discord" pointed a
39437
+ // non-developer at a developer bug tracker before they had sent a single
39438
+ // task (replay 2026-10-04, PRO user in Malaysia, bead codeagent-sak0).
39439
+ // Help lives in the app (Profile › Help → FAQ + Contact support).
39394
39440
  `Ready when you are \u2014 try **"explain ${repo}"** or **"what should I work on first?"**`
39395
39441
  ].join("\n");
39396
39442
  }
@@ -39772,14 +39818,14 @@ var import_crypto5 = require("crypto");
39772
39818
 
39773
39819
  // src/services/turn-files/git-changeset.ts
39774
39820
  var import_child_process29 = require("child_process");
39775
- var fs77 = __toESM(require("fs/promises"));
39821
+ var fs78 = __toESM(require("fs/promises"));
39776
39822
  var import_fs10 = require("fs");
39777
- var path87 = __toESM(require("path"));
39823
+ var path88 = __toESM(require("path"));
39778
39824
 
39779
39825
  // src/services/turn-files/review-ignore.ts
39780
39826
  var import_ignore2 = __toESM(require("ignore"));
39781
- var fs76 = __toESM(require("fs"));
39782
- var path86 = __toESM(require("path"));
39827
+ var fs77 = __toESM(require("fs"));
39828
+ var path87 = __toESM(require("path"));
39783
39829
  var CURATED_REVIEW_IGNORE = [
39784
39830
  // Google Cloud SDK (the incident) — installs a huge python tree.
39785
39831
  "google-cloud-sdk/",
@@ -39823,7 +39869,7 @@ var CURATED_REVIEW_IGNORE = [
39823
39869
  function makeReviewIgnore(repoRoot) {
39824
39870
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
39825
39871
  try {
39826
- const custom = fs76.readFileSync(path86.join(repoRoot, ".codeam", "reviewignore"), "utf8");
39872
+ const custom = fs77.readFileSync(path87.join(repoRoot, ".codeam", "reviewignore"), "utf8");
39827
39873
  ig.add(custom);
39828
39874
  } catch {
39829
39875
  }
@@ -39858,7 +39904,7 @@ async function collectRepoChangeset(opts) {
39858
39904
  const rows = parseStatus(status2).filter(
39859
39905
  (row) => !isIgnoredFilePath(row.filePath) && !reviewIgnore(row.filePath) && // A socket, FIFO or device node is never a change to review (a
39860
39906
  // `cc-socks/1522.sock` reached the Files tab).
39861
- isReviewablePath(path87.join(opts.repoRoot, row.filePath))
39907
+ isReviewablePath(path88.join(opts.repoRoot, row.filePath))
39862
39908
  );
39863
39909
  const MAX_CHANGESET_FILES = Math.max(1, Number(process.env.CODEAM_MAX_CHANGESET_FILES ?? 500));
39864
39910
  const truncated = rows.length > MAX_CHANGESET_FILES;
@@ -39875,7 +39921,7 @@ async function collectRepoChangeset(opts) {
39875
39921
  let stats;
39876
39922
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
39877
39923
  const lineCount = await readUntrackedLineCount(
39878
- path87.join(opts.repoRoot, row.filePath)
39924
+ path88.join(opts.repoRoot, row.filePath)
39879
39925
  );
39880
39926
  stats = { added: lineCount, removed: 0 };
39881
39927
  } else {
@@ -39906,7 +39952,7 @@ function readUntrackedLineCount(absPath) {
39906
39952
  }
39907
39953
  async function defaultReadUntrackedLineCount(absPath) {
39908
39954
  try {
39909
- const content = await fs77.readFile(absPath, "utf8");
39955
+ const content = await fs78.readFile(absPath, "utf8");
39910
39956
  let count = 0;
39911
39957
  let pos = -1;
39912
39958
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -40017,8 +40063,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
40017
40063
  if (hasGit) {
40018
40064
  out2.push({
40019
40065
  repoRoot: dir,
40020
- repoPath: path87.relative(workingDir, dir),
40021
- repoName: path87.basename(dir)
40066
+ repoPath: path88.relative(workingDir, dir),
40067
+ repoName: path88.basename(dir)
40022
40068
  });
40023
40069
  return;
40024
40070
  }
@@ -40026,7 +40072,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
40026
40072
  if (!entry.isDirectory) continue;
40027
40073
  if (entry.name === "node_modules") continue;
40028
40074
  if (entry.name === "dist" || entry.name === "build") continue;
40029
- await walk2(path87.join(dir, entry.name), depth2 + 1);
40075
+ await walk2(path88.join(dir, entry.name), depth2 + 1);
40030
40076
  }
40031
40077
  }
40032
40078
  }
@@ -40040,8 +40086,8 @@ function isReviewablePath(absPath) {
40040
40086
  }
40041
40087
 
40042
40088
  // src/services/turn-files/files-outbox.ts
40043
- var fs78 = __toESM(require("fs/promises"));
40044
- var path88 = __toESM(require("path"));
40089
+ var fs79 = __toESM(require("fs/promises"));
40090
+ var path89 = __toESM(require("path"));
40045
40091
  var import_os14 = require("os");
40046
40092
  var HOME_OUTBOX_DIR = ".codeam/outbox";
40047
40093
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -40074,16 +40120,16 @@ var FilesOutbox = class {
40074
40120
  backoffIndex = 0;
40075
40121
  stopped = false;
40076
40122
  constructor(opts) {
40077
- const base = opts.baseDir ?? path88.join(homeDir(), HOME_OUTBOX_DIR);
40078
- this.filePath = path88.join(base, `${opts.sessionId}.jsonl`);
40123
+ const base = opts.baseDir ?? path89.join(homeDir(), HOME_OUTBOX_DIR);
40124
+ this.filePath = path89.join(base, `${opts.sessionId}.jsonl`);
40079
40125
  this.post = opts.post;
40080
40126
  this.autoSchedule = opts.autoSchedule !== false;
40081
40127
  }
40082
40128
  /** Persist the entry to disk and trigger a flush. Returns once the
40083
40129
  * line is durable on disk (not once the POST succeeds). */
40084
40130
  async enqueue(entry) {
40085
- await fs78.mkdir(path88.dirname(this.filePath), { recursive: true });
40086
- await fs78.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
40131
+ await fs79.mkdir(path89.dirname(this.filePath), { recursive: true });
40132
+ await fs79.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
40087
40133
  this.backoffIndex = 0;
40088
40134
  if (this.autoSchedule) this.scheduleFlush(0);
40089
40135
  }
@@ -40174,7 +40220,7 @@ var FilesOutbox = class {
40174
40220
  async readAll() {
40175
40221
  let raw = "";
40176
40222
  try {
40177
- raw = await fs78.readFile(this.filePath, "utf8");
40223
+ raw = await fs79.readFile(this.filePath, "utf8");
40178
40224
  } catch {
40179
40225
  return [];
40180
40226
  }
@@ -40198,12 +40244,12 @@ var FilesOutbox = class {
40198
40244
  async rewrite(entries2) {
40199
40245
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
40200
40246
  if (entries2.length === 0) {
40201
- await fs78.unlink(this.filePath).catch(() => void 0);
40247
+ await fs79.unlink(this.filePath).catch(() => void 0);
40202
40248
  return;
40203
40249
  }
40204
40250
  const payload = entries2.map((e) => JSON.stringify(e)).join("\n") + "\n";
40205
- await fs78.writeFile(tmpPath, payload, "utf8");
40206
- await fs78.rename(tmpPath, this.filePath);
40251
+ await fs79.writeFile(tmpPath, payload, "utf8");
40252
+ await fs79.rename(tmpPath, this.filePath);
40207
40253
  }
40208
40254
  };
40209
40255
  function applyJitter(ms) {
@@ -40550,48 +40596,6 @@ async function readActiveConversationMarker(cwd, homeDir2) {
40550
40596
  }
40551
40597
  }
40552
40598
 
40553
- // src/services/turn-marker.ts
40554
- var fs80 = __toESM(require("fs"));
40555
- var os57 = __toESM(require("os"));
40556
- var path90 = __toESM(require("path"));
40557
- var depth = 0;
40558
- function codeamHome() {
40559
- return path90.join(os57.homedir(), ".codeam");
40560
- }
40561
- function turnMarkerPath(pid = process.pid, home = codeamHome()) {
40562
- return path90.join(home, "turns", String(pid));
40563
- }
40564
- function mark() {
40565
- try {
40566
- const file = turnMarkerPath();
40567
- fs80.mkdirSync(path90.dirname(file), { recursive: true });
40568
- fs80.writeFileSync(file, String(Date.now()));
40569
- } catch {
40570
- }
40571
- }
40572
- function clear() {
40573
- try {
40574
- fs80.rmSync(turnMarkerPath(), { force: true });
40575
- } catch {
40576
- }
40577
- }
40578
- async function withTurnMarker(fn) {
40579
- if (depth++ === 0) mark();
40580
- try {
40581
- return await fn();
40582
- } finally {
40583
- if (--depth === 0) clear();
40584
- }
40585
- }
40586
- function isProcessMidTurn(pid, home) {
40587
- if (!pid) return false;
40588
- try {
40589
- return fs80.existsSync(turnMarkerPath(pid, home));
40590
- } catch {
40591
- return false;
40592
- }
40593
- }
40594
-
40595
40599
  // src/packs/gates.ts
40596
40600
  var import_node_child_process29 = require("child_process");
40597
40601
  var fs81 = __toESM(require("fs"));
@@ -41822,7 +41826,7 @@ var SHORT_TIMEOUT_MS = 2e4;
41822
41826
  var PREVIEW_TOOLS = [
41823
41827
  {
41824
41828
  name: "start_preview",
41825
- description: "Open this project's live Preview in the user's CodeAgent app \u2014 the same thing as their Preview button: it installs dependencies if needed, starts the dev server, publishes it on a public URL and switches the user's screen to it. Use it after you change anything visual (UI, styles, layout, copy) so you and the user can check the result, or whenever the user asks to see the app. Returns the public URL (you can curl it) or the exact error. Reuses a preview that is already running. Usually leave the arguments out: the project is detected automatically. Pass command/args/port only if you know the exact dev command.",
41829
+ description: `Open this project's live Preview in the user's CodeAgent app \u2014 the same thing as their Preview button: it installs dependencies if needed, starts the dev server, publishes it on a public URL and switches the user's screen to it. Use it after you change anything visual (UI, styles, layout, copy) so you and the user can check the result, or whenever the user asks to see the app. Returns the public URL (you can curl it) or the exact error. Only give the user a preview link when this tool says the preview is live \u2014 after an error or a "still starting" answer there is NO working link. Reuses a preview that is already running (code changes hot-reload; never stop and start it to refresh). Usually leave the arguments out: the project is detected automatically. Pass command/args/port only if you know the exact dev command.`,
41826
41830
  inputSchema: {
41827
41831
  type: "object",
41828
41832
  properties: {
@@ -41859,7 +41863,7 @@ var PREVIEW_TOOLS = [
41859
41863
  },
41860
41864
  {
41861
41865
  name: "stop_preview",
41862
- description: "Stop the Preview (dev server + public URL). Only when the user asks, or to restart it cleanly.",
41866
+ description: "Stop the Preview (dev server + public URL). Only when the user asks. Never to apply code changes \u2014 the dev server hot-reloads them; to run a different dev command, call start_preview with that command instead.",
41863
41867
  inputSchema: { type: "object", properties: {}, additionalProperties: false }
41864
41868
  }
41865
41869
  ];
@@ -41919,12 +41923,17 @@ function describeResult(raw) {
41919
41923
  };
41920
41924
  }
41921
41925
  case "starting":
41922
- return { text: String(r.message ?? "The preview is starting."), isError: false };
41926
+ return {
41927
+ text: `${String(r.message ?? "The preview is starting.")} It is not serving yet, so there is no link to give the user until preview_status says it is running.`,
41928
+ isError: false
41929
+ };
41923
41930
  case "idle":
41924
41931
  return { text: "No preview is running.", isError: false };
41925
41932
  case "error":
41926
41933
  return {
41927
- text: `Preview failed at ${String(r.stage)}: ${String(r.message)}`,
41934
+ // The agent once answered a failed spawn with "the preview is open, here
41935
+ // is the link" (2026-10-05). Say plainly that nothing is serving.
41936
+ text: `Preview failed at ${String(r.stage)}: ${String(r.message)}. The preview is NOT running \u2014 do not give the user a preview link; tell them what failed.`,
41928
41937
  isError: true
41929
41938
  };
41930
41939
  default:
@@ -42253,6 +42262,8 @@ function mergeWithLocalMcpServers(integrationServers) {
42253
42262
  var http12 = __toESM(require("http"));
42254
42263
  var import_node_crypto14 = require("crypto");
42255
42264
  var START_WAIT_MS = 24e4;
42265
+ var MAX_AGENT_RESTARTS = 3;
42266
+ var AGENT_RESTART_WINDOW_MS = 10 * 6e4;
42256
42267
  var MAX_SELECTOR = 500;
42257
42268
  var MAX_LABEL = 80;
42258
42269
  var AgentPreviewBridge = class {
@@ -42264,6 +42275,12 @@ var AgentPreviewBridge = class {
42264
42275
  inflight = null;
42265
42276
  lastError = null;
42266
42277
  bound = null;
42278
+ /** When the agent tore the preview down, per session (see MAX_AGENT_RESTARTS). */
42279
+ restarts = /* @__PURE__ */ new Map();
42280
+ now;
42281
+ constructor(opts = {}) {
42282
+ this.now = opts.now ?? Date.now;
42283
+ }
42267
42284
  /** Start the loopback server once. `null` when it could not bind — the
42268
42285
  * preview tools are then simply absent, never a failed session. */
42269
42286
  listen() {
@@ -42390,6 +42407,7 @@ var AgentPreviewBridge = class {
42390
42407
  const ctx = this.ctx;
42391
42408
  if (!ctx?.pluginAuthToken) return { ok: false, message: "The session is still starting." };
42392
42409
  if (!activePreviews.has(ctx.sessionId)) return { ok: true, message: "No preview was running." };
42410
+ if (!this.takeRestart(ctx.sessionId)) return { ok: false, message: RESTART_CAPPED_MESSAGE };
42393
42411
  await killPreview(ctx.sessionId);
42394
42412
  resetBuildHealState(ctx.sessionId);
42395
42413
  await postPreviewEvent({
@@ -42411,7 +42429,15 @@ var AgentPreviewBridge = class {
42411
42429
  // ─── Internals ─────────────────────────────────────────────────────────
42412
42430
  async launch(ctx, pluginAuthToken, override) {
42413
42431
  this.lastError = null;
42414
- const already = serving(ctx.sessionId);
42432
+ let already = serving(ctx.sessionId);
42433
+ const wanted = override && detectionFromOverride(override);
42434
+ if (already && wanted && !sameCommand(already.detection, wanted)) {
42435
+ if (!this.takeRestart(ctx.sessionId)) {
42436
+ return { status: "error", stage: "restart_limit", message: RESTART_CAPPED_MESSAGE };
42437
+ }
42438
+ await killPreview(ctx.sessionId);
42439
+ already = null;
42440
+ }
42415
42441
  if (already) {
42416
42442
  await postPreviewEvent({
42417
42443
  sessionId: ctx.sessionId,
@@ -42458,6 +42484,21 @@ var AgentPreviewBridge = class {
42458
42484
  this.lastError = err;
42459
42485
  return { status: "error", ...err };
42460
42486
  }
42487
+ /** Records one agent-driven teardown; false once the window's cap is spent. */
42488
+ takeRestart(sessionId) {
42489
+ const now = this.now();
42490
+ const recent = (this.restarts.get(sessionId) ?? []).filter(
42491
+ (t2) => now - t2 < AGENT_RESTART_WINDOW_MS
42492
+ );
42493
+ if (recent.length >= MAX_AGENT_RESTARTS) {
42494
+ this.restarts.set(sessionId, recent);
42495
+ log.info("agent-preview", `restart cap reached for session=${sessionId}`);
42496
+ return false;
42497
+ }
42498
+ recent.push(now);
42499
+ this.restarts.set(sessionId, recent);
42500
+ return true;
42501
+ }
42461
42502
  async handle(req, res) {
42462
42503
  const reply = (code, body) => {
42463
42504
  res.writeHead(code, { "content-type": "application/json" });
@@ -42500,6 +42541,10 @@ function running(active2, reused) {
42500
42541
  inspector: Boolean(active2.inspector)
42501
42542
  };
42502
42543
  }
42544
+ var RESTART_CAPPED_MESSAGE = `The preview was already restarted ${MAX_AGENT_RESTARTS} times in the last ${AGENT_RESTART_WINDOW_MS / 6e4} minutes, so it stays as it is. Dev servers hot-reload: your code changes show up without a restart. If it is genuinely broken, tell the user what you saw.`;
42545
+ function sameCommand(a, b) {
42546
+ return a.command === b.command && a.port === b.port && JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []);
42547
+ }
42503
42548
  function detectionFromOverride(o) {
42504
42549
  if (!o.command || !Number.isInteger(o.port) || o.port <= 0 || o.port > 65535) return null;
42505
42550
  return {
@@ -51224,7 +51269,7 @@ async function autoUpgradeBeforeCriticalCommand() {
51224
51269
  if (process.env.NODE_ENV === "test") return;
51225
51270
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
51226
51271
  if (process.env.CI) return;
51227
- const current2 = true ? "2.76.21" : null;
51272
+ const current2 = true ? "2.76.23" : null;
51228
51273
  if (!current2) return;
51229
51274
  const cache = readCache();
51230
51275
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -51241,7 +51286,7 @@ function checkForUpdates() {
51241
51286
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
51242
51287
  if (process.env.CI) return;
51243
51288
  if (!process.stdout.isTTY) return;
51244
- const current2 = true ? "2.76.21" : null;
51289
+ const current2 = true ? "2.76.23" : null;
51245
51290
  if (!current2) return;
51246
51291
  const cache = readCache();
51247
51292
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -51518,12 +51563,13 @@ var path109 = __toESM(require("path"));
51518
51563
  var SELF_UPDATE_PKG = "codeam-cli";
51519
51564
  var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
51520
51565
  var SELF_UPDATE_STARTUP_DELAY_MS = 5e3;
51566
+ var SELF_UPDATE_BOOT_QUIET_MS = 10 * 6e4;
51521
51567
  var SELF_UPDATE_DEFER_MAX_MS = 24 * 60 * 60 * 1e3;
51522
51568
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
51523
51569
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
51524
51570
  var SELF_UPDATE_LS_TIMEOUT_MS = 15e3;
51525
51571
  function currentCliVersion() {
51526
- return true ? "2.76.21" : null;
51572
+ return true ? "2.76.23" : null;
51527
51573
  }
51528
51574
  async function installedVersion(deps) {
51529
51575
  const ls = await deps.run(
@@ -51734,7 +51780,7 @@ function signalHostReady(send = process.send?.bind(process)) {
51734
51780
  }
51735
51781
  function defaultDeps() {
51736
51782
  return {
51737
- ownVersion: true ? "2.76.21" : null,
51783
+ ownVersion: true ? "2.76.23" : null,
51738
51784
  root: cliVersionsRoot(),
51739
51785
  args: process.argv.slice(3),
51740
51786
  execPath: process.execPath,
@@ -52279,6 +52325,8 @@ var HostAgentSupervisor = class {
52279
52325
  /** epoch ms when the CURRENT pending restart was first owed — the ceiling
52280
52326
  * in {@link SELF_UPDATE_DEFER_MAX_MS} is measured from here. */
52281
52327
  pendingRestartSince = null;
52328
+ /** epoch ms of `start()`; null until then. See {@link SELF_UPDATE_BOOT_QUIET_MS}. */
52329
+ startedAt = null;
52282
52330
  /** Guards the one-shot 'connected' telemetry on the first heartbeat. */
52283
52331
  reportedConnected = false;
52284
52332
  /** Live-metrics collector — stateful across beats (CPU delta + latency). */
@@ -52340,6 +52388,7 @@ var HostAgentSupervisor = class {
52340
52388
  }
52341
52389
  /** Open the control channel (reusing the relay) + start heartbeats. */
52342
52390
  start() {
52391
+ this.startedAt = this.now();
52343
52392
  if (process.env.CODESPACES === "true") {
52344
52393
  log.info("keep-awake", "skipped (codespace \u2014 no physical sleep to prevent)");
52345
52394
  } else if (this.isContainerEnv()) {
@@ -52515,6 +52564,13 @@ var HostAgentSupervisor = class {
52515
52564
  maybeRestartForUpdate(version3) {
52516
52565
  const midTurn = [...this.children.values()].some((c2) => this.isChildMidTurn(c2.proc.pid));
52517
52566
  const fleetBusy = this.fleetLanes.size > 0;
52567
+ if (this.justBootedWithSessions()) {
52568
+ log.info(
52569
+ "host-agent",
52570
+ `self-update: ${version3} installed but sessions resumed by this boot are being served \u2014 deferring restart to the next idle tick (or the next boot)`
52571
+ );
52572
+ return false;
52573
+ }
52518
52574
  if (midTurn || fleetBusy) {
52519
52575
  const since = this.pendingRestartSince ?? this.now();
52520
52576
  const waited = this.now() - since;
@@ -52533,6 +52589,12 @@ var HostAgentSupervisor = class {
52533
52589
  this.onUpdated(version3);
52534
52590
  return true;
52535
52591
  }
52592
+ /** Inside the post-boot quiet window AND serving (or still resuming) a session. */
52593
+ justBootedWithSessions() {
52594
+ if (this.startedAt === null) return false;
52595
+ if (this.now() - this.startedAt >= SELF_UPDATE_BOOT_QUIET_MS) return false;
52596
+ return this.children.size > 0 || this.pendingOrphanReplacements > 0 || [...this.resumeStates.values()].some((st3) => st3.timer !== null);
52597
+ }
52536
52598
  /** Number of live children — for tests + diagnostics. */
52537
52599
  childCount() {
52538
52600
  return this.children.size;
@@ -54245,7 +54307,7 @@ function checkChokidar() {
54245
54307
  }
54246
54308
  async function doctor(args2 = []) {
54247
54309
  const json = args2.includes("--json");
54248
- const cliVersion = true ? "2.76.21" : "0.0.0-dev";
54310
+ const cliVersion = true ? "2.76.23" : "0.0.0-dev";
54249
54311
  const apiBase2 = resolveApiBaseUrl();
54250
54312
  const diagnosticId = (0, import_node_crypto17.randomUUID)();
54251
54313
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -54781,7 +54843,7 @@ async function mcpWarm(argv = [], opts = {}) {
54781
54843
  // src/commands/version.ts
54782
54844
  var import_picocolors15 = __toESM(require("picocolors"));
54783
54845
  function version2() {
54784
- const v = true ? "2.76.21" : "unknown";
54846
+ const v = true ? "2.76.23" : "unknown";
54785
54847
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
54786
54848
  }
54787
54849