codeam-cli 2.61.87 → 2.61.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.js +670 -406
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2561,6 +2561,80 @@ function getSkillDefinition(id) {
2561
2561
  return isSkillId(id) ? SKILL_REGISTRY[id] : null;
2562
2562
  }
2563
2563
 
2564
+ // ../../packages/shared/src/skills/agent-standard.ts
2565
+ var AGENT_STANDARD_MARKER = "<!-- codeam:agent-standard -->";
2566
+ var AGENT_STANDARD_TEXT = `# Working standard
2567
+
2568
+ You are an AI coding agent working on the user's project through CodeAgent Mobile. Follow this standard on every task.
2569
+
2570
+ ## How to work
2571
+ - **Understand before acting.** Restate the goal, read the relevant code, and be clear on what "done" looks like before changing anything.
2572
+ - **Plan first for anything non-trivial** (3+ steps or a design decision): outline the approach and the files you'll touch, and share it before implementing. Skip the ceremony for small, obvious fixes.
2573
+ - **Ground every claim in reality** \u2014 the actual code, tests, or output, never guesswork. If you are unsure, say so and verify.
2574
+ - **Ask when intent is genuinely ambiguous** \u2014 one sharp question. At a real fork, give a recommendation, not a survey of every option.
2575
+ - **Stay in scope.** Solve what was asked; no "while I'm here" refactors or speculative abstractions. Note unrelated issues instead of acting on them.
2576
+ - **Favor the simplest solution that fully solves the problem.** Fix root causes, not symptoms \u2014 no temporary patches and no defensive code for cases that can't happen.
2577
+ - **Verify your work and show the evidence** \u2014 run the project's tests, linters, and build, and read the output. "It runs" is not "it's done."
2578
+ - **Match the project's existing style, structure, and conventions.** Comment only the non-obvious WHY, briefly \u2014 don't narrate the code.
2579
+ - **Stop when stuck.** If the same fix fails twice, step back and reconsider the approach rather than repeating variations.
2580
+
2581
+ ## Safety
2582
+ - **Never expose or exfiltrate** secrets, credentials, tokens, or customer data, and never print a credential's value.
2583
+ - **Treat destructive or irreversible actions as needing explicit confirmation** \u2014 force-push, history rewrite, bulk deletes, hard resets, dropping data. Don't run them unprompted.
2584
+ - **Don't push to a shared/default branch or make outward-facing changes** unless the user asked for it.
2585
+ - **Report honestly when you finish**: what you changed, what you verified, and anything you could not.`;
2586
+ var AGENT_STANDARD_BLOCK = `${AGENT_STANDARD_MARKER}
2587
+ ${AGENT_STANDARD_TEXT}
2588
+ ${AGENT_STANDARD_MARKER}`;
2589
+
2590
+ // ../../packages/shared/src/guardrails/index.ts
2591
+ var GUARDRAIL_CATEGORIES = [
2592
+ "secretRead",
2593
+ "destructiveShell",
2594
+ "protectedBranch",
2595
+ "outwardIrreversible"
2596
+ ];
2597
+ var DEFAULT_GUARDRAIL_POLICY = {
2598
+ secretRead: "confirm",
2599
+ destructiveShell: "confirm",
2600
+ protectedBranch: "confirm",
2601
+ outwardIrreversible: "confirm"
2602
+ };
2603
+ var GUARDRAIL_CATEGORY_META = {
2604
+ secretRead: {
2605
+ id: "secretRead",
2606
+ label: "Reading secrets",
2607
+ description: "Reading .env, key, or credential files."
2608
+ },
2609
+ destructiveShell: {
2610
+ id: "destructiveShell",
2611
+ label: "Destructive commands",
2612
+ description: "Bulk deletes, hard resets, and other irreversible shell actions."
2613
+ },
2614
+ protectedBranch: {
2615
+ id: "protectedBranch",
2616
+ label: "Protected branches",
2617
+ description: "Committing or pushing to a shared branch (main, master, release)."
2618
+ },
2619
+ outwardIrreversible: {
2620
+ id: "outwardIrreversible",
2621
+ label: "Outward & irreversible",
2622
+ description: "Force-push, publish, deploy, or send \u2014 hard to undo."
2623
+ }
2624
+ };
2625
+ function isGuardrailDisposition(x) {
2626
+ return x === "deny" || x === "confirm" || x === "off";
2627
+ }
2628
+ function normalizeGuardrailPolicy(raw) {
2629
+ const src = raw && typeof raw === "object" ? raw : {};
2630
+ const out2 = {};
2631
+ for (const cat of GUARDRAIL_CATEGORIES) {
2632
+ const v = src[cat];
2633
+ out2[cat] = isGuardrailDisposition(v) ? v : DEFAULT_GUARDRAIL_POLICY[cat];
2634
+ }
2635
+ return out2;
2636
+ }
2637
+
2564
2638
  // ../../packages/shared/src/api-url.ts
2565
2639
  var DEFAULT_API_BASE_URL = "https://api.codeagent-mobile.com";
2566
2640
  var DEV_API_BASE_URL = "https://dev-api.codeagent-mobile.com";
@@ -2898,11 +2972,11 @@ function quiet(fn) {
2898
2972
  log.debug(TAG, "ignored sync error", err);
2899
2973
  }
2900
2974
  }
2901
- function rmIfExistsQuiet(path85) {
2975
+ function rmIfExistsQuiet(path87) {
2902
2976
  try {
2903
- fs2.rmSync(path85, { force: true });
2977
+ fs2.rmSync(path87, { force: true });
2904
2978
  } catch (err) {
2905
- log.debug(TAG, `rmIfExists failed for ${path85}`, err);
2979
+ log.debug(TAG, `rmIfExists failed for ${path87}`, err);
2906
2980
  }
2907
2981
  }
2908
2982
  function killQuiet(target, signal = "SIGTERM") {
@@ -3048,9 +3122,9 @@ var _default = makeConfig();
3048
3122
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, clearAll, saveCliConfig, loadCliConfig } = _default;
3049
3123
 
3050
3124
  // src/commands/pair-auto.ts
3051
- var fs62 = __toESM(require("fs"));
3052
- var os50 = __toESM(require("os"));
3053
- var path66 = __toESM(require("path"));
3125
+ var fs63 = __toESM(require("fs"));
3126
+ var os51 = __toESM(require("os"));
3127
+ var path67 = __toESM(require("path"));
3054
3128
  var import_crypto4 = require("crypto");
3055
3129
 
3056
3130
  // src/services/telemetry.service.ts
@@ -3086,8 +3160,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? (0, import_pat
3086
3160
  return decodedFile;
3087
3161
  };
3088
3162
  }
