codeam-cli 2.65.2 → 2.65.4

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 +16 -0
  2. package/dist/index.js +841 -743
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -976,6 +976,12 @@ var PUBLIC_TO_INTERNAL = {
976
976
  // MiniMax proxy). Its internal runtime is therefore `claude`.
977
977
  [HOUSE_AGENT_ID]: "claude"
978
978
  };
979
+ function isPublicToInternalKey(v) {
980
+ return Object.prototype.hasOwnProperty.call(PUBLIC_TO_INTERNAL, v);
981
+ }
982
+ function publicToInternal(publicId) {
983
+ return isPublicToInternalKey(publicId) ? PUBLIC_TO_INTERNAL[publicId] : null;
984
+ }
979
985
  var TERMINAL_AGENT_PREFIX = "__terminal__:";
980
986
  var AGENT_ID_ALIASES = {
981
987
  claude_code: "claude",
@@ -3321,9 +3327,9 @@ var _default = makeConfig();
3321
3327
  var { getConfig, ensurePluginId, addSession, removeSession, setActiveSession, getActiveSession, getActiveSessionForAgent, setDisable1mContext, setSessionAgent, setSquadAuto, getSquadAuto, clearAll, saveCliConfig, loadCliConfig } = _default;
3322
3328
 
3323
3329
  // src/commands/pair-auto.ts
3324
- var fs64 = __toESM(require("fs"));
3325
- var os54 = __toESM(require("os"));
3326
- var path69 = __toESM(require("path"));
3330
+ var fs65 = __toESM(require("fs"));
3331
+ var os55 = __toESM(require("os"));
3332
+ var path70 = __toESM(require("path"));
3327
3333
  var import_crypto4 = require("crypto");
3328
3334
 
3329
3335
  // src/services/telemetry.service.ts
@@ -8073,7 +8079,7 @@ function readAnonId() {
8073
8079
  }
8074
8080
  function superProperties() {
8075
8081
  return {
8076
- cliVersion: true ? "2.65.2" : "0.0.0-dev",
8082
+ cliVersion: true ? "2.65.4" : "0.0.0-dev",
8077
8083
  nodeVersion: process.version,
8078
8084
  platform: process.platform,
8079
8085
  arch: process.arch,
@@ -8254,7 +8260,7 @@ var os4 = __toESM(require("os"));
8254
8260
  // package.json
8255
8261
  var package_default = {
8256
8262
  name: "codeam-cli",
8257
- version: "2.65.2",
8263
+ version: "2.65.4",
8258
8264
  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.",
8259
8265
  type: "commonjs",
8260
8266
  main: "dist/index.js",
@@ -9706,7 +9712,7 @@ var CommandRelayService = class _CommandRelayService {
9706
9712
  // fresh + clear the "CLI update available" banner after a self-update
9707
9713
  // (a codespace that reinstalls @latest reconnects via heartbeat, not
9708
9714
  // pair/reconnect). Older backends ignore the extra field.
9709
- ..."2.65.2" ? { ideVersion: "2.65.2" } : {}
9715
+ ..."2.65.4" ? { ideVersion: "2.65.4" } : {}
9710
9716
  }).then(() => log.trace("relay", `heartbeat ok online=${online}`)).catch((err) => log.trace("relay", `heartbeat failed online=${online}`, err));
9711
9717
  }
9712
9718
  /**
@@ -11098,9 +11104,9 @@ function closeAllTerminals() {
11098
11104
  }
11099
11105
 
11100
11106
  // src/commands/start/handlers.ts
11101
- var fs63 = __toESM(require("fs"));
11102
- var os53 = __toESM(require("os"));
11103
- var path68 = __toESM(require("path"));
11107
+ var fs64 = __toESM(require("fs"));
11108
+ var os54 = __toESM(require("os"));
11109
+ var path69 = __toESM(require("path"));
11104
11110
  var import_crypto3 = require("crypto");
11105
11111
  var import_child_process26 = require("child_process");
11106
11112
 
@@ -11932,8 +11938,8 @@ function findGitRoot2(startDir) {
11932
11938
 
11933
11939
  // src/commands/link.ts
11934
11940
  var import_node_crypto8 = require("crypto");
11935
- var fs32 = __toESM(require("fs"));
11936
- var path37 = __toESM(require("path"));
11941
+ var fs33 = __toESM(require("fs"));
11942
+ var path38 = __toESM(require("path"));
11937
11943
  var import_chokidar = __toESM(require("chokidar"));
11938
11944
  var import_picocolors2 = __toESM(require("picocolors"));
11939
11945
 
@@ -15556,12 +15562,310 @@ var ClaudeDeployStrategy = class {
15556
15562
 
15557
15563
  // src/agents/codex/runtime.ts
15558
15564
  var import_node_child_process5 = require("child_process");
15559
- var path25 = __toESM(require("path"));
15565
+ var path26 = __toESM(require("path"));
15560
15566
 
15561
15567
  // src/agents/codex/history.ts
15562
15568
  var import_node_fs3 = __toESM(require("fs"));
15563
15569
  var import_node_path2 = __toESM(require("path"));
15564
15570
  var import_node_os = __toESM(require("os"));
15571
+
15572
+ // src/agents/acp/squad-roster.ts
15573
+ var fs20 = __toESM(require("fs"));
15574
+ var os18 = __toESM(require("os"));
15575
+ var path23 = __toESM(require("path"));
15576
+ var PROMPT_MAX = 500;
15577
+ var REPLY_SUMMARY_MAX = 1e3;
15578
+ var PREAMBLE_MAX = 2e3;
15579
+ var BRIEFING_DEFAULT_MAX = 8e3;
15580
+ var GENERIC_SPECIALTY = "general implementation tasks";
15581
+ function clip(s, max) {
15582
+ return s.length > max ? s.slice(0, max) : s;
15583
+ }
15584
+ function defaultMember() {
15585
+ return {
15586
+ acpSessionId: null,
15587
+ provisioned: false,
15588
+ binaryVerified: false,
15589
+ lastTurnIndex: 0,
15590
+ contextTextFallback: false
15591
+ };
15592
+ }
15593
+ function journalPathFor(homeDir2, sessionId) {
15594
+ return path23.join(homeDir2, ".codeam", `squad-journal-${sessionId}.json`);
15595
+ }
15596
+ function loadJournal(journalPath) {
15597
+ try {
15598
+ const raw = JSON.parse(fs20.readFileSync(journalPath, "utf-8"));
15599
+ return Array.isArray(raw.turns) ? raw.turns : [];
15600
+ } catch {
15601
+ return [];
15602
+ }
15603
+ }
15604
+ var SquadState = class {
15605
+ /** Set by the caller after fetchSquadRoster; null until then. */
15606
+ roster = null;
15607
+ /**
15608
+ * Autonomous chained handoffs (P2-2, PRO). Seeded from the persisted
15609
+ * `SavedSession.squadAuto` at session start and rewritten by
15610
+ * `squad_configure`. Read-only to callers — mutate via {@link setAuto}, which
15611
+ * clamps the budget and re-arms the chain.
15612
+ */
15613
+ autoConfig = { enabled: false, hopBudget: SQUAD_HOP_BUDGET_DEFAULT };
15614
+ /**
15615
+ * Hops left in the CURRENT chain. Reset to the budget on every USER-initiated
15616
+ * prompt (so a user turn always interrupts and re-arms) and decremented by
15617
+ * each self-accepted handoff.
15618
+ */
15619
+ hopsLeft = 0;
15620
+ /** Lifetime handoff counters for `squad_stats` (in-memory, this process). */
15621
+ handoffCounters = { proposed: 0, accepted: 0, auto: 0 };
15622
+ journalPath;
15623
+ turns;
15624
+ members = /* @__PURE__ */ new Map();
15625
+ constructor(opts) {
15626
+ this.journalPath = journalPathFor(opts.homeDir ?? os18.homedir(), opts.sessionId);
15627
+ this.turns = loadJournal(this.journalPath);
15628
+ if (opts.auto) this.setAuto(opts.auto);
15629
+ }
15630
+ get auto() {
15631
+ return this.autoConfig;
15632
+ }
15633
+ /** Apply a new mode (clamping the budget) and re-arm the chain. */
15634
+ setAuto(value) {
15635
+ this.autoConfig = {
15636
+ enabled: value.enabled === true,
15637
+ hopBudget: clampHopBudget(value.hopBudget)
15638
+ };
15639
+ this.resetHops();
15640
+ return this.autoConfig;
15641
+ }
15642
+ hopsRemaining() {
15643
+ return this.hopsLeft;
15644
+ }
15645
+ /** Re-arm the chain — called at the start of every USER-initiated turn. */
15646
+ resetHops() {
15647
+ this.hopsLeft = this.autoConfig.enabled ? this.autoConfig.hopBudget : 0;
15648
+ }
15649
+ /** Spend one hop on a self-accepted handoff. */
15650
+ consumeHop() {
15651
+ if (this.hopsLeft > 0) this.hopsLeft -= 1;
15652
+ }
15653
+ countProposal(opts) {
15654
+ this.handoffCounters.proposed += 1;
15655
+ if (opts.auto) this.handoffCounters.auto += 1;
15656
+ }
15657
+ countAccepted() {
15658
+ this.handoffCounters.accepted += 1;
15659
+ }
15660
+ /**
15661
+ * Per-member activity for the `squad_stats` relay command, derived from the
15662
+ * journal (the same shared history the delta briefing reads) plus the
15663
+ * in-memory handoff counters. `filesTouched` counts DISTINCT paths — a member
15664
+ * that edited the same file across three turns touched ONE file.
15665
+ */
15666
+ stats() {
15667
+ const byAgent = /* @__PURE__ */ new Map();
15668
+ for (const t2 of this.turns) {
15669
+ let row = byAgent.get(t2.agentId);
15670
+ if (!row) {
15671
+ row = { turns: 0, files: /* @__PURE__ */ new Set() };
15672
+ byAgent.set(t2.agentId, row);
15673
+ }
15674
+ row.turns += 1;
15675
+ for (const f of t2.filesTouched) row.files.add(f);
15676
+ }
15677
+ const members = [...byAgent.entries()].map(([agentId, row]) => ({
15678
+ agentId,
15679
+ turns: row.turns,
15680
+ filesTouched: row.files.size
15681
+ }));
15682
+ return { members, handoffs: { ...this.handoffCounters }, sinceTurn: 1 };
15683
+ }
15684
+ /** Returns (creating on first access) the mutable per-agent state. */
15685
+ member(agentId) {
15686
+ let m = this.members.get(agentId);
15687
+ if (!m) {
15688
+ m = defaultMember();
15689
+ this.members.set(agentId, m);
15690
+ }
15691
+ return m;
15692
+ }
15693
+ /** Appends a journal entry and persists (fire-and-forget durability). */
15694
+ recordTurn(entry) {
15695
+ const turn = {
15696
+ turn: this.turns.length + 1,
15697
+ agentId: entry.agentId,
15698
+ prompt: clip(entry.prompt, PROMPT_MAX),
15699
+ replySummary: clip(entry.replySummary, REPLY_SUMMARY_MAX),
15700
+ filesTouched: entry.filesTouched
15701
+ };
15702
+ this.turns.push(turn);
15703
+ this.persist();
15704
+ }
15705
+ turnCount() {
15706
+ return this.turns.length;
15707
+ }
15708
+ entriesSince(turnIndex) {
15709
+ return this.turns.filter((t2) => t2.turn > turnIndex);
15710
+ }
15711
+ persist() {
15712
+ try {
15713
+ fs20.mkdirSync(path23.dirname(this.journalPath), { recursive: true, mode: 448 });
15714
+ fs20.writeFileSync(this.journalPath, JSON.stringify({ turns: this.turns }), { mode: 384 });
15715
+ } catch {
15716
+ }
15717
+ }
15718
+ };
15719
+ function specialtyFor(agentId) {
15720
+ return SQUAD_SPECIALTIES[agentId] ?? GENERIC_SPECIALTY;
15721
+ }
15722
+ var TEAM_PREAMBLE_MARKER = "[Team context]";
15723
+ var TEAM_PREAMBLE_LINES = [
15724
+ "[Team context] You are the active agent in a CodeAgent Mobile session where the user",
15725
+ "has a squad of agents and can pass work between them. Your available teammates:",
15726
+ "If a task clearly fits a teammate better than you, you MAY propose a handoff. The fence",
15727
+ `MUST be a three-backtick code block with the info string exactly ${HANDOFF_FENCE_TAG}`,
15728
+ "(never a single backtick, never bare text) with the JSON alone on its own line inside",
15729
+ "it, exactly like this:",
15730
+ "```" + HANDOFF_FENCE_TAG,
15731
+ '{"to":"<teammate id>","reason":"<one sentence>","prompt":"<the prompt they should run>"}',
15732
+ "```",
15733
+ '"to" MUST be one of the ids shown above, written EXACTLY as shown (e.g. "claude", never',
15734
+ 'a display name like "Claude Code"). Propose at most one handoff per reply, only when',
15735
+ "genuinely better, and never announce the block in prose \u2014 the app renders it as a card",
15736
+ "the user can accept."
15737
+ ];
15738
+ var TEAM_PREAMBLE_BULLET_RE = /^- .+ — best at: /;
15739
+ var BRIEFING_MARKER = "[Team update]";
15740
+ var BRIEFING_HEADER = "[Team update] While you were away, other agents worked on this session:";
15741
+ var BRIEFING_FOOTER = "Continue from the CURRENT state of the working tree.";
15742
+ function buildTeamPreamble(roster, currentAgent, opts) {
15743
+ const others = roster.agents.filter((a) => a.agentId !== currentAgent);
15744
+ if (others.length === 0) return null;
15745
+ const lines = [
15746
+ TEAM_PREAMBLE_LINES[0],
15747
+ TEAM_PREAMBLE_LINES[1],
15748
+ ...others.map(
15749
+ (a) => `- ${a.displayName} (id: ${a.agentId}) \u2014 best at: ${specialtyFor(a.agentId)}`
15750
+ )
15751
+ ];
15752
+ if (opts.handoffInstructions) {
15753
+ lines.push(...TEAM_PREAMBLE_LINES.slice(2));
15754
+ }
15755
+ return clip(lines.join("\n"), PREAMBLE_MAX);
15756
+ }
15757
+ function renderJournalEntry(e) {
15758
+ const filesClause = e.filesTouched.length > 0 ? ` (files: ${e.filesTouched.join(", ")})` : "";
15759
+ return `- turn ${e.turn} (${e.agentId}): ${e.prompt} \u2192 ${e.replySummary}${filesClause}`;
15760
+ }
15761
+ function buildDeltaBriefing(entries, maxChars = BRIEFING_DEFAULT_MAX) {
15762
+ if (entries.length === 0) return null;
15763
+ const header = BRIEFING_HEADER;
15764
+ const footer = BRIEFING_FOOTER;
15765
+ const envelope = header.length + 1 + footer.length + 1;
15766
+ const sorted = [...entries].sort((a, b) => a.turn - b.turn);
15767
+ const lines = [];
15768
+ let bodyLen = 0;
15769
+ for (let i = sorted.length - 1; i >= 0; i--) {
15770
+ const line = renderJournalEntry(sorted[i]);
15771
+ const addedLen = line.length + (lines.length > 0 ? 1 : 0);
15772
+ if (lines.length > 0 && envelope + bodyLen + addedLen > maxChars) break;
15773
+ lines.unshift(line);
15774
+ bodyLen += addedLen;
15775
+ }
15776
+ return [header, lines.join("\n"), footer].join("\n");
15777
+ }
15778
+
15779
+ // src/agents/acp/squad-context.ts
15780
+ var SQUAD_CONTEXT_URI = "codeam://squad-context";
15781
+ var HANDOFF_MARKER = "[Session handoff]";
15782
+ var HANDOFF_TERMINATOR = "--- End of handoff context ---";
15783
+ function buildSquadContextBlock(text) {
15784
+ return {
15785
+ type: "resource",
15786
+ resource: { uri: SQUAD_CONTEXT_URI, mimeType: "text/plain", text }
15787
+ };
15788
+ }
15789
+ function isSquadContextBlock(block) {
15790
+ return block.type === "resource" && block.resource.uri === SQUAD_CONTEXT_URI;
15791
+ }
15792
+ function isLeakedSquadContextText(text) {
15793
+ return text.trim().startsWith(SQUAD_CONTEXT_URI);
15794
+ }
15795
+ function looksLikeUnsupportedPromptShape(err) {
15796
+ const code = err?.code;
15797
+ if (code === -32602) return true;
15798
+ const message = err instanceof Error ? err.message : String(err ?? "");
15799
+ if (/invalid[ _]params|-32602/i.test(message)) return true;
15800
+ return /\bresource\b/i.test(message) && /unsupported|not supported/i.test(message);
15801
+ }
15802
+ function skipWhile(lines, start2, keepGoing) {
15803
+ let i = start2;
15804
+ while (i < lines.length && keepGoing(lines[i])) i++;
15805
+ return i;
15806
+ }
15807
+ function endOfTeamPreamble(lines, start2) {
15808
+ if (lines[start2] !== TEAM_PREAMBLE_LINES[0]) return -1;
15809
+ if (lines[start2 + 1] !== TEAM_PREAMBLE_LINES[1]) return -1;
15810
+ return skipWhile(
15811
+ lines,
15812
+ start2 + 2,
15813
+ (line) => TEAM_PREAMBLE_BULLET_RE.test(line) || TEAM_PREAMBLE_LINES.includes(line)
15814
+ );
15815
+ }
15816
+ function endOfTerminatedBlock(lines, start2, terminator) {
15817
+ for (let i = start2; i < lines.length; i++) {
15818
+ if (lines[i].trimEnd() === terminator) return i + 1;
15819
+ }
15820
+ return -1;
15821
+ }
15822
+ function stripSquadContext(text) {
15823
+ if (!text.includes(HANDOFF_MARKER) && !text.includes(BRIEFING_MARKER) && !text.includes(TEAM_PREAMBLE_MARKER)) {
15824
+ return text;
15825
+ }
15826
+ const lines = text.split("\n");
15827
+ const kept = [];
15828
+ let i = 0;
15829
+ let stripped = false;
15830
+ while (i < lines.length) {
15831
+ const line = lines[i];
15832
+ if (line.startsWith(HANDOFF_MARKER)) {
15833
+ const end = endOfTerminatedBlock(lines, i, HANDOFF_TERMINATOR);
15834
+ if (end !== -1) {
15835
+ i = end;
15836
+ stripped = true;
15837
+ continue;
15838
+ }
15839
+ } else if (line.startsWith(BRIEFING_MARKER)) {
15840
+ const end = endOfTerminatedBlock(lines, i, BRIEFING_FOOTER);
15841
+ if (end !== -1) {
15842
+ i = end;
15843
+ stripped = true;
15844
+ continue;
15845
+ }
15846
+ } else if (line.startsWith(TEAM_PREAMBLE_MARKER)) {
15847
+ const end = endOfTeamPreamble(lines, i);
15848
+ if (end !== -1) {
15849
+ i = end;
15850
+ stripped = true;
15851
+ continue;
15852
+ }
15853
+ }
15854
+ kept.push(line);
15855
+ i++;
15856
+ }
15857
+ if (!stripped) return text;
15858
+ return kept.join("\n").trim();
15859
+ }
15860
+
15861
+ // src/agents/acp/agent-meta-blocks.ts
15862
+ var AGENT_META_BLOCK_MARKERS = ["<recommended_plugins>"];
15863
+ function isAgentMetaBlock(text) {
15864
+ const trimmed = text.trim();
15865
+ return AGENT_META_BLOCK_MARKERS.some((marker) => trimmed.startsWith(marker));
15866
+ }
15867
+
15868
+ // src/agents/codex/history.ts
15565
15869
  function resolveHistoryDir2(_cwd, homeOverride) {
15566
15870
  const home = homeOverride ?? import_node_os.default.homedir();
15567
15871
  const sessionsRoot = import_node_path2.default.join(home, ".codex", "sessions");
@@ -15620,6 +15924,8 @@ function isSyntheticCodexTurn(role, text) {
15620
15924
  if (trimmed.startsWith("<environment_context>")) return true;
15621
15925
  if (trimmed.startsWith("<turn_aborted>")) return true;
15622
15926
  if (/^(<<ccr:[^>]*>>\s*)+$/.test(trimmed)) return true;
15927
+ if (isLeakedSquadContextText(trimmed)) return true;
15928
+ if (isAgentMetaBlock(trimmed)) return true;
15623
15929
  return false;
15624
15930
  }
15625
15931
  function parseHistoryFile2(filePath) {
@@ -15916,16 +16222,16 @@ function getCurrentUsage2(historyDir) {
15916
16222
  var import_node_child_process4 = require("child_process");
15917
16223
 
15918
16224
  // src/agents/codex/local-token.ts
15919
- var fs21 = __toESM(require("fs"));
15920
- var os19 = __toESM(require("os"));
15921
- var path24 = __toESM(require("path"));
16225
+ var fs22 = __toESM(require("fs"));
16226
+ var os20 = __toESM(require("os"));
16227
+ var path25 = __toESM(require("path"));
15922
16228
  function codexCredentialsPath() {
15923
- return path24.join(os19.homedir(), ".codex", "auth.json");
16229
+ return path25.join(os20.homedir(), ".codex", "auth.json");
15924
16230
  }
15925
16231
  async function extractLocalCodexToken() {
15926
16232
  const file = codexCredentialsPath();
15927
- if (!fs21.existsSync(file)) return null;
15928
- const credential = fs21.readFileSync(file, "utf8").trim();
16233
+ if (!fs22.existsSync(file)) return null;
16234
+ const credential = fs22.readFileSync(file, "utf8").trim();
15929
16235
  if (credential.length === 0) return null;
15930
16236
  return { method: "oauth", credential, source: "flat-file" };
15931
16237
  }
@@ -16148,7 +16454,7 @@ function augmentNpmGlobalBin(os67) {
16148
16454
  if (result.status !== 0) return;
16149
16455
  const prefix = result.stdout.toString().trim();
16150
16456
  if (!prefix) return;
16151
- const binDir = os67.id === "win32" ? prefix : path25.join(prefix, "bin");
16457
+ const binDir = os67.id === "win32" ? prefix : path26.join(prefix, "bin");
16152
16458
  os67.augmentPath([binDir]);
16153
16459
  } catch {
16154
16460
  }
@@ -16233,7 +16539,7 @@ var import_node_child_process9 = require("child_process");
16233
16539
  // src/agents/coderabbit/installer.ts
16234
16540
  var import_node_child_process7 = require("child_process");
16235
16541
  var import_node_fs5 = require("fs");
16236
- var path27 = __toESM(require("path"));
16542
+ var path28 = __toESM(require("path"));
16237
16543
 
16238
16544
  // src/commands/host/os-packages.ts
16239
16545
  var import_node_child_process6 = require("child_process");
@@ -16564,7 +16870,7 @@ function writeUnzipShim(os67, runner) {
16564
16870
  const python = ["python3", "python"].find((p2) => runner.which(p2));
16565
16871
  if (!python) return null;
16566
16872
  const dir = os67.scratchPath("codeam-cr-prereq");
16567
- const shim = path27.join(dir, "unzip");
16873
+ const shim = path28.join(dir, "unzip");
16568
16874
  const script = `#!/bin/sh
16569
16875
  set -e
16570
16876
  archive=""
@@ -16714,9 +17020,9 @@ async function ensureCoderabbitInstalled(os67, deps = {}) {
16714
17020
 
16715
17021
  // src/agents/coderabbit/link.ts
16716
17022
  var import_node_child_process8 = require("child_process");
16717
- var fs23 = __toESM(require("fs"));
16718
- var os21 = __toESM(require("os"));
16719
- var path28 = __toESM(require("path"));
17023
+ var fs24 = __toESM(require("fs"));
17024
+ var os22 = __toESM(require("os"));
17025
+ var path29 = __toESM(require("path"));
16720
17026
 
16721
17027
  // src/agents/strategy.ts
16722
17028
  function validateNonEmptyCredential(token) {
@@ -16725,12 +17031,12 @@ function validateNonEmptyCredential(token) {
16725
17031
 
16726
17032
  // src/agents/coderabbit/link.ts
16727
17033
  function authPath() {
16728
- return path28.join(os21.homedir(), ".coderabbit", "auth.json");
17034
+ return path29.join(os22.homedir(), ".coderabbit", "auth.json");
16729
17035
  }
16730
17036
  async function extractLocalCoderabbitToken() {
16731
17037
  const file = authPath();
16732
- if (!fs23.existsSync(file)) return null;
16733
- const credential = fs23.readFileSync(file, "utf8").trim();
17038
+ if (!fs24.existsSync(file)) return null;
17039
+ const credential = fs24.readFileSync(file, "utf8").trim();
16734
17040
  if (credential.length === 0) return null;
16735
17041
  return { method: "oauth", credential, source: "flat-file" };
16736
17042
  }
@@ -17074,39 +17380,39 @@ CodeRabbit review timed out after ${Math.round(
17074
17380
  };
17075
17381
 
17076
17382
  // src/agents/cursor/history.ts
17077
- var fs24 = __toESM(require("fs"));
17078
- var os22 = __toESM(require("os"));
17079
- var path29 = __toESM(require("path"));
17383
+ var fs25 = __toESM(require("fs"));
17384
+ var os23 = __toESM(require("os"));
17385
+ var path30 = __toESM(require("path"));
17080
17386
  var import_node_crypto5 = require("crypto");
17081
- var HISTORY_ROOT = path29.join(os22.homedir(), ".cursor", "projects");
17082
- var CURSOR_HOME = path29.join(os22.homedir(), ".cursor");
17387
+ var HISTORY_ROOT = path30.join(os23.homedir(), ".cursor", "projects");
17388
+ var CURSOR_HOME = path30.join(os23.homedir(), ".cursor");
17083
17389
  var STORE_FILES = ["store.db", "store.db-wal", "store.db-shm"];
17084
17390
  function acpSessionDir(sessionId) {
17085
- return path29.join(CURSOR_HOME, "acp-sessions", sessionId);
17391
+ return path30.join(CURSOR_HOME, "acp-sessions", sessionId);
17086
17392
  }
17087
17393
  function nativeStoreDir(cwd, sessionId) {
17088
- const chatsRoot = path29.join(CURSOR_HOME, "chats");
17394
+ const chatsRoot = path30.join(CURSOR_HOME, "chats");
17089
17395
  let buckets = [];
17090
17396
  try {
17091
- buckets = fs24.readdirSync(chatsRoot);
17397
+ buckets = fs25.readdirSync(chatsRoot);
17092
17398
  } catch {
17093
17399
  }
17094
17400
  for (const b of buckets) {
17095
- const candidate = path29.join(chatsRoot, b, sessionId);
17096
- if (fs24.existsSync(path29.join(candidate, "store.db"))) return candidate;
17401
+ const candidate = path30.join(chatsRoot, b, sessionId);
17402
+ if (fs25.existsSync(path30.join(candidate, "store.db"))) return candidate;
17097
17403
  }
17098
- const computed = path29.join(chatsRoot, (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
17099
- return fs24.existsSync(computed) ? computed : null;
17404
+ const computed = path30.join(chatsRoot, (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
17405
+ return fs25.existsSync(computed) ? computed : null;
17100
17406
  }
17101
17407
  function copyStoreFiles(srcDir, dstDir) {
17102
- fs24.mkdirSync(dstDir, { recursive: true });
17408
+ fs25.mkdirSync(dstDir, { recursive: true });
17103
17409
  for (const f of STORE_FILES) {
17104
- const dst = path29.join(dstDir, f);
17105
- if (fs24.existsSync(dst)) fs24.rmSync(dst, { force: true });
17410
+ const dst = path30.join(dstDir, f);
17411
+ if (fs25.existsSync(dst)) fs25.rmSync(dst, { force: true });
17106
17412
  }
17107
17413
  for (const f of STORE_FILES) {
17108
- const src = path29.join(srcDir, f);
17109
- if (fs24.existsSync(src)) fs24.copyFileSync(src, path29.join(dstDir, f));
17414
+ const src = path30.join(srcDir, f);
17415
+ if (fs25.existsSync(src)) fs25.copyFileSync(src, path30.join(dstDir, f));
17110
17416
  }
17111
17417
  }
17112
17418
  function bridgeNativeToAcp(cwd, sessionId) {
@@ -17118,8 +17424,8 @@ function bridgeNativeToAcp(cwd, sessionId) {
17118
17424
  }
17119
17425
  const dst = acpSessionDir(sessionId);
17120
17426
  copyStoreFiles(src, dst);
17121
- fs24.writeFileSync(
17122
- path29.join(dst, "meta.json"),
17427
+ fs25.writeFileSync(
17428
+ path30.join(dst, "meta.json"),
17123
17429
  JSON.stringify({ schemaVersion: 1, cwd })
17124
17430
  );
17125
17431
  log.info("cursor", `baton bridge native\u2192acp ok (${sessionId.slice(0, 8)})`);
@@ -17130,11 +17436,11 @@ function bridgeNativeToAcp(cwd, sessionId) {
17130
17436
  function bridgeAcpToNative(cwd, sessionId) {
17131
17437
  try {
17132
17438
  const src = acpSessionDir(sessionId);
17133
- if (!fs24.existsSync(path29.join(src, "store.db"))) {
17439
+ if (!fs25.existsSync(path30.join(src, "store.db"))) {
17134
17440
  log.warn("cursor", `baton bridge: no acp store for ${sessionId.slice(0, 8)} \u2014 skip`);
17135
17441
  return;
17136
17442
  }
17137
- const dst = nativeStoreDir(cwd, sessionId) ?? path29.join(CURSOR_HOME, "chats", (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
17443
+ const dst = nativeStoreDir(cwd, sessionId) ?? path30.join(CURSOR_HOME, "chats", (0, import_node_crypto5.createHash)("md5").update(cwd).digest("hex"), sessionId);
17138
17444
  copyStoreFiles(src, dst);
17139
17445
  log.info("cursor", `baton bridge acp\u2192native ok (${sessionId.slice(0, 8)})`);
17140
17446
  } catch (err) {
@@ -17145,26 +17451,26 @@ function encodeCursorCwd(cwd) {
17145
17451
  return cwd.replace(/^[/\\]+/, "").replace(/[/\\:]/g, "-");
17146
17452
  }
17147
17453
  function resolveHistoryFile3(cwd, sessionId, root = HISTORY_ROOT) {
17148
- const rel = path29.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
17149
- const primary = path29.join(root, encodeCursorCwd(cwd), rel);
17150
- if (fs24.existsSync(primary)) return primary;
17454
+ const rel = path30.join("agent-transcripts", sessionId, `${sessionId}.jsonl`);
17455
+ const primary = path30.join(root, encodeCursorCwd(cwd), rel);
17456
+ if (fs25.existsSync(primary)) return primary;
17151
17457
  let entries;
17152
17458
  try {
17153
- entries = fs24.readdirSync(root, { withFileTypes: true });
17459
+ entries = fs25.readdirSync(root, { withFileTypes: true });
17154
17460
  } catch {
17155
17461
  return null;
17156
17462
  }
17157
17463
  for (const e of entries) {
17158
17464
  if (!e.isDirectory()) continue;
17159
- const candidate = path29.join(root, e.name, rel);
17160
- if (fs24.existsSync(candidate)) return candidate;
17465
+ const candidate = path30.join(root, e.name, rel);
17466
+ if (fs25.existsSync(candidate)) return candidate;
17161
17467
  }
17162
17468
  return null;
17163
17469
  }
17164
17470
  function resolveHistoryDir3(cwd) {
17165
- if (!fs24.existsSync(HISTORY_ROOT)) return null;
17166
- const dir = path29.join(HISTORY_ROOT, encodeCursorCwd(cwd));
17167
- return fs24.existsSync(dir) ? dir : null;
17471
+ if (!fs25.existsSync(HISTORY_ROOT)) return null;
17472
+ const dir = path30.join(HISTORY_ROOT, encodeCursorCwd(cwd));
17473
+ return fs25.existsSync(dir) ? dir : null;
17168
17474
  }
17169
17475
  function extractText2(content) {
17170
17476
  if (!Array.isArray(content)) return "";
@@ -17177,7 +17483,7 @@ function unwrapUserQuery(text) {
17177
17483
  function parseHistoryFile3(filePath) {
17178
17484
  let raw;
17179
17485
  try {
17180
- raw = fs24.readFileSync(filePath, "utf8");
17486
+ raw = fs25.readFileSync(filePath, "utf8");
17181
17487
  } catch {
17182
17488
  return [];
17183
17489
  }
@@ -17215,16 +17521,16 @@ function getCurrentUsage3(_historyDir) {
17215
17521
  var import_node_child_process10 = require("child_process");
17216
17522
 
17217
17523
  // src/agents/cursor/local-token.ts
17218
- var fs25 = __toESM(require("fs"));
17219
- var os23 = __toESM(require("os"));
17220
- var path30 = __toESM(require("path"));
17524
+ var fs26 = __toESM(require("fs"));
17525
+ var os24 = __toESM(require("os"));
17526
+ var path31 = __toESM(require("path"));
17221
17527
  function cursorCredentialsPath() {
17222
- return path30.join(os23.homedir(), ".cursor", "auth.json");
17528
+ return path31.join(os24.homedir(), ".cursor", "auth.json");
17223
17529
  }
17224
17530
  async function extractLocalCursorToken() {
17225
17531
  const file = cursorCredentialsPath();
17226
- if (!fs25.existsSync(file)) return null;
17227
- const credential = fs25.readFileSync(file, "utf8").trim();
17532
+ if (!fs26.existsSync(file)) return null;
17533
+ const credential = fs26.readFileSync(file, "utf8").trim();
17228
17534
  if (credential.length === 0) return null;
17229
17535
  return { method: "oauth", credential, source: "flat-file" };
17230
17536
  }
@@ -17467,12 +17773,12 @@ var CursorRuntimeStrategy = class {
17467
17773
  };
17468
17774
 
17469
17775
  // src/agents/aider/history.ts
17470
- var fs26 = __toESM(require("fs"));
17471
- var path31 = __toESM(require("path"));
17776
+ var fs27 = __toESM(require("fs"));
17777
+ var path32 = __toESM(require("path"));
17472
17778
  var AIDER_HISTORY_FILE = ".aider.chat.history.md";
17473
17779
  function resolveHistoryDir4(cwd) {
17474
- const candidate = path31.join(cwd, AIDER_HISTORY_FILE);
17475
- return fs26.existsSync(candidate) ? cwd : null;
17780
+ const candidate = path32.join(cwd, AIDER_HISTORY_FILE);
17781
+ return fs27.existsSync(candidate) ? cwd : null;
17476
17782
  }
17477
17783
  function parseHistoryFile4(_filePath) {
17478
17784
  return [];
@@ -17485,10 +17791,10 @@ function getCurrentUsage4(_historyDir) {
17485
17791
  var import_node_child_process12 = require("child_process");
17486
17792
 
17487
17793
  // src/agents/aider/local-token.ts
17488
- var fs27 = __toESM(require("fs"));
17489
- var os24 = __toESM(require("os"));
17490
- var path32 = __toESM(require("path"));
17491
- var AIDER_CONF_FILE = path32.join(os24.homedir(), ".aider.conf.yml");
17794
+ var fs28 = __toESM(require("fs"));
17795
+ var os25 = __toESM(require("os"));
17796
+ var path33 = __toESM(require("path"));
17797
+ var AIDER_CONF_FILE = path33.join(os25.homedir(), ".aider.conf.yml");
17492
17798
  var API_KEY_ENV_VARS = [
17493
17799
  "ANTHROPIC_API_KEY",
17494
17800
  "OPENAI_API_KEY",
@@ -17503,8 +17809,8 @@ async function extractLocalAiderToken() {
17503
17809
  return { method: "api_key", credential: value.trim(), source: "flat-file" };
17504
17810
  }
17505
17811
  }
17506
- if (fs27.existsSync(AIDER_CONF_FILE)) {
17507
- const conf = fs27.readFileSync(AIDER_CONF_FILE, "utf8");
17812
+ if (fs28.existsSync(AIDER_CONF_FILE)) {
17813
+ const conf = fs28.readFileSync(AIDER_CONF_FILE, "utf8");
17508
17814
  const match = conf.match(/^api-key:\s*['"]?([^'"\n]+)['"]?\s*$/m);
17509
17815
  if (match) {
17510
17816
  return { method: "api_key", credential: match[1].trim(), source: "flat-file" };
@@ -17880,19 +18186,19 @@ var import_node_crypto6 = require("crypto");
17880
18186
  var import_node_child_process13 = require("child_process");
17881
18187
 
17882
18188
  // src/agents/gemini/local-token.ts
17883
- var fs29 = __toESM(require("fs"));
17884
- var os26 = __toESM(require("os"));
17885
- var path34 = __toESM(require("path"));
18189
+ var fs30 = __toESM(require("fs"));
18190
+ var os27 = __toESM(require("os"));
18191
+ var path35 = __toESM(require("path"));
17886
18192
  function geminiCredentialsPath() {
17887
- return path34.join(os26.homedir(), ".gemini", "oauth_creds.json");
18193
+ return path35.join(os27.homedir(), ".gemini", "oauth_creds.json");
17888
18194
  }
17889
18195
  function geminiCredentialsPaths() {
17890
18196
  return [geminiCredentialsPath()];
17891
18197
  }
17892
18198
  async function extractLocalGeminiToken() {
17893
18199
  const file = geminiCredentialsPath();
17894
- if (!fs29.existsSync(file)) return null;
17895
- const credential = fs29.readFileSync(file, "utf8").trim();
18200
+ if (!fs30.existsSync(file)) return null;
18201
+ const credential = fs30.readFileSync(file, "utf8").trim();
17896
18202
  if (credential.length === 0) return null;
17897
18203
  return { method: "oauth", credential, source: "flat-file" };
17898
18204
  }
@@ -17948,20 +18254,20 @@ function geminiLoginLauncher() {
17948
18254
  }
17949
18255
 
17950
18256
  // src/agents/gemini/history.ts
17951
- var fs30 = __toESM(require("fs"));
17952
- var os27 = __toESM(require("os"));
17953
- var path35 = __toESM(require("path"));
17954
- var GEMINI_ROOT = path35.join(os27.homedir(), ".gemini");
18257
+ var fs31 = __toESM(require("fs"));
18258
+ var os28 = __toESM(require("os"));
18259
+ var path36 = __toESM(require("path"));
18260
+ var GEMINI_ROOT = path36.join(os28.homedir(), ".gemini");
17955
18261
  function projectNameForCwd(cwd, root) {
17956
18262
  try {
17957
18263
  const parsed = JSON.parse(
17958
- fs30.readFileSync(path35.join(root, "projects.json"), "utf8")
18264
+ fs31.readFileSync(path36.join(root, "projects.json"), "utf8")
17959
18265
  );
17960
18266
  const map = parsed.projects;
17961
18267
  if (map && typeof map === "object") {
17962
18268
  if (typeof map[cwd] === "string") return map[cwd];
17963
18269
  try {
17964
- const rp = fs30.realpathSync(cwd);
18270
+ const rp = fs31.realpathSync(cwd);
17965
18271
  if (typeof map[rp] === "string") return map[rp];
17966
18272
  } catch {
17967
18273
  }
@@ -17970,7 +18276,7 @@ function projectNameForCwd(cwd, root) {
17970
18276
  } catch (err) {
17971
18277
  log.debug("gemini", `projects.json unreadable at ${root} \u2014 using basename fallback`, err);
17972
18278
  }
17973
- return path35.basename(cwd) || null;
18279
+ return path36.basename(cwd) || null;
17974
18280
  }
17975
18281
  function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17976
18282
  const name = projectNameForCwd(cwd, root);
@@ -17978,8 +18284,8 @@ function resolveHistoryDir5(cwd, root = GEMINI_ROOT) {
17978
18284
  log.warn("gemini", `resolveHistoryDir \u2014 could not derive a project name for cwd=${cwd}`);
17979
18285
  return null;
17980
18286
  }
17981
- const dir = path35.join(root, "tmp", name, "chats");
17982
- if (!fs30.existsSync(dir)) {
18287
+ const dir = path36.join(root, "tmp", name, "chats");
18288
+ if (!fs31.existsSync(dir)) {
17983
18289
  log.debug("gemini", `resolveHistoryDir \u2014 chats dir not present yet: ${dir} (project=${name})`);
17984
18290
  return null;
17985
18291
  }
@@ -17991,7 +18297,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
17991
18297
  if (!dir) return null;
17992
18298
  let files;
17993
18299
  try {
17994
- files = fs30.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
18300
+ files = fs31.readdirSync(dir).filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
17995
18301
  } catch (err) {
17996
18302
  log.warn("gemini", `resolveHistoryFile \u2014 cannot read chats dir ${dir} (id8=${id8})`, err);
17997
18303
  return null;
@@ -18003,12 +18309,12 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
18003
18309
  const byName = files.find((f) => id8.length > 0 && f.includes(id8));
18004
18310
  if (byName) {
18005
18311
  log.info("gemini", `resolveHistoryFile \u2014 matched by filename id8=${id8}: ${byName}`);
18006
- return path35.join(dir, byName);
18312
+ return path36.join(dir, byName);
18007
18313
  }
18008
18314
  for (const f of files) {
18009
- const full = path35.join(dir, f);
18315
+ const full = path36.join(dir, f);
18010
18316
  try {
18011
- const firstLine = fs30.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
18317
+ const firstLine = fs31.readFileSync(full, "utf8").split("\n", 1)[0] ?? "";
18012
18318
  const hdr = JSON.parse(firstLine);
18013
18319
  if (hdr.sessionId === sessionId) {
18014
18320
  log.info("gemini", `resolveHistoryFile \u2014 matched by header sessionId: ${f}`);
@@ -18021,7 +18327,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
18021
18327
  let newest = null;
18022
18328
  for (const f of files) {
18023
18329
  try {
18024
- const mtime = fs30.statSync(path35.join(dir, f)).mtimeMs;
18330
+ const mtime = fs31.statSync(path36.join(dir, f)).mtimeMs;
18025
18331
  if (!newest || mtime > newest.mtime) newest = { file: f, mtime };
18026
18332
  } catch {
18027
18333
  }
@@ -18030,7 +18336,7 @@ function resolveHistoryFile4(cwd, sessionId, root = GEMINI_ROOT) {
18030
18336
  "gemini",
18031
18337
  `resolveHistoryFile \u2014 no id8=${id8} match among ${files.length} file(s) in ${dir}; falling back to newest=${newest?.file ?? "none"}`
18032
18338
  );
18033
- return newest ? path35.join(dir, newest.file) : null;
18339
+ return newest ? path36.join(dir, newest.file) : null;
18034
18340
  }
18035
18341
  function extractGeminiText(content) {
18036
18342
  const fromParts = (arr) => Array.isArray(arr) ? arr.map((p2) => {
@@ -18058,7 +18364,7 @@ function isSyntheticGeminiTurn(text) {
18058
18364
  function parseHistoryFile5(filePath) {
18059
18365
  let raw;
18060
18366
  try {
18061
- raw = fs30.readFileSync(filePath, "utf8");
18367
+ raw = fs31.readFileSync(filePath, "utf8");
18062
18368
  } catch (err) {
18063
18369
  log.warn("gemini", `parseHistoryFile \u2014 cannot read ${filePath}`, err);
18064
18370
  return [];
@@ -18099,7 +18405,7 @@ function parseHistoryFile5(filePath) {
18099
18405
  }
18100
18406
  log.trace(
18101
18407
  "gemini",
18102
- `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path35.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
18408
+ `parseHistoryFile \u2014 ${out2.length} turn(s) from ${path36.basename(filePath)}` + (malformed > 0 ? ` (${malformed} malformed line(s) skipped)` : "")
18103
18409
  );
18104
18410
  return out2;
18105
18411
  }
@@ -18243,42 +18549,42 @@ var import_node_os3 = require("os");
18243
18549
  var import_node_path4 = require("path");
18244
18550
 
18245
18551
  // src/agents/kimi/history.ts
18246
- var fs31 = __toESM(require("fs"));
18247
- var os28 = __toESM(require("os"));
18248
- var path36 = __toESM(require("path"));
18552
+ var fs32 = __toESM(require("fs"));
18553
+ var os29 = __toESM(require("os"));
18554
+ var path37 = __toESM(require("path"));
18249
18555
  var import_node_crypto7 = require("crypto");
18250
18556
  function kimiHome() {
18251
- return process.env.KIMI_CODE_HOME || path36.join(os28.homedir(), ".kimi-code");
18557
+ return process.env.KIMI_CODE_HOME || path37.join(os29.homedir(), ".kimi-code");
18252
18558
  }
18253
18559
  function workDirKey(cwd) {
18254
18560
  const hash = (0, import_node_crypto7.createHash)("sha256").update(cwd).digest("hex").slice(0, 12);
18255
- return `wd_${path36.basename(cwd)}_${hash}`;
18561
+ return `wd_${path37.basename(cwd)}_${hash}`;
18256
18562
  }
18257
18563
  function resolveHistoryDir6(cwd) {
18258
- const dir = path36.join(kimiHome(), "sessions", workDirKey(cwd));
18259
- if (!fs31.existsSync(dir)) {
18564
+ const dir = path37.join(kimiHome(), "sessions", workDirKey(cwd));
18565
+ if (!fs32.existsSync(dir)) {
18260
18566
  log.debug("kimi", `resolveHistoryDir \u2014 session bucket not present yet: ${dir}`);
18261
18567
  return null;
18262
18568
  }
18263
18569
  return dir;
18264
18570
  }
18265
- var WIRE_REL = path36.join("agents", "main", "wire.jsonl");
18571
+ var WIRE_REL = path37.join("agents", "main", "wire.jsonl");
18266
18572
  function resolveHistoryFile5(cwd, sessionId) {
18267
18573
  const fromIndex = sessionDirFromIndex(sessionId);
18268
18574
  if (fromIndex) {
18269
- const p2 = path36.join(fromIndex, WIRE_REL);
18270
- if (fs31.existsSync(p2)) return p2;
18575
+ const p2 = path37.join(fromIndex, WIRE_REL);
18576
+ if (fs32.existsSync(p2)) return p2;
18271
18577
  }
18272
- const bucket2 = path36.join(kimiHome(), "sessions", workDirKey(cwd));
18273
- const computed = path36.join(bucket2, sessionId, WIRE_REL);
18274
- if (fs31.existsSync(computed)) return computed;
18578
+ const bucket2 = path37.join(kimiHome(), "sessions", workDirKey(cwd));
18579
+ const computed = path37.join(bucket2, sessionId, WIRE_REL);
18580
+ if (fs32.existsSync(computed)) return computed;
18275
18581
  const scanned = scanBucketsForSession(sessionId);
18276
18582
  if (scanned) return scanned;
18277
18583
  return null;
18278
18584
  }
18279
18585
  function sessionDirFromIndex(sessionId) {
18280
18586
  try {
18281
- const raw = fs31.readFileSync(path36.join(kimiHome(), "session_index.jsonl"), "utf8");
18587
+ const raw = fs32.readFileSync(path37.join(kimiHome(), "session_index.jsonl"), "utf8");
18282
18588
  for (const line of raw.split("\n")) {
18283
18589
  if (!line.includes(sessionId)) continue;
18284
18590
  try {
@@ -18294,22 +18600,22 @@ function sessionDirFromIndex(sessionId) {
18294
18600
  return null;
18295
18601
  }
18296
18602
  function scanBucketsForSession(sessionId) {
18297
- const sessionsRoot = path36.join(kimiHome(), "sessions");
18603
+ const sessionsRoot = path37.join(kimiHome(), "sessions");
18298
18604
  let buckets;
18299
18605
  try {
18300
- buckets = fs31.readdirSync(sessionsRoot, { withFileTypes: true });
18606
+ buckets = fs32.readdirSync(sessionsRoot, { withFileTypes: true });
18301
18607
  } catch {
18302
18608
  return null;
18303
18609
  }
18304
18610
  for (const b of buckets) {
18305
18611
  if (!b.isDirectory()) continue;
18306
- const candidate = path36.join(sessionsRoot, b.name, sessionId, WIRE_REL);
18307
- if (fs31.existsSync(candidate)) return candidate;
18612
+ const candidate = path37.join(sessionsRoot, b.name, sessionId, WIRE_REL);
18613
+ if (fs32.existsSync(candidate)) return candidate;
18308
18614
  }
18309
18615
  return null;
18310
18616
  }
18311
18617
  async function discoverSessionId2(cwd, opts) {
18312
- const bucket2 = path36.join(kimiHome(), "sessions", workDirKey(cwd));
18618
+ const bucket2 = path37.join(kimiHome(), "sessions", workDirKey(cwd));
18313
18619
  const floor = opts.sinceMs - 2e3;
18314
18620
  const deadline = Date.now() + (opts.timeoutMs ?? 15e3);
18315
18621
  for (; ; ) {
@@ -18322,7 +18628,7 @@ async function discoverSessionId2(cwd, opts) {
18322
18628
  function newestSessionSince(bucket2, floorMs) {
18323
18629
  let entries;
18324
18630
  try {
18325
- entries = fs31.readdirSync(bucket2, { withFileTypes: true });
18631
+ entries = fs32.readdirSync(bucket2, { withFileTypes: true });
18326
18632
  } catch {
18327
18633
  return null;
18328
18634
  }
@@ -18332,7 +18638,7 @@ function newestSessionSince(bucket2, floorMs) {
18332
18638
  if (!e.isDirectory() || !e.name.startsWith("session_")) continue;
18333
18639
  let mtime;
18334
18640
  try {
18335
- mtime = fs31.statSync(path36.join(bucket2, e.name)).mtimeMs;
18641
+ mtime = fs32.statSync(path37.join(bucket2, e.name)).mtimeMs;
18336
18642
  } catch {
18337
18643
  continue;
18338
18644
  }
@@ -18353,7 +18659,7 @@ function joinTextParts(parts) {
18353
18659
  function parseHistoryFile6(filePath) {
18354
18660
  let raw;
18355
18661
  try {
18356
- raw = fs31.readFileSync(filePath, "utf8");
18662
+ raw = fs32.readFileSync(filePath, "utf8");
18357
18663
  } catch {
18358
18664
  return [];
18359
18665
  }
@@ -18731,7 +19037,7 @@ function parseLinkArgs(args2) {
18731
19037
  if (apiKeyFileArg) {
18732
19038
  const filePath = apiKeyFileArg.slice("--api-key-file=".length);
18733
19039
  try {
18734
- apiKey = fs32.readFileSync(path37.resolve(filePath), "utf8").trim();
19040
+ apiKey = fs33.readFileSync(path38.resolve(filePath), "utf8").trim();
18735
19041
  } catch (err) {
18736
19042
  throw new Error(`Could not read --api-key-file ${filePath}: ${err.message}`);
18737
19043
  }
@@ -18858,7 +19164,7 @@ async function link(args2 = []) {
18858
19164
  return;
18859
19165
  }
18860
19166
  if (parsed.tokenFile) {
18861
- const credential = fs32.readFileSync(path37.resolve(parsed.tokenFile), "utf8").trim();
19167
+ const credential = fs33.readFileSync(path38.resolve(parsed.tokenFile), "utf8").trim();
18862
19168
  if (!credential) {
18863
19169
  showError(`--token-file ${parsed.tokenFile} is empty.`);
18864
19170
  process.exit(1);
@@ -19077,13 +19383,13 @@ async function linkDryRunPreflight(ctx) {
19077
19383
  // src/agents/coderabbit/configure.ts
19078
19384
  var import_node_child_process17 = require("child_process");
19079
19385
  var import_node_fs6 = require("fs");
19080
- var path39 = __toESM(require("path"));
19386
+ var path40 = __toESM(require("path"));
19081
19387
 
19082
19388
  // src/agents/coderabbit/oauth.ts
19083
19389
  var import_node_child_process16 = require("child_process");
19084
- var fs33 = __toESM(require("fs"));
19085
- var os29 = __toESM(require("os"));
19086
- var path38 = __toESM(require("path"));
19390
+ var fs34 = __toESM(require("fs"));
19391
+ var os30 = __toESM(require("os"));
19392
+ var path39 = __toESM(require("path"));
19087
19393
  function parseCoderabbitAuthEvent(line) {
19088
19394
  const l = line.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "").trim();
19089
19395
  if (!l || l[0] !== "{") return null;
@@ -19132,8 +19438,8 @@ function resolvePython() {
19132
19438
  function spawnCoderabbitLoginProc(cmd, args2) {
19133
19439
  const python = resolvePython();
19134
19440
  if (python) {
19135
- const helper = path38.join(os29.tmpdir(), "codeam-cr-pty.py");
19136
- fs33.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
19441
+ const helper = path39.join(os30.tmpdir(), "codeam-cr-pty.py");
19442
+ fs34.writeFileSync(helper, PYTHON_PTY_HELPER, { mode: 420 });
19137
19443
  return (0, import_node_child_process16.spawn)(python, [helper, cmd, ...args2], {
19138
19444
  stdio: ["pipe", "pipe", "pipe"],
19139
19445
  env: { ...process.env, TERM: "xterm-256color", COLUMNS: "220", LINES: "50" },
@@ -19244,7 +19550,7 @@ function runCoderabbitOAuthLogin(deps) {
19244
19550
  });
19245
19551
  }
19246
19552
  function coderabbitDir(home) {
19247
- return path38.join(home ?? os29.homedir(), ".coderabbit");
19553
+ return path39.join(home ?? os30.homedir(), ".coderabbit");
19248
19554
  }
19249
19555
  var NON_CREDENTIAL = /* @__PURE__ */ new Set(["doctor.json", "machine-id"]);
19250
19556
  function snapshotCredentialDir(home) {
@@ -19252,14 +19558,14 @@ function snapshotCredentialDir(home) {
19252
19558
  const snap = {};
19253
19559
  let entries;
19254
19560
  try {
19255
- entries = fs33.readdirSync(dir, { withFileTypes: true });
19561
+ entries = fs34.readdirSync(dir, { withFileTypes: true });
19256
19562
  } catch {
19257
19563
  return snap;
19258
19564
  }
19259
19565
  for (const e of entries) {
19260
19566
  if (!e.isFile() || NON_CREDENTIAL.has(e.name)) continue;
19261
19567
  try {
19262
- const st3 = fs33.statSync(path38.join(dir, e.name));
19568
+ const st3 = fs34.statSync(path39.join(dir, e.name));
19263
19569
  snap[e.name] = `${st3.mtimeMs}:${st3.size}`;
19264
19570
  } catch {
19265
19571
  }
@@ -19277,7 +19583,7 @@ function diffCapturedCredential(before, home) {
19277
19583
  }
19278
19584
  if (!best) return null;
19279
19585
  try {
19280
- return { file: best.file, contents: fs33.readFileSync(path38.join(dir, best.file), "utf8") };
19586
+ return { file: best.file, contents: fs34.readFileSync(path39.join(dir, best.file), "utf8") };
19281
19587
  } catch {
19282
19588
  return null;
19283
19589
  }
@@ -19354,7 +19660,7 @@ function collectChangedFiles(cwd) {
19354
19660
  return [...byPath.values()];
19355
19661
  }
19356
19662
  function restoreCoderabbitOauthBlob(os67, value) {
19357
- const dir = path39.join(os67.homeDir(), ".coderabbit");
19663
+ const dir = path40.join(os67.homeDir(), ".coderabbit");
19358
19664
  (0, import_node_fs6.mkdirSync)(dir, { recursive: true });
19359
19665
  let file = "auth.json";
19360
19666
  let contents = value.trim();
@@ -19362,13 +19668,13 @@ function restoreCoderabbitOauthBlob(os67, value) {
19362
19668
  try {
19363
19669
  const parsed = JSON.parse(contents);
19364
19670
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
19365
- file = path39.basename(parsed.file);
19671
+ file = path40.basename(parsed.file);
19366
19672
  contents = parsed.contents;
19367
19673
  }
19368
19674
  } catch {
19369
19675
  }
19370
19676
  }
19371
- (0, import_node_fs6.writeFileSync)(path39.join(dir, file), contents, { mode: 384 });
19677
+ (0, import_node_fs6.writeFileSync)(path40.join(dir, file), contents, { mode: 384 });
19372
19678
  }
19373
19679
  function installFailureMessage(result) {
19374
19680
  return result.error ?? "CodeRabbit CLI could not be installed";
@@ -19384,10 +19690,10 @@ async function configureCoderabbit(input, deps = {}) {
19384
19690
  const home = os67.homeDir();
19385
19691
  os67.augmentPath(
19386
19692
  os67.id === "win32" ? [
19387
- path39.join(home, ".local", "bin"),
19388
- path39.join(process.env.APPDATA ?? path39.join(home, "AppData", "Roaming"), "npm"),
19389
- path39.join(home, "scoop", "shims")
19390
- ] : [path39.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
19693
+ path40.join(home, ".local", "bin"),
19694
+ path40.join(process.env.APPDATA ?? path40.join(home, "AppData", "Roaming"), "npm"),
19695
+ path40.join(home, "scoop", "shims")
19696
+ ] : [path40.join(home, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"]
19391
19697
  );
19392
19698
  const installed2 = os67.findInPath("coderabbit") !== null;
19393
19699
  const base = () => ({
@@ -19696,9 +20002,9 @@ function defaultRunGh(args2) {
19696
20002
 
19697
20003
  // src/commands/host-agent.ts
19698
20004
  var import_node_child_process25 = require("child_process");
19699
- var os42 = __toESM(require("os"));
19700
- var fs46 = __toESM(require("fs"));
19701
- var path50 = __toESM(require("path"));
20005
+ var os43 = __toESM(require("os"));
20006
+ var fs47 = __toESM(require("fs"));
20007
+ var path51 = __toESM(require("path"));
19702
20008
 
19703
20009
  // src/integrations/manifest.ts
19704
20010
  var import_node_fs8 = __toESM(require("fs"));
@@ -19822,12 +20128,12 @@ function persistOrClearSkillsFromPayload(skills) {
19822
20128
 
19823
20129
  // src/commands/host/agent-install.ts
19824
20130
  var import_child_process14 = require("child_process");
19825
- var os33 = __toESM(require("os"));
20131
+ var os34 = __toESM(require("os"));
19826
20132
  function runAgentInstallScript(script, opts = {}) {
19827
20133
  const timeoutMs = opts.timeoutMs ?? 18e4;
19828
20134
  const scope = opts.logScope ?? "agent-install";
19829
20135
  return new Promise((resolve9) => {
19830
- const home = process.env.HOME || os33.homedir();
20136
+ const home = process.env.HOME || os34.homedir();
19831
20137
  const child = (0, import_child_process14.spawn)("sh", ["-c", script], {
19832
20138
  env: { ...process.env, HOME: home },
19833
20139
  stdio: ["ignore", "pipe", "pipe"]
@@ -19893,14 +20199,14 @@ function describeReason(reason) {
19893
20199
  }
19894
20200
 
19895
20201
  // src/commands/host/host-client.ts
19896
- var fs37 = __toESM(require("fs"));
19897
- var os34 = __toESM(require("os"));
19898
- var path42 = __toESM(require("path"));
20202
+ var fs38 = __toESM(require("fs"));
20203
+ var os35 = __toESM(require("os"));
20204
+ var path43 = __toESM(require("path"));
19899
20205
  var import_node_crypto9 = require("crypto");
19900
20206
  function sampleCpuTimes() {
19901
20207
  let idle = 0;
19902
20208
  let total = 0;
19903
- for (const cpu of os34.cpus()) {
20209
+ for (const cpu of os35.cpus()) {
19904
20210
  const t2 = cpu.times;
19905
20211
  idle += t2.idle;
19906
20212
  total += t2.user + t2.nice + t2.sys + t2.idle + t2.irq;
@@ -19919,8 +20225,8 @@ var MetricsCollector = class {
19919
20225
  const prev = this.prevCpu;
19920
20226
  this.prevCpu = current2;
19921
20227
  if (!prev) {
19922
- const cores = os34.cpus().length || 1;
19923
- const proxy = os34.loadavg()[0] / cores * 100;
20228
+ const cores = os35.cpus().length || 1;
20229
+ const proxy = os35.loadavg()[0] / cores * 100;
19924
20230
  return Math.min(100, Math.max(0, Math.round(proxy)));
19925
20231
  }
19926
20232
  const idleDelta = current2.idle - prev.idle;
@@ -19933,8 +20239,8 @@ var MetricsCollector = class {
19933
20239
  collect() {
19934
20240
  return {
19935
20241
  cpuPct: this.cpuPct(),
19936
- ramUsedMb: Math.round((os34.totalmem() - os34.freemem()) / 1048576),
19937
- ramTotalMb: Math.round(os34.totalmem() / 1048576),
20242
+ ramUsedMb: Math.round((os35.totalmem() - os35.freemem()) / 1048576),
20243
+ ramTotalMb: Math.round(os35.totalmem() / 1048576),
19938
20244
  latencyMs: this.lastLatencyMs
19939
20245
  };
19940
20246
  }
@@ -19943,19 +20249,19 @@ function apiBase() {
19943
20249
  return process.env.CODEAM_API_URL ?? resolveApiBaseUrl();
19944
20250
  }
19945
20251
  function hostIdentityPath() {
19946
- return path42.join(os34.homedir(), ".codeam", "host-agent.json");
20252
+ return path43.join(os35.homedir(), ".codeam", "host-agent.json");
19947
20253
  }
19948
20254
  function collectOsInfo() {
19949
20255
  return {
19950
- distro: os34.platform(),
19951
- arch: os34.arch(),
19952
- kernel: os34.release(),
20256
+ distro: os35.platform(),
20257
+ arch: os35.arch(),
20258
+ kernel: os35.release(),
19953
20259
  nodeVersion: process.versions.node
19954
20260
  };
19955
20261
  }
19956
20262
  function loadHostIdentity() {
19957
20263
  try {
19958
- const raw = fs37.readFileSync(hostIdentityPath(), "utf8");
20264
+ const raw = fs38.readFileSync(hostIdentityPath(), "utf8");
19959
20265
  const parsed = JSON.parse(raw);
19960
20266
  if (typeof parsed === "object" && parsed !== null && typeof parsed.hostId === "string" && typeof parsed.hostToken === "string" && typeof parsed.controlPluginId === "string") {
19961
20267
  const p2 = parsed;
@@ -19974,8 +20280,8 @@ function loadHostIdentity() {
19974
20280
  }
19975
20281
  function saveHostIdentity(identity) {
19976
20282
  const file = hostIdentityPath();
19977
- fs37.mkdirSync(path42.dirname(file), { recursive: true, mode: 448 });
19978
- fs37.writeFileSync(file, JSON.stringify(identity, null, 2), {
20283
+ fs38.mkdirSync(path43.dirname(file), { recursive: true, mode: 448 });
20284
+ fs38.writeFileSync(file, JSON.stringify(identity, null, 2), {
19979
20285
  encoding: "utf8",
19980
20286
  mode: 384
19981
20287
  });
@@ -20020,7 +20326,7 @@ function isTerminalEnrollError(err) {
20020
20326
  }
20021
20327
  function deleteHostIdentity() {
20022
20328
  try {
20023
- fs37.rmSync(hostIdentityPath(), { force: true });
20329
+ fs38.rmSync(hostIdentityPath(), { force: true });
20024
20330
  } catch {
20025
20331
  }
20026
20332
  }
@@ -20044,7 +20350,7 @@ async function postJson(pathname, body) {
20044
20350
  function resolveHostLabel(label) {
20045
20351
  const explicit = label?.trim();
20046
20352
  const envLabel = process.env.CODEAM_HOST_LABEL?.trim();
20047
- const resolved = explicit || envLabel || os34.hostname();
20353
+ const resolved = explicit || envLabel || os35.hostname();
20048
20354
  return resolved.slice(0, 80);
20049
20355
  }
20050
20356
  async function redeemEnrollToken(token, label) {
@@ -20155,17 +20461,17 @@ async function reportDeployProgress(auth, deployId, step, message, sessionId) {
20155
20461
  }
20156
20462
 
20157
20463
  // src/commands/host/workspace.ts
20158
- var fs38 = __toESM(require("fs"));
20159
- var os35 = __toESM(require("os"));
20160
- var path43 = __toESM(require("path"));
20464
+ var fs39 = __toESM(require("fs"));
20465
+ var os36 = __toESM(require("os"));
20466
+ var path44 = __toESM(require("path"));
20161
20467
  var import_node_child_process20 = require("child_process");
20162
20468
  var import_node_util4 = require("util");
20163
20469
  var execFileP4 = (0, import_node_util4.promisify)(import_node_child_process20.execFile);
20164
20470
  function isAbsolutePathTarget(target) {
20165
- return path43.isAbsolute(target);
20471
+ return path44.isAbsolute(target);
20166
20472
  }
20167
20473
  function selfHostedWorkspaceRoot() {
20168
- return path43.join(os35.homedir(), ".codeam", "self-hosted");
20474
+ return path44.join(os36.homedir(), ".codeam", "self-hosted");
20169
20475
  }
20170
20476
  function nonInteractiveGitEnv() {
20171
20477
  return {
@@ -20235,15 +20541,15 @@ async function configureGitCredentials(dest, repoRef, cloneToken, provider = "gi
20235
20541
  const isGitlab = provider === "gitlab";
20236
20542
  if (isGitlab ? !gitlabProjectPath(repoRef.trim()) : !githubOwnerRepo(repoRef.trim())) return;
20237
20543
  if (!cloneToken) return;
20238
- const credFile = path43.join(dest, ".git", "codeam-credentials");
20544
+ const credFile = path44.join(dest, ".git", "codeam-credentials");
20239
20545
  const credLine = isGitlab ? `https://oauth2:${cloneToken}@gitlab.com
20240
20546
  ` : `https://x-access-token:${cloneToken}@github.com
20241
20547
  `;
20242
- fs38.writeFileSync(credFile, credLine, { mode: 384 });
20548
+ fs39.writeFileSync(credFile, credLine, { mode: 384 });
20243
20549
  restrictToOwner(credFile);
20244
20550
  const env = nonInteractiveGitEnv();
20245
20551
  const git2 = (args2) => execFileP4("git", ["-C", dest, ...args2], { timeout: 3e4, env });
20246
- const credFilePosix = credFile.split(path43.sep).join("/");
20552
+ const credFilePosix = credFile.split(path44.sep).join("/");
20247
20553
  await git2(["config", "--local", "--replace-all", "credential.helper", ""]).catch(() => {
20248
20554
  });
20249
20555
  await git2([
@@ -20276,17 +20582,17 @@ function maskToken(text, cloneToken) {
20276
20582
  }
20277
20583
  async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "github", branch) {
20278
20584
  if (isAbsolutePathTarget(repoOrPath)) {
20279
- if (!fs38.existsSync(repoOrPath)) {
20585
+ if (!fs39.existsSync(repoOrPath)) {
20280
20586
  throw new Error(`deploy target path does not exist: ${repoOrPath}`);
20281
20587
  }
20282
20588
  return repoOrPath;
20283
20589
  }
20284
- const dest = path43.join(selfHostedWorkspaceRoot(), deployId);
20285
- if (fs38.existsSync(path43.join(dest, ".git"))) {
20590
+ const dest = path44.join(selfHostedWorkspaceRoot(), deployId);
20591
+ if (fs39.existsSync(path44.join(dest, ".git"))) {
20286
20592
  if (cloneToken) await configureGitCredentials(dest, repoOrPath, cloneToken, provider);
20287
20593
  return dest;
20288
20594
  }
20289
- fs38.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
20595
+ fs39.mkdirSync(selfHostedWorkspaceRoot(), { recursive: true, mode: 448 });
20290
20596
  const cloneUrl = repoCloneUrl(repoOrPath, cloneToken, provider);
20291
20597
  const cloneArgs = branch ? ["clone", "--depth", "1", "--branch", branch, cloneUrl, dest] : ["clone", "--depth", "1", cloneUrl, dest];
20292
20598
  try {
@@ -20304,9 +20610,9 @@ async function prepareWorkspace(repoOrPath, deployId, cloneToken, provider = "gi
20304
20610
  }
20305
20611
 
20306
20612
  // src/commands/host/agent-provisioning.ts
20307
- var fs39 = __toESM(require("fs"));
20308
- var os36 = __toESM(require("os"));
20309
- var path44 = __toESM(require("path"));
20613
+ var fs40 = __toESM(require("fs"));
20614
+ var os37 = __toESM(require("os"));
20615
+ var path45 = __toESM(require("path"));
20310
20616
  var PUBLIC_TO_INTERNAL_AGENT = {
20311
20617
  claude_code: "claude",
20312
20618
  claude: "claude",
@@ -20323,22 +20629,22 @@ function toInternalAgentId(publicAgentId) {
20323
20629
  return PUBLIC_TO_INTERNAL_AGENT[publicAgentId] ?? null;
20324
20630
  }
20325
20631
  function ensureDir(dir) {
20326
- fs39.mkdirSync(dir, { recursive: true, mode: 448 });
20632
+ fs40.mkdirSync(dir, { recursive: true, mode: 448 });
20327
20633
  }
20328
20634
  function writeFile0600(filePath, contents) {
20329
- ensureDir(path44.dirname(filePath));
20330
- fs39.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
20635
+ ensureDir(path45.dirname(filePath));
20636
+ fs40.writeFileSync(filePath, contents, { encoding: "utf8", mode: 384 });
20331
20637
  restrictToOwner(filePath);
20332
20638
  }
20333
20639
  function rmIfExists(filePath) {
20334
20640
  try {
20335
- fs39.rmSync(filePath, { force: true });
20641
+ fs40.rmSync(filePath, { force: true });
20336
20642
  } catch {
20337
20643
  }
20338
20644
  }
20339
20645
  var claudeProvisioner = {
20340
20646
  write(auth, home) {
20341
- const credentialsJson = path44.join(home, ".claude", ".credentials.json");
20647
+ const credentialsJson = path45.join(home, ".claude", ".credentials.json");
20342
20648
  if (auth.kind === "api_key") {
20343
20649
  rmIfExists(credentialsJson);
20344
20650
  return { ANTHROPIC_API_KEY: auth.value };
@@ -20350,8 +20656,8 @@ var claudeProvisioner = {
20350
20656
  } else {
20351
20657
  rmIfExists(credentialsJson);
20352
20658
  }
20353
- const claudeJson = path44.join(home, ".claude.json");
20354
- if (!fs39.existsSync(claudeJson)) {
20659
+ const claudeJson = path45.join(home, ".claude.json");
20660
+ if (!fs40.existsSync(claudeJson)) {
20355
20661
  writeFile0600(
20356
20662
  claudeJson,
20357
20663
  JSON.stringify({ hasCompletedOnboarding: true, customApiKeyResponses: { approved: [] } })
@@ -20362,7 +20668,7 @@ var claudeProvisioner = {
20362
20668
  };
20363
20669
  var codexProvisioner = {
20364
20670
  write(auth, home) {
20365
- const authJson = path44.join(home, ".codex", "auth.json");
20671
+ const authJson = path45.join(home, ".codex", "auth.json");
20366
20672
  if (auth.kind === "api_key") {
20367
20673
  rmIfExists(authJson);
20368
20674
  return { OPENAI_API_KEY: auth.value };
@@ -20373,8 +20679,8 @@ var codexProvisioner = {
20373
20679
  };
20374
20680
  var geminiProvisioner = {
20375
20681
  write(auth, home) {
20376
- const settingsJson = path44.join(home, ".gemini", "settings.json");
20377
- const oauthCreds = path44.join(home, ".gemini", "oauth_creds.json");
20682
+ const settingsJson = path45.join(home, ".gemini", "settings.json");
20683
+ const oauthCreds = path45.join(home, ".gemini", "oauth_creds.json");
20378
20684
  if (auth.kind === "api_key") {
20379
20685
  rmIfExists(oauthCreds);
20380
20686
  writeFile0600(settingsJson, '{"security":{"auth":{"selectedType":"gemini-api-key"}}}');
@@ -20387,7 +20693,7 @@ var geminiProvisioner = {
20387
20693
  };
20388
20694
  var cursorProvisioner = {
20389
20695
  write(auth, home) {
20390
- const authJson = path44.join(home, ".config", "cursor", "auth.json");
20696
+ const authJson = path45.join(home, ".config", "cursor", "auth.json");
20391
20697
  if (auth.kind === "api_key") {
20392
20698
  rmIfExists(authJson);
20393
20699
  return { CURSOR_API_KEY: auth.value };
@@ -20429,22 +20735,22 @@ max_context_size = 262144
20429
20735
  var kimiProvisioner = {
20430
20736
  write(auth, home) {
20431
20737
  const credentialsFiles = [
20432
- path44.join(home, ".kimi", "credentials", "kimi-code.json"),
20433
- path44.join(home, ".kimi-code", "credentials", "kimi-code.json")
20738
+ path45.join(home, ".kimi", "credentials", "kimi-code.json"),
20739
+ path45.join(home, ".kimi-code", "credentials", "kimi-code.json")
20434
20740
  ];
20435
20741
  if (auth.kind === "api_key") {
20436
20742
  credentialsFiles.forEach(rmIfExists);
20437
20743
  return { KIMI_API_KEY: auth.value };
20438
20744
  }
20439
20745
  credentialsFiles.forEach((f) => writeFile0600(f, auth.value));
20440
- writeFile0600(path44.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
20746
+ writeFile0600(path45.join(home, ".kimi-code", "config.toml"), KIMI_MANAGED_CONFIG_TOML);
20441
20747
  return {};
20442
20748
  }
20443
20749
  };
20444
20750
  var coderabbitProvisioner = {
20445
20751
  write(auth, home) {
20446
- const dir = path44.join(home, ".coderabbit");
20447
- const authJson = path44.join(dir, "auth.json");
20752
+ const dir = path45.join(home, ".coderabbit");
20753
+ const authJson = path45.join(dir, "auth.json");
20448
20754
  if (auth.kind === "api_key") {
20449
20755
  rmIfExists(authJson);
20450
20756
  return { CODERABBIT_API_KEY: auth.value };
@@ -20456,13 +20762,13 @@ var coderabbitProvisioner = {
20456
20762
  try {
20457
20763
  const parsed = JSON.parse(value);
20458
20764
  if (typeof parsed.file === "string" && typeof parsed.contents === "string") {
20459
- file = path44.basename(parsed.file);
20765
+ file = path45.basename(parsed.file);
20460
20766
  contents = parsed.contents;
20461
20767
  }
20462
20768
  } catch {
20463
20769
  }
20464
20770
  }
20465
- writeFile0600(path44.join(dir, file), contents);
20771
+ writeFile0600(path45.join(dir, file), contents);
20466
20772
  return {};
20467
20773
  }
20468
20774
  };
@@ -20490,7 +20796,7 @@ var UnsupportedAgentError = class extends Error {
20490
20796
  this.agentId = agentId;
20491
20797
  }
20492
20798
  };
20493
- function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os36.homedir()) {
20799
+ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os37.homedir()) {
20494
20800
  const internal = toInternalAgentId(publicAgentId);
20495
20801
  if (!internal) throw new UnsupportedAgentError(publicAgentId);
20496
20802
  const provisioner = PROVISIONERS[internal];
@@ -20500,11 +20806,11 @@ function provisionAgentCredentials(publicAgentId, auth, homeDir2 = os36.homedir(
20500
20806
 
20501
20807
  // src/commands/host/git-tooling.ts
20502
20808
  var import_node_child_process21 = require("child_process");
20503
- var fs40 = __toESM(require("fs"));
20504
- var os37 = __toESM(require("os"));
20505
- var path45 = __toESM(require("path"));
20809
+ var fs41 = __toESM(require("fs"));
20810
+ var os38 = __toESM(require("os"));
20811
+ var path46 = __toESM(require("path"));
20506
20812
  function codeamBinDir() {
20507
- return process.env.CODEAM_BIN_DIR ?? path45.join(os37.homedir(), ".codeam", "bin");
20813
+ return process.env.CODEAM_BIN_DIR ?? path46.join(os38.homedir(), ".codeam", "bin");
20508
20814
  }
20509
20815
  var FALLBACK_GH_VERSION = "2.62.0";
20510
20816
  var RELEASE_API = "https://api.github.com/repos/cli/cli/releases/latest";
@@ -20536,7 +20842,7 @@ async function download(url2, dest) {
20536
20842
  const res = await fetch(url2, { headers: { "User-Agent": "codeam-cli" } });
20537
20843
  if (!res.ok || !res.body) return false;
20538
20844
  const buf = Buffer.from(await res.arrayBuffer());
20539
- fs40.writeFileSync(dest, buf);
20845
+ fs41.writeFileSync(dest, buf);
20540
20846
  return true;
20541
20847
  } catch {
20542
20848
  return false;
@@ -20559,8 +20865,8 @@ async function ensureGhCli(runner, token, deps = {}) {
20559
20865
  const version3 = await resolveVersionFn(token);
20560
20866
  const asset = `gh_${version3}_${osToken}_${arch2}`;
20561
20867
  const url2 = `https://github.com/cli/cli/releases/download/v${version3}/${asset}.${ext}`;
20562
- const tmpRoot = fs40.mkdtempSync(path45.join(os37.tmpdir(), "codeam-gh-"));
20563
- const archive = path45.join(tmpRoot, `${asset}.${ext}`);
20868
+ const tmpRoot = fs41.mkdtempSync(path46.join(os38.tmpdir(), "codeam-gh-"));
20869
+ const archive = path46.join(tmpRoot, `${asset}.${ext}`);
20564
20870
  if (!await downloadFn(url2, archive)) {
20565
20871
  log.warn("host-agent", "gh download failed \u2014 skipping (git pull/push still work via the credential helper)");
20566
20872
  return null;
@@ -20570,16 +20876,16 @@ async function ensureGhCli(runner, token, deps = {}) {
20570
20876
  log.warn("host-agent", `gh archive extraction failed (code=${String(extract.code)}) \u2014 skipping`);
20571
20877
  return null;
20572
20878
  }
20573
- const extractedBin = path45.join(tmpRoot, asset, "bin", binaryName);
20574
- if (!fs40.existsSync(extractedBin)) {
20879
+ const extractedBin = path46.join(tmpRoot, asset, "bin", binaryName);
20880
+ if (!fs41.existsSync(extractedBin)) {
20575
20881
  log.warn("host-agent", "gh binary not found in the extracted archive \u2014 skipping");
20576
20882
  return null;
20577
20883
  }
20578
20884
  const binDir = codeamBinDir();
20579
- fs40.mkdirSync(binDir, { recursive: true });
20580
- const target = path45.join(binDir, binaryName);
20581
- fs40.copyFileSync(extractedBin, target);
20582
- fs40.chmodSync(target, 493);
20885
+ fs41.mkdirSync(binDir, { recursive: true });
20886
+ const target = path46.join(binDir, binaryName);
20887
+ fs41.copyFileSync(extractedBin, target);
20888
+ fs41.chmodSync(target, 493);
20583
20889
  log.info("host-agent", `gh installed to ${target} (v${version3})`);
20584
20890
  return target;
20585
20891
  } catch (e) {
@@ -20639,8 +20945,8 @@ async function ensureGlabCli(runner, deps = {}) {
20639
20945
  const version3 = await resolveLatestGlabVersion();
20640
20946
  const asset = `glab_${version3}_${osToken}_${arch2}`;
20641
20947
  const url2 = `https://gitlab.com/gitlab-org/cli/-/releases/v${version3}/downloads/${asset}.${ext}`;
20642
- const tmpRoot = fs40.mkdtempSync(path45.join(os37.tmpdir(), "codeam-glab-"));
20643
- const archive = path45.join(tmpRoot, `${asset}.${ext}`);
20948
+ const tmpRoot = fs41.mkdtempSync(path46.join(os38.tmpdir(), "codeam-glab-"));
20949
+ const archive = path46.join(tmpRoot, `${asset}.${ext}`);
20644
20950
  if (!await downloadFn(url2, archive)) {
20645
20951
  log.warn("host-agent", "glab download failed \u2014 skipping (git push/pull still work)");
20646
20952
  return null;
@@ -20651,20 +20957,20 @@ async function ensureGlabCli(runner, deps = {}) {
20651
20957
  return null;
20652
20958
  }
20653
20959
  const candidates = [
20654
- path45.join(tmpRoot, "bin", binaryName),
20655
- path45.join(tmpRoot, asset, "bin", binaryName),
20656
- path45.join(tmpRoot, binaryName)
20960
+ path46.join(tmpRoot, "bin", binaryName),
20961
+ path46.join(tmpRoot, asset, "bin", binaryName),
20962
+ path46.join(tmpRoot, binaryName)
20657
20963
  ];
20658
- const extractedBin = candidates.find((c2) => fs40.existsSync(c2));
20964
+ const extractedBin = candidates.find((c2) => fs41.existsSync(c2));
20659
20965
  if (!extractedBin) {
20660
20966
  log.warn("host-agent", "glab binary not found in the extracted archive \u2014 skipping");
20661
20967
  return null;
20662
20968
  }
20663
20969
  const binDir = codeamBinDir();
20664
- fs40.mkdirSync(binDir, { recursive: true });
20665
- const target = path45.join(binDir, binaryName);
20666
- fs40.copyFileSync(extractedBin, target);
20667
- fs40.chmodSync(target, 493);
20970
+ fs41.mkdirSync(binDir, { recursive: true });
20971
+ const target = path46.join(binDir, binaryName);
20972
+ fs41.copyFileSync(extractedBin, target);
20973
+ fs41.chmodSync(target, 493);
20668
20974
  log.info("host-agent", `glab installed to ${target} (v${version3})`);
20669
20975
  return target;
20670
20976
  } catch (e) {
@@ -20861,24 +21167,24 @@ var HeadroomStatsReporter = class {
20861
21167
  };
20862
21168
 
20863
21169
  // src/commands/host/headroom-bootstrap.ts
20864
- var fs42 = __toESM(require("fs"));
20865
- var path47 = __toESM(require("path"));
20866
- var os39 = __toESM(require("os"));
21170
+ var fs43 = __toESM(require("fs"));
21171
+ var path48 = __toESM(require("path"));
21172
+ var os40 = __toESM(require("os"));
20867
21173
 
20868
21174
  // src/commands/host/headroom-config.ts
20869
- var fs41 = __toESM(require("fs"));
20870
- var os38 = __toESM(require("os"));
20871
- var path46 = __toESM(require("path"));
21175
+ var fs42 = __toESM(require("fs"));
21176
+ var os39 = __toESM(require("os"));
21177
+ var path47 = __toESM(require("path"));
20872
21178
  function headroomConfigPath() {
20873
- return path46.join(os38.homedir(), ".codeam", "headroom-config.json");
21179
+ return path47.join(os39.homedir(), ".codeam", "headroom-config.json");
20874
21180
  }
20875
21181
  function persistHeadroomConfig(config) {
20876
21182
  try {
20877
21183
  const file = headroomConfigPath();
20878
- fs41.mkdirSync(path46.dirname(file), { recursive: true, mode: 448 });
21184
+ fs42.mkdirSync(path47.dirname(file), { recursive: true, mode: 448 });
20879
21185
  const tmp = `${file}.tmp-${process.pid}`;
20880
- fs41.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
20881
- fs41.renameSync(tmp, file);
21186
+ fs42.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
21187
+ fs42.renameSync(tmp, file);
20882
21188
  restrictToOwner(file);
20883
21189
  } catch (err) {
20884
21190
  log.warn(
@@ -20888,21 +21194,21 @@ function persistHeadroomConfig(config) {
20888
21194
  }
20889
21195
  }
20890
21196
  function agentSettingsPath(kind) {
20891
- const home = os38.homedir();
20892
- if (kind === "claude") return path46.join(home, ".claude", "settings.json");
20893
- if (kind === "codex") return path46.join(home, ".codex", "auth.json");
20894
- if (kind === "copilot") return path46.join(home, ".config", "github-copilot", "hosts.json");
21197
+ const home = os39.homedir();
21198
+ if (kind === "claude") return path47.join(home, ".claude", "settings.json");
21199
+ if (kind === "codex") return path47.join(home, ".codex", "auth.json");
21200
+ if (kind === "copilot") return path47.join(home, ".config", "github-copilot", "hosts.json");
20895
21201
  return null;
20896
21202
  }
20897
21203
  function backupAgentHeadroomConfig(kind) {
20898
21204
  const src = agentSettingsPath(kind);
20899
21205
  if (!src) return;
20900
21206
  try {
20901
- if (!fs41.existsSync(src)) return;
20902
- const dest = path46.join(os38.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20903
- fs41.mkdirSync(path46.dirname(dest), { recursive: true, mode: 448 });
20904
- fs41.copyFileSync(src, dest);
20905
- fs41.chmodSync(dest, 384);
21207
+ if (!fs42.existsSync(src)) return;
21208
+ const dest = path47.join(os39.homedir(), ".codeam", `headroom-backup-${kind}.json`);
21209
+ fs42.mkdirSync(path47.dirname(dest), { recursive: true, mode: 448 });
21210
+ fs42.copyFileSync(src, dest);
21211
+ fs42.chmodSync(dest, 384);
20906
21212
  log.info("host-agent", `headroom config backup: ${src} \u2192 ${dest}`);
20907
21213
  } catch (err) {
20908
21214
  log.warn(
@@ -20914,12 +21220,12 @@ function backupAgentHeadroomConfig(kind) {
20914
21220
  function restoreAgentHeadroomConfig(kind) {
20915
21221
  const dest = agentSettingsPath(kind);
20916
21222
  if (!dest) return false;
20917
- const src = path46.join(os38.homedir(), ".codeam", `headroom-backup-${kind}.json`);
20918
- if (!fs41.existsSync(src)) return false;
21223
+ const src = path47.join(os39.homedir(), ".codeam", `headroom-backup-${kind}.json`);
21224
+ if (!fs42.existsSync(src)) return false;
20919
21225
  try {
20920
- fs41.mkdirSync(path46.dirname(dest), { recursive: true, mode: 448 });
20921
- fs41.copyFileSync(src, dest);
20922
- fs41.chmodSync(dest, 384);
21226
+ fs42.mkdirSync(path47.dirname(dest), { recursive: true, mode: 448 });
21227
+ fs42.copyFileSync(src, dest);
21228
+ fs42.chmodSync(dest, 384);
20923
21229
  log.info("host-agent", `headroom config restored: ${src} \u2192 ${dest}`);
20924
21230
  return true;
20925
21231
  } catch (err) {
@@ -20932,7 +21238,7 @@ function restoreAgentHeadroomConfig(kind) {
20932
21238
  }
20933
21239
  function readHeadroomChildEnv() {
20934
21240
  try {
20935
- const raw = fs41.readFileSync(headroomConfigPath(), "utf8");
21241
+ const raw = fs42.readFileSync(headroomConfigPath(), "utf8");
20936
21242
  const parsed = JSON.parse(raw);
20937
21243
  if (typeof parsed !== "object" || parsed === null) return {};
20938
21244
  const o = parsed;
@@ -20968,49 +21274,49 @@ function bundledClaudeBinDir() {
20968
21274
  const roots = /* @__PURE__ */ new Set();
20969
21275
  let dir = __dirname;
20970
21276
  for (let i = 0; i < 6; i++) {
20971
- roots.add(path47.join(dir, "node_modules"));
20972
- const parent = path47.dirname(dir);
21277
+ roots.add(path48.join(dir, "node_modules"));
21278
+ const parent = path48.dirname(dir);
20973
21279
  if (parent === dir) break;
20974
21280
  dir = parent;
20975
21281
  }
20976
21282
  try {
20977
21283
  const main2 = require.resolve("@anthropic-ai/claude-agent-sdk");
20978
- const marker = `${path47.sep}@anthropic-ai${path47.sep}`;
21284
+ const marker = `${path48.sep}@anthropic-ai${path48.sep}`;
20979
21285
  const idx = main2.lastIndexOf(marker);
20980
21286
  if (idx !== -1) roots.add(main2.slice(0, idx));
20981
21287
  } catch {
20982
21288
  }
20983
21289
  for (const nm of roots) {
20984
- const atAnthropic = path47.join(nm, "@anthropic-ai");
21290
+ const atAnthropic = path48.join(nm, "@anthropic-ai");
20985
21291
  let entries;
20986
21292
  try {
20987
- entries = fs42.readdirSync(atAnthropic);
21293
+ entries = fs43.readdirSync(atAnthropic);
20988
21294
  } catch {
20989
21295
  continue;
20990
21296
  }
20991
21297
  for (const entry of entries) {
20992
21298
  if (!entry.startsWith("claude-agent-sdk-")) continue;
20993
- const bin = path47.join(atAnthropic, entry, "claude");
20994
- if (fs42.existsSync(bin)) return path47.dirname(bin);
21299
+ const bin = path48.join(atAnthropic, entry, "claude");
21300
+ if (fs43.existsSync(bin)) return path48.dirname(bin);
20995
21301
  }
20996
21302
  }
20997
21303
  return null;
20998
21304
  }
20999
21305
  async function getFreeDiskBytes(dir) {
21000
21306
  try {
21001
- const s = await fs42.promises.statfs(dir);
21307
+ const s = await fs43.promises.statfs(dir);
21002
21308
  return s.bsize * s.bavail;
21003
21309
  } catch {
21004
21310
  return null;
21005
21311
  }
21006
21312
  }
21007
21313
  function headroomModelsCached() {
21008
- const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path47.join(
21009
- process.env.HF_HOME || path47.join(os39.homedir(), ".cache", "huggingface"),
21314
+ const hubDir = process.env.HUGGINGFACE_HUB_CACHE || path48.join(
21315
+ process.env.HF_HOME || path48.join(os40.homedir(), ".cache", "huggingface"),
21010
21316
  "hub"
21011
21317
  );
21012
21318
  return HEADROOM_MODELS.every(
21013
- (m) => fs42.existsSync(path47.join(hubDir, `models--${m.repo.replace("/", "--")}`))
21319
+ (m) => fs43.existsSync(path48.join(hubDir, `models--${m.repo.replace("/", "--")}`))
21014
21320
  );
21015
21321
  }
21016
21322
  async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner, opts = {}) {
@@ -21079,7 +21385,7 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
21079
21385
  if (initKind === "claude") {
21080
21386
  const claudeDir = bundledClaudeBinDir();
21081
21387
  if (claudeDir) {
21082
- initEnv.PATH = `${claudeDir}${path47.delimiter}${process.env["PATH"] ?? ""}`;
21388
+ initEnv.PATH = `${claudeDir}${path48.delimiter}${process.env["PATH"] ?? ""}`;
21083
21389
  log.info("host-agent", `headroom init: bundled claude on PATH (${claudeDir})`);
21084
21390
  } else {
21085
21391
  log.warn("host-agent", "headroom init: bundled claude binary not found \u2014 init may fail");
@@ -21116,19 +21422,19 @@ async function setupHeadroomForSelfHosted(agent, runner = defaultHeadroomRunner,
21116
21422
  }
21117
21423
 
21118
21424
  // src/commands/host/house-proxy-config.ts
21119
- var fs43 = __toESM(require("fs"));
21120
- var os40 = __toESM(require("os"));
21121
- var path48 = __toESM(require("path"));
21425
+ var fs44 = __toESM(require("fs"));
21426
+ var os41 = __toESM(require("os"));
21427
+ var path49 = __toESM(require("path"));
21122
21428
  function houseProxyConfigPath() {
21123
- return path48.join(os40.homedir(), ".codeam", "house-proxy.json");
21429
+ return path49.join(os41.homedir(), ".codeam", "house-proxy.json");
21124
21430
  }
21125
21431
  function persistHouseProxyConfig(config) {
21126
21432
  try {
21127
21433
  const file = houseProxyConfigPath();
21128
- fs43.mkdirSync(path48.dirname(file), { recursive: true, mode: 448 });
21434
+ fs44.mkdirSync(path49.dirname(file), { recursive: true, mode: 448 });
21129
21435
  const tmp = `${file}.tmp-${process.pid}`;
21130
- fs43.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
21131
- fs43.renameSync(tmp, file);
21436
+ fs44.writeFileSync(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 384 });
21437
+ fs44.renameSync(tmp, file);
21132
21438
  restrictToOwner(file);
21133
21439
  } catch (err) {
21134
21440
  log.warn(
@@ -21139,13 +21445,13 @@ function persistHouseProxyConfig(config) {
21139
21445
  }
21140
21446
  function clearHouseProxyConfig() {
21141
21447
  try {
21142
- fs43.rmSync(houseProxyConfigPath(), { force: true });
21448
+ fs44.rmSync(houseProxyConfigPath(), { force: true });
21143
21449
  } catch {
21144
21450
  }
21145
21451
  }
21146
21452
  function readHouseProxyChildEnv() {
21147
21453
  try {
21148
- const raw = fs43.readFileSync(houseProxyConfigPath(), "utf8");
21454
+ const raw = fs44.readFileSync(houseProxyConfigPath(), "utf8");
21149
21455
  const parsed = JSON.parse(raw);
21150
21456
  if (typeof parsed !== "object" || parsed === null) return {};
21151
21457
  const o = parsed;
@@ -21178,9 +21484,9 @@ function readHouseProxyChildEnv() {
21178
21484
  var import_node_child_process23 = require("child_process");
21179
21485
 
21180
21486
  // src/lib/updateNotifier.ts
21181
- var fs44 = __toESM(require("fs"));
21182
- var os41 = __toESM(require("os"));
21183
- var path49 = __toESM(require("path"));
21487
+ var fs45 = __toESM(require("fs"));
21488
+ var os42 = __toESM(require("os"));
21489
+ var path50 = __toESM(require("path"));
21184
21490
  var https6 = __toESM(require("https"));
21185
21491
  var import_node_child_process22 = require("child_process");
21186
21492
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -21189,12 +21495,12 @@ var REGISTRY_URL = `https://registry.npmjs.org/${PKG_NAME}/latest`;
21189
21495
  var TTL_MS = 24 * 60 * 60 * 1e3;
21190
21496
  var REQUEST_TIMEOUT_MS = 1500;
21191
21497
  function cachePath() {
21192
- const dir = path49.join(os41.homedir(), ".codeam");
21193
- return path49.join(dir, "update-check.json");
21498
+ const dir = path50.join(os42.homedir(), ".codeam");
21499
+ return path50.join(dir, "update-check.json");
21194
21500
  }
21195
21501
  function readCache() {
21196
21502
  try {
21197
- const raw = fs44.readFileSync(cachePath(), "utf8");
21503
+ const raw = fs45.readFileSync(cachePath(), "utf8");
21198
21504
  const parsed = JSON.parse(raw);
21199
21505
  if (typeof parsed.fetchedAt !== "number" || typeof parsed.latest !== "string") return null;
21200
21506
  return parsed;
@@ -21205,10 +21511,10 @@ function readCache() {
21205
21511
  function writeCache(cache) {
21206
21512
  try {
21207
21513
  const file = cachePath();
21208
- fs44.mkdirSync(path49.dirname(file), { recursive: true });
21514
+ fs45.mkdirSync(path50.dirname(file), { recursive: true });
21209
21515
  const tmp = `${file}.${process.pid}.tmp`;
21210
- fs44.writeFileSync(tmp, JSON.stringify(cache));
21211
- fs44.renameSync(tmp, file);
21516
+ fs45.writeFileSync(tmp, JSON.stringify(cache));
21517
+ fs45.renameSync(tmp, file);
21212
21518
  } catch {
21213
21519
  }
21214
21520
  }
@@ -21282,8 +21588,8 @@ function isLinkedInstall() {
21282
21588
  timeout: 2e3
21283
21589
  }).trim();
21284
21590
  if (!root) return false;
21285
- const pkgPath = path49.join(root, PKG_NAME);
21286
- return fs44.lstatSync(pkgPath).isSymbolicLink();
21591
+ const pkgPath = path50.join(root, PKG_NAME);
21592
+ return fs45.lstatSync(pkgPath).isSymbolicLink();
21287
21593
  } catch {
21288
21594
  return false;
21289
21595
  }
@@ -21319,7 +21625,7 @@ function maybeAutoUpdate(currentVersion, latest) {
21319
21625
  return;
21320
21626
  }
21321
21627
  try {
21322
- fs44.unlinkSync(cachePath());
21628
+ fs45.unlinkSync(cachePath());
21323
21629
  } catch {
21324
21630
  }
21325
21631
  process.stderr.write(` ${import_picocolors3.default.green("\u2713")} Updated. Resuming session...
@@ -21335,7 +21641,7 @@ async function autoUpgradeBeforeCriticalCommand() {
21335
21641
  if (process.env.NODE_ENV === "test") return;
21336
21642
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
21337
21643
  if (process.env.CI) return;
21338
- const current2 = true ? "2.65.2" : null;
21644
+ const current2 = true ? "2.65.4" : null;
21339
21645
  if (!current2) return;
21340
21646
  const cache = readCache();
21341
21647
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -21352,7 +21658,7 @@ function checkForUpdates() {
21352
21658
  if (process.env.CODEAM_DISABLE_UPDATE_CHECK === "1") return;
21353
21659
  if (process.env.CI) return;
21354
21660
  if (!process.stdout.isTTY) return;
21355
- const current2 = true ? "2.65.2" : null;
21661
+ const current2 = true ? "2.65.4" : null;
21356
21662
  if (!current2) return;
21357
21663
  const cache = readCache();
21358
21664
  const fresh = cache && Date.now() - cache.fetchedAt < TTL_MS;
@@ -21372,7 +21678,7 @@ var SELF_UPDATE_INTERVAL_MS = 60 * 60 * 1e3;
21372
21678
  var SELF_UPDATE_VIEW_TIMEOUT_MS = 3e4;
21373
21679
  var SELF_UPDATE_INSTALL_TIMEOUT_MS = 18e4;
21374
21680
  function currentCliVersion() {
21375
- return true ? "2.65.2" : null;
21681
+ return true ? "2.65.4" : null;
21376
21682
  }
21377
21683
  function runCmd(cmd, args2, timeoutMs) {
21378
21684
  return new Promise((resolve9) => {
@@ -21439,7 +21745,7 @@ async function runSelfUpdate() {
21439
21745
 
21440
21746
  // src/commands/host/teardown.ts
21441
21747
  var import_node_child_process24 = require("child_process");
21442
- var fs45 = __toESM(require("fs"));
21748
+ var fs46 = __toESM(require("fs"));
21443
21749
  var defaultDisableService = () => {
21444
21750
  try {
21445
21751
  (0, import_node_child_process24.execFileSync)("systemctl", ["disable", "--now", "codeam-host-agent"], { stdio: "ignore" });
@@ -21448,7 +21754,7 @@ var defaultDisableService = () => {
21448
21754
  };
21449
21755
  var defaultTeardownHeadroom = () => {
21450
21756
  try {
21451
- const kind = JSON.parse(fs45.readFileSync(headroomConfigPath(), "utf8")).agent;
21757
+ const kind = JSON.parse(fs46.readFileSync(headroomConfigPath(), "utf8")).agent;
21452
21758
  if (kind) {
21453
21759
  (0, import_node_child_process24.execFileSync)("headroom", ["unwrap", kind], { stdio: "ignore", timeout: 15e3 });
21454
21760
  }
@@ -21516,8 +21822,8 @@ function maybeResumeLocalHeadroomReporter(ctx) {
21516
21822
  if (process.env["HEADROOM_ENABLED"] === "1") return null;
21517
21823
  try {
21518
21824
  const file = headroomConfigPath();
21519
- if (!fs46.existsSync(file)) return null;
21520
- const cfg = JSON.parse(fs46.readFileSync(file, "utf8"));
21825
+ if (!fs47.existsSync(file)) return null;
21826
+ const cfg = JSON.parse(fs47.readFileSync(file, "utf8"));
21521
21827
  if (!cfg?.enabled) return null;
21522
21828
  const agent = cfg.agent ?? "claude";
21523
21829
  const ingestUrl = `${resolveApiBaseUrl()}/api/sessions/${ctx.sessionId}/headroom-savings`;
@@ -22104,13 +22410,13 @@ var HostAgentSupervisor = class {
22104
22410
  const relay = this.relay;
22105
22411
  if (!relay) return;
22106
22412
  const raw = cmd.payload?.path;
22107
- const target = typeof raw === "string" && raw.trim() ? path50.resolve(raw.trim()) : os42.homedir();
22413
+ const target = typeof raw === "string" && raw.trim() ? path51.resolve(raw.trim()) : os43.homedir();
22108
22414
  try {
22109
- const dirents = await fs46.promises.readdir(target, { withFileTypes: true });
22415
+ const dirents = await fs47.promises.readdir(target, { withFileTypes: true });
22110
22416
  const entries = dirents.filter((d3) => !d3.name.startsWith(".")).map((d3) => ({ name: d3.name, isDir: d3.isDirectory() })).sort(
22111
22417
  (a, b) => a.isDir === b.isDir ? a.name.localeCompare(b.name) : a.isDir ? -1 : 1
22112
22418
  );
22113
- const parent = path50.dirname(target);
22419
+ const parent = path51.dirname(target);
22114
22420
  await relay.sendResult(cmd.id, "completed", {
22115
22421
  path: target,
22116
22422
  // null at the filesystem root so the UI can hide the ".." affordance.
@@ -22343,14 +22649,14 @@ var HostAgentSupervisor = class {
22343
22649
  API_TIMEOUT_MS: "3000000",
22344
22650
  CODEAM_AUTO_TOKEN: payload.autoPairToken
22345
22651
  };
22346
- const houseConfigDir = path50.join(
22347
- os42.homedir(),
22652
+ const houseConfigDir = path51.join(
22653
+ os43.homedir(),
22348
22654
  ".codeam",
22349
22655
  "house-claude",
22350
22656
  payload.deployId
22351
22657
  );
22352
22658
  try {
22353
- fs46.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
22659
+ fs47.mkdirSync(houseConfigDir, { recursive: true, mode: 448 });
22354
22660
  } catch {
22355
22661
  }
22356
22662
  childEnv.CLAUDE_CONFIG_DIR = houseConfigDir;
@@ -22376,7 +22682,7 @@ var HostAgentSupervisor = class {
22376
22682
  report("installing", "installing agent CLI");
22377
22683
  await this.runAgentInstall(payload.agentInstallScript);
22378
22684
  }
22379
- const home = process.env.HOME || os42.homedir();
22685
+ const home = process.env.HOME || os43.homedir();
22380
22686
  childEnv.PATH = `${home}/.local/bin:${process.env.PATH ?? ""}`;
22381
22687
  if (payload.cloneToken) {
22382
22688
  try {
@@ -22384,13 +22690,13 @@ var HostAgentSupervisor = class {
22384
22690
  if ((payload.repoProvider ?? "github") === "gitlab") {
22385
22691
  const glabCmd = await ensureGlabCli(defaultGitToolingRunner);
22386
22692
  if (glabCmd) {
22387
- childEnv.PATH = `${codeamBinDir()}${path50.delimiter}${childEnv.PATH}`;
22693
+ childEnv.PATH = `${codeamBinDir()}${path51.delimiter}${childEnv.PATH}`;
22388
22694
  await ensureGlabAuth(defaultGitToolingRunner, glabCmd, payload.cloneToken);
22389
22695
  }
22390
22696
  } else {
22391
22697
  const ghCmd = await ensureGhCli(defaultGitToolingRunner, payload.cloneToken);
22392
22698
  if (ghCmd) {
22393
- childEnv.PATH = `${codeamBinDir()}${path50.delimiter}${childEnv.PATH}`;
22699
+ childEnv.PATH = `${codeamBinDir()}${path51.delimiter}${childEnv.PATH}`;
22394
22700
  await ensureGhAuth(defaultGitToolingRunner, ghCmd, payload.cloneToken);
22395
22701
  }
22396
22702
  }
@@ -22410,7 +22716,7 @@ var HostAgentSupervisor = class {
22410
22716
  }
22411
22717
  if (payload.headroomEnabled && payload.headroomAgent && payload.headroomSavingsIngestUrl && isHeadroomSupportedAgent(payload.headroomAgent)) {
22412
22718
  report("headroom", "setting up Headroom proxy");
22413
- const freeBytes = await this.getFreeDisk(os42.homedir());
22719
+ const freeBytes = await this.getFreeDisk(os43.homedir());
22414
22720
  const alreadyInstalled = this.isHeadroomInstalled();
22415
22721
  if (!alreadyInstalled && freeBytes !== null && freeBytes < HEADROOM_MIN_FREE_DISK_BYTES) {
22416
22722
  const freeGb = (freeBytes / 1e9).toFixed(1);
@@ -22469,9 +22775,9 @@ var HostAgentSupervisor = class {
22469
22775
  );
22470
22776
  if (!payload.suppressOnboardingWelcome) {
22471
22777
  try {
22472
- const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path50.join(os42.homedir(), ".claude");
22473
- const projectDir = path50.join(cfgDir, "projects", encodeCwd(cwd));
22474
- const hasPriorConversation = fs46.existsSync(projectDir) && fs46.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
22778
+ const cfgDir = childEnv.CLAUDE_CONFIG_DIR || path51.join(os43.homedir(), ".claude");
22779
+ const projectDir = path51.join(cfgDir, "projects", encodeCwd(cwd));
22780
+ const hasPriorConversation = fs47.existsSync(projectDir) && fs47.readdirSync(projectDir).some((f) => f.endsWith(".jsonl"));
22475
22781
  if (hasPriorConversation) {
22476
22782
  childEnv.CODEAM_RESUME_LATEST = "1";
22477
22783
  log.info(
@@ -22570,7 +22876,7 @@ var HostAgentSupervisor = class {
22570
22876
  if (this.children.size > 0) return;
22571
22877
  const session = getActiveSession();
22572
22878
  if (!session || !session.pluginId || !session.pollSecret || !session.agent) return;
22573
- const cwd = session.cwd && fs46.existsSync(session.cwd) ? session.cwd : process.cwd();
22879
+ const cwd = session.cwd && fs47.existsSync(session.cwd) ? session.cwd : process.cwd();
22574
22880
  const proc = this.resumeSpawner(
22575
22881
  { ...readHeadroomChildEnv(), ...readHouseProxyChildEnv() },
22576
22882
  cwd
@@ -22667,12 +22973,12 @@ var HostAgentSupervisor = class {
22667
22973
  this.children.delete(deployId);
22668
22974
  }
22669
22975
  const dirs = [
22670
- path50.join(selfHostedWorkspaceRoot(), deployId),
22671
- path50.join(os42.homedir(), ".codeam", "house-claude", deployId)
22976
+ path51.join(selfHostedWorkspaceRoot(), deployId),
22977
+ path51.join(os43.homedir(), ".codeam", "house-claude", deployId)
22672
22978
  ];
22673
22979
  for (const dir of dirs) {
22674
22980
  try {
22675
- fs46.rmSync(dir, { recursive: true, force: true });
22981
+ fs47.rmSync(dir, { recursive: true, force: true });
22676
22982
  } catch (err) {
22677
22983
  log.warn(
22678
22984
  "host-agent",
@@ -22809,9 +23115,9 @@ async function configureHeadroom(action, ctx, deps) {
22809
23115
  }
22810
23116
 
22811
23117
  // src/services/headroom/budget-relaunch.ts
22812
- var fs47 = __toESM(require("fs"));
22813
- var os43 = __toESM(require("os"));
22814
- var path51 = __toESM(require("path"));
23118
+ var fs48 = __toESM(require("fs"));
23119
+ var os44 = __toESM(require("os"));
23120
+ var path52 = __toESM(require("path"));
22815
23121
  var import_child_process15 = require("child_process");
22816
23122
  function amendDeploymentManifestBudget(manifest, budget) {
22817
23123
  const rawArgs = manifest.proxy_args ?? [];
@@ -22845,7 +23151,7 @@ function amendDeploymentManifestBudget(manifest, budget) {
22845
23151
  return { ...manifest, proxy_args: newArgs, base_env: newEnv };
22846
23152
  }
22847
23153
  function findHeadroomDeployments(homeDir2, deps) {
22848
- const deployDir = path51.join(homeDir2, ".headroom", "deploy");
23154
+ const deployDir = path52.join(homeDir2, ".headroom", "deploy");
22849
23155
  let profiles;
22850
23156
  try {
22851
23157
  profiles = deps.readDir(deployDir);
@@ -22854,7 +23160,7 @@ function findHeadroomDeployments(homeDir2, deps) {
22854
23160
  }
22855
23161
  const results = [];
22856
23162
  for (const profile of profiles) {
22857
- const manifestPath = path51.join(deployDir, profile, "manifest.json");
23163
+ const manifestPath = path52.join(deployDir, profile, "manifest.json");
22858
23164
  let raw;
22859
23165
  try {
22860
23166
  raw = deps.readJson(manifestPath);
@@ -22886,8 +23192,8 @@ async function applyBudgetToHeadroom(budget, deps) {
22886
23192
  }
22887
23193
  function writeManifestReal(manifestPath, manifest) {
22888
23194
  const tmp = manifestPath + ".codeam.tmp";
22889
- fs47.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
22890
- fs47.renameSync(tmp, manifestPath);
23195
+ fs48.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + "\n", { mode: 384 });
23196
+ fs48.renameSync(tmp, manifestPath);
22891
23197
  }
22892
23198
  function restartDeploymentReal(profile) {
22893
23199
  try {
@@ -22922,11 +23228,11 @@ function spawnProxyReal2(_budget) {
22922
23228
  );
22923
23229
  }
22924
23230
  function makeRealApplyBudgetDeps() {
22925
- const homeDir2 = os43.homedir();
23231
+ const homeDir2 = os44.homedir();
22926
23232
  return {
22927
23233
  findDeployments: () => findHeadroomDeployments(homeDir2, {
22928
- readDir: (dir) => fs47.readdirSync(dir),
22929
- readJson: (filePath) => JSON.parse(fs47.readFileSync(filePath, "utf8"))
23234
+ readDir: (dir) => fs48.readdirSync(dir),
23235
+ readJson: (filePath) => JSON.parse(fs48.readFileSync(filePath, "utf8"))
22930
23236
  }),
22931
23237
  writeManifest: writeManifestReal,
22932
23238
  restartDeployment: restartDeploymentReal,
@@ -23059,47 +23365,47 @@ async function readUsageReport(deps = {}) {
23059
23365
  }
23060
23366
 
23061
23367
  // src/agents/acp/guardrail-config.ts
23062
- var fs48 = __toESM(require("fs"));
23063
- var path52 = __toESM(require("path"));
23064
- var os44 = __toESM(require("os"));
23368
+ var fs49 = __toESM(require("fs"));
23369
+ var path53 = __toESM(require("path"));
23370
+ var os45 = __toESM(require("os"));
23065
23371
  var current = null;
23066
- function guardrailConfigPath(homeDir2 = os44.homedir()) {
23067
- return path52.join(homeDir2, ".codeam", "guardrails.json");
23372
+ function guardrailConfigPath(homeDir2 = os45.homedir()) {
23373
+ return path53.join(homeDir2, ".codeam", "guardrails.json");
23068
23374
  }
23069
- function loadGuardrailPolicy(homeDir2 = os44.homedir()) {
23375
+ function loadGuardrailPolicy(homeDir2 = os45.homedir()) {
23070
23376
  try {
23071
- current = normalizeGuardrailPolicy(JSON.parse(fs48.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
23377
+ current = normalizeGuardrailPolicy(JSON.parse(fs49.readFileSync(guardrailConfigPath(homeDir2), "utf8")));
23072
23378
  } catch {
23073
23379
  current = { ...DEFAULT_GUARDRAIL_POLICY };
23074
23380
  }
23075
23381
  return current;
23076
23382
  }
23077
- function getGuardrailPolicy(homeDir2 = os44.homedir()) {
23383
+ function getGuardrailPolicy(homeDir2 = os45.homedir()) {
23078
23384
  return current ?? loadGuardrailPolicy(homeDir2);
23079
23385
  }
23080
- function setGuardrailPolicy(raw, homeDir2 = os44.homedir()) {
23386
+ function setGuardrailPolicy(raw, homeDir2 = os45.homedir()) {
23081
23387
  const next = normalizeGuardrailPolicy(raw);
23082
23388
  current = next;
23083
23389
  try {
23084
23390
  const p2 = guardrailConfigPath(homeDir2);
23085
- fs48.mkdirSync(path52.dirname(p2), { recursive: true });
23086
- fs48.writeFileSync(p2, JSON.stringify(next, null, 2));
23391
+ fs49.mkdirSync(path53.dirname(p2), { recursive: true });
23392
+ fs49.writeFileSync(p2, JSON.stringify(next, null, 2));
23087
23393
  } catch {
23088
23394
  }
23089
23395
  return next;
23090
23396
  }
23091
23397
 
23092
23398
  // src/services/preview/port-registry.ts
23093
- var fs49 = __toESM(require("fs"));
23094
- var os45 = __toESM(require("os"));
23095
- var path53 = __toESM(require("path"));
23399
+ var fs50 = __toESM(require("fs"));
23400
+ var os46 = __toESM(require("os"));
23401
+ var path54 = __toESM(require("path"));
23096
23402
  var import_child_process16 = require("child_process");
23097
23403
  function registryPath() {
23098
- return path53.join(os45.homedir(), ".codeam", "preview-ports.json");
23404
+ return path54.join(os46.homedir(), ".codeam", "preview-ports.json");
23099
23405
  }
23100
23406
  function readRegistry() {
23101
23407
  try {
23102
- const raw = fs49.readFileSync(registryPath(), "utf8");
23408
+ const raw = fs50.readFileSync(registryPath(), "utf8");
23103
23409
  const parsed = JSON.parse(raw);
23104
23410
  if (parsed && typeof parsed === "object") return parsed;
23105
23411
  } catch {
@@ -23109,10 +23415,10 @@ function readRegistry() {
23109
23415
  function writeRegistry(reg) {
23110
23416
  try {
23111
23417
  const file = registryPath();
23112
- fs49.mkdirSync(path53.dirname(file), { recursive: true });
23418
+ fs50.mkdirSync(path54.dirname(file), { recursive: true });
23113
23419
  const tmp = `${file}.tmp`;
23114
- fs49.writeFileSync(tmp, JSON.stringify(reg), "utf8");
23115
- fs49.renameSync(tmp, file);
23420
+ fs50.writeFileSync(tmp, JSON.stringify(reg), "utf8");
23421
+ fs50.renameSync(tmp, file);
23116
23422
  } catch (err) {
23117
23423
  log.warn("preview", `port-registry write failed: ${err instanceof Error ? err.message : String(err)}`);
23118
23424
  }
@@ -23178,7 +23484,7 @@ function reclaimOwnOrphanPort(port) {
23178
23484
 
23179
23485
  // src/services/preview/host-allow.ts
23180
23486
  var import_fs2 = require("fs");
23181
- var path54 = __toESM(require("path"));
23487
+ var path55 = __toESM(require("path"));
23182
23488
  var NEXT_ALLOWED_ORIGINS = [
23183
23489
  "*.trycloudflare.com",
23184
23490
  "*.preview.codeagent-mobile.com",
@@ -23198,7 +23504,7 @@ var MARKER_DIR = ".codeam";
23198
23504
  var MARKER_FILE = "preview-host-allow.json";
23199
23505
  var ORIG_INFIX = ".codeam-orig";
23200
23506
  function markerPath(cwd) {
23201
- return path54.join(cwd, MARKER_DIR, MARKER_FILE);
23507
+ return path55.join(cwd, MARKER_DIR, MARKER_FILE);
23202
23508
  }
23203
23509
  async function fileExists(p2) {
23204
23510
  try {
@@ -23211,13 +23517,13 @@ async function fileExists(p2) {
23211
23517
  async function findConfigFile(cwd, framework) {
23212
23518
  const base = CONFIG_BASENAMES[framework];
23213
23519
  for (const ext of CONFIG_EXTS) {
23214
- if (await fileExists(path54.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
23520
+ if (await fileExists(path55.join(cwd, `${base}${ext}`))) return `${base}${ext}`;
23215
23521
  }
23216
23522
  return null;
23217
23523
  }
23218
23524
  async function dependsOn(cwd, pkgName) {
23219
23525
  try {
23220
- const raw = await import_fs2.promises.readFile(path54.join(cwd, "package.json"), "utf8");
23526
+ const raw = await import_fs2.promises.readFile(path55.join(cwd, "package.json"), "utf8");
23221
23527
  const pkg = JSON.parse(raw);
23222
23528
  return !!(pkg.dependencies?.[pkgName] ?? pkg.devDependencies?.[pkgName]);
23223
23529
  } catch {
@@ -23225,11 +23531,11 @@ async function dependsOn(cwd, pkgName) {
23225
23531
  }
23226
23532
  }
23227
23533
  async function isEsmConfig(cwd, configFile) {
23228
- const ext = path54.extname(configFile);
23534
+ const ext = path55.extname(configFile);
23229
23535
  if (ext === ".mjs" || ext === ".mts" || ext === ".ts") return true;
23230
23536
  if (ext === ".cjs") return false;
23231
23537
  try {
23232
- const raw = await import_fs2.promises.readFile(path54.join(cwd, "package.json"), "utf8");
23538
+ const raw = await import_fs2.promises.readFile(path55.join(cwd, "package.json"), "utf8");
23233
23539
  return JSON.parse(raw).type === "module";
23234
23540
  } catch {
23235
23541
  return false;
@@ -23312,7 +23618,7 @@ function shimFor(framework, origBasename, esm) {
23312
23618
  return framework === "next" ? nextShim(origBasename, esm) : viteShim(origBasename, esm);
23313
23619
  }
23314
23620
  async function writeMarker(cwd, marker) {
23315
- await import_fs2.promises.mkdir(path54.join(cwd, MARKER_DIR), { recursive: true });
23621
+ await import_fs2.promises.mkdir(path55.join(cwd, MARKER_DIR), { recursive: true });
23316
23622
  await import_fs2.promises.writeFile(markerPath(cwd), JSON.stringify(marker, null, 2), "utf8");
23317
23623
  }
23318
23624
  async function readMarker(cwd) {
@@ -23327,9 +23633,9 @@ async function restorePreviewHostAllow(cwd) {
23327
23633
  const marker = await readMarker(cwd);
23328
23634
  if (!marker) return;
23329
23635
  try {
23330
- const configAbs = path54.join(cwd, marker.configFile);
23636
+ const configAbs = path55.join(cwd, marker.configFile);
23331
23637
  if (marker.backupFile) {
23332
- const backupAbs = path54.join(cwd, marker.backupFile);
23638
+ const backupAbs = path55.join(cwd, marker.backupFile);
23333
23639
  if (await fileExists(backupAbs)) {
23334
23640
  await import_fs2.promises.rm(configAbs, { force: true });
23335
23641
  await import_fs2.promises.rename(backupAbs, configAbs);
@@ -23362,16 +23668,16 @@ async function applyPreviewHostAllow(cwd) {
23362
23668
  }
23363
23669
  if (!framework) return;
23364
23670
  if (existing) {
23365
- const ext = path54.extname(existing);
23671
+ const ext = path55.extname(existing);
23366
23672
  const origBasename = `${CONFIG_BASENAMES[framework]}${ORIG_INFIX}${ext}`;
23367
23673
  const esm = await isEsmConfig(cwd, existing);
23368
- await import_fs2.promises.rename(path54.join(cwd, existing), path54.join(cwd, origBasename));
23369
- await import_fs2.promises.writeFile(path54.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
23674
+ await import_fs2.promises.rename(path55.join(cwd, existing), path55.join(cwd, origBasename));
23675
+ await import_fs2.promises.writeFile(path55.join(cwd, existing), shimFor(framework, origBasename, esm), "utf8");
23370
23676
  await writeMarker(cwd, { framework, configFile: existing, backupFile: origBasename });
23371
23677
  log.info("preview", `host-allow: wrapped ${existing} (${framework}) for tunnel access`);
23372
23678
  } else {
23373
23679
  const configFile = `${CONFIG_BASENAMES[framework]}.mjs`;
23374
- await import_fs2.promises.writeFile(path54.join(cwd, configFile), shimFor(framework, null, true), "utf8");
23680
+ await import_fs2.promises.writeFile(path55.join(cwd, configFile), shimFor(framework, null, true), "utf8");
23375
23681
  await writeMarker(cwd, { framework, configFile, backupFile: null });
23376
23682
  log.info("preview", `host-allow: created ${configFile} (${framework}) for tunnel access`);
23377
23683
  }
@@ -24053,19 +24359,19 @@ function activePreviewSessionIds() {
24053
24359
 
24054
24360
  // src/services/preview/start-orchestrator.ts
24055
24361
  var import_child_process21 = require("child_process");
24056
- var fs57 = __toESM(require("fs"));
24057
- var path61 = __toESM(require("path"));
24362
+ var fs58 = __toESM(require("fs"));
24363
+ var path62 = __toESM(require("path"));
24058
24364
  var import_which2 = __toESM(require("which"));
24059
24365
 
24060
24366
  // src/services/project-env/index.ts
24061
24367
  var import_fs6 = require("fs");
24062
- var path60 = __toESM(require("path"));
24368
+ var path61 = __toESM(require("path"));
24063
24369
 
24064
24370
  // src/beads/project-key.ts
24065
24371
  var import_child_process20 = require("child_process");
24066
24372
  var crypto2 = __toESM(require("crypto"));
24067
- var fs55 = __toESM(require("fs"));
24068
- var path59 = __toESM(require("path"));
24373
+ var fs56 = __toESM(require("fs"));
24374
+ var path60 = __toESM(require("path"));
24069
24375
  function normalizeOrigin(raw) {
24070
24376
  const trimmed = raw.trim();
24071
24377
  if (!trimmed) return null;
@@ -24091,17 +24397,17 @@ function normalizeOrigin(raw) {
24091
24397
  return `${host2}/${pathPart}`;
24092
24398
  }
24093
24399
  function findRepoRoot(cwd) {
24094
- let dir = path59.resolve(cwd);
24400
+ let dir = path60.resolve(cwd);
24095
24401
  const seen = /* @__PURE__ */ new Set();
24096
24402
  for (let i = 0; i < 256; i++) {
24097
24403
  if (seen.has(dir)) return null;
24098
24404
  seen.add(dir);
24099
24405
  try {
24100
- const stat3 = fs55.statSync(path59.join(dir, ".git"), { throwIfNoEntry: false });
24406
+ const stat3 = fs56.statSync(path60.join(dir, ".git"), { throwIfNoEntry: false });
24101
24407
  if (stat3 && (stat3.isDirectory() || stat3.isFile())) return dir;
24102
24408
  } catch {
24103
24409
  }
24104
- const parent = path59.dirname(dir);
24410
+ const parent = path60.dirname(dir);
24105
24411
  if (parent === dir) return null;
24106
24412
  dir = parent;
24107
24413
  }
@@ -24112,7 +24418,7 @@ var _execSeam2 = {
24112
24418
  const out2 = (0, import_child_process20.execFileSync)(file, args2, opts);
24113
24419
  return typeof out2 === "string" ? out2 : out2.toString("utf8");
24114
24420
  },
24115
- realpath: (p2) => fs55.realpathSync(p2)
24421
+ realpath: (p2) => fs56.realpathSync(p2)
24116
24422
  };
24117
24423
  function readOrigin(cwd) {
24118
24424
  try {
@@ -24141,7 +24447,7 @@ function deriveProjectIdentity(cwd = process.cwd()) {
24141
24447
  } catch {
24142
24448
  }
24143
24449
  const hash = crypto2.createHash("sha256").update(real).digest("hex");
24144
- return { projectKey: `path:${hash}`, projectLabel: path59.basename(real) || "project" };
24450
+ return { projectKey: `path:${hash}`, projectLabel: path60.basename(real) || "project" };
24145
24451
  }
24146
24452
 
24147
24453
  // src/services/project-env/index.ts
@@ -24154,7 +24460,7 @@ async function readIfExists(p2) {
24154
24460
  }
24155
24461
  async function syncProjectEnvUp(cwd, ctx) {
24156
24462
  if (!ctx.pluginAuthToken) return;
24157
- const content = await readIfExists(path60.join(cwd, ".env"));
24463
+ const content = await readIfExists(path61.join(cwd, ".env"));
24158
24464
  if (content == null) return;
24159
24465
  try {
24160
24466
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -24176,7 +24482,7 @@ async function syncProjectEnvUp(cwd, ctx) {
24176
24482
  }
24177
24483
  async function restoreProjectEnvIfMissing(cwd, ctx) {
24178
24484
  if (!ctx.pluginAuthToken) return false;
24179
- const envPath = path60.join(cwd, ".env");
24485
+ const envPath = path61.join(cwd, ".env");
24180
24486
  if (await readIfExists(envPath) != null) return false;
24181
24487
  try {
24182
24488
  const { projectKey, projectLabel } = deriveProjectIdentity(cwd);
@@ -24187,7 +24493,7 @@ async function restoreProjectEnvIfMissing(cwd, ctx) {
24187
24493
  projectKey
24188
24494
  });
24189
24495
  if (!stored) return false;
24190
- const tmp = path60.join(cwd, ".env.codeam-restore.tmp");
24496
+ const tmp = path61.join(cwd, ".env.codeam-restore.tmp");
24191
24497
  await import_fs6.promises.writeFile(tmp, stored.content, { encoding: "utf8", mode: 384 });
24192
24498
  await import_fs6.promises.rename(tmp, envPath);
24193
24499
  log.info("project-env", `restored .env (${stored.keyCount} vars) for ${projectLabel}`);
@@ -24264,8 +24570,8 @@ function normalizeDetectionForSpawn(detection, cwd) {
24264
24570
  if (args2.length === 0) return detection;
24265
24571
  const binName = args2[0];
24266
24572
  if (binName.startsWith("-")) return detection;
24267
- const binPath = path61.join(cwd, "node_modules", ".bin", binName);
24268
- if (!fs57.existsSync(binPath)) return detection;
24573
+ const binPath = path62.join(cwd, "node_modules", ".bin", binName);
24574
+ if (!fs58.existsSync(binPath)) return detection;
24269
24575
  return {
24270
24576
  ...detection,
24271
24577
  command: binPath,
@@ -24638,9 +24944,9 @@ async function establishTunnel(ctx, dev) {
24638
24944
 
24639
24945
  // src/beads/bd-adapter.ts
24640
24946
  var import_child_process22 = require("child_process");
24641
- var fs58 = __toESM(require("fs"));
24642
- var os47 = __toESM(require("os"));
24643
- var path62 = __toESM(require("path"));
24947
+ var fs59 = __toESM(require("fs"));
24948
+ var os48 = __toESM(require("os"));
24949
+ var path63 = __toESM(require("path"));
24644
24950
  var BD_PACKAGE = "@beads/bd";
24645
24951
  function resolveBundledBdBinary() {
24646
24952
  return _resolveSeam.resolveBundled();
@@ -24652,11 +24958,11 @@ function _defaultResolveBundled() {
24652
24958
  } catch {
24653
24959
  return null;
24654
24960
  }
24655
- const binDir = path62.join(path62.dirname(pkgJsonPath), "bin");
24961
+ const binDir = path63.join(path63.dirname(pkgJsonPath), "bin");
24656
24962
  const binaryName = process.platform === "win32" ? "bd.exe" : "bd";
24657
- const binaryPath = path62.join(binDir, binaryName);
24963
+ const binaryPath = path63.join(binDir, binaryName);
24658
24964
  try {
24659
- fs58.accessSync(binaryPath, fs58.constants.F_OK);
24965
+ fs59.accessSync(binaryPath, fs59.constants.F_OK);
24660
24966
  return binaryPath;
24661
24967
  } catch {
24662
24968
  return null;
@@ -24666,13 +24972,13 @@ function resolveBdOnPath() {
24666
24972
  return _resolveSeam.resolveOnPath();
24667
24973
  }
24668
24974
  function _defaultResolveOnPath() {
24669
- const dirs = (process.env.PATH ?? "").split(path62.delimiter).filter(Boolean);
24975
+ const dirs = (process.env.PATH ?? "").split(path63.delimiter).filter(Boolean);
24670
24976
  const candidates = process.platform === "win32" ? ["bd.exe", "bd.cmd", "bd"] : ["bd"];
24671
24977
  for (const dir of dirs) {
24672
24978
  for (const candidate of candidates) {
24673
- const full = path62.join(dir, candidate);
24979
+ const full = path63.join(dir, candidate);
24674
24980
  try {
24675
- fs58.accessSync(full, fs58.constants.F_OK);
24981
+ fs59.accessSync(full, fs59.constants.F_OK);
24676
24982
  return full;
24677
24983
  } catch {
24678
24984
  }
@@ -24757,7 +25063,7 @@ var BdAdapter = class {
24757
25063
  const env = { ...process.env };
24758
25064
  if (!env.HOME) {
24759
25065
  try {
24760
- const home = os47.homedir();
25066
+ const home = os48.homedir();
24761
25067
  if (home) env.HOME = home;
24762
25068
  } catch {
24763
25069
  }
@@ -24849,9 +25155,9 @@ function coerceIssue(row, projectKey) {
24849
25155
 
24850
25156
  // src/beads/provisioner.ts
24851
25157
  var import_child_process25 = require("child_process");
24852
- var fs60 = __toESM(require("fs"));
24853
- var os49 = __toESM(require("os"));
24854
- var path64 = __toESM(require("path"));
25158
+ var fs61 = __toESM(require("fs"));
25159
+ var os50 = __toESM(require("os"));
25160
+ var path65 = __toESM(require("path"));
24855
25161
 
24856
25162
  // src/beads/install-bd.ts
24857
25163
  var import_child_process23 = require("child_process");
@@ -24916,9 +25222,9 @@ async function installBd(platform3 = process.platform) {
24916
25222
 
24917
25223
  // src/beads/install-dolt.ts
24918
25224
  var import_child_process24 = require("child_process");
24919
- var fs59 = __toESM(require("fs"));
24920
- var os48 = __toESM(require("os"));
24921
- var path63 = __toESM(require("path"));
25225
+ var fs60 = __toESM(require("fs"));
25226
+ var os49 = __toESM(require("os"));
25227
+ var path64 = __toESM(require("path"));
24922
25228
  var DOLT_INSTALL_SH_URL = "https://github.com/dolthub/dolt/releases/latest/download/install.sh";
24923
25229
  var DOLT_MSI_URL = "https://github.com/dolthub/dolt/releases/latest/download/dolt-windows-amd64.msi";
24924
25230
  function resolveDoltInstallStrategy(platform3) {
@@ -25007,14 +25313,14 @@ async function installDoltToDir(targetDir, platform3 = process.platform, arch2 =
25007
25313
  return result;
25008
25314
  }
25009
25315
  var _doltPathSeam = {
25010
- homedir: () => os48.homedir(),
25316
+ homedir: () => os49.homedir(),
25011
25317
  getPath: () => process.env.PATH ?? "",
25012
25318
  setPath: (p2) => {
25013
25319
  process.env.PATH = p2;
25014
25320
  },
25015
25321
  exists: (p2) => {
25016
25322
  try {
25017
- fs59.accessSync(p2, fs59.constants.F_OK);
25323
+ fs60.accessSync(p2, fs60.constants.F_OK);
25018
25324
  return true;
25019
25325
  } catch {
25020
25326
  return false;
@@ -25025,7 +25331,7 @@ function doltBinaryNames(platform3) {
25025
25331
  return platform3 === "win32" ? ["dolt.exe", "dolt.cmd", "dolt"] : ["dolt"];
25026
25332
  }
25027
25333
  function knownDoltDirs(platform3) {
25028
- const P3 = platform3 === "win32" ? path63.win32 : path63.posix;
25334
+ const P3 = platform3 === "win32" ? path64.win32 : path64.posix;
25029
25335
  const home = _doltPathSeam.homedir();
25030
25336
  if (platform3 === "win32") {
25031
25337
  return [
@@ -25041,7 +25347,7 @@ function knownDoltDirs(platform3) {
25041
25347
  ].filter(Boolean);
25042
25348
  }
25043
25349
  function ensureDoltResolvable(platform3 = process.platform) {
25044
- const P3 = platform3 === "win32" ? path63.win32 : path63.posix;
25350
+ const P3 = platform3 === "win32" ? path64.win32 : path64.posix;
25045
25351
  const delim = platform3 === "win32" ? ";" : ":";
25046
25352
  const names = doltBinaryNames(platform3);
25047
25353
  const pathDirs = _doltPathSeam.getPath().split(delim).filter(Boolean);
@@ -25218,17 +25524,17 @@ var _provisionSeam = {
25218
25524
  };
25219
25525
  var _linkSeam = {
25220
25526
  platform: () => process.platform,
25221
- homedir: () => os49.homedir(),
25527
+ homedir: () => os50.homedir(),
25222
25528
  isWritableDir: (dir) => {
25223
25529
  try {
25224
- fs60.accessSync(dir, fs60.constants.W_OK);
25530
+ fs61.accessSync(dir, fs61.constants.W_OK);
25225
25531
  return true;
25226
25532
  } catch {
25227
25533
  return false;
25228
25534
  }
25229
25535
  },
25230
25536
  ensureDir: (dir) => {
25231
- fs60.mkdirSync(dir, { recursive: true });
25537
+ fs61.mkdirSync(dir, { recursive: true });
25232
25538
  },
25233
25539
  /**
25234
25540
  * A directory to symlink `bd` into so the AGENT's shell + Claude Code's
@@ -25249,9 +25555,9 @@ var _linkSeam = {
25249
25555
  * which `linkBdOntoPath` creates if missing.
25250
25556
  */
25251
25557
  cliBinDir: () => {
25252
- const pathDirs = (process.env.PATH ?? "").split(path64.delimiter).filter(Boolean);
25558
+ const pathDirs = (process.env.PATH ?? "").split(path65.delimiter).filter(Boolean);
25253
25559
  const home = _linkSeam.homedir();
25254
- const localBin = home ? path64.join(home, ".local", "bin") : null;
25560
+ const localBin = home ? path65.join(home, ".local", "bin") : null;
25255
25561
  if (localBin) {
25256
25562
  try {
25257
25563
  _linkSeam.ensureDir(localBin);
@@ -25261,16 +25567,16 @@ var _linkSeam = {
25261
25567
  const candidates = [];
25262
25568
  if (localBin) candidates.push(localBin);
25263
25569
  try {
25264
- candidates.push(path64.dirname(process.execPath));
25570
+ candidates.push(path65.dirname(process.execPath));
25265
25571
  } catch {
25266
25572
  }
25267
25573
  candidates.push("/usr/local/bin");
25268
25574
  const entry = process.argv[1];
25269
25575
  if (entry) {
25270
25576
  try {
25271
- candidates.push(path64.dirname(fs60.realpathSync(entry)));
25577
+ candidates.push(path65.dirname(fs61.realpathSync(entry)));
25272
25578
  } catch {
25273
- candidates.push(path64.dirname(entry));
25579
+ candidates.push(path65.dirname(entry));
25274
25580
  }
25275
25581
  }
25276
25582
  const onPathWritable = candidates.find(
@@ -25282,20 +25588,20 @@ var _linkSeam = {
25282
25588
  /** Current symlink target at `linkPath`, or null when absent / not a link. */
25283
25589
  readlink: (linkPath) => {
25284
25590
  try {
25285
- return fs60.readlinkSync(linkPath);
25591
+ return fs61.readlinkSync(linkPath);
25286
25592
  } catch {
25287
25593
  return null;
25288
25594
  }
25289
25595
  },
25290
- unlink: (linkPath) => fs60.unlinkSync(linkPath),
25291
- symlink: (target, linkPath) => fs60.symlinkSync(target, linkPath)
25596
+ unlink: (linkPath) => fs61.unlinkSync(linkPath),
25597
+ symlink: (target, linkPath) => fs61.symlinkSync(target, linkPath)
25292
25598
  };
25293
25599
  function linkBdOntoPath(binaryPath) {
25294
25600
  if (_linkSeam.platform() === "win32") return;
25295
25601
  const binDir = _linkSeam.cliBinDir();
25296
25602
  if (!binDir) return;
25297
25603
  _linkSeam.ensureDir(binDir);
25298
- const linkPath = path64.join(binDir, "bd");
25604
+ const linkPath = path65.join(binDir, "bd");
25299
25605
  if (linkPath === binaryPath) return;
25300
25606
  const current2 = _linkSeam.readlink(linkPath);
25301
25607
  if (current2 === binaryPath) return;
@@ -25490,7 +25796,7 @@ function dedupeRecipes(agents) {
25490
25796
 
25491
25797
  // src/beads/watcher.ts
25492
25798
  var crypto4 = __toESM(require("crypto"));
25493
- var path65 = __toESM(require("path"));
25799
+ var path66 = __toESM(require("path"));
25494
25800
  var API_BASE6 = resolveApiBaseUrl();
25495
25801
  var DEBOUNCE_MS2 = 400;
25496
25802
  var ZERO_SUMMARY = {
@@ -25514,7 +25820,7 @@ var BeadsWatcher = class {
25514
25820
  constructor(opts) {
25515
25821
  this.opts = opts;
25516
25822
  this.bd = opts.adapter ?? new BdAdapter({ cwd: opts.cwd, beadsDir: opts.beadsDir });
25517
- this.feedPath = opts.feedPath ?? path65.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
25823
+ this.feedPath = opts.feedPath ?? path66.join(opts.cwd ?? process.cwd(), ".beads", "last-touched");
25518
25824
  this.apiBase = opts.apiBaseUrl ?? API_BASE6;
25519
25825
  }
25520
25826
  opts;
@@ -26013,8 +26319,8 @@ function cleanupAttachmentTempFiles() {
26013
26319
  function saveFilesTemp(files) {
26014
26320
  return files.filter(({ base64 }) => base64 && base64.length > 0).map(({ filename, base64 }) => {
26015
26321
  const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
26016
- const tmpPath = path68.join(os53.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
26017
- fs63.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
26322
+ const tmpPath = path69.join(os54.tmpdir(), `codeam-${(0, import_crypto3.randomUUID)()}-${safeName}`);
26323
+ fs64.writeFileSync(tmpPath, Buffer.from(base64, "base64"));
26018
26324
  pendingAttachmentFiles.add(tmpPath);
26019
26325
  return tmpPath;
26020
26326
  });
@@ -26232,10 +26538,10 @@ var listFiles = async (ctx, cmd, parsed) => {
26232
26538
  await ctx.relay.sendResult(cmd.id, "completed", result);
26233
26539
  };
26234
26540
  var envReadH = async (ctx, cmd) => {
26235
- const envPath = path68.join(process.cwd(), ".env");
26541
+ const envPath = path69.join(process.cwd(), ".env");
26236
26542
  await restoreProjectEnvIfMissing(process.cwd(), ctx);
26237
26543
  try {
26238
- const raw = await fs63.promises.readFile(envPath, "utf8");
26544
+ const raw = await fs64.promises.readFile(envPath, "utf8");
26239
26545
  await ctx.relay.sendResult(cmd.id, "completed", {
26240
26546
  exists: true,
26241
26547
  vars: parseDotenv(raw)
@@ -26266,15 +26572,15 @@ var envWriteH = async (ctx, cmd, parsed) => {
26266
26572
  }
26267
26573
  seen.add(v.key);
26268
26574
  }
26269
- const envPath = path68.join(process.cwd(), ".env");
26270
- const tmpPath = path68.join(process.cwd(), ".env.codeam.tmp");
26575
+ const envPath = path69.join(process.cwd(), ".env");
26576
+ const tmpPath = path69.join(process.cwd(), ".env.codeam.tmp");
26271
26577
  try {
26272
- await fs63.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
26273
- await fs63.promises.rename(tmpPath, envPath);
26578
+ await fs64.promises.writeFile(tmpPath, serializeDotenv(vars), "utf8");
26579
+ await fs64.promises.rename(tmpPath, envPath);
26274
26580
  await ctx.relay.sendResult(cmd.id, "completed", { ok: true, count: vars.length });
26275
26581
  void syncProjectEnvUp(process.cwd(), ctx);
26276
26582
  } catch (err) {
26277
- await fs63.promises.rm(tmpPath, { force: true }).catch(() => void 0);
26583
+ await fs64.promises.rm(tmpPath, { force: true }).catch(() => void 0);
26278
26584
  await ctx.relay.sendResult(cmd.id, "failed", { error: err.message });
26279
26585
  }
26280
26586
  };
@@ -26323,7 +26629,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
26323
26629
  let configuredAgent = rawAgentId;
26324
26630
  if (!configuredAgent) {
26325
26631
  try {
26326
- const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26632
+ const raw = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
26327
26633
  configuredAgent = raw.agent ?? "";
26328
26634
  } catch {
26329
26635
  }
@@ -26357,7 +26663,7 @@ var headroomConfigureH = async (ctx, cmd, parsed) => {
26357
26663
  persist: persistHeadroomConfig,
26358
26664
  readEnabled: () => {
26359
26665
  try {
26360
- const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26666
+ const raw = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
26361
26667
  return raw.enabled === true;
26362
26668
  } catch {
26363
26669
  return false;
@@ -26679,7 +26985,7 @@ var headroomBudgetH = async (ctx, cmd) => {
26679
26985
  }
26680
26986
  let headroomActive = false;
26681
26987
  try {
26682
- const raw = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26988
+ const raw = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
26683
26989
  headroomActive = raw.enabled === true;
26684
26990
  } catch {
26685
26991
  }
@@ -26689,7 +26995,7 @@ var headroomBudgetH = async (ctx, cmd) => {
26689
26995
  }
26690
26996
  let existingConfig = { enabled: true };
26691
26997
  try {
26692
- existingConfig = JSON.parse(fs63.readFileSync(headroomConfigPath(), "utf8"));
26998
+ existingConfig = JSON.parse(fs64.readFileSync(headroomConfigPath(), "utf8"));
26693
26999
  } catch {
26694
27000
  }
26695
27001
  if (payload.budgetEnabled && payload.budgetUsd != null) {
@@ -26802,9 +27108,9 @@ var CLI_UPDATE_MAX_ATTEMPTS = 3;
26802
27108
  function buildNpmInstallInvocation(opts) {
26803
27109
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
26804
27110
  const execPath = opts?.execPath ?? process.execPath;
26805
- const exists2 = opts?.existsSync ?? fs63.existsSync;
27111
+ const exists2 = opts?.existsSync ?? fs64.existsSync;
26806
27112
  const platform3 = opts?.platform ?? process.platform;
26807
- const p2 = platform3 === "win32" ? path68.win32 : path68.posix;
27113
+ const p2 = platform3 === "win32" ? path69.win32 : path69.posix;
26808
27114
  const normalized = entryScript.split(/[\\/]/).join("/");
26809
27115
  const marker = "/lib/node_modules/codeam-cli/";
26810
27116
  const markerIdx = normalized.indexOf(marker);
@@ -26826,7 +27132,7 @@ function isPermissionError(stderr) {
26826
27132
  function resolveGlobalNodeModulesDir(opts) {
26827
27133
  const entryScript = opts?.entryScript ?? process.argv[1] ?? "";
26828
27134
  const platform3 = opts?.platform ?? process.platform;
26829
- const p2 = platform3 === "win32" ? path68.win32 : path68.posix;
27135
+ const p2 = platform3 === "win32" ? path69.win32 : path69.posix;
26830
27136
  const marker = "/lib/node_modules/codeam-cli/";
26831
27137
  const markerIdx = entryScript.split(/[\\/]/).join("/").indexOf(marker);
26832
27138
  if (markerIdx <= 0) return null;
@@ -26836,9 +27142,9 @@ function resolveGlobalNodeModulesDir(opts) {
26836
27142
  var STALE_STAGING_AGE_MS = CLI_UPDATE_INSTALL_TIMEOUT_MS;
26837
27143
  function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
26838
27144
  if (!nodeModulesDir) return 0;
26839
- const readdirSync15 = deps?.readdirSync ?? fs63.readdirSync;
26840
- const statSync17 = deps?.statSync ?? fs63.statSync;
26841
- const rmSync9 = deps?.rmSync ?? fs63.rmSync;
27145
+ const readdirSync15 = deps?.readdirSync ?? fs64.readdirSync;
27146
+ const statSync17 = deps?.statSync ?? fs64.statSync;
27147
+ const rmSync9 = deps?.rmSync ?? fs64.rmSync;
26842
27148
  let removed = 0;
26843
27149
  let entries;
26844
27150
  try {
@@ -26848,7 +27154,7 @@ function sweepStaleCliStagingDirs(nodeModulesDir, now = Date.now(), deps) {
26848
27154
  }
26849
27155
  for (const name of entries) {
26850
27156
  if (!/^\.codeam-cli-/.test(name)) continue;
26851
- const full = path68.join(nodeModulesDir, name);
27157
+ const full = path69.join(nodeModulesDir, name);
26852
27158
  try {
26853
27159
  const st3 = statSync17(full);
26854
27160
  if (now - st3.mtimeMs < STALE_STAGING_AGE_MS) continue;
@@ -27728,7 +28034,7 @@ function resolveTokenValue(args2) {
27728
28034
  if (fileFlag) {
27729
28035
  const path92 = fileFlag.slice("--token-file=".length);
27730
28036
  try {
27731
- const content = fs64.readFileSync(path92, "utf8").trim();
28037
+ const content = fs65.readFileSync(path92, "utf8").trim();
27732
28038
  if (content.length === 0) fail(`--token-file ${path92} is empty`);
27733
28039
  rmIfExistsQuiet(path92);
27734
28040
  return content;
@@ -27759,7 +28065,7 @@ async function claimOnce(token, pluginId, pluginSecretHash) {
27759
28065
  pluginId,
27760
28066
  ideName: "codeam-cli (codespace)",
27761
28067
  ideVersion: process.env.npm_package_version ?? "unknown",
27762
- hostname: os54.hostname(),
28068
+ hostname: os55.hostname(),
27763
28069
  codespaceName: process.env.CODESPACE_NAME ?? "",
27764
28070
  // Current git branch of the codespace's working directory, so the
27765
28071
  // backend can populate `PairedSession.branch` for the codespace pair.
@@ -27820,7 +28126,7 @@ async function claim(token, pluginId, pluginSecretHash) {
27820
28126
  }
27821
28127
  }
27822
28128
  function pairAutoLockPath() {
27823
- return path69.join(os54.homedir(), ".codeam", "pair-auto.lock");
28129
+ return path70.join(os55.homedir(), ".codeam", "pair-auto.lock");
27824
28130
  }
27825
28131
  function isLivePairAuto(pid) {
27826
28132
  if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
@@ -27830,7 +28136,7 @@ function isLivePairAuto(pid) {
27830
28136
  if (e.code !== "EPERM") return false;
27831
28137
  }
27832
28138
  try {
27833
- return fs64.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
28139
+ return fs65.readFileSync(`/proc/${pid}/cmdline`, "utf8").includes("codeam");
27834
28140
  } catch {
27835
28141
  return true;
27836
28142
  }
@@ -27840,24 +28146,24 @@ function isLiveCodeam(pid) {
27840
28146
  }
27841
28147
  function daemonLockPath(sessionId) {
27842
28148
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
27843
- return path69.join(os54.homedir(), ".codeam", `daemon-${safe}.lock`);
28149
+ return path70.join(os55.homedir(), ".codeam", `daemon-${safe}.lock`);
27844
28150
  }
27845
28151
  function acquireDaemonLock(sessionId) {
27846
28152
  const lockPath = daemonLockPath(sessionId);
27847
28153
  try {
27848
- fs64.mkdirSync(path69.dirname(lockPath), { recursive: true });
28154
+ fs65.mkdirSync(path70.dirname(lockPath), { recursive: true });
27849
28155
  try {
27850
- fs64.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
28156
+ fs65.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27851
28157
  } catch (e) {
27852
28158
  if (e.code !== "EEXIST") throw e;
27853
- const holder = Number(fs64.readFileSync(lockPath, "utf8").trim());
28159
+ const holder = Number(fs65.readFileSync(lockPath, "utf8").trim());
27854
28160
  if (holder && holder !== process.pid && isLiveCodeam(holder)) return false;
27855
- fs64.writeFileSync(lockPath, String(process.pid));
28161
+ fs65.writeFileSync(lockPath, String(process.pid));
27856
28162
  }
27857
28163
  const release3 = () => {
27858
28164
  try {
27859
- if (fs64.existsSync(lockPath) && Number(fs64.readFileSync(lockPath, "utf8").trim()) === process.pid) {
27860
- fs64.unlinkSync(lockPath);
28165
+ if (fs65.existsSync(lockPath) && Number(fs65.readFileSync(lockPath, "utf8").trim()) === process.pid) {
28166
+ fs65.unlinkSync(lockPath);
27861
28167
  }
27862
28168
  } catch {
27863
28169
  }
@@ -27879,19 +28185,19 @@ function acquireDaemonLock(sessionId) {
27879
28185
  function acquireSingletonLock() {
27880
28186
  const lockPath = pairAutoLockPath();
27881
28187
  try {
27882
- fs64.mkdirSync(path69.dirname(lockPath), { recursive: true });
28188
+ fs65.mkdirSync(path70.dirname(lockPath), { recursive: true });
27883
28189
  try {
27884
- fs64.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
28190
+ fs65.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
27885
28191
  } catch (e) {
27886
28192
  if (e.code !== "EEXIST") throw e;
27887
- const holder = Number(fs64.readFileSync(lockPath, "utf8").trim());
28193
+ const holder = Number(fs65.readFileSync(lockPath, "utf8").trim());
27888
28194
  if (isLivePairAuto(holder)) return false;
27889
- fs64.writeFileSync(lockPath, String(process.pid));
28195
+ fs65.writeFileSync(lockPath, String(process.pid));
27890
28196
  }
27891
28197
  process.once("exit", () => {
27892
28198
  try {
27893
- if (fs64.existsSync(lockPath) && Number(fs64.readFileSync(lockPath, "utf8").trim()) === process.pid) {
27894
- fs64.unlinkSync(lockPath);
28199
+ if (fs65.existsSync(lockPath) && Number(fs65.readFileSync(lockPath, "utf8").trim()) === process.pid) {
28200
+ fs65.unlinkSync(lockPath);
27895
28201
  }
27896
28202
  } catch {
27897
28203
  }
@@ -28343,7 +28649,7 @@ var AgentService = class _AgentService {
28343
28649
  };
28344
28650
 
28345
28651
  // src/agents/acp/adapters.ts
28346
- var path70 = __toESM(require("path"));
28652
+ var path71 = __toESM(require("path"));
28347
28653
 
28348
28654
  // src/agents/kimi/installer.ts
28349
28655
  var import_node_child_process27 = require("child_process");
@@ -28463,13 +28769,13 @@ function resolveBin(pkgName, binName) {
28463
28769
  try {
28464
28770
  const manifestPath = require_.resolve(`${pkgName}/package.json`);
28465
28771
  const manifest = require_(`${pkgName}/package.json`);
28466
- const pkgDir = path70.dirname(manifestPath);
28772
+ const pkgDir = path71.dirname(manifestPath);
28467
28773
  const bin = manifest.bin;
28468
28774
  if (!bin) return null;
28469
- if (typeof bin === "string") return path70.resolve(pkgDir, bin);
28775
+ if (typeof bin === "string") return path71.resolve(pkgDir, bin);
28470
28776
  const target = binName ?? Object.keys(bin)[0];
28471
28777
  if (!target || !bin[target]) return null;
28472
- return path70.resolve(pkgDir, bin[target]);
28778
+ return path71.resolve(pkgDir, bin[target]);
28473
28779
  } catch {
28474
28780
  return null;
28475
28781
  }
@@ -28658,286 +28964,6 @@ var os56 = __toESM(require("os"));
28658
28964
  var https7 = __toESM(require("https"));
28659
28965
  var http6 = __toESM(require("http"));
28660
28966
  var import_zod2 = require("zod");
28661
-
28662
- // src/agents/acp/squad-roster.ts
28663
- var fs65 = __toESM(require("fs"));
28664
- var os55 = __toESM(require("os"));
28665
- var path71 = __toESM(require("path"));
28666
- var PROMPT_MAX = 500;
28667
- var REPLY_SUMMARY_MAX = 1e3;
28668
- var PREAMBLE_MAX = 2e3;
28669
- var BRIEFING_DEFAULT_MAX = 8e3;
28670
- var GENERIC_SPECIALTY = "general implementation tasks";
28671
- function clip(s, max) {
28672
- return s.length > max ? s.slice(0, max) : s;
28673
- }
28674
- function defaultMember() {
28675
- return {
28676
- acpSessionId: null,
28677
- provisioned: false,
28678
- binaryVerified: false,
28679
- lastTurnIndex: 0,
28680
- contextTextFallback: false
28681
- };
28682
- }
28683
- function journalPathFor(homeDir2, sessionId) {
28684
- return path71.join(homeDir2, ".codeam", `squad-journal-${sessionId}.json`);
28685
- }
28686
- function loadJournal(journalPath) {
28687
- try {
28688
- const raw = JSON.parse(fs65.readFileSync(journalPath, "utf-8"));
28689
- return Array.isArray(raw.turns) ? raw.turns : [];
28690
- } catch {
28691
- return [];
28692
- }
28693
- }
28694
- var SquadState = class {
28695
- /** Set by the caller after fetchSquadRoster; null until then. */
28696
- roster = null;
28697
- /**
28698
- * Autonomous chained handoffs (P2-2, PRO). Seeded from the persisted
28699
- * `SavedSession.squadAuto` at session start and rewritten by
28700
- * `squad_configure`. Read-only to callers — mutate via {@link setAuto}, which
28701
- * clamps the budget and re-arms the chain.
28702
- */
28703
- autoConfig = { enabled: false, hopBudget: SQUAD_HOP_BUDGET_DEFAULT };
28704
- /**
28705
- * Hops left in the CURRENT chain. Reset to the budget on every USER-initiated
28706
- * prompt (so a user turn always interrupts and re-arms) and decremented by
28707
- * each self-accepted handoff.
28708
- */
28709
- hopsLeft = 0;
28710
- /** Lifetime handoff counters for `squad_stats` (in-memory, this process). */
28711
- handoffCounters = { proposed: 0, accepted: 0, auto: 0 };
28712
- journalPath;
28713
- turns;
28714
- members = /* @__PURE__ */ new Map();
28715
- constructor(opts) {
28716
- this.journalPath = journalPathFor(opts.homeDir ?? os55.homedir(), opts.sessionId);
28717
- this.turns = loadJournal(this.journalPath);
28718
- if (opts.auto) this.setAuto(opts.auto);
28719
- }
28720
- get auto() {
28721
- return this.autoConfig;
28722
- }
28723
- /** Apply a new mode (clamping the budget) and re-arm the chain. */
28724
- setAuto(value) {
28725
- this.autoConfig = {
28726
- enabled: value.enabled === true,
28727
- hopBudget: clampHopBudget(value.hopBudget)
28728
- };
28729
- this.resetHops();
28730
- return this.autoConfig;
28731
- }
28732
- hopsRemaining() {
28733
- return this.hopsLeft;
28734
- }
28735
- /** Re-arm the chain — called at the start of every USER-initiated turn. */
28736
- resetHops() {
28737
- this.hopsLeft = this.autoConfig.enabled ? this.autoConfig.hopBudget : 0;
28738
- }
28739
- /** Spend one hop on a self-accepted handoff. */
28740
- consumeHop() {
28741
- if (this.hopsLeft > 0) this.hopsLeft -= 1;
28742
- }
28743
- countProposal(opts) {
28744
- this.handoffCounters.proposed += 1;
28745
- if (opts.auto) this.handoffCounters.auto += 1;
28746
- }
28747
- countAccepted() {
28748
- this.handoffCounters.accepted += 1;
28749
- }
28750
- /**
28751
- * Per-member activity for the `squad_stats` relay command, derived from the
28752
- * journal (the same shared history the delta briefing reads) plus the
28753
- * in-memory handoff counters. `filesTouched` counts DISTINCT paths — a member
28754
- * that edited the same file across three turns touched ONE file.
28755
- */
28756
- stats() {
28757
- const byAgent = /* @__PURE__ */ new Map();
28758
- for (const t2 of this.turns) {
28759
- let row = byAgent.get(t2.agentId);
28760
- if (!row) {
28761
- row = { turns: 0, files: /* @__PURE__ */ new Set() };
28762
- byAgent.set(t2.agentId, row);
28763
- }
28764
- row.turns += 1;
28765
- for (const f of t2.filesTouched) row.files.add(f);
28766
- }
28767
- const members = [...byAgent.entries()].map(([agentId, row]) => ({
28768
- agentId,
28769
- turns: row.turns,
28770
- filesTouched: row.files.size
28771
- }));
28772
- return { members, handoffs: { ...this.handoffCounters }, sinceTurn: 1 };
28773
- }
28774
- /** Returns (creating on first access) the mutable per-agent state. */
28775
- member(agentId) {
28776
- let m = this.members.get(agentId);
28777
- if (!m) {
28778
- m = defaultMember();
28779
- this.members.set(agentId, m);
28780
- }
28781
- return m;
28782
- }
28783
- /** Appends a journal entry and persists (fire-and-forget durability). */
28784
- recordTurn(entry) {
28785
- const turn = {
28786
- turn: this.turns.length + 1,
28787
- agentId: entry.agentId,
28788
- prompt: clip(entry.prompt, PROMPT_MAX),
28789
- replySummary: clip(entry.replySummary, REPLY_SUMMARY_MAX),
28790
- filesTouched: entry.filesTouched
28791
- };
28792
- this.turns.push(turn);
28793
- this.persist();
28794
- }
28795
- turnCount() {
28796
- return this.turns.length;
28797
- }
28798
- entriesSince(turnIndex) {
28799
- return this.turns.filter((t2) => t2.turn > turnIndex);
28800
- }
28801
- persist() {
28802
- try {
28803
- fs65.mkdirSync(path71.dirname(this.journalPath), { recursive: true, mode: 448 });
28804
- fs65.writeFileSync(this.journalPath, JSON.stringify({ turns: this.turns }), { mode: 384 });
28805
- } catch {
28806
- }
28807
- }
28808
- };
28809
- function specialtyFor(agentId) {
28810
- return SQUAD_SPECIALTIES[agentId] ?? GENERIC_SPECIALTY;
28811
- }
28812
- var TEAM_PREAMBLE_MARKER = "[Team context]";
28813
- var TEAM_PREAMBLE_LINES = [
28814
- "[Team context] You are the active agent in a CodeAgent Mobile session where the user",
28815
- "has a squad of agents and can pass work between them. Your available teammates:",
28816
- "If a task clearly fits a teammate better than you, you MAY propose a handoff by ending",
28817
- `your reply with a fenced code block tagged ${HANDOFF_FENCE_TAG} containing ONE JSON object:`,
28818
- '{"to":"<teammate id>","reason":"<one sentence>","prompt":"<the prompt they should run>"}',
28819
- "Propose at most one handoff per reply, only when genuinely better, and never announce",
28820
- "the block in prose \u2014 the app renders it as a card the user can accept."
28821
- ];
28822
- var TEAM_PREAMBLE_BULLET_RE = /^- .+ — best at: /;
28823
- var BRIEFING_MARKER = "[Team update]";
28824
- var BRIEFING_HEADER = "[Team update] While you were away, other agents worked on this session:";
28825
- var BRIEFING_FOOTER = "Continue from the CURRENT state of the working tree.";
28826
- function buildTeamPreamble(roster, currentAgent, opts) {
28827
- const others = roster.agents.filter((a) => a.agentId !== currentAgent);
28828
- if (others.length === 0) return null;
28829
- const lines = [
28830
- TEAM_PREAMBLE_LINES[0],
28831
- TEAM_PREAMBLE_LINES[1],
28832
- ...others.map((a) => `- ${a.displayName} \u2014 best at: ${specialtyFor(a.agentId)}`)
28833
- ];
28834
- if (opts.handoffInstructions) {
28835
- lines.push(...TEAM_PREAMBLE_LINES.slice(2));
28836
- }
28837
- return clip(lines.join("\n"), PREAMBLE_MAX);
28838
- }
28839
- function renderJournalEntry(e) {
28840
- const filesClause = e.filesTouched.length > 0 ? ` (files: ${e.filesTouched.join(", ")})` : "";
28841
- return `- turn ${e.turn} (${e.agentId}): ${e.prompt} \u2192 ${e.replySummary}${filesClause}`;
28842
- }
28843
- function buildDeltaBriefing(entries, maxChars = BRIEFING_DEFAULT_MAX) {
28844
- if (entries.length === 0) return null;
28845
- const header = BRIEFING_HEADER;
28846
- const footer = BRIEFING_FOOTER;
28847
- const envelope = header.length + 1 + footer.length + 1;
28848
- const sorted = [...entries].sort((a, b) => a.turn - b.turn);
28849
- const lines = [];
28850
- let bodyLen = 0;
28851
- for (let i = sorted.length - 1; i >= 0; i--) {
28852
- const line = renderJournalEntry(sorted[i]);
28853
- const addedLen = line.length + (lines.length > 0 ? 1 : 0);
28854
- if (lines.length > 0 && envelope + bodyLen + addedLen > maxChars) break;
28855
- lines.unshift(line);
28856
- bodyLen += addedLen;
28857
- }
28858
- return [header, lines.join("\n"), footer].join("\n");
28859
- }
28860
-
28861
- // src/agents/acp/squad-context.ts
28862
- var SQUAD_CONTEXT_URI = "codeam://squad-context";
28863
- var HANDOFF_MARKER = "[Session handoff]";
28864
- var HANDOFF_TERMINATOR = "--- End of handoff context ---";
28865
- function buildSquadContextBlock(text) {
28866
- return {
28867
- type: "resource",
28868
- resource: { uri: SQUAD_CONTEXT_URI, mimeType: "text/plain", text }
28869
- };
28870
- }
28871
- function isSquadContextBlock(block) {
28872
- return block.type === "resource" && block.resource.uri === SQUAD_CONTEXT_URI;
28873
- }
28874
- function looksLikeUnsupportedPromptShape(err) {
28875
- const code = err?.code;
28876
- if (code === -32602) return true;
28877
- const message = err instanceof Error ? err.message : String(err ?? "");
28878
- if (/invalid[ _]params|-32602/i.test(message)) return true;
28879
- return /\bresource\b/i.test(message) && /unsupported|not supported/i.test(message);
28880
- }
28881
- function skipWhile(lines, start2, keepGoing) {
28882
- let i = start2;
28883
- while (i < lines.length && keepGoing(lines[i])) i++;
28884
- return i;
28885
- }
28886
- function endOfTeamPreamble(lines, start2) {
28887
- if (lines[start2] !== TEAM_PREAMBLE_LINES[0]) return -1;
28888
- if (lines[start2 + 1] !== TEAM_PREAMBLE_LINES[1]) return -1;
28889
- return skipWhile(
28890
- lines,
28891
- start2 + 2,
28892
- (line) => TEAM_PREAMBLE_BULLET_RE.test(line) || TEAM_PREAMBLE_LINES.includes(line)
28893
- );
28894
- }
28895
- function endOfTerminatedBlock(lines, start2, terminator) {
28896
- for (let i = start2; i < lines.length; i++) {
28897
- if (lines[i].trimEnd() === terminator) return i + 1;
28898
- }
28899
- return -1;
28900
- }
28901
- function stripSquadContext(text) {
28902
- if (!text.includes(HANDOFF_MARKER) && !text.includes(BRIEFING_MARKER) && !text.includes(TEAM_PREAMBLE_MARKER)) {
28903
- return text;
28904
- }
28905
- const lines = text.split("\n");
28906
- const kept = [];
28907
- let i = 0;
28908
- let stripped = false;
28909
- while (i < lines.length) {
28910
- const line = lines[i];
28911
- if (line.startsWith(HANDOFF_MARKER)) {
28912
- const end = endOfTerminatedBlock(lines, i, HANDOFF_TERMINATOR);
28913
- if (end !== -1) {
28914
- i = end;
28915
- stripped = true;
28916
- continue;
28917
- }
28918
- } else if (line.startsWith(BRIEFING_MARKER)) {
28919
- const end = endOfTerminatedBlock(lines, i, BRIEFING_FOOTER);
28920
- if (end !== -1) {
28921
- i = end;
28922
- stripped = true;
28923
- continue;
28924
- }
28925
- } else if (line.startsWith(TEAM_PREAMBLE_MARKER)) {
28926
- const end = endOfTeamPreamble(lines, i);
28927
- if (end !== -1) {
28928
- i = end;
28929
- stripped = true;
28930
- continue;
28931
- }
28932
- }
28933
- kept.push(line);
28934
- i++;
28935
- }
28936
- if (!stripped) return text;
28937
- return kept.join("\n").trim();
28938
- }
28939
-
28940
- // src/services/history.service.ts
28941
28967
  var historyRecordSchema = import_zod2.z.object({
28942
28968
  type: import_zod2.z.string().optional(),
28943
28969
  timestamp: import_zod2.z.union([import_zod2.z.string(), import_zod2.z.number()]).optional(),
@@ -28960,6 +28986,7 @@ var CONVERSATION_BATCH_SIZE = 30;
28960
28986
  function scrubSquadContext(messages) {
28961
28987
  const out2 = [];
28962
28988
  for (const m of messages) {
28989
+ if (isLeakedSquadContextText(m.text) || isAgentMetaBlock(m.text)) continue;
28963
28990
  const text = stripSquadContext(m.text);
28964
28991
  if (text === m.text) {
28965
28992
  out2.push(m);
@@ -28991,7 +29018,11 @@ function parseJsonl(filePath) {
28991
29018
  }
28992
29019
  const result = historyRecordSchema.safeParse(parsedJson);
28993
29020
  if (!result.success) {
28994
- log.warn("history:parseJsonl", `record failed schema validation in ${filePath}`, result.error.issues);
29021
+ log.warn(
29022
+ "history:parseJsonl",
29023
+ `record failed schema validation in ${filePath}`,
29024
+ result.error.issues
29025
+ );
28995
29026
  continue;
28996
29027
  }
28997
29028
  const record2 = result.data;
@@ -29256,7 +29287,14 @@ var HistoryService = class _HistoryService {
29256
29287
  const inputTokens = (lastUsage["input_tokens"] ?? lastUsage["prompt_tokens"] ?? 0) + (lastUsage["cache_read_input_tokens"] ?? 0) + (lastUsage["cache_creation_input_tokens"] ?? 0);
29257
29288
  const outputTokens = lastUsage["output_tokens"] ?? lastUsage["completion_tokens"] ?? 0;
29258
29289
  const percent = Math.min(100, Math.round(inputTokens / total * 100));
29259
- return { used: inputTokens, total, percent, model: lastModel, outputTokens, cacheReadTokens: lastUsage["cache_read_input_tokens"] ?? 0 };
29290
+ return {
29291
+ used: inputTokens,
29292
+ total,
29293
+ percent,
29294
+ model: lastModel,
29295
+ outputTokens,
29296
+ cacheReadTokens: lastUsage["cache_read_input_tokens"] ?? 0
29297
+ };
29260
29298
  }
29261
29299
  /**
29262
29300
  * Estimate the API cost for the current month in the current project directory.
@@ -29429,7 +29467,9 @@ var HistoryService = class _HistoryService {
29429
29467
  ok = await post("/api/sessions/conversation", body, this.pluginAuthToken);
29430
29468
  }
29431
29469
  if (!ok) {
29432
- throw new Error(`Failed to upload conversation batch ${i + 1}/${totalBatches} after all retries`);
29470
+ throw new Error(
29471
+ `Failed to upload conversation batch ${i + 1}/${totalBatches} after all retries`
29472
+ );
29433
29473
  }
29434
29474
  }
29435
29475
  const last = messages[messages.length - 1];
@@ -35339,6 +35379,9 @@ var REASON_MAX = 1e3;
35339
35379
  var PROMPT_MAX2 = 8e3;
35340
35380
  var FENCE_OPEN = "```" + HANDOFF_FENCE_TAG;
35341
35381
  var FENCE_RE = new RegExp("```" + HANDOFF_FENCE_TAG + "\\s*\\n([\\s\\S]*?)\\n?```", "g");
35382
+ var DEGENERATE_LINE_RE = new RegExp(
35383
+ "^[ \\t]*(`{0,2})[ \\t]*" + HANDOFF_FENCE_TAG + "[ \\t]+(\\{.*\\})[ \\t]*\\1[ \\t]*\\r?$"
35384
+ );
35342
35385
  var OUTER_FENCE_RE = /(`{4,})[\s\S]*?\1/g;
35343
35386
  var outerFencePlaceholder = (i) => `@@HANDOFF_MASK_${i}@@`;
35344
35387
  function maskOuterFences(text) {
@@ -35351,62 +35394,117 @@ function maskOuterFences(text) {
35351
35394
  const restore = (s) => spans.reduce((acc, span, i) => acc.split(outerFencePlaceholder(i)).join(span), s);
35352
35395
  return { masked, restore };
35353
35396
  }
35354
- function parseProposal(raw, currentAgent, validTargets) {
35397
+ function parseProposalShape(raw) {
35355
35398
  let parsed;
35356
35399
  try {
35357
35400
  parsed = JSON.parse(raw);
35358
35401
  } catch {
35359
- log.debug("handoffProtocol", "dropped proposal: malformed JSON");
35360
- return null;
35361
- }
35362
- if (typeof parsed !== "object" || parsed === null) {
35363
- log.debug("handoffProtocol", "dropped proposal: not a JSON object");
35364
35402
  return null;
35365
35403
  }
35404
+ if (typeof parsed !== "object" || parsed === null) return null;
35366
35405
  const { to, reason, prompt } = parsed;
35367
- if (typeof to !== "string" || to.length === 0) {
35368
- log.debug("handoffProtocol", 'dropped proposal: missing/invalid "to"');
35406
+ if (typeof to !== "string" || to.length === 0) return null;
35407
+ if (typeof reason !== "string" || reason.length === 0 || reason.length > REASON_MAX) {
35369
35408
  return null;
35370
35409
  }
35371
- if (!validTargets.has(to)) {
35372
- log.debug("handoffProtocol", `dropped proposal: unknown target "${to}"`);
35410
+ if (typeof prompt !== "string" || prompt.length === 0 || prompt.length > PROMPT_MAX2) {
35373
35411
  return null;
35374
35412
  }
35375
- if (to === currentAgent) {
35376
- log.debug("handoffProtocol", "dropped proposal: target is the current agent");
35413
+ return { to, reason, prompt };
35414
+ }
35415
+ function resolveHandoffTarget(raw, validTargets) {
35416
+ const trimmed = (raw ?? "").trim();
35417
+ if (!trimmed) return null;
35418
+ const lower = trimmed.toLowerCase();
35419
+ for (const target of validTargets) {
35420
+ if (target.toLowerCase() === lower) return target;
35421
+ }
35422
+ const viaAlias = normalizeAgentId(trimmed);
35423
+ if (viaAlias && validTargets.has(viaAlias)) return viaAlias;
35424
+ const viaPublic = publicToInternal(lower);
35425
+ if (viaPublic && validTargets.has(viaPublic)) return viaPublic;
35426
+ for (const meta of Object.values(AGENT_REGISTRY)) {
35427
+ if (meta.displayName.toLowerCase() === lower && validTargets.has(meta.id)) {
35428
+ return meta.id;
35429
+ }
35430
+ }
35431
+ return null;
35432
+ }
35433
+ function parseProposal(raw, currentAgent, validTargets) {
35434
+ const shape = parseProposalShape(raw);
35435
+ if (!shape) {
35436
+ log.debug("handoffProtocol", "dropped proposal: malformed JSON or invalid shape");
35377
35437
  return null;
35378
35438
  }
35379
- if (typeof reason !== "string" || reason.length === 0 || reason.length > REASON_MAX) {
35380
- log.debug("handoffProtocol", 'dropped proposal: invalid "reason"');
35439
+ const to = resolveHandoffTarget(shape.to, validTargets);
35440
+ if (!to) {
35441
+ log.debug("handoffProtocol", `dropped proposal: unknown target "${shape.to}"`);
35381
35442
  return null;
35382
35443
  }
35383
- if (typeof prompt !== "string" || prompt.length === 0 || prompt.length > PROMPT_MAX2) {
35384
- log.debug("handoffProtocol", 'dropped proposal: invalid "prompt"');
35444
+ if (to === currentAgent) {
35445
+ log.debug("handoffProtocol", "dropped proposal: target is the current agent");
35385
35446
  return null;
35386
35447
  }
35387
- return { to, reason, prompt };
35448
+ return { to, reason: shape.reason, prompt: shape.prompt };
35449
+ }
35450
+ function collapseSeams(s) {
35451
+ return s.replace(/(?:\r?\n){3,}/g, "\n\n").trim();
35388
35452
  }
35389
35453
  function stripFences(masked) {
35390
- const stripped = masked.replace(FENCE_RE, "");
35391
- return stripped.replace(/(?:\r?\n){3,}/g, "\n\n").trim();
35454
+ return collapseSeams(masked.replace(FENCE_RE, ""));
35455
+ }
35456
+ function lastNonBlankLine(masked) {
35457
+ const parts = masked.split("\n");
35458
+ const starts = [];
35459
+ let offset = 0;
35460
+ for (const p2 of parts) {
35461
+ starts.push(offset);
35462
+ offset += p2.length + 1;
35463
+ }
35464
+ for (let i = parts.length - 1; i >= 0; i--) {
35465
+ if (parts[i].trim().length > 0) return { line: parts[i], start: starts[i] };
35466
+ }
35467
+ return null;
35468
+ }
35469
+ function trailingDegenerateMatch(masked) {
35470
+ const last = lastNonBlankLine(masked);
35471
+ if (!last) return null;
35472
+ const match = last.line.match(DEGENERATE_LINE_RE);
35473
+ return match ? { match, start: last.start } : null;
35392
35474
  }
35393
35475
  function extractHandoffProposal(text, currentAgent, validTargets) {
35394
35476
  const { masked, restore } = maskOuterFences(text);
35395
35477
  const matches = [...masked.matchAll(FENCE_RE)];
35396
- if (matches.length === 0) {
35478
+ if (matches.length > 0) {
35479
+ const last = matches[matches.length - 1];
35480
+ const proposal = parseProposal(last[1].trim(), currentAgent, validTargets);
35481
+ const cleanText = restore(stripFences(masked));
35482
+ return { cleanText, proposal };
35483
+ }
35484
+ const degenerate = trailingDegenerateMatch(masked);
35485
+ if (degenerate) {
35486
+ const proposal = parseProposal(degenerate.match[2].trim(), currentAgent, validTargets);
35487
+ if (proposal) {
35488
+ const { start: start2 } = degenerate;
35489
+ const stripped = masked.slice(0, start2) + masked.slice(start2 + degenerate.match[0].length);
35490
+ return { cleanText: restore(collapseSeams(stripped)), proposal };
35491
+ }
35397
35492
  return { cleanText: text, proposal: null };
35398
35493
  }
35399
- const last = matches[matches.length - 1];
35400
- const proposal = parseProposal(last[1].trim(), currentAgent, validTargets);
35401
- const cleanText = restore(stripFences(masked));
35402
- return { cleanText, proposal };
35494
+ return { cleanText: text, proposal: null };
35403
35495
  }
35404
35496
  function stripHandoffFences(text) {
35405
35497
  const { masked, restore } = maskOuterFences(text);
35406
- if (masked.search(FENCE_RE) === -1) {
35407
- return text;
35498
+ if (masked.search(FENCE_RE) !== -1) {
35499
+ return restore(stripFences(masked));
35500
+ }
35501
+ const degenerate = trailingDegenerateMatch(masked);
35502
+ if (degenerate && parseProposalShape(degenerate.match[2].trim())) {
35503
+ const { start: start2 } = degenerate;
35504
+ const stripped = masked.slice(0, start2) + masked.slice(start2 + degenerate.match[0].length);
35505
+ return restore(collapseSeams(stripped));
35408
35506
  }
35409
- return restore(stripFences(masked));
35507
+ return text;
35410
35508
  }
35411
35509
  function handoffFenceStartMasked(text) {
35412
35510
  const { masked } = maskOuterFences(text);
@@ -44473,7 +44571,7 @@ function checkChokidar() {
44473
44571
  }
44474
44572
  async function doctor(args2 = []) {
44475
44573
  const json = args2.includes("--json");
44476
- const cliVersion = true ? "2.65.2" : "0.0.0-dev";
44574
+ const cliVersion = true ? "2.65.4" : "0.0.0-dev";
44477
44575
  const apiBase2 = resolveApiBaseUrl();
44478
44576
  const diagnosticId = (0, import_node_crypto13.randomUUID)();
44479
44577
  log.info("doctor", `run id=${diagnosticId} cli=${cliVersion}`);
@@ -44864,7 +44962,7 @@ async function mcpRun(args2) {
44864
44962
  // src/commands/version.ts
44865
44963
  var import_picocolors15 = __toESM(require("picocolors"));
44866
44964
  function version2() {
44867
- const v = true ? "2.65.2" : "unknown";
44965
+ const v = true ? "2.65.4" : "unknown";
44868
44966
  console.log(`${import_picocolors15.default.bold("codeam-cli")} ${import_picocolors15.default.cyan(v)}`);
44869
44967
  }
44870
44968