3089
- function normalizeWindowsPath(path85) {
3090
- return path85.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3163
+ function normalizeWindowsPath(path87) {
3164
+ return path87.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
3091
3165
  }
3092
3166
 
3093
3167
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -5567,9 +5641,9 @@ async function addSourceContext(frames) {
5567
5641
  LRU_FILE_CONTENTS_CACHE.reduce();
5568
5642
  return frames;
5569
5643
  }
5570
- function getContextLinesFromFile(path85, ranges, output) {
5644
+ function getContextLinesFromFile(path87, ranges, output) {
5571
5645
  return new Promise((resolve9) => {
5572
- const stream = (0, import_node_fs.createReadStream)(path85);
5646
+ const stream = (0, import_node_fs.createReadStream)(path87);
5573
5647
  const lineReaded = (0, import_node_readline.createInterface)({
5574
5648
  input: stream
5575
5649
  });
@@ -5584,7 +5658,7 @@ function getContextLinesFromFile(path85, ranges, output) {
5584
5658
  let rangeStart = range[0];
5585
5659
  let rangeEnd = range[1];
5586
5660
  function onStreamError() {
5587
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path85, 1);
5661
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path87, 1);
5588
5662
  lineReaded.close();
5589
5663
  lineReaded.removeAllListeners();
5590
5664
  destroyStreamAndResolve();
@@ -5645,8 +5719,8 @@ function clearLineContext(frame) {
5645
5719
  delete frame.context_line;
5646
5720
  delete frame.post_context;
5647
5721
  }
5648
- function shouldSkipContextLinesForFile(path85) {
5649
- return path85.startsWith("node:") || path85.endsWith(".min.js") || path85.endsWith(".min.cjs") || path85.endsWith(".min.mjs") || path85.startsWith("data:");
5722
+ function shouldSkipContextLinesForFile(path87) {
5723
+ return path87.startsWith("node:") || path87.endsWith(".min.js") || path87.endsWith(".min.cjs") || path87.endsWith(".min.mjs") || path87.startsWith("data:");
5650
5724
  }
5651
5725
  function shouldSkipContextLinesForFrame(frame) {
5652
5726
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -5664,19 +5738,19 @@ function makeLineReaderRanges(lines) {
5664
5738
  let i = 0;
5665
5739
  const line = lines[0];
5666
5740
  if ("number" != typeof line) return [];
5667
- let current = makeContextRange(line);
5741
+ let current2 = makeContextRange(line);
5668
5742
  const out2 = [];
5669
5743
  while (true) {
5670
5744
  if (i === lines.length - 1) {
5671
- out2.push(current);
5745
+ out2.push(current2);
5672
5746
  break;
5673
5747
  }
5674
5748
  const next = lines[i + 1];
5675
5749
  if ("number" != typeof next) break;
5676
- if (next <= current[1]) current[1] = next + DEFAULT_LINES_OF_CONTEXT;
5750
+ if (next <= current2[1]) current2[1] = next + DEFAULT_LINES_OF_CONTEXT;
5677
5751
  else {
5678
- out2.push(current);
5679
- current = makeContextRange(next);
5752
+ out2.push(current2);
5753
+ current2 = makeContextRange(next);
5680
5754
  }
5681
5755
  i++;
5682
5756
  }
@@ -7673,12 +7747,12 @@ var PostHogContext = class {
7673
7747
  }
7674
7748
  resolve(context, options) {
7675
7749
  if (options?.fresh === true) return context;
7676
- const current = this.get() || {};
7750
+ const current2 = this.get() || {};
7677
7751
  return {
7678
- distinctId: context.distinctId ?? current.distinctId,
7679
- sessionId: context.sessionId ?? current.sessionId,
7752
+ distinctId: context.distinctId ?? current2.distinctId,
7753
+ sessionId: context.sessionId ?? current2.sessionId,
7680
7754
  properties: {
7681
- ...current.properties || {},
7755
+ ...current2.properties || {},
7682
7756
  ...context.properties || {}
7683
7757
  }
7684
7758
  };
@@ -7800,7 +7874,7 @@ function readAnonId() {
7800
7874
  }
7801
7875
  function superProperties() {
7802
7876
  return {
7803
- cliVersion: true ? "2.61.87" : "0.0.0-dev",
7877
+ cliVersion: true ? "2.61.89" : "0.0.0-dev",
7804
7878
  nodeVersion: process.version,
7805
7879
  platform: process.platform,
7806
7880
  arch: process.arch,
@@ -7981,7 +8055,7 @@ var os4 = __toESM(require("os"));
7981
8055
  // package.json
7982
8056
  var package_default = {
7983
8057
  name: "codeam-cli",
7984
- version: "2.61.87",
8058
+ version: "2.61.89",
7985
8059
  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.",
7986
8060
  type: "commonjs",
7987
8061
  main: "dist/index.js",
@@ -9257,7 +9331,7 @@ var CommandRelayService = class _CommandRelayService {
9257
9331
  // fresh + clear the "CLI update available" banner after a self-update
9258
9332
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9259
9333
  // pair/reconnect). Older backends ignore the extra field.
9260
- ..."2.61.87" ? { ideVersion: "2.61.87" } : {}
9334
+ ..."2.61.89" ? { ideVersion: "2.61.89" } : {}
9261
9335
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9262
9336
  }
9263
9337
  /**
@@ -9342,7 +9416,7 @@ function parseUnifiedDiff(diff) {
9342
9416
  const rawLines = diff.split(/\r?\n/);
9343
9417
  const fileStatus = detectFileStatus(rawLines);
9344
9418
  const hunks = [];
9345
- let current = null;
9419
+ let current2 = null;
9346
9420
  let oldLine = 0;
9347
9421
  let newLine = 0;
9348
9422
  let totalAdded = 0;
@@ -9351,10 +9425,10 @@ function parseUnifiedDiff(diff) {
9351
9425
  if (raw.startsWith("@@")) {
9352
9426
  const match = raw.match(HUNK_HEADER_RE);
9353
9427
  if (!match) continue;
9354
- if (current) hunks.push(current);
9428
+ if (current2) hunks.push(current2);
9355
9429
  oldLine = parseInt(match[1], 10);
9356
9430
  newLine = parseInt(match[2], 10);
9357
- current = {
9431
+ current2 = {
9358
9432
  header: raw,
9359
9433
  lines: [],
9360
9434
  linesAdded: 0,
@@ -9362,30 +9436,30 @@ function parseUnifiedDiff(diff) {
9362
9436
  };
9363
9437
  continue;
9364
9438
  }
9365
- if (current === null) continue;
9439
+ if (current2 === null) continue;
9366
9440
  if (raw.startsWith("\\ No newline")) continue;
9367
9441
  if (raw.startsWith("+")) {
9368
- current.lines.push({ type: "add", lineNumber: newLine, text: raw.slice(1) });
9369
- current.linesAdded += 1;
9442
+ current2.lines.push({ type: "add", lineNumber: newLine, text: raw.slice(1) });
9443
+ current2.linesAdded += 1;
9370
9444
  totalAdded += 1;
9371
9445
  newLine += 1;
9372
9446
  continue;
9373
9447
  }
9374
9448
  if (raw.startsWith("-")) {
9375
- current.lines.push({ type: "remove", lineNumber: oldLine, text: raw.slice(1) });
9376
- current.linesRemoved += 1;
9449
+ current2.lines.push({ type: "remove", lineNumber: oldLine, text: raw.slice(1) });
9450
+ current2.linesRemoved += 1;
9377
9451
  totalRemoved += 1;
9378
9452
  oldLine += 1;
9379
9453
  continue;
9380
9454
  }
9381
9455
  if (raw.startsWith(" ")) {
9382
- current.lines.push({ type: "context", lineNumber: newLine, text: raw.slice(1) });
9456
+ current2.lines.push({ type: "context", lineNumber: newLine, text: raw.slice(1) });
9383
9457
  newLine += 1;
9384
9458
  oldLine += 1;
9385
9459
  continue;
9386
9460
  }
9387
9461
  }
9388
- if (current) hunks.push(current);
9462
+ if (current2) hunks.push(current2);
9389
9463
  return {
9390
9464
  fileStatus,
9391
9465
  hunks,
@@ -9484,10 +9558,10 @@ var WINDOWS_LEGACY_JUNCTIONS = [
9484
9558
  /[\\/]Start Menu([\\/]|$)/i,
9485
9559
  /[\\/]Templates([\\/]|$)/i
9486
9560
  ];
9487
- function isUnsafeWindowsWatchRoot(dir, homedir49) {
9561
+ function isUnsafeWindowsWatchRoot(dir, homedir51) {
9488
9562
  const norm = (p2) => p2.replace(/\//g, "\\").replace(/\\+$/, "").toLowerCase();
9489
9563
  const cwd = norm(dir);
9490
- const home = norm(homedir49);
9564
+ const home = norm(homedir51);
9491
9565
  if (cwd === home) return true;
9492
9566
  if (/^[a-z]:$/.test(cwd)) return true;
9493
9567
  const sysRoots = [
@@ -10631,9 +10705,9 @@ function closeAllTerminals() {
10631
10705
  }
10632
10706
 
10633
10707
  // src/commands/start/handlers.ts
10634
- var fs61 = __toESM(require("fs"));
10635
- var os49 = __toESM(require("os"));
10636
- var path65 = __toESM(require("path"));
10708
+ var fs62 = __toESM(require("fs"));
10709
+ var os50 = __toESM(require("os"));
10710
+ var path66 = __toESM(require("path"));
10637
10711
  var import_crypto3 = require("crypto");
10638
10712
  var import_child_process24 = require("child_process");
10639
10713
 
@@ -14113,10 +14187,10 @@ function buildForPlatform(platform3) {
14113
14187
  var import_node_crypto4 = require("crypto");
14114
14188
 
14115
14189
  // src/agents/claude/resolver.ts
14116
- function buildClaudeLaunch(extraArgs = [], os61 = createOsStrategy()) {
14117
- const found = os61.findInPath("claude") ?? os61.findInPath("claude-code");
14190
+ function buildClaudeLaunch(extraArgs = [], os63 = createOsStrategy()) {
14191
+ const found = os63.findInPath("claude") ?? os63.findInPath("claude-code");
14118
14192
  if (!found) return null;
14119
- return os61.buildLaunch(found, extraArgs);
14193
+ return os63.buildLaunch(found, extraArgs);
14120
14194
  }
14121
14195
 
14122
14196
  // src/agents/claude/installer.ts
@@ -14144,11 +14218,11 @@ function isAvailable() {
14144
14218
  function augmentPath() {
14145
14219
  const dirs = probeInstallDirs();
14146
14220
  const sep7 = path17.delimiter;
14147
- const current = process.env.PATH ?? "";
14148
- const existing = new Set(current.split(sep7).filter(Boolean));
14221
+ const current2 = process.env.PATH ?? "";
14222
+ const existing = new Set(current2.split(sep7).filter(Boolean));
14149
14223
  const additions = dirs.filter((d3) => !existing.has(d3));
14150
14224
  if (additions.length === 0) return;
14151
- process.env.PATH = additions.join(sep7) + sep7 + current;
14225
+ process.env.PATH = additions.join(sep7) + sep7 + current2;
14152
14226
  }
14153
14227
  function runInstaller() {
14154
14228
  const isWindows = process.platform === "win32";
@@ -14706,8 +14780,8 @@ var ClaudeRuntimeStrategy = class {
14706
14780
  meta = getAgent("claude");
14707
14781
  mode = "interactive";
14708
14782
  os;
14709
- constructor(os61) {
14710
- this.os = os61;
14783
+ constructor(os63) {
14784
+ this.os = os63;
14711
14785
  }
14712
14786
  /**
14713
14787
  * Claude Code's react-ink TUI enables bracketed-paste mode at
@@ -15487,8 +15561,8 @@ function codexCredentialLocator() {
15487
15561
  function codexLoginLauncher() {
15488
15562
  return {
15489
15563
  async ensureInstalled() {
15490
- const os61 = createOsStrategy();
15491
- return os61.findInPath("codex") !== null;
15564
+ const os63 = createOsStrategy();
15565
+ return os63.findInPath("codex") !== null;
15492
15566
  },
15493
15567
  launch() {
15494
15568
  return (0, import_node_child_process4.spawn)("codex", ["login"], { stdio: "inherit" });
@@ -15511,8 +15585,8 @@ var CodexRuntimeStrategy = class {
15511
15585
  meta = getAgent("codex");
15512
15586
  mode = "interactive";
15513
15587
  os;
15514
- constructor(os61) {
15515
- this.os = os61;
15588
+ constructor(os63) {
15589
+ this.os = os63;
15516
15590
  }
15517
15591
  async prepareLaunch() {
15518
15592
  let binary = this.os.findInPath("codex");
@@ -15621,12 +15695,12 @@ var CodexRuntimeStrategy = class {
15621
15695
  });
15622
15696
  }
15623
15697
  };
15624
- function resolveNpm(os61) {
15625
- return os61.id === "win32" ? "npm.cmd" : "npm";
15698
+ function resolveNpm(os63) {
15699
+ return os63.id === "win32" ? "npm.cmd" : "npm";
15626
15700
  }
15627
- async function installCodexViaNpm(os61) {
15701
+ async function installCodexViaNpm(os63) {
15628
15702
  return new Promise((resolve9, reject) => {
15629
- const proc = (0, import_node_child_process5.spawn)(resolveNpm(os61), ["install", "-g", "@openai/codex"], {
15703
+ const proc = (0, import_node_child_process5.spawn)(resolveNpm(os63), ["install", "-g", "@openai/codex"], {
15630
15704
  stdio: "inherit"
15631
15705
  });
15632
15706
  proc.on("close", (code) => {
@@ -15643,16 +15717,16 @@ async function installCodexViaNpm(os61) {
15643
15717
  });
15644
15718
  });
15645
15719
  }
15646
- function augmentNpmGlobalBin(os61) {
15720
+ function augmentNpmGlobalBin(os63) {
15647
15721
  try {
15648
- const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os61), ["prefix", "-g"], {
15722
+ const result = (0, import_node_child_process5.spawnSync)(resolveNpm(os63), ["prefix", "-g"], {
15649
15723
  stdio: ["ignore", "pipe", "ignore"]
15650
15724
  });
15651
15725
  if (result.status !== 0) return;
15652
15726
  const prefix = result.stdout.toString().trim();
15653
15727
  if (!prefix) return;
15654
- const binDir = os61.id === "win32" ? prefix : path25.join(prefix, "bin");
15655
- os61.augmentPath([binDir]);
15728
+ const binDir = os63.id === "win32" ? prefix : path25.join(prefix, "bin");
15729
+ os63.augmentPath([binDir]);
15656
15730
  } catch {
15657
15731
  }
15658
15732
  }
@@ -15736,9 +15810,9 @@ var import_node_child_process8 = require("child_process");
15736
15810
  // src/agents/coderabbit/installer.ts
15737
15811
  var import_node_child_process6 = require("child_process");
15738
15812
  var INSTALL_URL = "https://cli.coderabbit.ai/install.sh";
15739
- async function ensureCoderabbitInstalled(os61) {
15740
- if (os61.findInPath("coderabbit")) return true;
15741
- if (os61.id === "win32") {
15813
+ async function ensureCoderabbitInstalled(os63) {
15814
+ if (os63.findInPath("coderabbit")) return true;
15815
+ if (os63.id === "win32") {
15742
15816
  console.error(
15743
15817
  "\n \u2717 CodeRabbit on Windows requires WSL.\n Install the CLI inside your WSL distribution\n (curl -fsSL https://cli.coderabbit.ai/install.sh | sh)\n then re-run `codeam link coderabbit` from WSL.\n"
15744
15818
  );
@@ -15771,8 +15845,8 @@ async function ensureCoderabbitInstalled(os61) {
15771
15845
  proc.on("error", () => finish(false));
15772
15846
  });
15773
15847
  if (!ok) return false;
15774
- os61.augmentPath([`${os61.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
15775
- return os61.findInPath("coderabbit") !== null;
15848
+ os63.augmentPath([`${os63.homeDir()}/.local/bin`, "/opt/homebrew/bin"]);
15849
+ return os63.findInPath("coderabbit") !== null;
15776
15850
  }
15777
15851
 
15778
15852
  // src/agents/coderabbit/link.ts
@@ -15807,10 +15881,10 @@ function coderabbitCredentialLocator() {
15807
15881
  validate: validateNonEmptyCredential
15808
15882
  };
15809
15883
  }
15810
- function coderabbitLoginLauncher(os61) {
15884
+ function coderabbitLoginLauncher(os63) {
15811
15885
  return {
15812
15886
  async ensureInstalled() {
15813
- return ensureCoderabbitInstalled(os61);
15887
+ return ensureCoderabbitInstalled(os63);
15814
15888
  },
15815
15889
  launch() {
15816
15890
  return (0, import_node_child_process7.spawn)("coderabbit", ["auth", "login"], { stdio: "inherit" });
@@ -15866,8 +15940,8 @@ function pickLine(obj) {
15866
15940
  function toHunk(raw, groupSeverity) {
15867
15941
  if (!raw || typeof raw !== "object") return null;
15868
15942
  const o = raw;
15869
- const path85 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
15870
- if (!path85) return null;
15943
+ const path87 = asString(pick(o, ["file_path", "filePath", "file", "path", "filename", "fileName"])) ?? asString(pick(o, ["location"])?.path);
15944
+ if (!path87) return null;
15871
15945
  const message = asString(
15872
15946
  pick(o, [
15873
15947
  "comment",
@@ -15884,7 +15958,7 @@ function toHunk(raw, groupSeverity) {
15884
15958
  const severity = normSeverity(pick(o, ["severity", "level", "priority", "impact"])) ?? normSeverity(groupSeverity);
15885
15959
  const locObj = pick(o, ["location"]) ?? o;
15886
15960
  return {
15887
- path: path85.trim(),
15961
+ path: path87.trim(),
15888
15962
  line: pickLine(o) ?? pickLine(locObj),
15889
15963
  severity,
15890
15964
  message: (title && message ? `${title}: ${message}` : title || message).trim() || "(no message)"
@@ -15967,10 +16041,10 @@ function parsePlain(stdout) {
15967
16041
  for (const line of stdout.split(/\r?\n/)) {
15968
16042
  const m = line.match(HUNK_LINE_RE);
15969
16043
  if (!m) continue;
15970
- const [, path85, lineNo, sevToken, message] = m;
15971
- if (!path85 || !lineNo || !message) continue;
16044
+ const [, path87, lineNo, sevToken, message] = m;
16045
+ if (!path87 || !lineNo || !message) continue;
15972
16046
  hunks.push({
15973
- path: path85.trim(),
16047
+ path: path87.trim(),
15974
16048
  line: Number(lineNo),
15975
16049
  severity: sevToken ? SEVERITY_MAP[sevToken.toLowerCase()] : void 0,
15976
16050
  message: message.trim().replace(/^[*-]\s+/, "")
@@ -16030,8 +16104,8 @@ var CoderabbitRuntimeStrategy = class {
16030
16104
  meta = getAgent("coderabbit");
16031
16105
  mode = "batch";
16032
16106
  os;
16033
- constructor(os61) {
16034
- this.os = os61;
16107
+ constructor(os63) {
16108
+ this.os = os63;
16035
16109
  }
16036
16110
  getDefaultArgs() {
16037
16111
  return ["review", "--agent"];
@@ -16302,10 +16376,10 @@ function cursorCredentialLocator() {
16302
16376
  validate: validateNonEmptyCredential
16303
16377
  };
16304
16378
  }
16305
- function cursorLoginLauncher(os61) {
16379
+ function cursorLoginLauncher(os63) {
16306
16380
  return {
16307
16381
  async ensureInstalled() {
16308
- if (os61.findInPath("cursor-agent")) return true;
16382
+ if (os63.findInPath("cursor-agent")) return true;
16309
16383
  console.error(
16310
16384
  "\n \u2717 cursor-agent binary not on PATH.\n Install Cursor (https://cursor.com/) and ensure the CLI\n plugin is enabled, then re-run `codeam link cursor`.\n"
16311
16385
  );
@@ -16369,8 +16443,8 @@ var CursorRuntimeStrategy = class {
16369
16443
  meta = getAgent("cursor");
16370
16444
  mode = "interactive";
16371
16445
  os;
16372
- constructor(os61) {
16373
- this.os = os61;
16446
+ constructor(os63) {
16447
+ this.os = os63;
16374
16448
  }
16375
16449
  async prepareLaunch() {
16376
16450
  const binary = this.os.findInPath("cursor-agent");
@@ -16586,10 +16660,10 @@ function aiderCredentialLocator() {
16586
16660
  validate: validateNonEmptyCredential
16587
16661
  };
16588
16662
  }
16589
- function aiderLoginLauncher(os61) {
16663
+ function aiderLoginLauncher(os63) {
16590
16664
  return {
16591
16665
  async ensureInstalled() {
16592
- if (os61.findInPath("aider")) return true;
16666
+ if (os63.findInPath("aider")) return true;
16593
16667
  console.error(
16594
16668
  "\n \u2717 aider binary not on PATH.\n Install Aider:\n pip install aider-chat\n then re-run `codeam link aider`.\n"
16595
16669
  );
@@ -16599,7 +16673,7 @@ function aiderLoginLauncher(os61) {
16599
16673
  console.error(
16600
16674
  "\n Aider has no interactive login flow.\n Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your shell,\n or re-run `codeam link aider --api-key=<your-key>`.\n"
16601
16675
  );
16602
- return (0, import_node_child_process11.spawn)(os61.id === "win32" ? "cmd.exe" : "sh", os61.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
16676
+ return (0, import_node_child_process11.spawn)(os63.id === "win32" ? "cmd.exe" : "sh", os63.id === "win32" ? ["/c", "exit", "0"] : ["-c", "exit 0"], {
16603
16677
  stdio: "ignore"
16604
16678
  });
16605
16679
  }
@@ -16671,8 +16745,8 @@ var AiderRuntimeStrategy = class {
16671
16745
  meta = getAgent("aider");
16672
16746
  mode = "interactive";
16673
16747
  os;
16674
- constructor(os61) {
16675
- this.os = os61;
16748
+ constructor(os63) {
16749
+ this.os = os63;
16676
16750
  }
16677
16751
  async prepareLaunch() {
16678
16752
  const binary = this.os.findInPath("aider");
@@ -16804,8 +16878,8 @@ function geminiCredentialLocator() {
16804
16878
  function geminiLoginLauncher() {
16805
16879
  return {
16806
16880
  async ensureInstalled() {
16807
- const os61 = createOsStrategy();
16808
- return os61.findInPath("gemini") !== null;
16881
+ const os63 = createOsStrategy();
16882
+ return os63.findInPath("gemini") !== null;
16809
16883
  },
16810
16884
  launch() {
16811
16885
  return (0, import_node_child_process12.spawn)("gemini", ["auth", "login"], { stdio: "inherit" });
@@ -16995,8 +17069,8 @@ var GeminiRuntimeStrategy = class {
16995
17069
  meta = getAgent("gemini");
16996
17070
  mode = "interactive";
16997
17071
  os;
16998
- constructor(os61) {
16999
- this.os = os61;
17072
+ constructor(os63) {
17073
+ this.os = os63;
17000
17074
  }
17001
17075
  async prepareLaunch() {
17002
17076
  const binary = this.os.findInPath("gemini");
@@ -17287,8 +17361,8 @@ var KimiRuntimeStrategy = class {
17287
17361
  meta = getAgent("kimi");
17288
17362
  mode = "interactive";
17289
17363
  os;
17290
- constructor(os61) {
17291
- this.os = os61;
17364
+ constructor(os63) {
17365
+ this.os = os63;
17292
17366
  }
17293
17367
  async prepareLaunch() {
17294
17368
  const binary = this.os.findInPath("kimi");
@@ -17430,8 +17504,8 @@ var OpencodeRuntimeStrategy = class {
17430
17504
  meta = getAgent("opencode");
17431
17505
  mode = "interactive";
17432
17506
  os;
17433
- constructor(os61) {
17434
- this.os = os61;
17507
+ constructor(os63) {
17508
+ this.os = os63;
17435
17509
  }
17436
17510
  async prepareLaunch() {
17437
17511
  const binary = this.os.findInPath("opencode");
@@ -17515,20 +17589,20 @@ var OpencodeRuntimeStrategy = class {
17515
17589
 
17516
17590
  // src/agents/registry.ts
17517
17591
  var runtimeBuilders = {
17518
- claude: (os61) => new ClaudeRuntimeStrategy(os61),
17519
- codex: (os61) => new CodexRuntimeStrategy(os61),
17520
- coderabbit: (os61) => new CoderabbitRuntimeStrategy(os61),
17521
- cursor: (os61) => new CursorRuntimeStrategy(os61),
17522
- aider: (os61) => new AiderRuntimeStrategy(os61),
17523
- gemini: (os61) => new GeminiRuntimeStrategy(os61),
17524
- kimi: (os61) => new KimiRuntimeStrategy(os61),
17525
- opencode: (os61) => new OpencodeRuntimeStrategy(os61)
17592
+ claude: (os63) => new ClaudeRuntimeStrategy(os63),
17593
+ codex: (os63) => new CodexRuntimeStrategy(os63),
17594
+ coderabbit: (os63) => new CoderabbitRuntimeStrategy(os63),
17595
+ cursor: (os63) => new CursorRuntimeStrategy(os63),
17596
+ aider: (os63) => new AiderRuntimeStrategy(os63),
17597
+ gemini: (os63) => new GeminiRuntimeStrategy(os63),
17598
+ kimi: (os63) => new KimiRuntimeStrategy(os63),
17599
+ opencode: (os63) => new OpencodeRuntimeStrategy(os63)
17526
17600
  };
17527
17601
  var deployBuilders = {
17528
17602
  claude: () => new ClaudeDeployStrategy(),
17529
17603
  codex: () => new CodexDeployStrategy()
17530
17604
  };
17531
- function createAgentStrategy(agent, os61 = createOsStrategy()) {
17605
+ function createAgentStrategy(agent, os63 = createOsStrategy()) {
17532
17606
  if (!AGENT_REGISTRY[agent]?.enabled) {
17533
17607
  throw new Error(
17534
17608
  `Agent "${agent}" is not supported in this codeam-cli version. Upgrade with 'npm i -g codeam-cli@latest'.`
@@ -17538,10 +17612,10 @@ function createAgentStrategy(agent, os61 = createOsStrategy()) {
17538
17612
  if (!build) {
17539
17613
  throw new Error(`No runtime strategy registered for agent "${agent}"`);
17540
17614
  }
17541
- return build(os61);
17615
+ return build(os63);
17542
17616
  }
17543
- function createInteractiveAgentStrategy(agent, os61 = createOsStrategy()) {
17544
- const s = createAgentStrategy(agent, os61);
17617
+ function createInteractiveAgentStrategy(agent, os63 = createOsStrategy()) {
17618
+ const s = createAgentStrategy(agent, os63);
17545
17619
  if (s.mode !== "interactive") {
17546
17620
  throw new Error(
17547
17621
  `Agent "${agent}" is a batch agent; use createAgentStrategy + .runOneShot for one-shot reviews.`
@@ -18238,26 +18312,26 @@ function restoreCoderabbitOauthBlob(value) {
18238
18312
  (0, import_node_fs5.writeFileSync)(path37.join(dir, file), contents, { mode: 384 });
18239
18313
  }
18240
18314
  async function configureCoderabbit(input, deps = {}) {
18241
- const os61 = deps.os ?? createOsStrategy();
18315
+ const os63 = deps.os ?? createOsStrategy();
18242
18316
  const ensureInstalled = deps.ensureInstalled ?? ensureCoderabbitInstalled;
18243
18317
  const isLoggedIn = deps.isLoggedIn ?? defaultIsLoggedIn;
18244
18318
  const runOAuth = deps.runOAuthLogin ?? runCoderabbitOAuthLogin;
18245
18319
  const snapshot = deps.snapshotDir ?? (() => snapshotCredentialDir());
18246
18320
  const capture2 = deps.captureCredential ?? ((b) => diffCapturedCredential(b));
18247
18321
  const loginWithApiKey = deps.loginWithApiKey ?? defaultLoginWithApiKey;
18248
- const home = os61.homeDir();
18249
- os61.augmentPath(
18250
- os61.id === "win32" ? [
18322
+ const home = os63.homeDir();
18323
+ os63.augmentPath(
18324
+ os63.id === "win32" ? [
18251
18325
  path37.join(home, ".local", "bin"),
18252
18326
  path37.join(process.env.APPDATA ?? path37.join(home, "AppData", "Roaming"), "npm"),
18253
18327
  path37.join(home, "scoop", "shims")
18254
18328
  ] : [path37.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
18255
18329
  );
18256
- const installed2 = os61.findInPath("coderabbit") !== null;
18330
+ const installed2 = os63.findInPath("coderabbit") !== null;
18257
18331
  const base = () => ({
18258
18332
  action: input.action,
18259
18333
  supported: true,
18260
- installed: os61.findInPath("coderabbit") !== null,
18334
+ installed: os63.findInPath("coderabbit") !== null,
18261
18335
  loggedIn: false
18262
18336
  });
18263
18337
  if (input.action === "status") {
@@ -18271,7 +18345,7 @@ async function configureCoderabbit(input, deps = {}) {
18271
18345
  const key = (input.apiKey ?? "").trim();
18272
18346
  if (!key) return { ...res2, error: "No API key provided" };
18273
18347
  if (!res2.installed) {
18274
- const ok = await ensureInstalled(os61);
18348
+ const ok = await ensureInstalled(os63);
18275
18349
  res2.installed = ok;
18276
18350
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
18277
18351
  }
@@ -18295,7 +18369,7 @@ async function configureCoderabbit(input, deps = {}) {
18295
18369
  }
18296
18370
  if (!res2.installed) {
18297
18371
  deps.onEvent?.({ kind: "installing" });
18298
- const ok = await ensureInstalled(os61);
18372
+ const ok = await ensureInstalled(os63);
18299
18373
  res2.installed = ok;
18300
18374
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
18301
18375
  }
@@ -18325,7 +18399,7 @@ async function configureCoderabbit(input, deps = {}) {
18325
18399
  const res2 = base();
18326
18400
  if (!installed2) {
18327
18401
  deps.onEvent?.({ kind: "installing" });
18328
- const ok = await ensureInstalled(os61);
18402
+ const ok = await ensureInstalled(os63);
18329
18403
  res2.installed = ok;
18330
18404
  if (!ok) return { ...res2, error: "CodeRabbit CLI could not be installed" };
18331
18405
  }
@@ -18365,7 +18439,7 @@ async function configureCoderabbit(input, deps = {}) {
18365
18439
  }
18366
18440
  const res = base();
18367
18441
  if (!res.installed) {
18368
- const ok = await ensureInstalled(os61);
18442
+ const ok = await ensureInstalled(os63);
18369
18443
  res.installed = ok;
18370
18444
  if (!ok) return { ...res, error: "CodeRabbit CLI is not installed" };
18371
18445
  }
@@ -18719,16 +18793,16 @@ var MetricsCollector = class {
18719
18793
  this.lastLatencyMs = Math.max(0, Math.round(latencyMs));
18720
18794
  }
18721
18795
  cpuPct() {
18722
- const current = sampleCpuTimes();
18796
+ const current2 = sampleCpuTimes();
18723
18797
  const prev = this.prevCpu;
18724
- this.prevCpu = current;
18798
+ this.prevCpu = current2;
18725
18799
  if (!prev) {
18726
18800
  const cores = os31.cpus().length || 1;
18727
18801
  const proxy = os31.loadavg()[0] / cores * 100;
18728
18802
  return Math.min(100, Math.max(0, Math.round(proxy)));
18729
18803
  }
18730
- const idleDelta = current.idle - prev.idle;
18731
- const totalDelta = current.total - prev.total;
18804
+ const idleDelta = current2.idle - prev.idle;
18805
+ const totalDelta = current2.total - prev.total;
18732
18806
  if (totalDelta <= 0) return 0;
18733
18807
  const busy = (1 - idleDelta / totalDelta) * 100;
18734
18808
  return Math.min(100, Math.max(0, Math.round(busy)));
@@ -20430,8 +20504,8 @@ async function autoUpgradeBeforeCriticalCommand() {
20430
20504
  if (process.env.NODE_ENV === "test") return;
20431
20505
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20432
20506
  if (process.env.CI) return;
20433
- const current = true ? "2.61.87" : null;
20434
- if (!current) return;
20507
+ const current2 = true ? "2.61.89" : null;
20508
+ if (!current2) return;
20435
20509
  const cache = readCache();
20436
20510
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
20437
20511
  let latest = fresh && cache ? cache.latest : null;
@@ -20440,19 +20514,19 @@ async function autoUpgradeBeforeCriticalCommand() {
20440
20514
  if (latest) writeCache({ fetchedAt: Date.now(), latest });
20441
20515
  }
20442
20516
  if (!latest) return;
20443
- maybeAutoUpdate(current, latest);
20517
+ maybeAutoUpdate(current2, latest);
20444
20518
  }
20445
20519
  function checkForUpdates() {
20446
20520
  if (process.env.NODE_ENV === "test") return;
20447
20521
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
20448
20522
  if (process.env.CI) return;
20449
20523
  if (!process.stdout.isTTY) return;
20450
- const current = true ? "2.61.87" : null;
20451
- if (!current) return;
20524
+ const current2 = true ? "2.61.89" : null;
20525
+ if (!current2) return;
20452
20526
  const cache = readCache();
20453
20527
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
20454
20528
  if (fresh && cache) {
20455
- maybeAutoUpdate(current, cache.latest);
20529
+ maybeAutoUpdate(current2, cache.latest);
20456
20530
  return;
20457
20531
  }
20458
20532
  void fetchLatest().then((latest) => {
@@ -20467,7 +20541,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
20467
20541
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
20468
20542
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
20469
20543
  function currentCliVersion() {
20470
- return true ? "2.61.87" : null;
20544
+ return true ? "2.61.89" : null;
20471
20545
  }
20472
20546
  function runCmd(cmd, args2, timeoutMs) {
20473
20547
  return new Promise((resolve9) => {
@@ -20479,8 +20553,8 @@ function runCmd(cmd, args2, timeoutMs) {
20479
20553
  }
20480
20554
  async function runSelfUpdate() {
20481
20555
  try {
20482
- const current = currentCliVersion();
20483
- if (!current) {
20556
+ const current2 = currentCliVersion();
20557
+ if (!current2) {
20484
20558
  log.trace("host-agent", "self-update: no __CLI_VERSION__ \u2014 skipping");
20485
20559
  return { status: "skipped" };
20486
20560
  }
@@ -20498,10 +20572,10 @@ async function runSelfUpdate() {
20498
20572
  log.trace("host-agent", "self-update: empty npm view output \u2014 skipping");
20499
20573
  return { status: "skipped" };
20500
20574
  }
20501
- if (compareSemver(latest, current) <= 0) {
20575
+ if (compareSemver(latest, current2) <= 0) {
20502
20576
  return { status: "current" };
20503
20577
  }
20504
- log.info("host-agent", `self-update: ${current} \u2192 ${latest} available \u2014 installing`);
20578
+ log.info("host-agent", `self-update: ${current2} \u2192 ${latest} available \u2014 installing`);
20505
20579
  const installArgs = ["install", "-g", `${SELF_UPDATE_PKG}@latest`];
20506
20580
  let install = await runCmd("npm", installArgs, SELF_UPDATE_INSTALL_TIMEOUT_MS);
20507
20581
  const isRoot = process.getuid?.() === 0;
@@ -20512,7 +20586,7 @@ async function runSelfUpdate() {
20512
20586
  if (install.code !== 0) {
20513
20587
  log.warn(
20514
20588
  "host-agent",
20515
- `self-update: install exited ${String(install.code)} \u2014 staying on ${current}`
20589
+ `self-update: install exited ${String(install.code)} \u2014 staying on ${current2}`
20516
20590
  );
20517
20591
  return { status: "skipped" };
20518
20592
  }
@@ -22069,17 +22143,48 @@ function makeRealApplyBudgetDeps() {
22069
22143
  };
22070
22144
  }
22071
22145
 
22072
- // src/services/preview/port-registry.ts
22146
+ // src/agents/acp/guardrail-config.ts
22073
22147
  var fs47 = __toESM(require("fs"));
22074
- var os41 = __toESM(require("os"));
22075
22148
  var path50 = __toESM(require("path"));
22149
+ var os41 = __toESM(require("os"));
22150
+ var current = null;
22151
+ function guardrailConfigPath(homeDir2 = os41.homedir()) {
22152
+ return path50.join(homeDir2, ".codeam", "guardrails.json");
22153
+ }
22154
+ function loadGuardrailPolicy(homeDir2 = os41.homedir()) {
22155
+ try {
22156
+ current = normalizeGuardrailPolicy(JSON.parse(fs47.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
22157
+ } catch {
22158
+ current = { ...DEFAULT_GUARDRAIL_POLICY };
22159
+ }
22160
+ return current;
22161
+ }
22162
+ function getGuardrailPolicy(homeDir2 = os41.homedir()) {
22163
+ return current ?? loadGuardrailPolicy(homeDir2);
22164
+ }
22165
+ function setGuardrailPolicy(raw, homeDir2 = os41.homedir()) {
22166
+ const next = normalizeGuardrailPolicy(raw);
22167
+ current = next;
22168
+ try {
22169
+ const p2 = guardrailConfigPath(homeDir2);
22170
+ fs47.mkdirSync(path50.dirname(p2), { recursive: true });
22171
+ fs47.writeFileSync(p2, JSON.stringify(next, null, 2));
22172
+ } catch {
22173
+ }
22174
+ return next;
22175
+ }
22176
+
22177
+ // src/services/preview/port-registry.ts
22178
+ var fs48 = __toESM(require("fs"));
22179
+ var os42 = __toESM(require("os"));
22180
+ var path51 = __toESM(require("path"));
22076
22181
  var import_child_process14 = require("child_process");
22077
22182
  function registryPath() {
22078
- return path50.join(os41.homedir(), ".codeam", "preview-ports.json");
22183
+ return path51.join(os42.homedir(), ".codeam", "preview-ports.json");
22079
22184
  }
22080
22185
  function readRegistry() {
22081
22186
  try {
22082
- const raw = fs47.readFileSync(registryPath(), "utf8");
22187
+ const raw = fs48.readFileSync(registryPath(), "utf8");
22083
22188
  const parsed = JSON.parse(raw);
22084
22189
  if (parsed && typeof parsed === "object") return parsed;
22085
22190
  } catch {
@@ -22089,10 +22194,10 @@ function readRegistry() {
22089
22194
  function writeRegistry(reg) {
22090
22195
  try {
22091
22196
  const file = registryPath();
22092
- fs47.mkdirSync(path50.dirname(file), { recursive: true });
22197
+ fs48.mkdirSync(path51.dirname(file), { recursive: true });
22093
22198
  const tmp = `${file}.tmp`;
22094
- fs47.writeFileSync(tmp, JSON.stringify(reg), "utf8");
22095
- fs47.renameSync(tmp, file);
22199
+ fs48.writeFileSync(tmp, JSON.stringify(reg), "utf8");
22200
+ fs48.renameSync(tmp, file);
22096
22201
  } catch (err) {
22097
22202
  log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
22098
22203
  }
@@ -22158,7 +22263,7 @@ function reclaimOwnOrphanPort(port) {
22158
22263
 
22159
22264
  // src/services/preview/host-allow.ts
22160
22265
  var import_fs = require("fs");
22161
- var path51 = __toESM(require("path"));
22266
+ var path52 = __toESM(require("path"));
22162
22267
  var NEXT_ALLOWED_ORIGINS = [
22163
22268
  "*.trycloudflare.com",
22164
22269
  "*.preview.codeagent-mobile.com",
@@ -22178,7 +22283,7 @@ var MARKER_DIR = ".codeam";
22178
22283
  var MARKER_FILE = "preview-host-allow.json";
22179
22284
  var ORIG_INFIX = ".codeam-orig";
22180
22285
  function markerPath(cwd) {
22181
- return path51.join(cwd, MARKER_DIR, MARKER_FILE);
22286
+ return path52.join(cwd, MARKER_DIR, MARKER_FILE);
22182
22287
  }
22183
22288
  async function fileExists(p2) {
22184
22289
  try {
@@ -22191,13 +22296,13 @@ async function fileExists(p2) {
22191
22296
  async function findConfigFile(cwd, framework) {
22192
22297
  const base = CONFIG_BASENAMES[framework];
22193
22298
  for (const ext of CONFIG_EXTS) {
22194
- if (await fileExists(path51.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
22299
+ if (await fileExists(path52.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
22195
22300
  }
22196
22301
  return null;
22197
22302
  }
22198
22303
  async function dependsOn(cwd, pkgName) {
22199
22304
  try {
22200
- const raw = await import_fs.promises.readFile(path51.join(cwd, "package.json"), "utf8");
22305
+ const raw = await import_fs.promises.readFile(path52.join(cwd, "package.json"), "utf8");
22201
22306
  const pkg = JSON.parse(raw);
22202
22307
  return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
22203
22308
  } catch {
@@ -22205,11 +22310,11 @@ async function dependsOn(cwd, pkgName) {
22205
22310
  }
22206
22311
  }
22207
22312
  async function isEsmConfig(cwd, configFile) {
22208
- const ext = path51.extname(configFile);
22313
+ const ext = path52.extname(configFile);
22209
22314
  if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
22210
22315
  if (ext === ".cjs") return false;
22211
22316
  try {
22212
- const raw = await import_fs.promises.readFile(path51.join(cwd, "package.json"), "utf8");
22317
+ const raw = await import_fs.promises.readFile(path52.join(cwd, "package.json"), "utf8");
22213
22318
  return JSON.parse(raw).type === "module";
22214
22319
  } catch {
22215
22320
  return false;
@@ -22292,7 +22397,7 @@ function shimFor(framework, origBasename, esm) {
22292
22397
  return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
22293
22398
  }
22294
22399
  async function writeMarker(cwd, marker) {
22295
- await import_fs.promises.mkdir(path51.join(cwd, MARKER_DIR), { recursive: true });
22400
+ await import_fs.promises.mkdir(path52.join(cwd, MARKER_DIR), { recursive: true });
22296
22401
  await import_fs.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
22297
22402
  }
22298
22403
  async function readMarker(cwd) {
@@ -22307,9 +22412,9 @@ async function restorePreviewHostAllow(cwd) {
22307
22412
  const marker = await readMarker(cwd);
22308
22413
  if (!marker) return;
22309
22414
  try {
22310
- const configAbs = path51.join(cwd, marker.configFile);
22415
+ const configAbs = path52.join(cwd, marker.configFile);
22311
22416
  if (marker.backupFile) {
22312
- const backupAbs = path51.join(cwd, marker.backupFile);
22417
+ const backupAbs = path52.join(cwd, marker.backupFile);
22313
22418
  if (await fileExists(backupAbs)) {
22314
22419
  await import_fs.promises.rm(configAbs, { force: true });
22315
22420
  await import_fs.promises.rename(backupAbs, configAbs);
@@ -22342,16 +22447,16 @@ async function applyPreviewHostAllow(cwd) {
22342
22447
  }
22343
22448
  if (!framework) return;
22344
22449
  if (existing) {
22345
- const ext = path51.extname(existing);
22450
+ const ext = path52.extname(existing);
22346
22451
  const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
22347
22452
  const esm = await isEsmConfig(cwd, existing);
22348
- await import_fs.promises.rename(path51.join(cwd, existing), path51.join(cwd, origBasename));
22349
- await import_fs.promises.writeFile(path51.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
22453
+ await import_fs.promises.rename(path52.join(cwd, existing), path52.join(cwd, origBasename));
22454
+ await import_fs.promises.writeFile(path52.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
22350
22455
  await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
22351
22456
  log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
22352
22457
  } else {
22353
22458
  const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
22354
- await import_fs.promises.writeFile(path51.join(cwd, configFile), shimFor(framework, null, true), "utf8");
22459
+ await import_fs.promises.writeFile(path52.join(cwd, configFile), shimFor(framework, null, true), "utf8");
22355
22460
  await writeMarker(cwd, { framework, configFile, backupFile: null });
22356
22461
  log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
22357
22462
  }
@@ -23033,19 +23138,19 @@ function activePreviewSessionIds() {
23033
23138
 
23034
23139
  // src/services/preview/start-orchestrator.ts
23035
23140
  var import_child_process19 = require("child_process");
23036
- var fs55 = __toESM(require("fs"));
23037
- var path58 = __toESM(require("path"));
23141
+ var fs56 = __toESM(require("fs"));
23142
+ var path59 = __toESM(require("path"));
23038
23143
  var import_which2 = __toESM(require("which"));
23039
23144
 
23040
23145
  // src/services/project-env/index.ts
23041
23146
  var import_fs5 = require("fs");
23042
- var path57 = __toESM(require("path"));
23147
+ var path58 = __toESM(require("path"));
23043
23148
 
23044
23149
  // src/beads/project-key.ts
23045
23150
  var import_child_process18 = require("child_process");
23046
23151
  var crypto2 = __toESM(require("crypto"));
23047
- var fs53 = __toESM(require("fs"));
23048
- var path56 = __toESM(require("path"));
23152
+ var fs54 = __toESM(require("fs"));
23153
+ var path57 = __toESM(require("path"));
23049
23154
  function normalizeOrigin(raw) {
23050
23155
  const trimmed = raw.trim();
23051
23156
  if (!trimmed) return null;
@@ -23071,17 +23176,17 @@ function normalizeOrigin(raw) {
23071
23176
  return `${host2}/${pathPart}`;
23072
23177
  }
23073
23178
  function findRepoRoot(cwd) {
23074
- let dir = path56.resolve(cwd);
23179
+ let dir = path57.resolve(cwd);
23075
23180
  const seen = /* @__PURE__ */ new Set();
23076
23181
  for (let i = 0; i < 256; i++) {
23077
23182
  if (seen.has(dir)) return null;
23078
23183
  seen.add(dir);
23079
23184
  try {
23080
- const stat3 = fs53.statSync(path56.join(dir, ".git"), { throwIfNoEntry: false });
23185
+ const stat3 = fs54.statSync(path57.join(dir, ".git"), { throwIfNoEntry: false });
23081
23186
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
23082
23187
  } catch {
23083
23188
  }
23084
- const parent = path56.dirname(dir);
23189
+ const parent = path57.dirname(dir);
23085
23190
  if (parent === dir) return null;
23086
23191
  dir = parent;
23087
23192
  }
@@ -23092,7 +23197,7 @@ var _execSeam2 = {
23092
23197
  const out2 = (0, import_child_process18.execFileSync)(file, args2, opts);
23093
23198
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
23094
23199
  },
23095
- realpath: (p2) => fs53.realpathSync(p2)
23200
+ realpath: (p2) => fs54.realpathSync(p2)
23096
23201
  };
23097
23202
  function readOrigin(cwd) {
23098
23203
  try {
@@ -23121,7 +23226,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
23121
23226
  } catch {
23122
23227
  }
23123
23228
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
23124
- return { projectKey: `path:${hash}`, projectLabel: path56.basename(real) || "project" };
23229
+ return { projectKey: `path:${hash}`, projectLabel: path57.basename(real) || "project" };
23125
23230
  }
23126
23231
 
23127
23232
  // src/services/project-env/index.ts
@@ -23134,7 +23239,7 @@ async function readIfExists(p2) {
23134
23239
  }
23135
23240
  async function syncProjectEnvUp(cwd, ctx) {
23136
23241
  if (!ctx.pluginAuthToken) return;
23137
- const content = await readIfExists(path57.join(cwd, ".env"));
23242
+ const content = await readIfExists(path58.join(cwd, ".env"));
23138
23243
  if (content == null) return;
23139
23244
  try {
23140
23245
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23156,7 +23261,7 @@ async function syncProjectEnvUp(cwd, ctx) {
23156
23261
  }
23157
23262
  async function restoreProjectEnvIfMissing(cwd, ctx) {
23158
23263
  if (!ctx.pluginAuthToken) return false;
23159
- const envPath = path57.join(cwd, ".env");
23264
+ const envPath = path58.join(cwd, ".env");
23160
23265
  if (await readIfExists(envPath) != null) return false;
23161
23266
  try {
23162
23267
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -23167,7 +23272,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
23167
23272
  projectKey
23168
23273
  });
23169
23274
  if (!stored) return false;
23170
- const tmp = path57.join(cwd, ".env.codeam-restore.tmp");
23275
+ const tmp = path58.join(cwd, ".env.codeam-restore.tmp");
23171
23276
  await import_fs5.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
23172
23277
  await import_fs5.promises.rename(tmp, envPath);
23173
23278
  log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
@@ -23244,8 +23349,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
23244
23349
  if (args2.length === 0) return detection;
23245
23350
  const binName = args2[0];
23246
23351
  if (binName.startsWith("-")) return detection;
23247
- const binPath = path58.join(cwd, "node_modules", ".bin", binName);
23248
- if (!fs55.existsSync(binPath)) return detection;
23352
+ const binPath = path59.join(cwd, "node_modules", ".bin", binName);
23353
+ if (!fs56.existsSync(binPath)) return detection;
23249
23354
  return {
23250
23355
  ...detection,
23251
23356
  command: binPath,
@@ -23618,9 +23723,9 @@ async function establishTunnel(ctx, dev) {
23618
23723
 
23619
23724
  // src/beads/bd-adapter.ts
23620
23725
  var import_child_process20 = require("child_process");
23621
- var fs56 = __toESM(require("fs"));
23622
- var os43 = __toESM(require("os"));
23623
- var path59 = __toESM(require("path"));
23726
+ var fs57 = __toESM(require("fs"));
23727
+ var os44 = __toESM(require("os"));
23728
+ var path60 = __toESM(require("path"));
23624
23729
  var BD_PACKAGE = "@beads/bd";
23625
23730
  function resolveBundledBdBinary() {
23626
23731
  return _resolveSeam.resolveBundled();
@@ -23632,11 +23737,11 @@ function _defaultResolveBundled() {
23632
23737
  } catch {
23633
23738
  return null;
23634
23739
  }
23635
- const binDir = path59.join(path59.dirname(pkgJsonPath), "bin");
23740
+ const binDir = path60.join(path60.dirname(pkgJsonPath), "bin");
23636
23741
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
23637
- const binaryPath = path59.join(binDir, binaryName);
23742
+ const binaryPath = path60.join(binDir, binaryName);
23638
23743
  try {
23639
- fs56.accessSync(binaryPath, fs56.constants.F_OK);
23744
+ fs57.accessSync(binaryPath, fs57.constants.F_OK);
23640
23745
  return binaryPath;
23641
23746
  } catch {
23642
23747
  return null;
@@ -23646,13 +23751,13 @@ function resolveBdOnPath() {
23646
23751
  return _resolveSeam.resolveOnPath();
23647
23752
  }
23648
23753
  function _defaultResolveOnPath() {
23649
- const dirs = (process.env.PATH ?? "").split(path59.delimiter).filter(Boolean);
23754
+ const dirs = (process.env.PATH ?? "").split(path60.delimiter).filter(Boolean);
23650
23755
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
23651
23756
  for (const dir of dirs) {
23652
23757
  for (const candidate of candidates) {
23653
- const full = path59.join(dir, candidate);
23758
+ const full = path60.join(dir, candidate);
23654
23759
  try {
23655
- fs56.accessSync(full, fs56.constants.F_OK);
23760
+ fs57.accessSync(full, fs57.constants.F_OK);
23656
23761
  return full;
23657
23762
  } catch {
23658
23763
  }
@@ -23737,7 +23842,7 @@ var BdAdapter = class {
23737
23842
  const env = { ...process.env };
23738
23843
  if (!env.HOME) {
23739
23844
  try {
23740
- const home = os43.homedir();
23845
+ const home = os44.homedir();
23741
23846
  if (home) env.HOME = home;
23742
23847
  } catch {
23743
23848
  }
@@ -23829,9 +23934,9 @@ function coerceIssue(row, projectKey) {
23829
23934
 
23830
23935
  // src/beads/provisioner.ts
23831
23936
  var import_child_process23 = require("child_process");
23832
- var fs58 = __toESM(require("fs"));
23833
- var os45 = __toESM(require("os"));
23834
- var path61 = __toESM(require("path"));
23937
+ var fs59 = __toESM(require("fs"));
23938
+ var os46 = __toESM(require("os"));
23939
+ var path62 = __toESM(require("path"));
23835
23940
 
23836
23941
  // src/beads/install-bd.ts
23837
23942
  var import_child_process21 = require("child_process");
@@ -23896,9 +24001,9 @@ async function installBd(platform3 = process.platform) {
23896
24001
 
23897
24002
  // src/beads/install-dolt.ts
23898
24003
  var import_child_process22 = require("child_process");
23899
- var fs57 = __toESM(require("fs"));
23900
- var os44 = __toESM(require("os"));
23901
- var path60 = __toESM(require("path"));
24004
+ var fs58 = __toESM(require("fs"));
24005
+ var os45 = __toESM(require("os"));
24006
+ var path61 = __toESM(require("path"));
23902
24007
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
23903
24008
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
23904
24009
  function resolveDoltInstallStrategy(platform3) {
@@ -23938,11 +24043,11 @@ function resolveDoltInstallStrategy(platform3) {
23938
24043
  }
23939
24044
  var DOLT_RELEASE_BASE = "https://github.com/dolthub/dolt/releases/latest/download";
23940
24045
  function doltPlatformTuple(platform3, arch2) {
23941
- const os61 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
24046
+ const os63 = platform3 === "win32" ? "windows" : platform3 === "darwin" ? "darwin" : "linux";
23942
24047
  const a = arch2 === "x64" ? "amd64" : arch2 === "arm64" ? "arm64" : null;
23943
24048
  if (!a) return null;
23944
- if (os61 === "windows" && a !== "amd64") return null;
23945
- return `${os61}-${a}`;
24049
+ if (os63 === "windows" && a !== "amd64") return null;
24050
+ return `${os63}-${a}`;
23946
24051
  }
23947
24052
  function resolveDoltTarballStrategy(targetDir, platform3, arch2) {
23948
24053
  const tuple = doltPlatformTuple(platform3, arch2);
@@ -23987,14 +24092,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
23987
24092
  return result;
23988
24093
  }
23989
24094
  var _doltPathSeam = {
23990
- homedir: () => os44.homedir(),
24095
+ homedir: () => os45.homedir(),
23991
24096
  getPath: () => process.env.PATH ?? "",
23992
24097
  setPath: (p2) => {
23993
24098
  process.env.PATH = p2;
23994
24099
  },
23995
24100
  exists: (p2) => {
23996
24101
  try {
23997
- fs57.accessSync(p2, fs57.constants.F_OK);
24102
+ fs58.accessSync(p2, fs58.constants.F_OK);
23998
24103
  return true;
23999
24104
  } catch {
24000
24105
  return false;
@@ -24005,7 +24110,7 @@ function doltBinaryNames(platform3) {
24005
24110
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
24006
24111
  }
24007
24112
  function knownDoltDirs(platform3) {
24008
- const P3 = platform3 === "win32" ? path60.win32 : path60.posix;
24113
+ const P3 = platform3 === "win32" ? path61.win32 : path61.posix;
24009
24114
  const home = _doltPathSeam.homedir();
24010
24115
  if (platform3 === "win32") {
24011
24116
  return [
@@ -24021,7 +24126,7 @@ function knownDoltDirs(platform3) {
24021
24126
  ].filter(Boolean);
24022
24127
  }
24023
24128
  function ensureDoltResolvable(platform3 = process.platform) {
24024
- const P3 = platform3 === "win32" ? path60.win32 : path60.posix;
24129
+ const P3 = platform3 === "win32" ? path61.win32 : path61.posix;
24025
24130
  const delim = platform3 === "win32" ? ";" : ":";
24026
24131
  const names = doltBinaryNames(platform3);
24027
24132
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -24198,17 +24303,17 @@ var _provisionSeam = {
24198
24303
  };
24199
24304
  var _linkSeam = {
24200
24305
  platform: () => process.platform,
24201
- homedir: () => os45.homedir(),
24306
+ homedir: () => os46.homedir(),
24202
24307
  isWritableDir: (dir) => {
24203
24308
  try {
24204
- fs58.accessSync(dir, fs58.constants.W_OK);
24309
+ fs59.accessSync(dir, fs59.constants.W_OK);
24205
24310
  return true;
24206
24311
  } catch {
24207
24312
  return false;
24208
24313
  }
24209
24314
  },
24210
24315
  ensureDir: (dir) => {
24211
- fs58.mkdirSync(dir, { recursive: true });
24316
+ fs59.mkdirSync(dir, { recursive: true });
24212
24317
  },
24213
24318
  /**
24214
24319
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -24229,9 +24334,9 @@ var _linkSeam = {
24229
24334
  * which `linkBdOntoPath` creates if missing.
24230
24335
  */
24231
24336
  cliBinDir: () => {
24232
- const pathDirs = (process.env.PATH ?? "").split(path61.delimiter).filter(Boolean);
24337
+ const pathDirs = (process.env.PATH ?? "").split(path62.delimiter).filter(Boolean);
24233
24338
  const home = _linkSeam.homedir();
24234
- const localBin = home ? path61.join(home, ".local", "bin") : null;
24339
+ const localBin = home ? path62.join(home, ".local", "bin") : null;
24235
24340
  if (localBin) {
24236
24341
  try {
24237
24342
  _linkSeam.ensureDir(localBin);
@@ -24241,16 +24346,16 @@ var _linkSeam = {
24241
24346
  const candidates = [];
24242
24347
  if (localBin) candidates.push(localBin);
24243
24348
  try {
24244
- candidates.push(path61.dirname(process.execPath));
24349
+ candidates.push(path62.dirname(process.execPath));
24245
24350
  } catch {
24246
24351
  }
24247
24352
  candidates.push("/usr/local/bin");
24248
24353
  const entry = process.argv[1];
24249
24354
  if (entry) {
24250
24355
  try {
24251
- candidates.push(path61.dirname(fs58.realpathSync(entry)));
24356
+ candidates.push(path62.dirname(fs59.realpathSync(entry)));
24252
24357
  } catch {
24253
- candidates.push(path61.dirname(entry));
24358
+ candidates.push(path62.dirname(entry));
24254
24359
  }
24255
24360
  }
24256
24361
  const onPathWritable = candidates.find(
@@ -24262,24 +24367,24 @@ var _linkSeam = {
24262
24367
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
24263
24368
  readlink: (linkPath) => {
24264
24369
  try {
24265
- return fs58.readlinkSync(linkPath);
24370
+ return fs59.readlinkSync(linkPath);
24266
24371
  } catch {
24267
24372
  return null;
24268
24373
  }
24269
24374
  },
24270
- unlink: (linkPath) => fs58.unlinkSync(linkPath),
24271
- symlink: (target, linkPath) => fs58.symlinkSync(target, linkPath)
24375
+ unlink: (linkPath) => fs59.unlinkSync(linkPath),
24376
+ symlink: (target, linkPath) => fs59.symlinkSync(target, linkPath)
24272
24377
  };
24273
24378
  function linkBdOntoPath(binaryPath) {
24274
24379
  if (_linkSeam.platform() === "win32") return;
24275
24380
  const binDir = _linkSeam.cliBinDir();
24276
24381
  if (!binDir) return;
24277
24382
  _linkSeam.ensureDir(binDir);
24278
- const linkPath = path61.join(binDir, "bd");
24383
+ const linkPath = path62.join(binDir, "bd");
24279
24384
  if (linkPath === binaryPath) return;
24280
- const current = _linkSeam.readlink(linkPath);
24281
- if (current === binaryPath) return;
24282
- if (current !== null) _linkSeam.unlink(linkPath);
24385
+ const current2 = _linkSeam.readlink(linkPath);
24386
+ if (current2 === binaryPath) return;
24387
+ if (current2 !== null) _linkSeam.unlink(linkPath);
24283
24388
  _linkSeam.symlink(binaryPath, linkPath);
24284
24389
  log.info("beads", `linked bd onto PATH: ${linkPath} -> ${binaryPath}`);
24285
24390
  }
@@ -24470,7 +24575,7 @@ function dedupeRecipes(agents) {
24470
24575
 
24471
24576
  // src/beads/watcher.ts
24472
24577
  var crypto4 = __toESM(require("crypto"));
24473
- var path62 = __toESM(require("path"));
24578
+ var path63 = __toESM(require("path"));
24474
24579
  var API_BASE6 = resolveApiBaseUrl();
24475
24580
  var DEBOUNCE_MS2 = 400;
24476
24581
  var ZERO_SUMMARY = {
@@ -24494,7 +24599,7 @@ var BeadsWatcher = class {
24494
24599
  constructor(opts) {
24495
24600
  this.opts = opts;
24496
24601
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
24497
- this.feedPath = opts.feedPath ?? path62.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
24602
+ this.feedPath = opts.feedPath ?? path63.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
24498
24603
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
24499
24604
  }
24500
24605
  opts;
@@ -24993,8 +25098,8 @@ function cleanupAttachmentTempFiles() {
24993
25098
  function saveFilesTemp(files) {
24994
25099
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
24995
25100
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
24996
- const tmpPath = path65.join(os49.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
24997
- fs61.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
25101
+ const tmpPath = path66.join(os50.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
25102
+ fs62.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
24998
25103
  pendingAttachmentFiles.add(tmpPath);
24999
25104
  return tmpPath;
25000
25105
  });
@@ -25206,10 +25311,10 @@ var listFiles = async (ctx, cmd, parsed) => {
25206
25311
  await ctx.relay.sendResult(cmd.id, "completed", result);
25207
25312
  };
25208
25313
  var envReadH = async (ctx, cmd) => {
25209
- const envPath = path65.join(process.cwd(), ".env");
25314
+ const envPath = path66.join(process.cwd(), ".env");
25210
25315
  await restoreProjectEnvIfMissing(process.cwd(), ctx);
25211
25316
  try {
25212
- const raw = await fs61.promises.readFile(envPath, "utf8");
25317
+ const raw = await fs62.promises.readFile(envPath, "utf8");
25213
25318
  await ctx.relay.sendResult(cmd.id, "completed", {
25214
25319
  exists: true,
25215
25320
  vars: parseDotenv(raw)
@@ -25240,15 +25345,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
25240
25345
  }
25241
25346
  seen.add(v.key);
25242
25347
  }
25243
- const envPath = path65.join(process.cwd(), ".env");
25244
- const tmpPath = path65.join(process.cwd(), ".env.codeam.tmp");
25348
+ const envPath = path66.join(process.cwd(), ".env");
25349
+ const tmpPath = path66.join(process.cwd(), ".env.codeam.tmp");
25245
25350
  try {
25246
- await fs61.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
25247
- await fs61.promises.rename(tmpPath, envPath);
25351
+ await fs62.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
25352
+ await fs62.promises.rename(tmpPath, envPath);
25248
25353
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
25249
25354
  void syncProjectEnvUp(process.cwd(), ctx);
25250
25355
  } catch (err) {
25251
- await fs61.promises.rm(tmpPath, { force: true }).catch(() => void 0);
25356
+ await fs62.promises.rm(tmpPath, { force: true }).catch(() => void 0);
25252
25357
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
25253
25358
  }
25254
25359
  };
@@ -25297,7 +25402,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
25297
25402
  let configuredAgent = rawAgentId;
25298
25403
  if (!configuredAgent) {
25299
25404
  try {
25300
- const raw = JSON.parse(fs61.readFileSync(headroomConfigPath(), "utf8"));
25405
+ const raw = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
25301
25406
  configuredAgent = raw.agent ?? "";
25302
25407
  } catch {
25303
25408
  }
@@ -25331,7 +25436,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
25331
25436
  persist: persistHeadroomConfig,
25332
25437
  readEnabled: () => {
25333
25438
  try {
25334
- const raw = JSON.parse(fs61.readFileSync(headroomConfigPath(), "utf8"));
25439
+ const raw = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
25335
25440
  return raw.enabled === true;
25336
25441
  } catch {
25337
25442
  return false;
@@ -25588,7 +25693,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
25588
25693
  });
25589
25694
  const token = ctx.pluginAuthToken;
25590
25695
  void (async () => {
25591
- const os61 = createOsStrategy();
25696
+ const os63 = createOsStrategy();
25592
25697
  try {
25593
25698
  const report = await reviewPullRequest(
25594
25699
  {
@@ -25597,7 +25702,7 @@ var vcsAgentReviewH = async (ctx, cmd, parsed) => {
25597
25702
  baseBranch: parsed.baseBranch
25598
25703
  },
25599
25704
  {
25600
- runReview: (input) => new CoderabbitRuntimeStrategy(os61).runOneShot(input),
25705
+ runReview: (input) => new CoderabbitRuntimeStrategy(os63).runOneShot(input),
25601
25706
  runGh: (args2) => defaultRunGh(args2),
25602
25707
  postReport: async (r) => {
25603
25708
  if (!token) return;
@@ -25635,7 +25740,7 @@ var headroomBudgetH = async (ctx, cmd) => {
25635
25740
  }
25636
25741
  let headroomActive = false;
25637
25742
  try {
25638
- const raw = JSON.parse(fs61.readFileSync(headroomConfigPath(), "utf8"));
25743
+ const raw = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
25639
25744
  headroomActive = raw.enabled === true;
25640
25745
  } catch {
25641
25746
  }
@@ -25645,7 +25750,7 @@ var headroomBudgetH = async (ctx, cmd) => {
25645
25750
  }
25646
25751
  let existingConfig = { enabled: true };
25647
25752
  try {
25648
- existingConfig = JSON.parse(fs61.readFileSync(headroomConfigPath(), "utf8"));
25753
+ existingConfig = JSON.parse(fs62.readFileSync(headroomConfigPath(), "utf8"));
25649
25754
  } catch {
25650
25755
  }
25651
25756
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -25758,9 +25863,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
25758
25863
  function buildNpmInstallInvocation(opts) {
25759
25864
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
25760
25865
  const execPath = opts?.execPath ?? process.execPath;
25761
- const exists2 = opts?.existsSync ?? fs61.existsSync;
25866
+ const exists2 = opts?.existsSync ?? fs62.existsSync;
25762
25867
  const platform3 = opts?.platform ?? process.platform;
25763
- const p2 = platform3 === "win32" ? path65.win32 : path65.posix;
25868
+ const p2 = platform3 === "win32" ? path66.win32 : path66.posix;
25764
25869
  const normalized = entryScript.split(/[\\/]/).join("/");
25765
25870
  const marker = "/lib/node_modules/codeam-cli/";
25766
25871
  const markerIdx = normalized.indexOf(marker);
@@ -25782,7 +25887,7 @@ function isPermissionError(stderr) {
25782
25887
  function resolveGlobalNodeModulesDir(opts) {
25783
25888
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
25784
25889
  const platform3 = opts?.platform ?? process.platform;
25785
- const p2 = platform3 === "win32" ? path65.win32 : path65.posix;
25890
+ const p2 = platform3 === "win32" ? path66.win32 : path66.posix;
25786
25891
  const marker = "/lib/node_modules/codeam-cli/";
25787
25892
  const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
25788
25893
  if (markerIdx <= 0) return null;
@@ -25792,9 +25897,9 @@ function resolveGlobalNodeModulesDir(opts) {
25792
25897
  var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
25793
25898
  function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
25794
25899
  if (!nodeModulesDir) return 0;
25795
- const readdirSync13 = deps?.readdirSync ?? fs61.readdirSync;
25796
- const statSync17 = deps?.statSync ?? fs61.statSync;
25797
- const rmSync9 = deps?.rmSync ?? fs61.rmSync;
25900
+ const readdirSync13 = deps?.readdirSync ?? fs62.readdirSync;
25901
+ const statSync17 = deps?.statSync ?? fs62.statSync;
25902
+ const rmSync9 = deps?.rmSync ?? fs62.rmSync;
25798
25903
  let removed = 0;
25799
25904
  let entries;
25800
25905
  try {
@@ -25804,7 +25909,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
25804
25909
  }
25805
25910
  for (const name of entries) {
25806
25911
  if (!/^\.codeam-cli-/.test(name)) continue;
25807
- const full = path65.join(nodeModulesDir, name);
25912
+ const full = path66.join(nodeModulesDir, name);
25808
25913
  try {
25809
25914
  const st3 = statSync17(full);
25810
25915
  if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
@@ -26351,6 +26456,15 @@ var savePreviewConfigH = (_ctx, _cmd, parsed) => {
26351
26456
  log.info("preview", `save_preview_config failed: ${String(err)}`);
26352
26457
  });
26353
26458
  };
26459
+ var guardrailConfigureH = async (ctx, cmd) => {
26460
+ const payload = cmd.payload;
26461
+ if (payload?.action === "write") {
26462
+ const policy = setGuardrailPolicy(payload.policy);
26463
+ await ctx.relay.sendResult(cmd.id, "completed", { policy });
26464
+ return;
26465
+ }
26466
+ await ctx.relay.sendResult(cmd.id, "completed", { policy: getGuardrailPolicy() });
26467
+ };
26354
26468
  var handlers = {
26355
26469
  start_task: startTask,
26356
26470
  provide_input: provideInput,
@@ -26402,6 +26516,7 @@ var handlers = {
26402
26516
  vcs_agent_review: vcsAgentReviewH,
26403
26517
  headroom_budget: headroomBudgetH,
26404
26518
  beads_configure: beadsConfigureH,
26519
+ guardrail_configure: guardrailConfigureH,
26405
26520
  cli_self_update: cliSelfUpdateH()
26406
26521
  };
26407
26522
  async function dispatchCommand(ctx, cmd) {
@@ -26671,11 +26786,11 @@ function resolveTokenValue(args2) {
26671
26786
  }
26672
26787
  const fileFlag = args2.find((a) => a.startsWith("--token-file="));
26673
26788
  if (fileFlag) {
26674
- const path85 = fileFlag.slice("--token-file=".length);
26789
+ const path87 = fileFlag.slice("--token-file=".length);
26675
26790
  try {
26676
- const content = fs62.readFileSync(path85, "utf8").trim();
26677
- if (content.length === 0) fail(`--token-file ${path85} is empty`);
26678
- rmIfExistsQuiet(path85);
26791
+ const content = fs63.readFileSync(path87, "utf8").trim();
26792
+ if (content.length === 0) fail(`--token-file ${path87} is empty`);
26793
+ rmIfExistsQuiet(path87);
26679
26794
  return content;
26680
26795
  } catch (err) {
26681
26796
  fail(`Could not read --token-file: ${err.message}`);
@@ -26704,7 +26819,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
26704
26819
  pluginId,
26705
26820
  ideName: "codeam-cli (codespace)",
26706
26821
  ideVersion: process.env.npm_package_version ?? "unknown",
26707
- hostname: os50.hostname(),
26822
+ hostname: os51.hostname(),
26708
26823
  codespaceName: process.env.CODESPACE_NAME ?? "",
26709
26824
  // Current git branch of the codespace's working directory, so the
26710
26825
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -26765,7 +26880,7 @@ async function claim(token, pluginId, pluginSecretHash) {
26765
26880
  }
26766
26881
  }
26767
26882
  function pairAutoLockPath() {
26768
- return path66.join(os50.homedir(), ".codeam", "pair-auto.lock");
26883
+ return path67.join(os51.homedir(), ".codeam", "pair-auto.lock");
26769
26884
  }
26770
26885
  function isLivePairAuto(pid) {
26771
26886
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -26775,7 +26890,7 @@ function isLivePairAuto(pid) {
26775
26890
  if (e.code !== "EPERM") return false;
26776
26891
  }
26777
26892
  try {
26778
- return fs62.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
26893
+ return fs63.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
26779
26894
  } catch {
26780
26895
  return true;
26781
26896
  }
@@ -26785,24 +26900,24 @@ function isLiveCodeam(pid) {
26785
26900
  }
26786
26901
  function daemonLockPath(sessionId) {
26787
26902
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
26788
- return path66.join(os50.homedir(), ".codeam", `daemon-${safe}.lock`);
26903
+ return path67.join(os51.homedir(), ".codeam", `daemon-${safe}.lock`);
26789
26904
  }
26790
26905
  function acquireDaemonLock(sessionId) {
26791
26906
  const lockPath = daemonLockPath(sessionId);
26792
26907
  try {
26793
- fs62.mkdirSync(path66.dirname(lockPath), { recursive: true });
26908
+ fs63.mkdirSync(path67.dirname(lockPath), { recursive: true });
26794
26909
  try {
26795
- fs62.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
26910
+ fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
26796
26911
  } catch (e) {
26797
26912
  if (e.code !== "EEXIST") throw e;
26798
- const holder = Number(fs62.readFileSync(lockPath, "utf8").trim());
26913
+ const holder = Number(fs63.readFileSync(lockPath, "utf8").trim());
26799
26914
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
26800
- fs62.writeFileSync(lockPath, String(process.pid));
26915
+ fs63.writeFileSync(lockPath, String(process.pid));
26801
26916
  }
26802
26917
  const release3 = () => {
26803
26918
  try {
26804
- if (fs62.existsSync(lockPath) && Number(fs62.readFileSync(lockPath, "utf8").trim()) === process.pid) {
26805
- fs62.unlinkSync(lockPath);
26919
+ if (fs63.existsSync(lockPath) && Number(fs63.readFileSync(lockPath, "utf8").trim()) === process.pid) {
26920
+ fs63.unlinkSync(lockPath);
26806
26921
  }
26807
26922
  } catch {
26808
26923
  }
@@ -26824,19 +26939,19 @@ function acquireDaemonLock(sessionId) {
26824
26939
  function acquireSingletonLock() {
26825
26940
  const lockPath = pairAutoLockPath();
26826
26941
  try {
26827
- fs62.mkdirSync(path66.dirname(lockPath), { recursive: true });
26942
+ fs63.mkdirSync(path67.dirname(lockPath), { recursive: true });
26828
26943
  try {
26829
- fs62.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
26944
+ fs63.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
26830
26945
  } catch (e) {
26831
26946
  if (e.code !== "EEXIST") throw e;
26832
- const holder = Number(fs62.readFileSync(lockPath, "utf8").trim());
26947
+ const holder = Number(fs63.readFileSync(lockPath, "utf8").trim());
26833
26948
  if (isLivePairAuto(holder)) return false;
26834
- fs62.writeFileSync(lockPath, String(process.pid));
26949
+ fs63.writeFileSync(lockPath, String(process.pid));
26835
26950
  }
26836
26951
  process.once("exit", () => {
26837
26952
  try {
26838
- if (fs62.existsSync(lockPath) && Number(fs62.readFileSync(lockPath, "utf8").trim()) === process.pid) {
26839
- fs62.unlinkSync(lockPath);
26953
+ if (fs63.existsSync(lockPath) && Number(fs63.readFileSync(lockPath, "utf8").trim()) === process.pid) {
26954
+ fs63.unlinkSync(lockPath);
26840
26955
  }
26841
26956
  } catch {
26842
26957
  }
@@ -27288,7 +27403,7 @@ var AgentService = class _AgentService {
27288
27403
  };
27289
27404
 
27290
27405
  // src/agents/acp/adapters.ts
27291
- var path68 = __toESM(require("path"));
27406
+ var path69 = __toESM(require("path"));
27292
27407
 
27293
27408
  // src/agents/acp/agent-binary.ts
27294
27409
  var import_fs6 = __toESM(require("fs"));
@@ -27321,14 +27436,14 @@ function defaultSdkDir() {
27321
27436
  return resolveSdkDirViaRequire();
27322
27437
  }
27323
27438
  function resolveClaudeNativeBinary(deps = {}) {
27324
- const existsSync27 = deps.existsSync ?? import_fs6.default.existsSync;
27439
+ const existsSync28 = deps.existsSync ?? import_fs6.default.existsSync;
27325
27440
  const platformKey = deps.platformKey ?? currentPlatformKey();
27326
27441
  const sdkDir = deps.sdkDir !== void 0 ? deps.sdkDir : defaultSdkDir();
27327
27442
  if (!sdkDir) return null;
27328
27443
  const scopeDir = import_path8.default.dirname(sdkDir);
27329
27444
  const binName = platformKey.startsWith("win32-") ? "claude.exe" : "claude";
27330
27445
  const candidate = import_path8.default.join(scopeDir, `claude-agent-sdk-${platformKey}`, binName);
27331
- return existsSync27(candidate) ? candidate : null;
27446
+ return existsSync28(candidate) ? candidate : null;
27332
27447
  }
27333
27448
  var realSleep = (ms) => new Promise((resolve9) => setTimeout(resolve9, ms));
27334
27449
  async function waitForClaudeNativeBinary(opts = {}) {
@@ -27379,18 +27494,18 @@ async function waitForCommandOnPath(cmd, opts = {}) {
27379
27494
  return check();
27380
27495
  }
27381
27496
  function resolveCursorAgentBinary(deps = {}) {
27382
- const existsSync27 = deps.existsSync ?? import_fs6.default.existsSync;
27497
+ const existsSync28 = deps.existsSync ?? import_fs6.default.existsSync;
27383
27498
  const platform3 = deps.platform ?? process.platform;
27384
27499
  const env = deps.env ?? process.env;
27385
27500
  if (platform3 === "win32") {
27386
27501
  const localAppData = env.LOCALAPPDATA;
27387
27502
  if (!localAppData) return null;
27388
27503
  const exe = import_path8.default.win32.join(localAppData, "cursor-agent", "cursor-agent.exe");
27389
- return existsSync27(exe) ? exe : null;
27504
+ return existsSync28(exe) ? exe : null;
27390
27505
  }
27391
27506
  const home = deps.homedir ?? import_os11.default.homedir();
27392
27507
  const unix = import_path8.default.posix.join(home, ".local", "bin", "cursor-agent");
27393
- return existsSync27(unix) ? unix : null;
27508
+ return existsSync28(unix) ? unix : null;
27394
27509
  }
27395
27510
  async function waitForCursorAgent(opts = {}) {
27396
27511
  const timeoutMs = opts.timeoutMs ?? 18e4;
@@ -27578,13 +27693,13 @@ function resolveBin(pkgName, binName) {
27578
27693
  try {
27579
27694
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
27580
27695
  const manifest = require_(`${pkgName}/package.json`);
27581
- const pkgDir = path68.dirname(manifestPath);
27696
+ const pkgDir = path69.dirname(manifestPath);
27582
27697
  const bin = manifest.bin;
27583
27698
  if (!bin) return null;
27584
- if (typeof bin === "string") return path68.resolve(pkgDir, bin);
27699
+ if (typeof bin === "string") return path69.resolve(pkgDir, bin);
27585
27700
  const target = binName ?? Object.keys(bin)[0];
27586
27701
  if (!target || !bin[target]) return null;
27587
- return path68.resolve(pkgDir, bin[target]);
27702
+ return path69.resolve(pkgDir, bin[target]);
27588
27703
  } catch {
27589
27704
  return null;
27590
27705
  }
@@ -27734,9 +27849,9 @@ async function resolveAcpAdapterWithRetry(agent, opts = {}) {
27734
27849
  var import_node_crypto11 = require("crypto");
27735
27850
 
27736
27851
  // src/services/history.service.ts
27737
- var fs64 = __toESM(require("fs"));
27738
- var path69 = __toESM(require("path"));
27739
- var os52 = __toESM(require("os"));
27852
+ var fs65 = __toESM(require("fs"));
27853
+ var path70 = __toESM(require("path"));
27854
+ var os53 = __toESM(require("os"));
27740
27855
  var https7 = __toESM(require("https"));
27741
27856
  var http6 = __toESM(require("http"));
27742
27857
  var import_zod2 = require("zod");
@@ -27763,7 +27878,7 @@ function parseJsonl(filePath) {
27763
27878
  const messages = [];
27764
27879
  let raw;
27765
27880
  try {
27766
- raw = fs64.readFileSync(filePath, "utf8");
27881
+ raw = fs65.readFileSync(filePath, "utf8");
27767
27882
  } catch (err) {
27768
27883
  if (err.code !== "ENOENT") {
27769
27884
  log.warn("history:parseJsonl", `read failed for ${filePath}`, err);
@@ -27904,7 +28019,7 @@ var HistoryService = class _HistoryService {
27904
28019
  return this._quotaPercent === null || Date.now() - this._quotaFetchedAt > ttlMs;
27905
28020
  }
27906
28021
  get projectDir() {
27907
- return this.runtime.resolveHistoryDir(this.cwd) ?? path69.join(os52.homedir(), ".claude", "projects", encodeCwd(this.cwd));
28022
+ return this.runtime.resolveHistoryDir(this.cwd) ?? path70.join(os53.homedir(), ".claude", "projects", encodeCwd(this.cwd));
27908
28023
  }
27909
28024
  /** Set the current Claude conversation ID (extracted from /cost command or session start) */
27910
28025
  setCurrentConversationId(id) {
@@ -27916,7 +28031,7 @@ var HistoryService = class _HistoryService {
27916
28031
  /** Return the current message count in the active conversation. */
27917
28032
  getCurrentMessageCount() {
27918
28033
  if (!this.currentConversationId) return 0;
27919
- const filePath = path69.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28034
+ const filePath = path70.join(this.projectDir, `${this.currentConversationId}.jsonl`);
27920
28035
  return parseJsonl(filePath).length;
27921
28036
  }
27922
28037
  /**
@@ -27927,7 +28042,7 @@ var HistoryService = class _HistoryService {
27927
28042
  const deadline = Date.now() + timeoutMs;
27928
28043
  while (Date.now() < deadline) {
27929
28044
  if (!this.currentConversationId) return null;
27930
- const filePath = path69.join(this.projectDir, `${this.currentConversationId}.jsonl`);
28045
+ const filePath = path70.join(this.projectDir, `${this.currentConversationId}.jsonl`);
27931
28046
  const messages = parseJsonl(filePath);
27932
28047
  if (messages.length > previousCount) {
27933
28048
  for (let i = messages.length - 1; i >= previousCount; i--) {
@@ -27953,16 +28068,16 @@ var HistoryService = class _HistoryService {
27953
28068
  const dir = this.projectDir;
27954
28069
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
27955
28070
  try {
27956
- const files = fs64.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
28071
+ const files = fs65.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
27957
28072
  try {
27958
- const stat3 = fs64.statSync(path69.join(dir, e.name));
28073
+ const stat3 = fs65.statSync(path70.join(dir, e.name));
27959
28074
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
27960
28075
  } catch {
27961
28076
  return { name: e.name, mtime: 0, birthtime: 0 };
27962
28077
  }
27963
28078
  }).filter((f) => f.birthtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
27964
28079
  if (files.length > 0) {
27965
- this.currentConversationId = path69.basename(files[0].name, ".jsonl");
28080
+ this.currentConversationId = path70.basename(files[0].name, ".jsonl");
27966
28081
  }
27967
28082
  } catch {
27968
28083
  }
@@ -27996,13 +28111,13 @@ var HistoryService = class _HistoryService {
27996
28111
  const cutoff = this.bootTimeMs - _HistoryService.BIRTHTIME_GRACE_MS;
27997
28112
  let entries;
27998
28113
  try {
27999
- entries = fs64.readdirSync(dir, { withFileTypes: true });
28114
+ entries = fs65.readdirSync(dir, { withFileTypes: true });
28000
28115
  } catch {
28001
28116
  return null;
28002
28117
  }
28003
28118
  const files = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
28004
28119
  try {
28005
- const stat3 = fs64.statSync(path69.join(dir, e.name));
28120
+ const stat3 = fs65.statSync(path70.join(dir, e.name));
28006
28121
  return { name: e.name, mtime: stat3.mtimeMs, birthtime: stat3.birthtimeMs };
28007
28122
  } catch {
28008
28123
  return { name: e.name, mtime: 0, birthtime: 0 };
@@ -28011,12 +28126,12 @@ var HistoryService = class _HistoryService {
28011
28126
  if (files.length === 0) return null;
28012
28127
  const targetFile = this.currentConversationId ? `${this.currentConversationId}.jsonl` : files[0].name;
28013
28128
  if (!files.some((f) => f.name === targetFile)) return null;
28014
- return this.extractUsageFromFile(path69.join(dir, targetFile));
28129
+ return this.extractUsageFromFile(path70.join(dir, targetFile));
28015
28130
  }
28016
28131
  extractUsageFromFile(filePath) {
28017
28132
  let raw;
28018
28133
  try {
28019
- raw = fs64.readFileSync(filePath, "utf8");
28134
+ raw = fs65.readFileSync(filePath, "utf8");
28020
28135
  } catch {
28021
28136
  return null;
28022
28137
  }
@@ -28061,9 +28176,9 @@ var HistoryService = class _HistoryService {
28061
28176
  let totalCost = 0;
28062
28177
  let files;
28063
28178
  try {
28064
- files = fs64.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
28179
+ files = fs65.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).filter((f) => {
28065
28180
  try {
28066
- return fs64.statSync(path69.join(projectDir, f)).mtimeMs >= monthStartMs;
28181
+ return fs65.statSync(path70.join(projectDir, f)).mtimeMs >= monthStartMs;
28067
28182
  } catch {
28068
28183
  return false;
28069
28184
  }
@@ -28074,7 +28189,7 @@ var HistoryService = class _HistoryService {
28074
28189
  for (const file of files) {
28075
28190
  let raw;
28076
28191
  try {
28077
- raw = fs64.readFileSync(path69.join(projectDir, file), "utf8");
28192
+ raw = fs65.readFileSync(path70.join(projectDir, file), "utf8");
28078
28193
  } catch {
28079
28194
  continue;
28080
28195
  }
@@ -28153,7 +28268,7 @@ var HistoryService = class _HistoryService {
28153
28268
  if (this.runtime.resolveHistoryFile) {
28154
28269
  return this.runtime.resolveHistoryFile(this.cwd, sessionId);
28155
28270
  }
28156
- return path69.join(this.projectDir, `${sessionId}.jsonl`);
28271
+ return path70.join(this.projectDir, `${sessionId}.jsonl`);
28157
28272
  }
28158
28273
  /**
28159
28274
  * Parse a conversation's messages from disk, agent-aware. Claude uses the
@@ -28187,7 +28302,7 @@ var HistoryService = class _HistoryService {
28187
28302
  };
28188
28303
  });
28189
28304
  }
28190
- return parseJsonl(path69.join(this.projectDir, `${sessionId}.jsonl`));
28305
+ return parseJsonl(path70.join(this.projectDir, `${sessionId}.jsonl`));
28191
28306
  }
28192
28307
  async loadConversation(sessionId) {
28193
28308
  const messages = this.readConversation(sessionId);
@@ -28255,7 +28370,7 @@ var HistoryService = class _HistoryService {
28255
28370
  if (!filePath) return false;
28256
28371
  let mtimeMs;
28257
28372
  try {
28258
- mtimeMs = fs64.statSync(filePath).mtimeMs;
28373
+ mtimeMs = fs65.statSync(filePath).mtimeMs;
28259
28374
  } catch {
28260
28375
  return false;
28261
28376
  }
@@ -28330,10 +28445,10 @@ var HistoryService = class _HistoryService {
28330
28445
 
28331
28446
  // src/agents/acp/client.ts
28332
28447
  var import_node_child_process29 = require("child_process");
28333
- var fs65 = __toESM(require("fs/promises"));
28448
+ var fs66 = __toESM(require("fs/promises"));
28334
28449
  var fsSync = __toESM(require("fs"));
28335
- var os54 = __toESM(require("os"));
28336
- var path71 = __toESM(require("path"));
28450
+ var os55 = __toESM(require("os"));
28451
+ var path72 = __toESM(require("path"));
28337
28452
  var import_node_stream = require("stream");
28338
28453
 
28339
28454
  // ../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -30527,7 +30642,7 @@ var Connection = class {
30527
30642
  if (this.abortController.signal.aborted) {
30528
30643
  return;
30529
30644
  }
30530
- let current = message;
30645
+ let current2 = message;
30531
30646
  let retry = false;
30532
30647
  try {
30533
30648
  for (const handler of [
@@ -30537,26 +30652,26 @@ var Connection = class {
30537
30652
  if (this.abortController.signal.aborted) {
30538
30653
  return;
30539
30654
  }
30540
- const result = await handler.handleMessage(current, this.context) ?? {
30655
+ const result = await handler.handleMessage(current2, this.context) ?? {
30541
30656
  handled: true
30542
30657
  };
30543
30658
  if (result.handled) {
30544
30659
  return;
30545
30660
  }
30546
- current = result.message ?? current;
30661
+ current2 = result.message ?? current2;
30547
30662
  retry = retry || Boolean(result.retry);
30548
30663
  }
30549
30664
  if (retry) {
30550
- this.retryQueue.push(current);
30551
- } else if (current.kind === "request") {
30552
- await current.responder.respondWithError(RequestError.methodNotFound(current.method));
30665
+ this.retryQueue.push(current2);
30666
+ } else if (current2.kind === "request") {
30667
+ await current2.responder.respondWithError(RequestError.methodNotFound(current2.method));
30553
30668
  }
30554
30669
  } catch (error) {
30555
30670
  if (this.abortController.signal.aborted) {
30556
30671
  return;
30557
30672
  }
30558
- if (current.kind === "request" && !current.responder.responded) {
30559
- await current.responder.respondWithResult(errorToRequestResult(error, current.responder.signal));
30673
+ if (current2.kind === "request" && !current2.responder.responded) {
30674
+ await current2.responder.respondWithResult(errorToRequestResult(error, current2.responder.signal));
30560
30675
  } else {
30561
30676
  const response = errorToResult(error);
30562
30677
  if ("error" in response) {
@@ -32359,8 +32474,8 @@ function createIdleTimeout(idleMs, makeError, activeIdleMs = idleMs) {
32359
32474
  }
32360
32475
 
32361
32476
  // src/agents/acp/internal-paths.ts
32362
- var path70 = __toESM(require("path"));
32363
- var os53 = __toESM(require("os"));
32477
+ var path71 = __toESM(require("path"));
32478
+ var os54 = __toESM(require("os"));
32364
32479
  var INTERNAL_TOKENS = [".codeam", "house-claude"];
32365
32480
  var SELF_HOSTED_WORKSPACE_RE = /\.codeam[/\\]self-hosted/gi;
32366
32481
  function textReferencesInternal(text) {
@@ -32368,13 +32483,13 @@ function textReferencesInternal(text) {
32368
32483
  const scrubbed = text.replace(SELF_HOSTED_WORKSPACE_RE, " ");
32369
32484
  return INTERNAL_TOKENS.some((t2) => scrubbed.includes(t2));
32370
32485
  }
32371
- function pathIsInternal(p2, homeDir2 = os53.homedir()) {
32486
+ function pathIsInternal(p2, homeDir2 = os54.homedir()) {
32372
32487
  if (!p2) return false;
32373
- const abs = path70.resolve(p2);
32374
- const home = path70.resolve(homeDir2);
32375
- const within = (root) => abs === root || abs.startsWith(root + path70.sep);
32376
- if (within(path70.join(home, ".codeam", "self-hosted"))) return false;
32377
- return within(path70.join(home, ".codeam")) || within(path70.join(home, ".beads")) || abs === path70.join(home, ".codeam-host.log") || abs.includes(`${path70.sep}house-claude${path70.sep}`) || abs.endsWith(`${path70.sep}house-claude`);
32488
+ const abs = path71.resolve(p2);
32489
+ const home = path71.resolve(homeDir2);
32490
+ const within = (root) => abs === root || abs.startsWith(root + path71.sep);
32491
+ if (within(path71.join(home, ".codeam", "self-hosted"))) return false;
32492
+ return within(path71.join(home, ".codeam")) || within(path71.join(home, ".beads")) || abs === path71.join(home, ".codeam-host.log") || abs.includes(`${path71.sep}house-claude${path71.sep}`) || abs.endsWith(`${path71.sep}house-claude`);
32378
32493
  }
32379
32494
  function toolCallReferencesInternal(call) {
32380
32495
  if (textReferencesInternal(call.title)) return true;
@@ -32395,6 +32510,89 @@ function internalPathPermissionOutcome(request) {
32395
32510
  }
32396
32511
  var INTERNAL_BLOCK_REASON = "This path is a CodeAgent platform internal (CodeAgent's own runtime plumbing, not part of the user's project) and is off-limits. Continue with the user's own project files.";
32397
32512
 
32513
+ // src/agents/acp/guardrails.ts
32514
+ var SECRET_RE = /(^|[\s"'`=(/\\])(\.env(\.[\w.-]+)?|[\w.-]+\.(pem|key|pfx|p12|jks|keystore)|id_rsa|id_ed25519|\.npmrc|\.pgpass|\.netrc|\.git-credentials|kubeconfig|credentials(\.[\w-]+)?)\b/i;
32515
+ var DESTRUCTIVE_RES = [
32516
+ /\brm\s+-[a-z]*f/i,
32517
+ // rm -rf / -fr / -f
32518
+ /\brm\s+[^\n]*--force/i,
32519
+ /\bgit\s+reset\s+--hard/i,
32520
+ /\bgit\s+clean\s+-[a-z]*f/i,
32521
+ /\bgit\s+checkout\s+--\s+\./i,
32522
+ // discard all local changes
32523
+ /\bshred\b/i,
32524
+ /\btruncate\s+-s\s*0/i,
32525
+ /\b(drop|truncate)\s+(table|database)\b/i,
32526
+ /\bmkfs\b/i,
32527
+ /\bdd\b[^\n]*\bof=/i
32528
+ ];
32529
+ var PROTECTED_BRANCHES = "main|master|develop|development|release[\\w./-]*|prod|production";
32530
+ var PROTECTED_PUSH_RE = new RegExp(`\\bgit\\s+push\\b[^\\n]*\\b(${PROTECTED_BRANCHES})\\b`, "i");
32531
+ var OUTWARD_RES = [
32532
+ /\bgit\s+push\b[^\n]*(--force\b|--force-with-lease\b|(?:^|\s)-f(?:\s|$))/i,
32533
+ /\b(npm|yarn|pnpm)\s+publish\b/i,
32534
+ /\bgh\s+release\s+create\b/i,
32535
+ /\bgit\s+push\b[^\n]*--tags\b/i,
32536
+ /\bvercel\b[^\n]*(--prod|deploy)/i,
32537
+ /\bnetlify\s+deploy\b/i,
32538
+ /\beas\s+(submit|build)\b/i
32539
+ ];
32540
+ function haystack(call) {
32541
+ let s = typeof call.title === "string" ? call.title : "";
32542
+ if (call.rawInput != null) {
32543
+ try {
32544
+ s += "\n" + JSON.stringify(call.rawInput);
32545
+ } catch {
32546
+ }
32547
+ }
32548
+ return s;
32549
+ }
32550
+ function matchedCategories(hay) {
32551
+ const m = /* @__PURE__ */ new Set();
32552
+ if (SECRET_RE.test(hay)) m.add("secretRead");
32553
+ if (DESTRUCTIVE_RES.some((re2) => re2.test(hay))) m.add("destructiveShell");
32554
+ if (OUTWARD_RES.some((re2) => re2.test(hay))) m.add("outwardIrreversible");
32555
+ if (PROTECTED_PUSH_RE.test(hay)) m.add("protectedBranch");
32556
+ return m;
32557
+ }
32558
+ function rejectOutcome(options) {
32559
+ const reject = options.find((o) => o.kind === "reject_always") ?? options.find((o) => o.kind === "reject_once");
32560
+ return reject ? { outcome: { outcome: "selected", optionId: reject.optionId } } : { outcome: { outcome: "cancelled" } };
32561
+ }
32562
+ function toolPathIsSecret(p2) {
32563
+ return !!p2 && SECRET_RE.test(p2);
32564
+ }
32565
+ var GUARDRAIL_SECRET_READ_BLOCK_REASON = "Reading this secret file is blocked by this session's guardrails (Reading secrets = Deny). Adjust it in the session Guardrails settings if intended.";
32566
+ function guardrailDecision(request, policy) {
32567
+ const hay = haystack(request.toolCall);
32568
+ if (!hay) return null;
32569
+ const matched = matchedCategories(hay);
32570
+ if (matched.size === 0) return null;
32571
+ let denyCat;
32572
+ let confirmCat;
32573
+ for (const cat of GUARDRAIL_CATEGORIES) {
32574
+ if (!matched.has(cat)) continue;
32575
+ const d3 = policy[cat];
32576
+ if (d3 === "deny") {
32577
+ denyCat = cat;
32578
+ break;
32579
+ }
32580
+ if (d3 === "confirm" && !confirmCat) confirmCat = cat;
32581
+ }
32582
+ if (denyCat) {
32583
+ return {
32584
+ kind: "deny",
32585
+ category: denyCat,
32586
+ reason: GUARDRAIL_CATEGORY_META[denyCat].description,
32587
+ outcome: rejectOutcome(request.options)
32588
+ };
32589
+ }
32590
+ if (confirmCat) {
32591
+ return { kind: "confirm", category: confirmCat, reason: GUARDRAIL_CATEGORY_META[confirmCat].description };
32592
+ }
32593
+ return null;
32594
+ }
32595
+
32398
32596
  // src/agents/acp/client.ts
32399
32597
  var TRANSIENT_ADAPTER_SPAWN_RE = /ETXTBSY|ENOENT/;
32400
32598
  var MAX_START_ATTEMPTS = 5;
@@ -33202,8 +33400,11 @@ var AcpClient = class {
33202
33400
  if (!isLocalSession() && pathIsInternal(params.path)) {
33203
33401
  throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
33204
33402
  }
33403
+ if (!isLocalSession() && getGuardrailPolicy().secretRead === "deny" && toolPathIsSecret(params.path)) {
33404
+ throw new RequestError(-32002, GUARDRAIL_SECRET_READ_BLOCK_REASON, { uri: params.path });
33405
+ }
33205
33406
  try {
33206
- const content = await fs65.readFile(params.path, "utf8");
33407
+ const content = await fs66.readFile(params.path, "utf8");
33207
33408
  return applyLineRange(content, params.line ?? null, params.limit ?? null);
33208
33409
  } catch (err) {
33209
33410
  const code = err.code;
@@ -33226,7 +33427,7 @@ var AcpClient = class {
33226
33427
  throw new RequestError(-32002, INTERNAL_BLOCK_REASON, { uri: params.path });
33227
33428
  }
33228
33429
  try {
33229
- await fs65.writeFile(params.path, params.content, "utf8");
33430
+ await fs66.writeFile(params.path, params.content, "utf8");
33230
33431
  return {};
33231
33432
  } catch (err) {
33232
33433
  const code = err.code;
@@ -33286,29 +33487,29 @@ function applyLineRange(content, line, limit) {
33286
33487
  return { content: lines.slice(start2, end).join("\n") };
33287
33488
  }
33288
33489
  function knownAgentBinaryDirs() {
33289
- const home = os54.homedir();
33490
+ const home = os55.homedir();
33290
33491
  const out2 = [];
33291
33492
  out2.push("/tmp/codeam-node20/bin");
33292
33493
  for (const root of [
33293
33494
  "/usr/local/share/nvm/versions/node",
33294
- path71.join(home, ".nvm/versions/node")
33495
+ path72.join(home, ".nvm/versions/node")
33295
33496
  ]) {
33296
33497
  try {
33297
33498
  for (const child of fsSync.readdirSync(root)) {
33298
- out2.push(path71.join(root, child, "bin"));
33499
+ out2.push(path72.join(root, child, "bin"));
33299
33500
  }
33300
33501
  } catch {
33301
33502
  }
33302
33503
  }
33303
- out2.push(path71.join(home, ".volta/bin"));
33504
+ out2.push(path72.join(home, ".volta/bin"));
33304
33505
  out2.push("/usr/local/bin");
33305
33506
  out2.push("/usr/bin");
33306
- out2.push(path71.join(home, ".local/bin"));
33307
- out2.push(path71.join(home, "bin"));
33507
+ out2.push(path72.join(home, ".local/bin"));
33508
+ out2.push(path72.join(home, "bin"));
33308
33509
  if (process.platform === "win32") {
33309
33510
  const { LOCALAPPDATA, APPDATA } = process.env;
33310
- if (LOCALAPPDATA) out2.push(path71.join(LOCALAPPDATA, "cursor-agent"));
33311
- if (APPDATA) out2.push(path71.join(APPDATA, "npm"));
33511
+ if (LOCALAPPDATA) out2.push(path72.join(LOCALAPPDATA, "cursor-agent"));
33512
+ if (APPDATA) out2.push(path72.join(APPDATA, "npm"));
33312
33513
  }
33313
33514
  return out2.filter((p2) => {
33314
33515
  try {
@@ -33320,7 +33521,7 @@ function knownAgentBinaryDirs() {
33320
33521
  }
33321
33522
  function expandPathForAgentBinaries(existingPath) {
33322
33523
  const existing = new Set(
33323
- existingPath.split(path71.delimiter).filter((p2) => p2.length > 0)
33524
+ existingPath.split(path72.delimiter).filter((p2) => p2.length > 0)
33324
33525
  );
33325
33526
  const additions = [];
33326
33527
  for (const dir of knownAgentBinaryDirs()) {
@@ -33330,7 +33531,7 @@ function expandPathForAgentBinaries(existingPath) {
33330
33531
  }
33331
33532
  }
33332
33533
  if (additions.length === 0) return existingPath;
33333
- return [...additions, existingPath].filter((p2) => p2.length > 0).join(path71.delimiter);
33534
+ return [...additions, existingPath].filter((p2) => p2.length > 0).join(path72.delimiter);
33334
33535
  }
33335
33536
 
33336
33537
  // src/agents/acp/headroom-budget-proxy.ts
@@ -33812,15 +34013,15 @@ function commonPrefixLength(a, b) {
33812
34013
 
33813
34014
  // src/agents/acp/onboarding.ts
33814
34015
  var import_child_process27 = require("child_process");
33815
- var fs66 = __toESM(require("fs"));
33816
- var os55 = __toESM(require("os"));
33817
- var path72 = __toESM(require("path"));
34016
+ var fs67 = __toESM(require("fs"));
34017
+ var os56 = __toESM(require("os"));
34018
+ var path73 = __toESM(require("path"));
33818
34019
  var _onboardingSeam = {
33819
- markerPath: (sessionId) => path72.join(os55.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
33820
- exists: (p2) => fs66.existsSync(p2),
34020
+ markerPath: (sessionId) => path73.join(os56.homedir(), ".codeam", "welcomed", `${sessionId}.done`),
34021
+ exists: (p2) => fs67.existsSync(p2),
33821
34022
  write: (p2) => {
33822
- fs66.mkdirSync(path72.dirname(p2), { recursive: true });
33823
- fs66.writeFileSync(p2, "");
34023
+ fs67.mkdirSync(path73.dirname(p2), { recursive: true });
34024
+ fs67.writeFileSync(p2, "");
33824
34025
  },
33825
34026
  disabled: () => {
33826
34027
  const v = process.env.CODEAM_ONBOARDING_DISABLED;
@@ -33857,7 +34058,7 @@ function resolveRepoName(cwd) {
33857
34058
  if (name) return name;
33858
34059
  }
33859
34060
  }
33860
- const base = path72.basename(cwd || "");
34061
+ const base = path73.basename(cwd || "");
33861
34062
  if (base && !isUuid(base)) return base;
33862
34063
  return "this project";
33863
34064
  }
@@ -33873,7 +34074,7 @@ function buildOnboardingWelcome(cwd) {
33873
34074
  "",
33874
34075
  "Found a bug or have feedback? Reach us at:",
33875
34076
  "- GitHub: https://github.com/edgar-durand/codeagent-mobile-clients/issues",
33876
- "- Discord: https://discord.gg/ADMKwGAB",
34077
+ "- Discord: https://discord.gg/Np2pbMrV9f",
33877
34078
  "",
33878
34079
  `Ready when you are \u2014 try **"explain ${repo}"** or **"what should I work on first?"**`
33879
34080
  ].join("\n");
@@ -34115,13 +34316,13 @@ var import_crypto5 = require("crypto");
34115
34316
 
34116
34317
  // src/services/turn-files/git-changeset.ts
34117
34318
  var import_child_process28 = require("child_process");
34118
- var fs68 = __toESM(require("fs/promises"));
34119
- var path74 = __toESM(require("path"));
34319
+ var fs69 = __toESM(require("fs/promises"));
34320
+ var path75 = __toESM(require("path"));
34120
34321
 
34121
34322
  // src/services/turn-files/review-ignore.ts
34122
34323
  var import_ignore2 = __toESM(require("ignore"));
34123
- var fs67 = __toESM(require("fs"));
34124
- var path73 = __toESM(require("path"));
34324
+ var fs68 = __toESM(require("fs"));
34325
+ var path74 = __toESM(require("path"));
34125
34326
  var CURATED_REVIEW_IGNORE = [
34126
34327
  // Google Cloud SDK (the incident) — installs a huge python tree.
34127
34328
  "google-cloud-sdk/",
@@ -34160,7 +34361,7 @@ var CURATED_REVIEW_IGNORE = [
34160
34361
  function makeReviewIgnore(repoRoot) {
34161
34362
  const ig = (0, import_ignore2.default)().add(CURATED_REVIEW_IGNORE);
34162
34363
  try {
34163
- const custom = fs67.readFileSync(path73.join(repoRoot, ".codeam", "reviewignore"), "utf8");
34364
+ const custom = fs68.readFileSync(path74.join(repoRoot, ".codeam", "reviewignore"), "utf8");
34164
34365
  ig.add(custom);
34165
34366
  } catch {
34166
34367
  }
@@ -34205,7 +34406,7 @@ async function collectRepoChangeset(opts) {
34205
34406
  let stats;
34206
34407
  if (!truncated && row.fileStatus === "added" && numstatEntry === void 0) {
34207
34408
  const lineCount = await readUntrackedLineCount(
34208
- path74.join(opts.repoRoot, row.filePath)
34409
+ path75.join(opts.repoRoot, row.filePath)
34209
34410
  );
34210
34411
  stats = { added: lineCount, removed: 0 };
34211
34412
  } else {
@@ -34236,7 +34437,7 @@ function readUntrackedLineCount(absPath) {
34236
34437
  }
34237
34438
  async function defaultReadUntrackedLineCount(absPath) {
34238
34439
  try {
34239
- const content = await fs68.readFile(absPath, "utf8");
34440
+ const content = await fs69.readFile(absPath, "utf8");
34240
34441
  let count = 0;
34241
34442
  let pos = -1;
34242
34443
  while ((pos = content.indexOf("\n", pos + 1)) !== -1) {
@@ -34328,7 +34529,7 @@ function defaultRunGit(cwd, args2) {
34328
34529
  });
34329
34530
  }
34330
34531
  async function discoverRepos(workingDir, maxDepth = 4) {
34331
- const fs75 = await import("fs/promises");
34532
+ const fs77 = await import("fs/promises");
34332
34533
  const out2 = [];
34333
34534
  await walk(workingDir, 0);
34334
34535
  return out2;
@@ -34336,7 +34537,7 @@ async function discoverRepos(workingDir, maxDepth = 4) {
34336
34537
  if (depth > maxDepth) return;
34337
34538
  let entries = [];
34338
34539
  try {
34339
- const dirents = await fs75.readdir(dir, { withFileTypes: true });
34540
+ const dirents = await fs77.readdir(dir, { withFileTypes: true });
34340
34541
  entries = dirents.filter((d3) => !d3.name.startsWith(".") || d3.name === ".git").map((d3) => ({ name: d3.name, isDirectory: d3.isDirectory() }));
34341
34542
  } catch {
34342
34543
  return;
@@ -34347,8 +34548,8 @@ async function discoverRepos(workingDir, maxDepth = 4) {
34347
34548
  if (hasGit) {
34348
34549
  out2.push({
34349
34550
  repoRoot: dir,
34350
- repoPath: path74.relative(workingDir, dir),
34351
- repoName: path74.basename(dir)
34551
+ repoPath: path75.relative(workingDir, dir),
34552
+ repoName: path75.basename(dir)
34352
34553
  });
34353
34554
  return;
34354
34555
  }
@@ -34356,14 +34557,14 @@ async function discoverRepos(workingDir, maxDepth = 4) {
34356
34557
  if (!entry.isDirectory) continue;
34357
34558
  if (entry.name === "node_modules") continue;
34358
34559
  if (entry.name === "dist" || entry.name === "build") continue;
34359
- await walk(path74.join(dir, entry.name), depth + 1);
34560
+ await walk(path75.join(dir, entry.name), depth + 1);
34360
34561
  }
34361
34562
  }
34362
34563
  }
34363
34564
 
34364
34565
  // src/services/turn-files/files-outbox.ts
34365
- var fs69 = __toESM(require("fs/promises"));
34366
- var path75 = __toESM(require("path"));
34566
+ var fs70 = __toESM(require("fs/promises"));
34567
+ var path76 = __toESM(require("path"));
34367
34568
  var import_os12 = require("os");
34368
34569
  var HOME_OUTBOX_DIR = ".codeam/outbox";
34369
34570
  var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
@@ -34396,16 +34597,16 @@ var FilesOutbox = class {
34396
34597
  backoffIndex = 0;
34397
34598
  stopped = false;
34398
34599
  constructor(opts) {
34399
- const base = opts.baseDir ?? path75.join(homeDir(), HOME_OUTBOX_DIR);
34400
- this.filePath = path75.join(base, `${opts.sessionId}.jsonl`);
34600
+ const base = opts.baseDir ?? path76.join(homeDir(), HOME_OUTBOX_DIR);
34601
+ this.filePath = path76.join(base, `${opts.sessionId}.jsonl`);
34401
34602
  this.post = opts.post;
34402
34603
  this.autoSchedule = opts.autoSchedule !== false;
34403
34604
  }
34404
34605
  /** Persist the entry to disk and trigger a flush. Returns once the
34405
34606
  * line is durable on disk (not once the POST succeeds). */
34406
34607
  async enqueue(entry) {
34407
- await fs69.mkdir(path75.dirname(this.filePath), { recursive: true });
34408
- await fs69.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
34608
+ await fs70.mkdir(path76.dirname(this.filePath), { recursive: true });
34609
+ await fs70.appendFile(this.filePath, JSON.stringify(entry) + "\n", "utf8");
34409
34610
  this.backoffIndex = 0;
34410
34611
  if (this.autoSchedule) this.scheduleFlush(0);
34411
34612
  }
@@ -34496,7 +34697,7 @@ var FilesOutbox = class {
34496
34697
  async readAll() {
34497
34698
  let raw = "";
34498
34699
  try {
34499
- raw = await fs69.readFile(this.filePath, "utf8");
34700
+ raw = await fs70.readFile(this.filePath, "utf8");
34500
34701
  } catch {
34501
34702
  return [];
34502
34703
  }
@@ -34520,12 +34721,12 @@ var FilesOutbox = class {
34520
34721
  async rewrite(entries) {
34521
34722
  const tmpPath = `${this.filePath}.${process.pid}.tmp`;
34522
34723
  if (entries.length === 0) {
34523
- await fs69.unlink(this.filePath).catch(() => void 0);
34724
+ await fs70.unlink(this.filePath).catch(() => void 0);
34524
34725
  return;
34525
34726
  }
34526
34727
  const payload = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
34527
- await fs69.writeFile(tmpPath, payload, "utf8");
34528
- await fs69.rename(tmpPath, this.filePath);
34728
+ await fs70.writeFile(tmpPath, payload, "utf8");
34729
+ await fs70.rename(tmpPath, this.filePath);
34529
34730
  }
34530
34731
  };
34531
34732
  function applyJitter(ms) {
@@ -34749,9 +34950,9 @@ function replyIsCursorUpgradeRequired(finalText) {
34749
34950
  if (t2.length === 0 || t2.length > 200) return false;
34750
34951
  return t2.includes("upgrade your plan to continue") || t2.includes("upgrade your plan") && t2.includes("continue");
34751
34952
  }
34752
- function isGeminiIneligibleTier(haystack) {
34953
+ function isGeminiIneligibleTier(haystack2) {
34753
34954
  return /IneligibleTierError|UNSUPPORTED_CLIENT|no longer supported for Gemini Code Assist|not eligible for Gemini Code Assist/i.test(
34754
- haystack
34955
+ haystack2
34755
34956
  );
34756
34957
  }
34757
34958
  var ACP_AGENT_HOOKS = {
@@ -34775,7 +34976,7 @@ var ACP_AGENT_HOOKS = {
34775
34976
  },
34776
34977
  gemini: {
34777
34978
  statusPage: { vendor: "Google", url: "https://status.cloud.google.com" },
34778
- classifyStartupFailure: (haystack) => isGeminiIneligibleTier(haystack) ? "ineligible_tier" : null
34979
+ classifyStartupFailure: (haystack2) => isGeminiIneligibleTier(haystack2) ? "ineligible_tier" : null
34779
34980
  },
34780
34981
  copilot: {
34781
34982
  statusPage: { vendor: "GitHub", url: "https://www.githubstatus.com" }
@@ -34841,9 +35042,9 @@ The agent provider returned an overload/outage error, so this turn couldn\u2019t
34841
35042
  Follow the status here: [${info.url}](${info.url})` : "");
34842
35043
  }
34843
35044
  function startupFailureMessage(agent, detail, recentStderr) {
34844
- const haystack = `${detail}
35045
+ const haystack2 = `${detail}
34845
35046
  ${recentStderr}`;
34846
- if (agentHooks(agent)?.classifyStartupFailure?.(haystack) === "ineligible_tier") {
35047
+ if (agentHooks(agent)?.classifyStartupFailure?.(haystack2) === "ineligible_tier") {
34847
35048
  return [
34848
35049
  "\u26A0\uFE0F **Gemini couldn't start \u2014 your Google account isn't eligible.**",
34849
35050
  "",
@@ -34854,8 +35055,8 @@ ${recentStderr}`;
34854
35055
  "\u2022 a paid **Gemini Code Assist (Standard/Enterprise)** subscription."
34855
35056
  ].join("\n");
34856
35057
  }
34857
- if (looksLikeAuthFailure(haystack)) return AUTH_FAILURE_MESSAGE;
34858
- if (looksLikeProviderOutage(haystack)) return providerOutageMessage(agent);
35058
+ if (looksLikeAuthFailure(haystack2)) return AUTH_FAILURE_MESSAGE;
35059
+ if (looksLikeProviderOutage(haystack2)) return providerOutageMessage(agent);
34859
35060
  const tail = recentStderr.split("\n").filter(Boolean).slice(-3).join("\n");
34860
35061
  return [
34861
35062
  `\u26A0\uFE0F The ${agent} agent failed to start.`,
@@ -35153,6 +35354,55 @@ function buildAcpPromptBlocks(payload) {
35153
35354
  return blocks;
35154
35355
  }
35155
35356
 
35357
+ // src/agents/agent-standard.ts
35358
+ var fs72 = __toESM(require("fs"));
35359
+ var path78 = __toESM(require("path"));
35360
+ var os57 = __toESM(require("os"));
35361
+ function ensureAgentStandard(homeDir2 = os57.homedir()) {
35362
+ try {
35363
+ const file = path78.join(homeDir2, ".claude", "CLAUDE.md");
35364
+ let existing = "";
35365
+ try {
35366
+ existing = fs72.readFileSync(file, "utf8");
35367
+ } catch {
35368
+ }
35369
+ if (existing.includes(AGENT_STANDARD_MARKER)) return;
35370
+ fs72.mkdirSync(path78.dirname(file), { recursive: true });
35371
+ const next = existing.trim() ? `${existing.trimEnd()}
35372
+
35373
+ ${AGENT_STANDARD_BLOCK}
35374
+ ` : `${AGENT_STANDARD_BLOCK}
35375
+ `;
35376
+ fs72.writeFileSync(file, next);
35377
+ } catch {
35378
+ }
35379
+ }
35380
+ var _agentStandardSeam = {
35381
+ isLocalSession: () => isLocalSession(),
35382
+ markerPath: (sessionId) => path78.join(os57.homedir(), ".codeam", "agent-standard", `${sessionId}.done`),
35383
+ exists: (p2) => fs72.existsSync(p2),
35384
+ write: (p2) => {
35385
+ fs72.mkdirSync(path78.dirname(p2), { recursive: true });
35386
+ fs72.writeFileSync(p2, "");
35387
+ }
35388
+ };
35389
+ function isClaude(agent) {
35390
+ return agent === "claude" || agent === "claude_code";
35391
+ }
35392
+ function maybePrefaceAgentStandard(blocks, agent, sessionId, seam = _agentStandardSeam) {
35393
+ if (seam.isLocalSession()) return;
35394
+ if (isClaude(agent)) return;
35395
+ if (!sessionId) return;
35396
+ const marker = seam.markerPath(sessionId);
35397
+ try {
35398
+ if (seam.exists(marker)) return;
35399
+ seam.write(marker);
35400
+ } catch {
35401
+ return;
35402
+ }
35403
+ blocks.unshift({ type: "text", text: AGENT_STANDARD_TEXT });
35404
+ }
35405
+
35156
35406
  // src/agents/acp/promptEcho.ts
35157
35407
  var MAX_PROMPT_CHARS = 200;
35158
35408
  var MAX_AGENT_REPLY_CHARS = 280;
@@ -35270,6 +35520,7 @@ async function startTaskH(ctx) {
35270
35520
  }
35271
35521
  await streaming.beginTurn();
35272
35522
  history.appendUserPrompt(promptText);
35523
+ maybePrefaceAgentStandard(blocks, opts.agent, opts.sessionId);
35273
35524
  let turnClosed = false;
35274
35525
  try {
35275
35526
  const reply = await client3.prompt(blocks);
@@ -36321,14 +36572,14 @@ var AcpHistory = class {
36321
36572
  async flush() {
36322
36573
  if (this.summary === null || this.messages.length === 0) return;
36323
36574
  const timestamp = Date.now();
36324
- const current = { id: this.opts.acpSessionId, summary: this.summary, timestamp };
36325
- let sessions3 = [current];
36575
+ const current2 = { id: this.opts.acpSessionId, summary: this.summary, timestamp };
36576
+ let sessions3 = [current2];
36326
36577
  const listed = this.opts.listSessions ? await this.opts.listSessions() : null;
36327
36578
  if (listed && listed.length > 0) {
36328
36579
  sessions3 = listed.map(
36329
36580
  (s) => s.id === this.opts.acpSessionId && !s.summary ? { ...s, summary: this.summary } : s
36330
36581
  );
36331
- if (!sessions3.some((s) => s.id === this.opts.acpSessionId)) sessions3.unshift(current);
36582
+ if (!sessions3.some((s) => s.id === this.opts.acpSessionId)) sessions3.unshift(current2);
36332
36583
  }
36333
36584
  await Promise.all([
36334
36585
  this.publisher.pushSessionList({ agentId: this.opts.agent, sessions: sessions3 }),
@@ -36446,6 +36697,7 @@ async function runAcpSession(opts) {
36446
36697
  beginLoadReplay: () => streaming.beginLoadReplay(),
36447
36698
  endLoadReplay: () => streaming.endLoadReplay(),
36448
36699
  onRequestPermission: async (request) => {
36700
+ let guardrailConfirm = false;
36449
36701
  if (!isLocalSession()) {
36450
36702
  const denied = internalPathPermissionOutcome(request);
36451
36703
  if (denied) {
@@ -36455,8 +36707,17 @@ async function runAcpSession(opts) {
36455
36707
  );
36456
36708
  return denied;
36457
36709
  }
36710
+ const g = guardrailDecision(request, getGuardrailPolicy());
36711
+ if (g?.kind === "deny") {
36712
+ log.warn("acpRunner", `guardrail [${g.category}] \u2014 denying tool call`);
36713
+ return g.outcome;
36714
+ }
36715
+ if (g?.kind === "confirm") {
36716
+ guardrailConfirm = true;
36717
+ log.info("acpRunner", `guardrail [${g.category}] \u2014 requiring confirmation`);
36718
+ }
36458
36719
  }
36459
- if (opts.autoApprovePermissions) {
36720
+ if (opts.autoApprovePermissions && !guardrailConfirm) {
36460
36721
  const allow = pickAllowOption(request.options);
36461
36722
  if (allow) {
36462
36723
  log.info(
@@ -37539,21 +37800,21 @@ var StreamingEmitterService = class {
37539
37800
  classifyLines(lines, runtime) {
37540
37801
  const parseLine2 = runtime.parseTuiChrome?.bind(runtime);
37541
37802
  const groups = [];
37542
- let current = null;
37803
+ let current2 = null;
37543
37804
  const flush = () => {
37544
- if (!current) return;
37545
- const text = current.lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
37546
- if (text.length > 0) groups.push({ kind: current.kind, content: text });
37547
- current = null;
37805
+ if (!current2) return;
37806
+ const text = current2.lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
37807
+ if (text.length > 0) groups.push({ kind: current2.kind, content: text });
37808
+ current2 = null;
37548
37809
  };
37549
37810
  for (const rawLine of lines) {
37550
37811
  const kind = classifyLine(rawLine, parseLine2, runtime);
37551
37812
  if (kind === null) continue;
37552
- if (!current || current.kind !== kind) {
37813
+ if (!current2 || current2.kind !== kind) {
37553
37814
  flush();
37554
- current = { kind, lines: [rawLine] };
37815
+ current2 = { kind, lines: [rawLine] };
37555
37816
  } else {
37556
- current.lines.push(rawLine);
37817
+ current2.lines.push(rawLine);
37557
37818
  }
37558
37819
  }
37559
37820
  flush();
@@ -37783,9 +38044,9 @@ function startClaudeCredentialSync(opts) {
37783
38044
  }
37784
38045
 
37785
38046
  // src/beads/workflow-hint.ts
37786
- var fs71 = __toESM(require("fs"));
37787
- var path77 = __toESM(require("path"));
37788
- var os56 = __toESM(require("os"));
38047
+ var fs73 = __toESM(require("fs"));
38048
+ var path79 = __toESM(require("path"));
38049
+ var os58 = __toESM(require("os"));
37789
38050
  var BEADS_HINT_MARKER = "<!-- codeam:beads-workflow -->";
37790
38051
  var BEADS_HINT = `${BEADS_HINT_MARKER}
37791
38052
  # Beads (bd) \u2014 task tracking + persistent memory (ALWAYS use it)
@@ -37799,22 +38060,22 @@ This environment uses **bd (beads)** for issue/task tracking and persistent memo
37799
38060
  - \`bd ready\` (available work) \xB7 \`bd show <id>\` \xB7 \`bd update <id> --claim\` \xB7 \`bd close <id>\`.
37800
38061
  - Use \`bd remember "..."\` for persistent knowledge \u2014 do NOT use MEMORY.md files.
37801
38062
  ${BEADS_HINT_MARKER}`;
37802
- function ensureBeadsWorkflowHint(homeDir2 = os56.homedir()) {
38063
+ function ensureBeadsWorkflowHint(homeDir2 = os58.homedir()) {
37803
38064
  try {
37804
- const file = path77.join(homeDir2, ".claude", "CLAUDE.md");
38065
+ const file = path79.join(homeDir2, ".claude", "CLAUDE.md");
37805
38066
  let existing = "";
37806
38067
  try {
37807
- existing = fs71.readFileSync(file, "utf8");
38068
+ existing = fs73.readFileSync(file, "utf8");
37808
38069
  } catch {
37809
38070
  }
37810
38071
  if (existing.includes(BEADS_HINT_MARKER)) return;
37811
- fs71.mkdirSync(path77.dirname(file), { recursive: true });
38072
+ fs73.mkdirSync(path79.dirname(file), { recursive: true });
37812
38073
  const next = existing.trim() ? `${existing.trimEnd()}
37813
38074
 
37814
38075
  ${BEADS_HINT}
37815
38076
  ` : `${BEADS_HINT}
37816
38077
  `;
37817
- fs71.writeFileSync(file, next);
38078
+ fs73.writeFileSync(file, next);
37818
38079
  } catch {
37819
38080
  }
37820
38081
  }
@@ -37905,14 +38166,14 @@ var BatonController = class {
37905
38166
  async shutdown() {
37906
38167
  await Promise.allSettled([this.deps.local.stop(), this.deps.mobile.stop()]);
37907
38168
  }
37908
- async switchDriver(from, current, next, to, nextKind) {
38169
+ async switchDriver(from, current2, next, to, nextKind) {
37909
38170
  if (this._state !== from) return;
37910
38171
  this.setState("SWITCHING");
37911
38172
  const priorActive = this._active;
37912
38173
  const priorConversationId = this._conversationId;
37913
38174
  try {
37914
- await current.whenSafeToYield();
37915
- await current.stop();
38175
+ await current2.whenSafeToYield();
38176
+ await current2.stop();
37916
38177
  this._conversationId = await next.start(this._conversationId ?? void 0);
37917
38178
  this._active = nextKind;
37918
38179
  this.setState(to);
@@ -38186,7 +38447,7 @@ var AcpDriver = class {
38186
38447
  };
38187
38448
 
38188
38449
  // src/baton/transcript-mirror.ts
38189
- var fs72 = __toESM(require("fs"));
38450
+ var fs74 = __toESM(require("fs"));
38190
38451
  var TranscriptMirror = class {
38191
38452
  constructor(deps) {
38192
38453
  this.deps = deps;
@@ -38253,7 +38514,7 @@ var TranscriptMirror = class {
38253
38514
  }
38254
38515
  };
38255
38516
  function defaultWatch(file, onChange) {
38256
- const w3 = fs72.watch(file, { persistent: false }, () => onChange());
38517
+ const w3 = fs74.watch(file, { persistent: false }, () => onChange());
38257
38518
  return () => w3.close();
38258
38519
  }
38259
38520
 
@@ -38515,16 +38776,16 @@ function toEpochMs(ts) {
38515
38776
  }
38516
38777
 
38517
38778
  // src/agents/claude/onboarding.ts
38518
- var fs73 = __toESM(require("fs"));
38519
- var os58 = __toESM(require("os"));
38520
- var path78 = __toESM(require("path"));
38779
+ var fs75 = __toESM(require("fs"));
38780
+ var os60 = __toESM(require("os"));
38781
+ var path80 = __toESM(require("path"));
38521
38782
  var ONBOARDING_VERSION_SENTINEL = "9999.0.0";
38522
38783
  function ensureClaudeOnboarded(cwd) {
38523
38784
  try {
38524
- const file = path78.join(os58.homedir(), ".claude.json");
38785
+ const file = path80.join(os60.homedir(), ".claude.json");
38525
38786
  let config = {};
38526
38787
  try {
38527
- config = JSON.parse(fs73.readFileSync(file, "utf8"));
38788
+ config = JSON.parse(fs75.readFileSync(file, "utf8"));
38528
38789
  } catch {
38529
38790
  }
38530
38791
  let changed = false;
@@ -38549,8 +38810,8 @@ function ensureClaudeOnboarded(cwd) {
38549
38810
  }
38550
38811
  }
38551
38812
  if (!changed) return;
38552
- fs73.mkdirSync(path78.dirname(file), { recursive: true });
38553
- fs73.writeFileSync(file, JSON.stringify(config, null, 2));
38813
+ fs75.mkdirSync(path80.dirname(file), { recursive: true });
38814
+ fs75.writeFileSync(file, JSON.stringify(config, null, 2));
38554
38815
  log.info(
38555
38816
  "claude",
38556
38817
  `pre-completed Claude onboarding${cwd ? ` + trusted workspace ${cwd}` : ""}`
@@ -38653,6 +38914,9 @@ async function start(requestedAgent, presetSession) {
38653
38914
  let beads = null;
38654
38915
  const getBeads = () => beads;
38655
38916
  ensureBeadsWorkflowHint();
38917
+ if (!isLocalSession() && session.agent === "claude") {
38918
+ ensureAgentStandard();
38919
+ }
38656
38920
  const beadsReady = provisionBeadsForStart({
38657
38921
  sessionId: session.id,
38658
38922
  pluginId,
@@ -39277,7 +39541,7 @@ var import_picocolors11 = __toESM(require("picocolors"));
39277
39541
  var import_child_process29 = require("child_process");
39278
39542
  var import_util4 = require("util");
39279
39543
  var import_picocolors9 = __toESM(require("picocolors"));
39280
- var path79 = __toESM(require("path"));
39544
+ var path81 = __toESM(require("path"));
39281
39545
  var execFileP6 = (0, import_util4.promisify)(import_child_process29.execFile);
39282
39546
  var MAX_BUFFER = 8 * 1024 * 1024;
39283
39547
  function resetStdinForChild() {
@@ -39766,7 +40030,7 @@ var GitHubCodespacesProvider = class {
39766
40030
  });
39767
40031
  }
39768
40032
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
39769
- const remoteDir = path79.posix.dirname(remotePath);
40033
+ const remoteDir = path81.posix.dirname(remotePath);
39770
40034
  const parts = [
39771
40035
  `mkdir -p ${shellQuote(remoteDir)}`,
39772
40036
  `cat > ${shellQuote(remotePath)}`
@@ -39836,7 +40100,7 @@ function shellQuote(s) {
39836
40100
  // src/services/providers/gitpod.ts
39837
40101
  var import_child_process30 = require("child_process");
39838
40102
  var import_util5 = require("util");
39839
- var path80 = __toESM(require("path"));
40103
+ var path82 = __toESM(require("path"));
39840
40104
  var import_picocolors10 = __toESM(require("picocolors"));
39841
40105
  var execFileP7 = (0, import_util5.promisify)(import_child_process30.execFile);
39842
40106
  var MAX_BUFFER2 = 8 * 1024 * 1024;
@@ -40076,7 +40340,7 @@ var GitpodProvider = class {
40076
40340
  });
40077
40341
  }
40078
40342
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
40079
- const remoteDir = path80.posix.dirname(remotePath);
40343
+ const remoteDir = path82.posix.dirname(remotePath);
40080
40344
  const parts = [
40081
40345
  `mkdir -p ${shellQuote2(remoteDir)}`,
40082
40346
  `cat > ${shellQuote2(remotePath)}`
@@ -40112,7 +40376,7 @@ function shellQuote2(s) {
40112
40376
  // src/services/providers/gitlab-workspaces.ts
40113
40377
  var import_child_process31 = require("child_process");
40114
40378
  var import_util6 = require("util");
40115
- var path81 = __toESM(require("path"));
40379
+ var path83 = __toESM(require("path"));
40116
40380
  var execFileP8 = (0, import_util6.promisify)(import_child_process31.execFile);
40117
40381
  var MAX_BUFFER3 = 8 * 1024 * 1024;
40118
40382
  var GITLAB_API_BASE = process.env.CODEAM_GITLAB_API_URL ?? "https://gitlab.com/api/v4";
@@ -40372,7 +40636,7 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
40372
40636
  }
40373
40637
  async uploadFile(workspaceId, remotePath, contents, options = {}) {
40374
40638
  const sshHost = process.env.CODEAM_GITLAB_SSH_HOST ?? "workspaces.gitlab.com";
40375
- const remoteDir = path81.posix.dirname(remotePath);
40639
+ const remoteDir = path83.posix.dirname(remotePath);
40376
40640
  const parts = [`mkdir -p ${shellQuote3(remoteDir)}`, `cat > ${shellQuote3(remotePath)}`];
40377
40641
  if (options.mode != null) {
40378
40642
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote3(remotePath)}`);
@@ -40409,8 +40673,8 @@ Docs: https://docs.gitlab.com/ee/user/workspace/configuration.html`
40409
40673
  ["auth", "status", "--show-token"],
40410
40674
  { maxBuffer: MAX_BUFFER3 }
40411
40675
  );
40412
- const haystack = stdout + "\n" + stderr;
40413
- const m = haystack.match(/Token:\s+(\S+)/);
40676
+ const haystack2 = stdout + "\n" + stderr;
40677
+ const m = haystack2.match(/Token:\s+(\S+)/);
40414
40678
  return m?.[1] ?? null;
40415
40679
  } catch {
40416
40680
  return null;
@@ -40440,7 +40704,7 @@ function shellQuote3(s) {
40440
40704
  // src/services/providers/railway.ts
40441
40705
  var import_child_process32 = require("child_process");
40442
40706
  var import_util7 = require("util");
40443
- var path82 = __toESM(require("path"));
40707
+ var path84 = __toESM(require("path"));
40444
40708
  var execFileP9 = (0, import_util7.promisify)(import_child_process32.execFile);
40445
40709
  var MAX_BUFFER4 = 8 * 1024 * 1024;
40446
40710
  function resetStdinForChild4() {
@@ -40676,7 +40940,7 @@ var RailwayProvider = class {
40676
40940
  if (!projectId || !serviceId) {
40677
40941
  throw new Error("Invalid Railway workspace id (expected projectId/serviceId).");
40678
40942
  }
40679
- const remoteDir = path82.posix.dirname(remotePath);
40943
+ const remoteDir = path84.posix.dirname(remotePath);
40680
40944
  const parts = [`mkdir -p ${shellQuote4(remoteDir)}`, `cat > ${shellQuote4(remotePath)}`];
40681
40945
  if (options.mode != null) {
40682
40946
  parts.push(`chmod ${options.mode.toString(8)} ${shellQuote4(remotePath)}`);
@@ -41322,8 +41586,8 @@ async function invite() {
41322
41586
  var import_node_dns = require("dns");
41323
41587
  var import_node_util5 = require("util");
41324
41588
  var import_node_crypto13 = require("crypto");
41325
- var fs74 = __toESM(require("fs"));
41326
- var path83 = __toESM(require("path"));
41589
+ var fs76 = __toESM(require("fs"));
41590
+ var path85 = __toESM(require("path"));
41327
41591
  var import_picocolors14 = __toESM(require("picocolors"));
41328
41592
  var dnsResolveP = (0, import_node_util5.promisify)(import_node_dns.resolve);
41329
41593
  async function checkDns(apiBase2) {
@@ -41379,13 +41643,13 @@ async function checkHealth(apiBase2) {
41379
41643
  }
41380
41644
  }
41381
41645
  function checkConfigDir() {
41382
- const dir = path83.join(require("os").homedir(), ".codeam");
41646
+ const dir = path85.join(require("os").homedir(), ".codeam");
41383
41647
  try {
41384
- fs74.mkdirSync(dir, { recursive: true, mode: 448 });
41385
- const probe = path83.join(dir, ".doctor-probe");
41386
- fs74.writeFileSync(probe, "ok", { mode: 384 });
41387
- const read2 = fs74.readFileSync(probe, "utf8");
41388
- fs74.unlinkSync(probe);
41648
+ fs76.mkdirSync(dir, { recursive: true, mode: 448 });
41649
+ const probe = path85.join(dir, ".doctor-probe");
41650
+ fs76.writeFileSync(probe, "ok", { mode: 384 });
41651
+ const read2 = fs76.readFileSync(probe, "utf8");
41652
+ fs76.unlinkSync(probe);
41389
41653
  if (read2 !== "ok") throw new Error("write/read round-trip mismatch");
41390
41654
  return {
41391
41655
  id: "config-dir",
@@ -41425,9 +41689,9 @@ function checkSessions() {
41425
41689
  }
41426
41690
  }
41427
41691
  function checkAgentBinaries() {
41428
- const os61 = createOsStrategy();
41692
+ const os63 = createOsStrategy();
41429
41693
  return getEnabledAgents().map((meta) => {
41430
- const found = os61.findInPath(meta.binaryName);
41694
+ const found = os63.findInPath(meta.binaryName);
41431
41695
  return {
41432
41696
  id: `agent-${meta.id}`,
41433
41697
  label: `Agent binary: ${meta.displayName} (${meta.binaryName})`,
@@ -41449,7 +41713,7 @@ function checkNodePty() {
41449
41713
  detail: "not required on this platform"
41450
41714
  };
41451
41715
  }
41452
- const vendoredPath = path83.join(__dirname, "vendor", "node-pty");
41716
+ const vendoredPath = path85.join(__dirname, "vendor", "node-pty");
41453
41717
  for (const target of [vendoredPath, "node-pty"]) {
41454
41718
  try {
41455
41719
  require(target);
@@ -41491,7 +41755,7 @@ function checkChokidar() {
41491
41755
  }
41492
41756
  async function doctor(args2 = []) {
41493
41757
  const json = args2.includes("--json");
41494
- const cliVersion = true ? "2.61.87" : "0.0.0-dev";
41758
+ const cliVersion = true ? "2.61.89" : "0.0.0-dev";
41495
41759
  const apiBase2 = resolveApiBaseUrl();
41496
41760
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
41497
41761
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -41863,18 +42127,18 @@ async function mcpRun(args2) {
41863
42127
  pluginAuthToken,
41864
42128
  pollSecret: process.env.CODEAM_MCP_POLL_SECRET
41865
42129
  });
41866
- let current = null;
42130
+ let current2 = null;
41867
42131
  const proxy = new RestartableStdioProxy({
41868
42132
  spawnSpec: async () => {
41869
- current = await client3.getToken(id);
42133
+ current2 = await client3.getToken(id);
41870
42134
  const env = { ...delivery.staticEnv };
41871
42135
  for (const [envVar, field] of Object.entries(delivery.envMapping)) {
41872
- const value = current[field];
42136
+ const value = current2[field];
41873
42137
  if (typeof value === "string" && value) env[envVar] = value;
41874
42138
  }
41875
42139
  return { command: launcher, args: delivery.args, env };
41876
42140
  },
41877
- shouldRestartNow: () => current !== null && new Date(current.expiresAt).getTime() - Date.now() < RESTART_AHEAD_MS
42141
+ shouldRestartNow: () => current2 !== null && new Date(current2.expiresAt).getTime() - Date.now() < RESTART_AHEAD_MS
41878
42142
  });
41879
42143
  await proxy.start();
41880
42144
  }
@@ -41882,7 +42146,7 @@ async function mcpRun(args2) {
41882
42146
  // src/commands/version.ts
41883
42147
  var import_picocolors15 = __toESM(require("picocolors"));
41884
42148
  function version2() {
41885
- const v = true ? "2.61.87" : "unknown";
42149
+ const v = true ? "2.61.89" : "unknown";
41886
42150
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
41887
42151
  }
41888
42152
 
@@ -42031,10 +42295,10 @@ var EXIT_CODE_NAMES = {
42031
42295
  };
42032
42296
 
42033
42297
  // src/index.ts
42034
- var os60 = __toESM(require("os"));
42298
+ var os62 = __toESM(require("os"));
42035
42299
  if (!process.env.HOME) {
42036
42300
  try {
42037
- const home = os60.homedir();
42301
+ const home = os62.homedir();
42038
42302
  if (home) process.env.HOME = home;
42039
42303
  } catch {
42040
42304
  }