switchroom 0.21.9 → 0.21.10

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.
@@ -6770,7 +6770,7 @@ function codeSpanSafe(s) {
6770
6770
  return s.replace(/`/g, "`\u200b");
6771
6771
  }
6772
6772
  function escapeLinkHref(href) {
6773
- return href.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
6773
+ return href.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/[\x00-\x20\x7f]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`);
6774
6774
  }
6775
6775
  function repairEscapedWhitespace(text) {
6776
6776
  if (!/\\[nrt"\\]/.test(text))
@@ -30173,7 +30173,7 @@ __export(exports_history, {
30173
30173
  MIN_PREFIX_MATCH_CHARS: () => MIN_PREFIX_MATCH_CHARS2
30174
30174
  });
30175
30175
  import { chmodSync as chmodSync9, existsSync as existsSync29 } from "fs";
30176
- import { join as join37 } from "path";
30176
+ import { join as join38 } from "path";
30177
30177
  function loadDatabaseClass2() {
30178
30178
  if (DatabaseClass2 != null)
30179
30179
  return DatabaseClass2;
@@ -30231,7 +30231,7 @@ function initHistory2(stateDir, retentionDays = 30) {
30231
30231
  return;
30232
30232
  const Database = loadDatabaseClass2();
30233
30233
  mkdirStateSync(stateDir, { recursive: true, mode: 448 });
30234
- const path2 = join37(stateDir, "history.db");
30234
+ const path2 = join38(stateDir, "history.db");
30235
30235
  dbPath2 = path2;
30236
30236
  db2 = new Database(path2, { create: true });
30237
30237
  db2.exec("PRAGMA journal_mode = WAL");
@@ -30685,7 +30685,7 @@ var init_turn_flush_suppression = () => {};
30685
30685
  // ../src/agents/generation-stamp.ts
30686
30686
  import { createHash as createHash6 } from "node:crypto";
30687
30687
  import { existsSync as existsSync36, readFileSync as readFileSync35, writeFileSync as writeFileSync31 } from "node:fs";
30688
- import { join as join44 } from "node:path";
30688
+ import { join as join45 } from "node:path";
30689
30689
  function sha256Text(s) {
30690
30690
  return createHash6("sha256").update(s, "utf-8").digest("hex");
30691
30691
  }
@@ -30695,7 +30695,7 @@ function hashManagedClaudeMd(content3) {
30695
30695
  return sha256Text(managed);
30696
30696
  }
30697
30697
  function hashStampedFileOnDisk(agentDir, rel) {
30698
- const p = join44(agentDir, rel);
30698
+ const p = join45(agentDir, rel);
30699
30699
  if (!existsSync36(p))
30700
30700
  return null;
30701
30701
  let content3;
@@ -30707,7 +30707,7 @@ function hashStampedFileOnDisk(agentDir, rel) {
30707
30707
  return rel === "CLAUDE.md" ? hashManagedClaudeMd(content3) : sha256Text(content3);
30708
30708
  }
30709
30709
  function readGenerationStamp(agentDir) {
30710
- const p = join44(agentDir, GENERATION_STAMP_FILE);
30710
+ const p = join45(agentDir, GENERATION_STAMP_FILE);
30711
30711
  if (!existsSync36(p))
30712
30712
  return null;
30713
30713
  try {
@@ -33711,7 +33711,7 @@ var require_util = __commonJS((exports2) => {
33711
33711
  return path2;
33712
33712
  }
33713
33713
  exports2.normalize = normalize;
33714
- function join46(aRoot, aPath) {
33714
+ function join47(aRoot, aPath) {
33715
33715
  if (aRoot === "") {
33716
33716
  aRoot = ".";
33717
33717
  }
@@ -33743,7 +33743,7 @@ var require_util = __commonJS((exports2) => {
33743
33743
  }
33744
33744
  return joined;
33745
33745
  }
33746
- exports2.join = join46;
33746
+ exports2.join = join47;
33747
33747
  exports2.isAbsolute = function(aPath) {
33748
33748
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
33749
33749
  };
@@ -33916,7 +33916,7 @@ var require_util = __commonJS((exports2) => {
33916
33916
  parsed.path = parsed.path.substring(0, index2 + 1);
33917
33917
  }
33918
33918
  }
33919
- sourceURL = join46(urlGenerate(parsed), sourceURL);
33919
+ sourceURL = join47(urlGenerate(parsed), sourceURL);
33920
33920
  }
33921
33921
  return normalize(sourceURL);
33922
33922
  }
@@ -36522,9 +36522,9 @@ function renderAuthLine(state7, agentName3, now = Date.now()) {
36522
36522
 
36523
36523
  // gateway/quota-cache.ts
36524
36524
  import { existsSync as existsSync49, readFileSync as readFileSync49, writeFileSync as writeFileSync41, mkdirSync as mkdirSync42 } from "fs";
36525
- import { join as join59, dirname as dirname25 } from "path";
36525
+ import { join as join60, dirname as dirname25 } from "path";
36526
36526
  function defaultCachePath() {
36527
- return process.env.SWITCHROOM_QUOTA_CACHE_PATH ?? join59(process.env.HOME ?? "/tmp", ".switchroom", "quota-cache.json");
36527
+ return process.env.SWITCHROOM_QUOTA_CACHE_PATH ?? join60(process.env.HOME ?? "/tmp", ".switchroom", "quota-cache.json");
36528
36528
  }
36529
36529
  function readQuotaCache(opts = {}) {
36530
36530
  const path3 = opts.path ?? defaultCachePath();
@@ -36571,7 +36571,7 @@ var init_quota_cache = __esm(() => {
36571
36571
 
36572
36572
  // gateway/boot-probes.ts
36573
36573
  import { readFileSync as readFileSync50, readdirSync as readdirSync14, existsSync as existsSync50 } from "fs";
36574
- import { join as join60 } from "path";
36574
+ import { join as join61 } from "path";
36575
36575
  import { execFile as execFileCb } from "child_process";
36576
36576
  import { promisify } from "util";
36577
36577
  async function withTimeout(label, p, timeoutMs = PROBE_TIMEOUT_MS) {
@@ -36613,8 +36613,8 @@ function mapPlan(billingType, hasExtra) {
36613
36613
  }
36614
36614
  async function probeAccount(agentDir) {
36615
36615
  return withTimeout("Account", (async () => {
36616
- const claudeDir = join60(agentDir, ".claude");
36617
- const claudeJsonPath = join60(claudeDir, ".claude.json");
36616
+ const claudeDir = join61(agentDir, ".claude");
36617
+ const claudeJsonPath = join61(claudeDir, ".claude.json");
36618
36618
  let cfg = {};
36619
36619
  try {
36620
36620
  const raw = readFileSync50(claudeJsonPath, "utf8");
@@ -36635,8 +36635,8 @@ async function probeAccount(agentDir) {
36635
36635
  let tokenStr = "";
36636
36636
  let status = "ok";
36637
36637
  for (const candidate of [
36638
- join60(claudeDir, ".oauth-token.meta.json"),
36639
- join60(claudeDir, "accounts", "default", ".oauth-token.meta.json")
36638
+ join61(claudeDir, ".oauth-token.meta.json"),
36639
+ join61(claudeDir, "accounts", "default", ".oauth-token.meta.json")
36640
36640
  ]) {
36641
36641
  if (existsSync50(candidate)) {
36642
36642
  try {
@@ -37022,9 +37022,9 @@ async function probeQuota(claudeConfigDir, _agentDir, fetchImpl = fetch, opts =
37022
37022
  let claudeDirForProbe = null;
37023
37023
  for (const candidate of [
37024
37024
  claudeConfigDir,
37025
- join60(claudeConfigDir, "accounts", "default")
37025
+ join61(claudeConfigDir, "accounts", "default")
37026
37026
  ]) {
37027
- if (existsSync50(join60(candidate, ".oauth-token"))) {
37027
+ if (existsSync50(join61(candidate, ".oauth-token"))) {
37028
37028
  claudeDirForProbe = candidate;
37029
37029
  break;
37030
37030
  }
@@ -37259,7 +37259,7 @@ async function probeSkills(agentDir, opts = {}) {
37259
37259
  return withTimeout("Skills", (async () => {
37260
37260
  const fs3 = opts.fs ?? realSkillsFs;
37261
37261
  const max = opts.maxNamesShown ?? 3;
37262
- const skillsDir = join60(agentDir, ".claude", "skills");
37262
+ const skillsDir = join61(agentDir, ".claude", "skills");
37263
37263
  if (!fs3.exists(skillsDir)) {
37264
37264
  return { status: "ok", label: "Skills", detail: "no skills dir" };
37265
37265
  }
@@ -37274,17 +37274,17 @@ async function probeSkills(agentDir, opts = {}) {
37274
37274
  }
37275
37275
  const dangling = [];
37276
37276
  for (const name of entries) {
37277
- const skillPath = join60(skillsDir, name);
37277
+ const skillPath = join61(skillsDir, name);
37278
37278
  if (!fs3.exists(skillPath)) {
37279
37279
  dangling.push(name);
37280
37280
  continue;
37281
37281
  }
37282
- const skillMd = join60(skillPath, "SKILL.md");
37282
+ const skillMd = join61(skillPath, "SKILL.md");
37283
37283
  if (!fs3.exists(skillMd) && !fs3.exists(skillPath + ".md")) {
37284
37284
  continue;
37285
37285
  }
37286
37286
  }
37287
- const overlayDir = opts.overlaySkillsDir ?? join60(agentDir, "skills.d");
37287
+ const overlayDir = opts.overlaySkillsDir ?? join61(agentDir, "skills.d");
37288
37288
  const overlaySlugs = new Set;
37289
37289
  if (fs3.exists(overlayDir)) {
37290
37290
  let overlayEntries = [];
@@ -37326,7 +37326,7 @@ function renderBucketedSkills(switchroom, agent) {
37326
37326
  }
37327
37327
  async function probeConnections(agentDir, opts = {}) {
37328
37328
  return withTimeout("Connections", (async () => {
37329
- const path3 = join60(agentDir, ".claude", "connection-health.json");
37329
+ const path3 = join61(agentDir, ".claude", "connection-health.json");
37330
37330
  const read = opts.readFileImpl ?? ((p) => readFileSync50(p, "utf8"));
37331
37331
  let issues = [];
37332
37332
  try {
@@ -37367,7 +37367,7 @@ async function probeDrift(agentDir, opts = {}) {
37367
37367
  }
37368
37368
  } catch {}
37369
37369
  try {
37370
- const raw = readFileSync50(join60(agentDir, ".switchroom-drift.json"), "utf8");
37370
+ const raw = readFileSync50(join61(agentDir, ".switchroom-drift.json"), "utf8");
37371
37371
  const report = JSON.parse(raw);
37372
37372
  if (report?.version === 1 && Array.isArray(report.findings)) {
37373
37373
  const gen = report.generatedAt ? Date.parse(report.generatedAt) : NaN;
@@ -37727,7 +37727,7 @@ __export(exports_boot_card, {
37727
37727
  readRoutingMode: () => readRoutingMode,
37728
37728
  containerBootStartMs: () => containerBootStartMs
37729
37729
  });
37730
- import { join as join61 } from "path";
37730
+ import { join as join62 } from "path";
37731
37731
  import { readFileSync as readFileSync54, statSync as statSync19 } from "fs";
37732
37732
  function resolvePersonaName(slug, loadConfig3) {
37733
37733
  try {
@@ -37772,7 +37772,7 @@ function containerBootStartMs(fsImpl = { readFileSync: readFileSync54 }) {
37772
37772
  }
37773
37773
  }
37774
37774
  function readRoutingMode(agentDir, bootStartMs, fsImpl = { readFileSync: readFileSync54, statSync: statSync19 }) {
37775
- const path3 = join61(agentDir, ".routing-mode");
37775
+ const path3 = join62(agentDir, ".routing-mode");
37776
37776
  try {
37777
37777
  const raw = fsImpl.readFileSync(path3, "utf-8");
37778
37778
  const line = raw.split(`
@@ -37879,7 +37879,7 @@ function renderBootCard(opts) {
37879
37879
  return stackCardLines(flatLines);
37880
37880
  }
37881
37881
  async function runAllProbes(opts) {
37882
- const claudeDir = join61(opts.agentDir, ".claude");
37882
+ const claudeDir = join62(opts.agentDir, ".claude");
37883
37883
  const probes = {};
37884
37884
  const slug = opts.agentSlug ?? opts.agentName;
37885
37885
  await Promise.allSettled([
@@ -39870,7 +39870,7 @@ import {
39870
39870
  closeSync as closeSync18,
39871
39871
  existsSync as existsSync65,
39872
39872
  unlinkSync as unlinkSync33,
39873
- appendFileSync as appendFileSync11
39873
+ appendFileSync as appendFileSync12
39874
39874
  } from "fs";
39875
39875
 
39876
39876
  // ../src/util/atomic.ts
@@ -39887,7 +39887,7 @@ function fsyncPathSync(path) {
39887
39887
 
39888
39888
  // gateway/gateway.ts
39889
39889
  import { homedir as homedir22 } from "os";
39890
- import { join as join77, sep as sep6, basename as basename19 } from "path";
39890
+ import { join as join78, sep as sep6, basename as basename19 } from "path";
39891
39891
 
39892
39892
  // plugin-logger.ts
39893
39893
  import { appendFileSync, mkdirSync, renameSync as renameSync2, statSync, existsSync } from "fs";
@@ -41632,7 +41632,7 @@ function normalizeForSpeech(input) {
41632
41632
  const w = numberToWords(Number(n) * 1000);
41633
41633
  return w ? w : m;
41634
41634
  });
41635
- s = s.replace(/\b(\d{1,9})(ms|sec|min|kb|mb|gb|tb|hr|s|m|h|d)(?![a-z])/gi, (m, num, unitRaw) => {
41635
+ const unitReplacer = (m, num, unitRaw) => {
41636
41636
  const unit = UNIT_MAP[unitRaw.toLowerCase()];
41637
41637
  if (!unit)
41638
41638
  return m;
@@ -41641,7 +41641,9 @@ function normalizeForSpeech(input) {
41641
41641
  if (!w)
41642
41642
  return m;
41643
41643
  return `${w} ${n === 1 ? unit.s : unit.p}`;
41644
- });
41644
+ };
41645
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})(ms|sec|min|kb|mb|gb|tb|hr)(?![a-zA-Z])/gi, unitReplacer);
41646
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})(s|m|h|d)(?![a-zA-Z])/g, unitReplacer);
41645
41647
  s = s.replace(/(\S)\s*\+\s*(\S)/g, "$1 plus $2");
41646
41648
  s = s.replace(/\s=\s/g, " equals ");
41647
41649
  s = s.replace(/(\s)&(\s)/g, "$1and$2");
@@ -42003,7 +42005,7 @@ table omitted.`);
42003
42005
  const w = ordinalToWords(num);
42004
42006
  return w ?? m;
42005
42007
  });
42006
- s = s.replace(/\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi|s|m|h|d|g)(?![a-z])/gi, (m, num, unitRaw) => {
42008
+ const unitReplacer = (m, num, unitRaw) => {
42007
42009
  const unit = UNIT_MAP2[unitRaw.toLowerCase()];
42008
42010
  if (!unit)
42009
42011
  return m;
@@ -42012,7 +42014,9 @@ table omitted.`);
42012
42014
  if (!w)
42013
42015
  return m;
42014
42016
  return `${w} ${n === 1 ? unit.s : unit.p}`;
42015
- });
42017
+ };
42018
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi)(?![a-zA-Z])/gi, unitReplacer);
42019
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(s|m|h|d|g)(?![a-zA-Z])/g, unitReplacer);
42016
42020
  s = s.replace(/(\s)&(\s)/g, "$1and$2");
42017
42021
  s = s.replace(/(\w)&(\w)/g, "$1 and $2");
42018
42022
  s = s.replace(/(^|\s)@(\w)/g, "$1at $2");
@@ -48111,7 +48115,7 @@ table omitted.`);
48111
48115
  const w = ordinalToWords2(num);
48112
48116
  return w ?? m;
48113
48117
  });
48114
- s = s.replace(/\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi|s|m|h|d|g)(?![a-z])/gi, (m, num, unitRaw) => {
48118
+ const unitReplacer = (m, num, unitRaw) => {
48115
48119
  const unit = UNIT_MAP3[unitRaw.toLowerCase()];
48116
48120
  if (!unit)
48117
48121
  return m;
@@ -48120,7 +48124,9 @@ table omitted.`);
48120
48124
  if (!w)
48121
48125
  return m;
48122
48126
  return `${w} ${n === 1 ? unit.s : unit.p}`;
48123
- });
48127
+ };
48128
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi)(?![a-zA-Z])/gi, unitReplacer);
48129
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(s|m|h|d|g)(?![a-zA-Z])/g, unitReplacer);
48124
48130
  s = s.replace(/(\s)&(\s)/g, "$1and$2");
48125
48131
  s = s.replace(/(\w)&(\w)/g, "$1 and $2");
48126
48132
  s = s.replace(/(^|\s)@(\w)/g, "$1at $2");
@@ -65005,6 +65011,176 @@ function gfmFromMarkdown() {
65005
65011
  gfmTaskListItemFromMarkdown()
65006
65012
  ];
65007
65013
  }
65014
+ // render/html-fold.ts
65015
+ var HTML_FOLD_TAGS = {
65016
+ b: "bold",
65017
+ strong: "bold",
65018
+ i: "italic",
65019
+ em: "italic",
65020
+ s: "strike",
65021
+ del: "strike",
65022
+ strike: "strike",
65023
+ code: "code",
65024
+ a: "link",
65025
+ br: "break",
65026
+ pre: "pre"
65027
+ };
65028
+ var HTML_VOID_TAGS = new Set([
65029
+ "area",
65030
+ "base",
65031
+ "col",
65032
+ "embed",
65033
+ "hr",
65034
+ "img",
65035
+ "input",
65036
+ "link",
65037
+ "meta",
65038
+ "param",
65039
+ "source",
65040
+ "track",
65041
+ "wbr"
65042
+ ]);
65043
+ var HTML_BLOCK_LEVEL_TAGS = new Set([
65044
+ "address",
65045
+ "article",
65046
+ "blockquote",
65047
+ "center",
65048
+ "dd",
65049
+ "div",
65050
+ "dl",
65051
+ "dt",
65052
+ "fieldset",
65053
+ "figcaption",
65054
+ "figure",
65055
+ "footer",
65056
+ "form",
65057
+ "h1",
65058
+ "h2",
65059
+ "h3",
65060
+ "h4",
65061
+ "h5",
65062
+ "h6",
65063
+ "header",
65064
+ "hr",
65065
+ "li",
65066
+ "main",
65067
+ "nav",
65068
+ "ol",
65069
+ "p",
65070
+ "section",
65071
+ "table",
65072
+ "tbody",
65073
+ "td",
65074
+ "tfoot",
65075
+ "th",
65076
+ "thead",
65077
+ "tr",
65078
+ "ul"
65079
+ ]);
65080
+ function isBlockLevelTag(name) {
65081
+ return HTML_BLOCK_LEVEL_TAGS.has(name);
65082
+ }
65083
+ function isVoidTag(name) {
65084
+ return HTML_VOID_TAGS.has(name);
65085
+ }
65086
+ function escapeHtmlLiteral(text4) {
65087
+ return text4.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
65088
+ }
65089
+ var LANGUAGE_CLASS_RE = /(?:^|\s)class\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+))/i;
65090
+ function languageOf(tag) {
65091
+ const m = LANGUAGE_CLASS_RE.exec(tag.attrs);
65092
+ if (m == null)
65093
+ return null;
65094
+ const cls = m[1] ?? m[2] ?? m[3] ?? "";
65095
+ const lang = cls.split(/\s+/).map((c) => /^language-(.+)$/.exec(c)?.[1]).find((c) => c != null && c.length > 0);
65096
+ return lang != null && !lang.includes("`") ? lang : null;
65097
+ }
65098
+ var HTML_PASSTHROUGH_TAGS = new Set([
65099
+ "u",
65100
+ "sub",
65101
+ "sup",
65102
+ "details",
65103
+ "summary",
65104
+ "aside",
65105
+ "cite"
65106
+ ]);
65107
+ var HTML_TOKEN_RE = /<!--[\s\S]*?-->|<\/?[A-Za-z][A-Za-z0-9-]*(?:\s[^<>]*?)?\/?>/g;
65108
+ var TAG_RE = /^<(\/?)([A-Za-z][A-Za-z0-9-]*)((?:\s[^<>]*?)?)(\/?)>$/;
65109
+ var HREF_RE = /(?:^|\s)href\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+))/i;
65110
+ function classifyHtmlTag(raw) {
65111
+ if (raw.startsWith("<!--"))
65112
+ return { kind: "comment", name: "", raw, attrs: "" };
65113
+ const m = TAG_RE.exec(raw);
65114
+ if (m == null)
65115
+ return { kind: "other", name: "", raw, attrs: "" };
65116
+ const [, slash, name, attrs, selfClose] = m;
65117
+ const kind = slash === "/" ? "close" : selfClose === "/" ? "selfclose" : "open";
65118
+ return { kind, name: name.toLowerCase(), raw, attrs: attrs ?? "" };
65119
+ }
65120
+ function hrefOf(tag) {
65121
+ const m = HREF_RE.exec(tag.attrs);
65122
+ if (m == null)
65123
+ return null;
65124
+ const value = m[1] ?? m[2] ?? m[3] ?? "";
65125
+ return value.length > 0 ? value : null;
65126
+ }
65127
+ function isPassthroughTag(tag) {
65128
+ return tag.name.length > 0 && HTML_PASSTHROUGH_TAGS.has(tag.name);
65129
+ }
65130
+ function matchedTagOffsets(tokens) {
65131
+ const matched = new Set;
65132
+ const stack = [];
65133
+ for (const { tag, start } of tokens) {
65134
+ if (tag.kind === "open" && !isVoidTag(tag.name)) {
65135
+ stack.push({ name: tag.name, start });
65136
+ continue;
65137
+ }
65138
+ if (tag.kind !== "close")
65139
+ continue;
65140
+ for (let i = stack.length - 1;i >= 0; i--) {
65141
+ if (stack[i].name !== tag.name)
65142
+ continue;
65143
+ matched.add(stack[i].start);
65144
+ matched.add(start);
65145
+ stack.length = i;
65146
+ break;
65147
+ }
65148
+ }
65149
+ return matched;
65150
+ }
65151
+ function tokenizeHtml(raw, base) {
65152
+ const pieces = [];
65153
+ const re = new RegExp(HTML_TOKEN_RE.source, "g");
65154
+ let last = 0;
65155
+ let m;
65156
+ while ((m = re.exec(raw)) != null) {
65157
+ if (m.index > last) {
65158
+ pieces.push({
65159
+ kind: "text",
65160
+ text: raw.slice(last, m.index),
65161
+ start: base + last,
65162
+ end: base + m.index
65163
+ });
65164
+ }
65165
+ pieces.push({
65166
+ kind: "tag",
65167
+ tag: classifyHtmlTag(m[0]),
65168
+ start: base + m.index,
65169
+ end: base + m.index + m[0].length
65170
+ });
65171
+ last = m.index + m[0].length;
65172
+ }
65173
+ if (last < raw.length) {
65174
+ pieces.push({
65175
+ kind: "text",
65176
+ text: raw.slice(last),
65177
+ start: base + last,
65178
+ end: base + raw.length
65179
+ });
65180
+ }
65181
+ return pieces;
65182
+ }
65183
+
65008
65184
  // render/parse.ts
65009
65185
  function pos(node2) {
65010
65186
  const p = node2.position;
@@ -65023,11 +65199,32 @@ function isTgInlineEntityHref(href) {
65023
65199
  const h = href.toLowerCase();
65024
65200
  return TG_INLINE_ENTITY_HREFS.some((base) => h === base || h.startsWith(`${base}?`));
65025
65201
  }
65202
+ var FENCE_DELIM_RE = /^ {0,3}(`{3,}|~{3,})/;
65026
65203
  function markExpandableQuotes(markdown) {
65027
65204
  const expandableLineStarts = new Set;
65028
65205
  let out = "";
65029
65206
  let offset = 0;
65207
+ let openFence = null;
65030
65208
  for (const line of markdown.split(/(?<=\n)/)) {
65209
+ const body = line.replace(/\r?\n$/, "");
65210
+ const fence = FENCE_DELIM_RE.exec(body)?.[1] ?? null;
65211
+ if (openFence !== null) {
65212
+ out += line;
65213
+ if (fence !== null && fence[0] === openFence[0] && fence.length >= openFence.length && body.slice(body.indexOf(fence) + fence.length).trim() === "") {
65214
+ openFence = null;
65215
+ }
65216
+ offset += line.length;
65217
+ continue;
65218
+ }
65219
+ if (fence !== null) {
65220
+ const rest = body.slice(body.indexOf(fence) + fence.length);
65221
+ if (!(fence[0] === "`" && rest.includes("`"))) {
65222
+ openFence = fence;
65223
+ out += line;
65224
+ offset += line.length;
65225
+ continue;
65226
+ }
65227
+ }
65031
65228
  if (EXPANDABLE_MARKER_RE.test(line)) {
65032
65229
  expandableLineStarts.add(offset);
65033
65230
  out += " " + line.slice(2);
@@ -65048,7 +65245,7 @@ function lineStart(source, offset) {
65048
65245
  function foldAlign(a) {
65049
65246
  return a ?? null;
65050
65247
  }
65051
- function foldInline(node2, source) {
65248
+ function foldInline(node2, source, ctx) {
65052
65249
  switch (node2.type) {
65053
65250
  case "text":
65054
65251
  return { type: "plain", text: node2.value, ...pos(node2) };
@@ -65057,21 +65254,21 @@ function foldInline(node2, source) {
65057
65254
  const underline = source.slice(p.start, p.start + 2) === "__";
65058
65255
  return {
65059
65256
  type: underline ? "underline" : "bold",
65060
- children: foldInlineChildren(node2, source),
65257
+ children: foldInlineChildren(node2, source, ctx),
65061
65258
  ...p
65062
65259
  };
65063
65260
  }
65064
65261
  case "emphasis":
65065
- return { type: "italic", children: foldInlineChildren(node2, source), ...pos(node2) };
65262
+ return { type: "italic", children: foldInlineChildren(node2, source, ctx), ...pos(node2) };
65066
65263
  case "delete":
65067
- return { type: "strike", children: foldInlineChildren(node2, source), ...pos(node2) };
65264
+ return { type: "strike", children: foldInlineChildren(node2, source, ctx), ...pos(node2) };
65068
65265
  case "inlineCode":
65069
65266
  return { type: "code", text: node2.value, ...pos(node2) };
65070
65267
  case "link":
65071
65268
  return {
65072
65269
  type: "link",
65073
65270
  href: node2.url,
65074
- children: foldInlineChildren(node2, source),
65271
+ children: foldInlineChildren(node2, source, ctx),
65075
65272
  ...pos(node2)
65076
65273
  };
65077
65274
  case "image": {
@@ -65127,28 +65324,250 @@ function expandPlainNode(node2, source) {
65127
65324
  }
65128
65325
  return out;
65129
65326
  }
65130
- function buildInlines(children, source) {
65131
- return children.map((c) => foldInline(c, source)).flatMap((n) => n.type === "plain" ? expandPlainNode(n, source) : [n]);
65327
+ function findClosingTag(items, from, name) {
65328
+ let depth = 0;
65329
+ for (let i = from;i < items.length; i++) {
65330
+ const it = items[i];
65331
+ if (it.kind !== "tag" || it.tag.name !== name)
65332
+ continue;
65333
+ if (it.tag.kind === "open")
65334
+ depth++;
65335
+ else if (it.tag.kind === "close") {
65336
+ if (depth === 0)
65337
+ return i;
65338
+ depth--;
65339
+ }
65340
+ }
65341
+ return -1;
65342
+ }
65343
+ function inlineLiteralText(nodes) {
65344
+ let out = "";
65345
+ for (const n of nodes) {
65346
+ if (n.type !== "plain")
65347
+ return null;
65348
+ out += n.text;
65349
+ }
65350
+ return out;
65351
+ }
65352
+ var structuralSeparators = new WeakSet;
65353
+ function mkSeparator(ctx, start, end) {
65354
+ const node2 = {
65355
+ type: "raw",
65356
+ text: ctx.noBreaks === true ? " " : `
65357
+ `,
65358
+ start,
65359
+ end
65360
+ };
65361
+ structuralSeparators.add(node2);
65362
+ return node2;
65363
+ }
65364
+ function normalizeSeparators(nodes) {
65365
+ const out = [];
65366
+ for (const node2 of nodes) {
65367
+ if (!structuralSeparators.has(node2)) {
65368
+ out.push(node2);
65369
+ continue;
65370
+ }
65371
+ if (out.length === 0)
65372
+ continue;
65373
+ if (structuralSeparators.has(out[out.length - 1]))
65374
+ continue;
65375
+ out.push(node2);
65376
+ }
65377
+ while (out.length > 0 && structuralSeparators.has(out[out.length - 1]))
65378
+ out.pop();
65379
+ return out;
65380
+ }
65381
+ function literalTag(tag, start, end) {
65382
+ return { type: "plain", text: escapeHtmlLiteral(tag.raw), start, end };
65383
+ }
65384
+ function foldHtmlItems(items, active, ctx) {
65385
+ const out = [];
65386
+ let i = 0;
65387
+ while (i < items.length) {
65388
+ const it = items[i];
65389
+ if (it.kind === "inline") {
65390
+ out.push(it.node);
65391
+ i++;
65392
+ continue;
65393
+ }
65394
+ const tag = it.tag;
65395
+ if (tag.kind === "comment") {
65396
+ i++;
65397
+ continue;
65398
+ }
65399
+ if (HTML_FOLD_TAGS[tag.name] === "break" && tag.kind !== "close") {
65400
+ out.push(ctx.noBreaks === true ? { type: "raw", text: " ", start: it.start, end: it.end } : { type: "raw", text: `
65401
+ `, start: it.start, end: it.end });
65402
+ i++;
65403
+ continue;
65404
+ }
65405
+ if (tag.kind === "selfclose" || tag.kind === "open" && isVoidTag(tag.name)) {
65406
+ if (isPassthroughTag(tag)) {
65407
+ out.push({ type: "raw", text: tag.raw, start: it.start, end: it.end });
65408
+ } else if (isBlockLevelTag(tag.name)) {
65409
+ out.push(mkSeparator(ctx, it.start, it.end));
65410
+ }
65411
+ i++;
65412
+ continue;
65413
+ }
65414
+ if (isPassthroughTag(tag) && (tag.kind === "open" || tag.kind === "close")) {
65415
+ out.push(ctx.matched.has(it.start) ? { type: "raw", text: tag.raw, start: it.start, end: it.end } : literalTag(tag, it.start, it.end));
65416
+ i++;
65417
+ continue;
65418
+ }
65419
+ if (tag.kind === "open") {
65420
+ const close = findClosingTag(items, i + 1, tag.name);
65421
+ const closeItem = close >= 0 ? items[close] : undefined;
65422
+ if (closeItem !== undefined && closeItem.kind === "tag") {
65423
+ out.push(...foldMatchedTag(tag, closeItem, items.slice(i + 1, close), active, ctx, {
65424
+ start: it.start,
65425
+ end: closeItem.end
65426
+ }));
65427
+ i = close + 1;
65428
+ continue;
65429
+ }
65430
+ }
65431
+ if (ctx.matched.has(it.start) && tag.kind !== "other") {
65432
+ if (isBlockLevelTag(tag.name))
65433
+ out.push(mkSeparator(ctx, it.start, it.end));
65434
+ i++;
65435
+ continue;
65436
+ }
65437
+ out.push(literalTag(tag, it.start, it.end));
65438
+ i++;
65439
+ }
65440
+ return normalizeSeparators(out);
65441
+ }
65442
+ function foldMatchedTag(tag, closeTag, innerItems, active, ctx, span) {
65443
+ const target = HTML_FOLD_TAGS[tag.name];
65444
+ if (target === "pre") {
65445
+ const folded = buildPreBlock(innerItems, ctx, span);
65446
+ if (folded !== null)
65447
+ return folded;
65448
+ }
65449
+ if (target !== undefined && target !== "break" && target !== "pre") {
65450
+ const nested = new Set(active);
65451
+ nested.add(target);
65452
+ const inner2 = foldHtmlItems(innerItems, nested, ctx);
65453
+ if (active.has(target)) {
65454
+ return target === "link" ? [
65455
+ literalTag(tag, span.start, span.start + tag.raw.length),
65456
+ ...inner2,
65457
+ literalTag(closeTag.tag, closeTag.start, closeTag.end)
65458
+ ] : inner2;
65459
+ }
65460
+ const folded = buildFoldedTag(target, tag, inner2, span.start, span.end);
65461
+ return folded !== null ? [folded] : inner2;
65462
+ }
65463
+ const inner = foldHtmlItems(innerItems, active, ctx);
65464
+ if (!isBlockLevelTag(tag.name))
65465
+ return inner;
65466
+ return [
65467
+ mkSeparator(ctx, span.start, span.start + tag.raw.length),
65468
+ ...inner,
65469
+ mkSeparator(ctx, closeTag.start, closeTag.end)
65470
+ ];
65471
+ }
65472
+ function buildPreBlock(innerItems, ctx, span) {
65473
+ let body = innerItems;
65474
+ let language = null;
65475
+ const first = body[0];
65476
+ const last = body[body.length - 1];
65477
+ if (body.length >= 2 && first?.kind === "tag" && first.tag.kind === "open" && first.tag.name === "code" && last?.kind === "tag" && last.tag.kind === "close" && last.tag.name === "code") {
65478
+ language = languageOf(first.tag);
65479
+ body = body.slice(1, -1);
65480
+ }
65481
+ let text4 = "";
65482
+ for (const item of body) {
65483
+ if (item.kind !== "inline" || item.node.type !== "plain")
65484
+ return null;
65485
+ text4 += item.node.text;
65486
+ }
65487
+ text4 = text4.replace(/^\r?\n/, "").replace(/[ \t]*\r?\n[ \t]*$/, "");
65488
+ if (ctx.noBreaks === true) {
65489
+ return [{ type: "code", text: text4.replace(/\s*\r?\n\s*/g, " "), ...span }];
65490
+ }
65491
+ const fence = "```";
65492
+ return [
65493
+ mkSeparator(ctx, span.start, span.start),
65494
+ {
65495
+ type: "raw",
65496
+ text: `${fence}${language ?? ""}
65497
+ ${text4}
65498
+ ${fence}`,
65499
+ ...span
65500
+ },
65501
+ mkSeparator(ctx, span.end, span.end)
65502
+ ];
65132
65503
  }
65133
- function foldInlineChildren(node2, source) {
65134
- return buildInlines(node2.children, source);
65504
+ function buildFoldedTag(target, tag, children, start, end) {
65505
+ switch (target) {
65506
+ case "bold":
65507
+ case "italic":
65508
+ case "strike":
65509
+ if (children.length === 1 && children[0].type === target)
65510
+ return children[0];
65511
+ return { type: target, children, start, end };
65512
+ case "code": {
65513
+ const text4 = inlineLiteralText(children);
65514
+ return text4 === null ? null : { type: "code", text: text4, start, end };
65515
+ }
65516
+ case "link": {
65517
+ const href = hrefOf(tag);
65518
+ return href === null ? null : { type: "link", href, children, start, end };
65519
+ }
65520
+ default:
65521
+ return null;
65522
+ }
65523
+ }
65524
+ function htmlStringToItems(raw, base, source) {
65525
+ return tokenizeHtml(raw, base).flatMap((piece) => piece.kind === "tag" ? [{ kind: "tag", tag: piece.tag, start: piece.start, end: piece.end }] : expandPlainNode(mkPlain(piece.text, piece.start, piece.end), source).map((node2) => ({ kind: "inline", node: node2 })));
65526
+ }
65527
+ function buildInlines(children, source, ctx) {
65528
+ const items = [];
65529
+ let sawHtml = false;
65530
+ for (const child of children) {
65531
+ if (child.type === "html") {
65532
+ sawHtml = true;
65533
+ const p = pos(child);
65534
+ items.push(...htmlStringToItems(slice(source, child), p.start, source));
65535
+ continue;
65536
+ }
65537
+ const folded = foldInline(child, source, ctx);
65538
+ const expanded = folded.type === "plain" ? expandPlainNode(folded, source) : [folded];
65539
+ for (const node2 of expanded)
65540
+ items.push({ kind: "inline", node: node2 });
65541
+ }
65542
+ if (!sawHtml)
65543
+ return items.map((it) => it.node);
65544
+ return foldHtmlItems(items, new Set, ctx);
65135
65545
  }
65136
- function foldTableRow(row, source) {
65546
+ function foldInlineChildren(node2, source, ctx) {
65547
+ return buildInlines(node2.children, source, ctx);
65548
+ }
65549
+ function foldTableRow(row, source, ctx) {
65137
65550
  const cells = row.children.map((cell) => ({
65138
- children: buildInlines(cell.children, source),
65551
+ children: buildInlines(cell.children, source, { ...ctx, noBreaks: true }),
65139
65552
  ...pos(cell)
65140
65553
  }));
65141
65554
  return { cells, ...pos(row) };
65142
65555
  }
65143
- function foldBlock(node2, source, expandableLineStarts) {
65556
+ function isEmptyBlock(block) {
65557
+ return block.type === "paragraph" && block.children.length === 0;
65558
+ }
65559
+ function foldBlocks(nodes, source, expandableLineStarts, ctx) {
65560
+ return nodes.map((n) => foldBlock(n, source, expandableLineStarts, ctx)).filter((b) => !isEmptyBlock(b));
65561
+ }
65562
+ function foldBlock(node2, source, expandableLineStarts, ctx) {
65144
65563
  switch (node2.type) {
65145
65564
  case "paragraph":
65146
- return { type: "paragraph", children: foldInlineChildren(node2, source), ...pos(node2) };
65565
+ return { type: "paragraph", children: foldInlineChildren(node2, source, ctx), ...pos(node2) };
65147
65566
  case "heading":
65148
65567
  return {
65149
65568
  type: "heading",
65150
65569
  level: node2.depth,
65151
- children: foldInlineChildren(node2, source),
65570
+ children: foldInlineChildren(node2, source, { ...ctx, noBreaks: true }),
65152
65571
  ...pos(node2)
65153
65572
  };
65154
65573
  case "blockquote": {
@@ -65156,7 +65575,7 @@ function foldBlock(node2, source, expandableLineStarts) {
65156
65575
  const expandable = expandableLineStarts.has(lineStart(source, p.start));
65157
65576
  return {
65158
65577
  type: "blockquote",
65159
- children: node2.children.map((c) => foldBlock(c, source, expandableLineStarts)),
65578
+ children: foldBlocks(node2.children, source, expandableLineStarts, ctx),
65160
65579
  expandable,
65161
65580
  ...p
65162
65581
  };
@@ -65170,7 +65589,7 @@ function foldBlock(node2, source, expandableLineStarts) {
65170
65589
  };
65171
65590
  case "list": {
65172
65591
  const items = node2.children.map((li) => ({
65173
- children: li.children.map((c) => foldBlock(c, source, expandableLineStarts)),
65592
+ children: foldBlocks(li.children, source, expandableLineStarts, ctx),
65174
65593
  checked: li.checked ?? null,
65175
65594
  spread: li.spread ?? false,
65176
65595
  ...pos(li)
@@ -65191,8 +65610,8 @@ function foldBlock(node2, source, expandableLineStarts) {
65191
65610
  const [headerRow2, ...bodyRows] = rows;
65192
65611
  return {
65193
65612
  type: "table",
65194
- header: foldTableRow(headerRow2, source),
65195
- rows: bodyRows.map((r) => foldTableRow(r, source)),
65613
+ header: foldTableRow(headerRow2, source, ctx),
65614
+ rows: bodyRows.map((r) => foldTableRow(r, source, ctx)),
65196
65615
  align: (node2.align ?? []).map(foldAlign),
65197
65616
  ...pos(node2)
65198
65617
  };
@@ -65203,6 +65622,14 @@ function foldBlock(node2, source, expandableLineStarts) {
65203
65622
  children: [{ type: "raw", text: slice(source, node2), ...pos(node2) }],
65204
65623
  ...pos(node2)
65205
65624
  };
65625
+ case "html": {
65626
+ const p = pos(node2);
65627
+ return {
65628
+ type: "paragraph",
65629
+ children: foldHtmlItems(htmlStringToItems(slice(source, node2), p.start, source), new Set, ctx),
65630
+ ...p
65631
+ };
65632
+ }
65206
65633
  default:
65207
65634
  return {
65208
65635
  type: "paragraph",
@@ -65218,8 +65645,30 @@ function parse2(markdown) {
65218
65645
  mdastExtensions: [gfmFromMarkdown()]
65219
65646
  });
65220
65647
  return {
65221
- blocks: tree.children.map((child) => foldBlock(child, markdown, expandableLineStarts))
65648
+ blocks: foldBlocks(tree.children, markdown, expandableLineStarts, {
65649
+ matched: matchedTagOffsets(collectHtmlTokens(tree.children, markdown))
65650
+ })
65651
+ };
65652
+ }
65653
+ function collectHtmlTokens(nodes, source) {
65654
+ const out = [];
65655
+ const walk = (list2) => {
65656
+ for (const node2 of list2) {
65657
+ if (node2.type === "html") {
65658
+ const p = pos(node2);
65659
+ for (const piece of tokenizeHtml(slice(source, node2), p.start)) {
65660
+ if (piece.kind === "tag")
65661
+ out.push({ tag: piece.tag, start: piece.start });
65662
+ }
65663
+ continue;
65664
+ }
65665
+ const children = node2.children;
65666
+ if (Array.isArray(children))
65667
+ walk(children);
65668
+ }
65222
65669
  };
65670
+ walk(nodes);
65671
+ return out;
65223
65672
  }
65224
65673
 
65225
65674
  // render/render.ts
@@ -79880,6 +80329,62 @@ function normalizeTemporal(text4, tz, nowMs2) {
79880
80329
  return normalizeRelativeDays(normalizeUtcDatetimes(text4, tz, nowMs2), tz, nowMs2);
79881
80330
  }
79882
80331
 
80332
+ // gateway/speech-capture.ts
80333
+ import { appendFileSync as appendFileSync5 } from "node:fs";
80334
+ import { join as join34 } from "node:path";
80335
+ var SPEECH_CAPTURE_FILE_NAME = "speech-capture.jsonl";
80336
+ var SPEECH_CAPTURE_FILE_MODE = 384;
80337
+ function envFlagEnabled() {
80338
+ const v = process.env.SWITCHROOM_SPEECH_CAPTURE;
80339
+ return v === "1" || v === "true";
80340
+ }
80341
+ function isCaptureEnabled(override) {
80342
+ if (override !== undefined)
80343
+ return override;
80344
+ return envFlagEnabled();
80345
+ }
80346
+ var loggedEnabledOnce = false;
80347
+ var lastWriteErrorLoggedAt = null;
80348
+ var WRITE_ERROR_LOG_INTERVAL_MS = 5 * 60000;
80349
+ function logEnabledOnce() {
80350
+ if (loggedEnabledOnce)
80351
+ return;
80352
+ loggedEnabledOnce = true;
80353
+ try {
80354
+ process.stderr.write(`telegram gateway: speech-capture: enabled \u2014 writing $TELEGRAM_STATE_DIR/${SPEECH_CAPTURE_FILE_NAME}
80355
+ `);
80356
+ } catch {}
80357
+ }
80358
+ function logWriteErrorRateLimited(err, nowMs2) {
80359
+ if (lastWriteErrorLoggedAt !== null && nowMs2 - lastWriteErrorLoggedAt < WRITE_ERROR_LOG_INTERVAL_MS)
80360
+ return;
80361
+ lastWriteErrorLoggedAt = nowMs2;
80362
+ try {
80363
+ const msg = err instanceof Error ? err.message : String(err);
80364
+ process.stderr.write(`telegram gateway: speech-capture: write failed (further failures rate-limited ` + `${Math.round(WRITE_ERROR_LOG_INTERVAL_MS / 60000)}m) err=${msg}
80365
+ `);
80366
+ } catch {}
80367
+ }
80368
+ function captureSpeechText(text4, opts = {}) {
80369
+ if (!isCaptureEnabled(opts.enabled))
80370
+ return;
80371
+ logEnabledOnce();
80372
+ try {
80373
+ const stateDir = opts.stateDir ?? process.env.TELEGRAM_STATE_DIR;
80374
+ if (stateDir == null || stateDir.length === 0)
80375
+ return;
80376
+ const now = opts.now ?? Date.now;
80377
+ const line = `${JSON.stringify({ ts: now(), text: text4 })}
80378
+ `;
80379
+ appendFileSync5(join34(stateDir, SPEECH_CAPTURE_FILE_NAME), line, {
80380
+ encoding: "utf8",
80381
+ mode: SPEECH_CAPTURE_FILE_MODE
80382
+ });
80383
+ } catch (err) {
80384
+ logWriteErrorRateLimited(err, Date.now());
80385
+ }
80386
+ }
80387
+
79883
80388
  // gateway/outbound-send-path.ts
79884
80389
  var import_grammy11 = __toESM(require_mod2(), 1);
79885
80390
  import { statSync as statSync12 } from "fs";
@@ -80024,9 +80529,9 @@ import {
80024
80529
  statSync as statSync11,
80025
80530
  unlinkSync as unlinkSync14,
80026
80531
  writeFileSync as writeFileSync25,
80027
- appendFileSync as appendFileSync5
80532
+ appendFileSync as appendFileSync6
80028
80533
  } from "node:fs";
80029
- import { join as join34 } from "node:path";
80534
+ import { join as join35 } from "node:path";
80030
80535
  import { homedir as homedir9 } from "node:os";
80031
80536
 
80032
80537
  // hooks/audience-classify.mjs
@@ -80110,10 +80615,10 @@ function resolveStateDir2(explicit) {
80110
80615
  if (env != null && env !== "")
80111
80616
  return env;
80112
80617
  const home2 = process.env.HOME ?? homedir9();
80113
- return join34(home2, ".claude", "channels", "telegram");
80618
+ return join35(home2, ".claude", "channels", "telegram");
80114
80619
  }
80115
80620
  function resolveOutboxDir(stateDir) {
80116
- return join34(resolveStateDir2(stateDir), "outbox");
80621
+ return join35(resolveStateDir2(stateDir), "outbox");
80117
80622
  }
80118
80623
  var JOURNAL_FILE = "delivered.jsonl";
80119
80624
  var OUTBOX_MAX_AGE_MS = 30 * 60000;
@@ -80123,10 +80628,10 @@ function writeOutboxRecordAtomic(record, stateDir) {
80123
80628
  const dir = resolveOutboxDir(stateDir);
80124
80629
  try {
80125
80630
  mkdirSync29(dir, { recursive: true });
80126
- const finalPath = join34(dir, `${record.turnNonce}.json`);
80631
+ const finalPath = join35(dir, `${record.turnNonce}.json`);
80127
80632
  if (existsSync26(finalPath))
80128
80633
  return true;
80129
- const tmpPath = join34(dir, `.${record.turnNonce}.${process.pid}.tmp`);
80634
+ const tmpPath = join35(dir, `.${record.turnNonce}.${process.pid}.tmp`);
80130
80635
  writeFileSync25(tmpPath, JSON.stringify(record), { mode: 384 });
80131
80636
  renameSync14(tmpPath, finalPath);
80132
80637
  return true;
@@ -80144,7 +80649,7 @@ function listPendingRecords(stateDir) {
80144
80649
  }
80145
80650
  function readOutboxRecord(fileName, stateDir) {
80146
80651
  try {
80147
- const raw = readFileSync26(join34(resolveOutboxDir(stateDir), fileName), "utf8");
80652
+ const raw = readFileSync26(join35(resolveOutboxDir(stateDir), fileName), "utf8");
80148
80653
  return JSON.parse(raw);
80149
80654
  } catch {
80150
80655
  return null;
@@ -80152,8 +80657,8 @@ function readOutboxRecord(fileName, stateDir) {
80152
80657
  }
80153
80658
  function claimRecord(nonce, stateDir) {
80154
80659
  const dir = resolveOutboxDir(stateDir);
80155
- const from = join34(dir, `${nonce}.json`);
80156
- const to = join34(dir, `${nonce}.sending`);
80660
+ const from = join35(dir, `${nonce}.json`);
80661
+ const to = join35(dir, `${nonce}.sending`);
80157
80662
  try {
80158
80663
  renameSync14(from, to);
80159
80664
  return to;
@@ -80164,12 +80669,12 @@ function claimRecord(nonce, stateDir) {
80164
80669
  function releaseClaim(nonce, stateDir) {
80165
80670
  const dir = resolveOutboxDir(stateDir);
80166
80671
  try {
80167
- renameSync14(join34(dir, `${nonce}.sending`), join34(dir, `${nonce}.json`));
80672
+ renameSync14(join35(dir, `${nonce}.sending`), join35(dir, `${nonce}.json`));
80168
80673
  } catch {}
80169
80674
  }
80170
80675
  function removeClaimed(nonce, stateDir) {
80171
80676
  try {
80172
- unlinkSync14(join34(resolveOutboxDir(stateDir), `${nonce}.sending`));
80677
+ unlinkSync14(join35(resolveOutboxDir(stateDir), `${nonce}.sending`));
80173
80678
  } catch {}
80174
80679
  }
80175
80680
  function reclaimStaleSending(stateDir, now = Date.now()) {
@@ -80182,16 +80687,16 @@ function reclaimStaleSending(stateDir, now = Date.now()) {
80182
80687
  }
80183
80688
  for (const f of files) {
80184
80689
  try {
80185
- const st = statSync11(join34(dir, f));
80690
+ const st = statSync11(join35(dir, f));
80186
80691
  if (now - st.mtimeMs > OUTBOX_SENDING_TIMEOUT_MS) {
80187
- renameSync14(join34(dir, f), join34(dir, f.replace(/\.sending$/, ".json")));
80692
+ renameSync14(join35(dir, f), join35(dir, f.replace(/\.sending$/, ".json")));
80188
80693
  }
80189
80694
  } catch {}
80190
80695
  }
80191
80696
  }
80192
80697
  function readDeliveredNonces(stateDir) {
80193
80698
  const set = new Set;
80194
- const path2 = join34(resolveOutboxDir(stateDir), JOURNAL_FILE);
80699
+ const path2 = join35(resolveOutboxDir(stateDir), JOURNAL_FILE);
80195
80700
  if (!existsSync26(path2))
80196
80701
  return set;
80197
80702
  try {
@@ -80218,7 +80723,7 @@ function isBackstopDeliveredEntry(e) {
80218
80723
  function backstopAlreadyDelivered(nonce, stateDir) {
80219
80724
  if (nonce == null || nonce === "")
80220
80725
  return false;
80221
- const path2 = join34(resolveOutboxDir(stateDir), JOURNAL_FILE);
80726
+ const path2 = join35(resolveOutboxDir(stateDir), JOURNAL_FILE);
80222
80727
  if (!existsSync26(path2))
80223
80728
  return false;
80224
80729
  try {
@@ -80239,10 +80744,10 @@ var JOURNAL_KEEP = 2000;
80239
80744
  var JOURNAL_ROTATE_AT = 4000;
80240
80745
  function appendDelivered(entry, stateDir) {
80241
80746
  const dir = resolveOutboxDir(stateDir);
80242
- const path2 = join34(dir, JOURNAL_FILE);
80747
+ const path2 = join35(dir, JOURNAL_FILE);
80243
80748
  try {
80244
80749
  mkdirSync29(dir, { recursive: true });
80245
- appendFileSync5(path2, JSON.stringify(entry) + `
80750
+ appendFileSync6(path2, JSON.stringify(entry) + `
80246
80751
  `, { mode: 384 });
80247
80752
  compactJournalIfLarge(path2);
80248
80753
  } catch {}
@@ -80265,7 +80770,7 @@ function clearOutboxRecord(nonce, stateDir) {
80265
80770
  const dir = resolveOutboxDir(stateDir);
80266
80771
  for (const suffix of [".json", ".sending"]) {
80267
80772
  try {
80268
- unlinkSync14(join34(dir, `${nonce}${suffix}`));
80773
+ unlinkSync14(join35(dir, `${nonce}${suffix}`));
80269
80774
  } catch {}
80270
80775
  }
80271
80776
  }
@@ -80335,9 +80840,9 @@ import {
80335
80840
  readFileSync as readFileSync27,
80336
80841
  renameSync as renameSync15,
80337
80842
  writeFileSync as writeFileSync26,
80338
- appendFileSync as appendFileSync6
80843
+ appendFileSync as appendFileSync7
80339
80844
  } from "node:fs";
80340
- import { join as join35 } from "node:path";
80845
+ import { join as join36 } from "node:path";
80341
80846
 
80342
80847
  // hooks/narration-classify.mjs
80343
80848
  import { createHash as createHash5 } from "node:crypto";
@@ -80408,7 +80913,7 @@ var SHOWN_LEDGER_FILE = "shown-ledger.jsonl";
80408
80913
  var SHOWN_LEDGER_KEEP = 2000;
80409
80914
  var SHOWN_LEDGER_ROTATE_AT = 4000;
80410
80915
  function shownLedgerPath(stateDir) {
80411
- return join35(resolveOutboxDir(stateDir), SHOWN_LEDGER_FILE);
80916
+ return join36(resolveOutboxDir(stateDir), SHOWN_LEDGER_FILE);
80412
80917
  }
80413
80918
  function appendShownBlock(turnNonce, text4, stateDir, now = Date.now()) {
80414
80919
  if (turnNonce == null || turnNonce === "")
@@ -80421,7 +80926,7 @@ function appendShownBlock(turnNonce, text4, stateDir, now = Date.now()) {
80421
80926
  try {
80422
80927
  mkdirSync30(dir, { recursive: true });
80423
80928
  const entry = { turnNonce, hash: ledgerHashHex(trimmed), ts: now };
80424
- appendFileSync6(path2, JSON.stringify(entry) + `
80929
+ appendFileSync7(path2, JSON.stringify(entry) + `
80425
80930
  `, { mode: 384 });
80426
80931
  compactIfLarge(path2);
80427
80932
  } catch {}
@@ -81229,7 +81734,7 @@ function monotonicNowMs2() {
81229
81734
 
81230
81735
  // silent-end.ts
81231
81736
  import { existsSync as existsSync28, readFileSync as readFileSync28, writeFileSync as writeFileSync27, unlinkSync as unlinkSync15, mkdirSync as mkdirSync31 } from "node:fs";
81232
- import { dirname as dirname17, join as join36 } from "node:path";
81737
+ import { dirname as dirname17, join as join37 } from "node:path";
81233
81738
  import { homedir as homedir10 } from "node:os";
81234
81739
  var SILENT_END_MAX_RETRIES2 = 2;
81235
81740
  var SILENT_END_STALE_RECORD_MAX_AGE_MS2 = 30 * 60000;
@@ -81244,10 +81749,10 @@ function resolveStateDir3(deps) {
81244
81749
  if (env != null && env !== "")
81245
81750
  return env;
81246
81751
  const home2 = process.env.HOME ?? homedir10();
81247
- return join36(home2, ".claude", "channels", "telegram");
81752
+ return join37(home2, ".claude", "channels", "telegram");
81248
81753
  }
81249
81754
  function resolveStatePath3(deps) {
81250
- return join36(resolveStateDir3(deps), "silent-end-pending.json");
81755
+ return join37(resolveStateDir3(deps), "silent-end-pending.json");
81251
81756
  }
81252
81757
  function emitLog2(deps, line) {
81253
81758
  if (deps?.log != null)
@@ -81775,6 +82280,7 @@ async function sendReply(deps, req) {
81775
82280
  const protectContent = args.protect_content === true;
81776
82281
  const quoteText = args.quote_text;
81777
82282
  const access = loadAccess();
82283
+ captureSpeechText(text4);
81778
82284
  const voiceOutPlan = resolveVoiceOutPlan(access.voice_out, text4);
81779
82285
  const configParseMode = access.parseMode ?? "html";
81780
82286
  const format = args.format ?? configParseMode;
@@ -83102,20 +83608,20 @@ var INTERRUPTED_VIA = new Set([
83102
83608
  init_rich_send();
83103
83609
 
83104
83610
  // runtime-metrics.ts
83105
- import { mkdirSync as mkdirSync32, appendFileSync as appendFileSync7 } from "node:fs";
83106
- import { dirname as dirname18, join as join38 } from "node:path";
83611
+ import { mkdirSync as mkdirSync32, appendFileSync as appendFileSync8 } from "node:fs";
83612
+ import { dirname as dirname18, join as join39 } from "node:path";
83107
83613
  function resolveJsonlPath2() {
83108
83614
  const override = process.env.SWITCHROOM_RUNTIME_METRICS_PATH;
83109
83615
  if (override && override.trim() !== "")
83110
83616
  return override.trim();
83111
83617
  const base = process.env.SWITCHROOM_RUNTIME_STATE_DIR ?? "/state/agent";
83112
- return join38(base, "runtime-metrics.jsonl");
83618
+ return join39(base, "runtime-metrics.jsonl");
83113
83619
  }
83114
83620
  function appendJsonl2(line) {
83115
83621
  const path2 = resolveJsonlPath2();
83116
83622
  try {
83117
83623
  mkdirSync32(dirname18(path2), { recursive: true });
83118
- appendFileSync7(path2, line + `
83624
+ appendFileSync8(path2, line + `
83119
83625
  `, "utf-8");
83120
83626
  } catch (err) {
83121
83627
  process.stderr.write(`runtime-metrics: jsonl write failed: ${err.message}
@@ -83659,18 +84165,18 @@ import {
83659
84165
  unlinkSync as unlinkSync16,
83660
84166
  utimesSync
83661
84167
  } from "node:fs";
83662
- import { join as join39 } from "node:path";
84168
+ import { join as join40 } from "node:path";
83663
84169
  var TURN_ACTIVE_MARKER_FILE = "turn-active.json";
83664
84170
  var TURN_ACTIVE_HARD_TTL_MS = 10 * 60000;
83665
84171
  function writeTurnActiveMarker(stateDir, marker) {
83666
84172
  try {
83667
84173
  mkdirStateSync(stateDir, { recursive: true });
83668
- writeStateFileSync(join39(stateDir, TURN_ACTIVE_MARKER_FILE), JSON.stringify(marker, null, 2) + `
84174
+ writeStateFileSync(join40(stateDir, TURN_ACTIVE_MARKER_FILE), JSON.stringify(marker, null, 2) + `
83669
84175
  `, { mode: 384 });
83670
84176
  } catch {}
83671
84177
  }
83672
84178
  function touchTurnActiveMarker(stateDir) {
83673
- const path2 = join39(stateDir, TURN_ACTIVE_MARKER_FILE);
84179
+ const path2 = join40(stateDir, TURN_ACTIVE_MARKER_FILE);
83674
84180
  if (!existsSync31(path2))
83675
84181
  return;
83676
84182
  const now = new Date;
@@ -83685,11 +84191,11 @@ function touchTurnActiveMarker(stateDir) {
83685
84191
  }
83686
84192
  function removeTurnActiveMarker(stateDir) {
83687
84193
  try {
83688
- unlinkSync16(join39(stateDir, TURN_ACTIVE_MARKER_FILE));
84194
+ unlinkSync16(join40(stateDir, TURN_ACTIVE_MARKER_FILE));
83689
84195
  } catch {}
83690
84196
  }
83691
84197
  function readTurnActiveMarkerAgeMs(stateDir, now) {
83692
- const path2 = join39(stateDir, TURN_ACTIVE_MARKER_FILE);
84198
+ const path2 = join40(stateDir, TURN_ACTIVE_MARKER_FILE);
83693
84199
  try {
83694
84200
  const st = statSync13(path2);
83695
84201
  return (now ?? Date.now()) - st.mtimeMs;
@@ -86011,10 +86517,10 @@ function resolveAgentDirFromEnv() {
86011
86517
 
86012
86518
  // active-reactions.ts
86013
86519
  import { readFileSync as readFileSync30, writeFileSync as writeFileSync28, renameSync as renameSync16, existsSync as existsSync32, unlinkSync as unlinkSync17 } from "node:fs";
86014
- import { join as join40 } from "node:path";
86520
+ import { join as join41 } from "node:path";
86015
86521
  var ACTIVE_REACTIONS_FILENAME = ".active-reactions.json";
86016
86522
  function reactionsPath(agentDir) {
86017
- return join40(agentDir, ACTIVE_REACTIONS_FILENAME);
86523
+ return join41(agentDir, ACTIVE_REACTIONS_FILENAME);
86018
86524
  }
86019
86525
  function readActiveReactions(agentDir) {
86020
86526
  const p = reactionsPath(agentDir);
@@ -86079,10 +86585,10 @@ function clearActiveReactions(agentDir) {
86079
86585
 
86080
86586
  // active-reactions.ts
86081
86587
  import { readFileSync as readFileSync31, writeFileSync as writeFileSync29, renameSync as renameSync17, existsSync as existsSync33, unlinkSync as unlinkSync18 } from "node:fs";
86082
- import { join as join41 } from "node:path";
86588
+ import { join as join42 } from "node:path";
86083
86589
  var ACTIVE_REACTIONS_FILENAME2 = ".active-reactions.json";
86084
86590
  function reactionsPath2(agentDir) {
86085
- return join41(agentDir, ACTIVE_REACTIONS_FILENAME2);
86591
+ return join42(agentDir, ACTIVE_REACTIONS_FILENAME2);
86086
86592
  }
86087
86593
  function readActiveReactions2(agentDir) {
86088
86594
  const p = reactionsPath2(agentDir);
@@ -86962,12 +87468,12 @@ async function approvalRecord(args, opts) {
86962
87468
 
86963
87469
  // quota-check.ts
86964
87470
  import { readFileSync as readFileSync32, existsSync as existsSync34 } from "fs";
86965
- import { join as join42 } from "path";
87471
+ import { join as join43 } from "path";
86966
87472
  var OAUTH_BETA2 = "oauth-2025-04-20";
86967
87473
  var DEFAULT_USER_AGENT2 = "claude-cli/1.0.0 (external, cli)";
86968
87474
  var DEFAULT_PROBE_MODEL2 = "claude-haiku-4-5-20251001";
86969
87475
  function readOauthToken2(claudeConfigDir) {
86970
- const tokenFile = join42(claudeConfigDir, ".oauth-token");
87476
+ const tokenFile = join43(claudeConfigDir, ".oauth-token");
86971
87477
  if (!existsSync34(tokenFile))
86972
87478
  return null;
86973
87479
  try {
@@ -88357,7 +88863,7 @@ async function menuWithBannerStatic(deps, banner) {
88357
88863
 
88358
88864
  // gateway/session-model-file.ts
88359
88865
  import { readFileSync as readFileSync33, writeFileSync as writeFileSync30, renameSync as renameSync18, rmSync as rmSync7 } from "node:fs";
88360
- import { join as join43 } from "node:path";
88866
+ import { join as join44 } from "node:path";
88361
88867
  var SESSION_MODEL_FILE = ".session-model";
88362
88868
  var CONFIGURED_DEFAULT_MODEL_FILE = ".configured-default-model";
88363
88869
  var SESSION_MODEL_BOOT_ATTEMPTS_FILE = ".session-model-boot-attempts";
@@ -88379,28 +88885,28 @@ function writeSessionModelFile(agentDir, model, configuredDefaultAtWrite) {
88379
88885
  throw new Error(`refusing to persist non-canonical session model token: ${JSON.stringify(model)}`);
88380
88886
  }
88381
88887
  try {
88382
- rmSync7(join43(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88888
+ rmSync7(join44(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88383
88889
  } catch {}
88384
- atomicWrite(join43(agentDir, SESSION_MODEL_FILE), serializeSessionModel({ model, configuredDefaultAtWrite, ts: Date.now() }));
88890
+ atomicWrite(join44(agentDir, SESSION_MODEL_FILE), serializeSessionModel({ model, configuredDefaultAtWrite, ts: Date.now() }));
88385
88891
  }
88386
88892
  function readSessionModelFileRaw(agentDir) {
88387
88893
  try {
88388
- return readFileSync33(join43(agentDir, SESSION_MODEL_FILE), "utf8");
88894
+ return readFileSync33(join44(agentDir, SESSION_MODEL_FILE), "utf8");
88389
88895
  } catch {
88390
88896
  return null;
88391
88897
  }
88392
88898
  }
88393
88899
  function clearSessionModelFile(agentDir) {
88394
88900
  try {
88395
- rmSync7(join43(agentDir, SESSION_MODEL_FILE), { force: true });
88901
+ rmSync7(join44(agentDir, SESSION_MODEL_FILE), { force: true });
88396
88902
  } catch {}
88397
88903
  }
88398
88904
  function consumeSessionModelCarrierOnHealthyBoot(agentDir) {
88399
88905
  try {
88400
- rmSync7(join43(agentDir, SESSION_MODEL_FILE), { force: true });
88906
+ rmSync7(join44(agentDir, SESSION_MODEL_FILE), { force: true });
88401
88907
  } catch {}
88402
88908
  try {
88403
- rmSync7(join43(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88909
+ rmSync7(join44(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88404
88910
  } catch {}
88405
88911
  }
88406
88912
  function restoreSessionModelFileRaw(agentDir, raw) {
@@ -88409,12 +88915,12 @@ function restoreSessionModelFileRaw(agentDir, raw) {
88409
88915
  return;
88410
88916
  }
88411
88917
  try {
88412
- atomicWrite(join43(agentDir, SESSION_MODEL_FILE), raw);
88918
+ atomicWrite(join44(agentDir, SESSION_MODEL_FILE), raw);
88413
88919
  } catch {}
88414
88920
  }
88415
88921
  function readConfiguredDefaultModel(agentDir) {
88416
88922
  try {
88417
- const v = readFileSync33(join43(agentDir, CONFIGURED_DEFAULT_MODEL_FILE), "utf8").trim();
88923
+ const v = readFileSync33(join44(agentDir, CONFIGURED_DEFAULT_MODEL_FILE), "utf8").trim();
88418
88924
  return v.length > 0 ? v : null;
88419
88925
  } catch {
88420
88926
  return null;
@@ -88426,12 +88932,12 @@ function writeSessionEffortFile(agentDir, level, configuredDefaultAtWrite) {
88426
88932
  if (!EFFORT_LEVEL_RE.test(level)) {
88427
88933
  throw new Error(`refusing to persist non-allowlisted effort level: ${JSON.stringify(level)}`);
88428
88934
  }
88429
- atomicWrite(join43(agentDir, SESSION_EFFORT_FILE), `${JSON.stringify({ level, configuredDefaultAtWrite: configuredDefaultAtWrite ?? "", ts: Date.now() })}
88935
+ atomicWrite(join44(agentDir, SESSION_EFFORT_FILE), `${JSON.stringify({ level, configuredDefaultAtWrite: configuredDefaultAtWrite ?? "", ts: Date.now() })}
88430
88936
  `);
88431
88937
  }
88432
88938
  function clearSessionEffortFile(agentDir) {
88433
88939
  try {
88434
- rmSync7(join43(agentDir, SESSION_EFFORT_FILE), { force: true });
88940
+ rmSync7(join44(agentDir, SESSION_EFFORT_FILE), { force: true });
88435
88941
  } catch {}
88436
88942
  }
88437
88943
  var PREMIUM_RECOVERY_FILE = ".premium-recovery";
@@ -88454,13 +88960,13 @@ function writePremiumRecoveryFile(agentDir, premiumModel, chats) {
88454
88960
  if (clean.length === 0) {
88455
88961
  throw new Error("refusing to persist premium-recovery marker with no chats to notify");
88456
88962
  }
88457
- atomicWrite(join43(agentDir, PREMIUM_RECOVERY_FILE), `${JSON.stringify({ premiumModel, chats: clean, ts: Date.now() })}
88963
+ atomicWrite(join44(agentDir, PREMIUM_RECOVERY_FILE), `${JSON.stringify({ premiumModel, chats: clean, ts: Date.now() })}
88458
88964
  `);
88459
88965
  }
88460
88966
  function readPremiumRecoveryFile(agentDir) {
88461
88967
  let raw;
88462
88968
  try {
88463
- raw = readFileSync33(join43(agentDir, PREMIUM_RECOVERY_FILE), "utf8");
88969
+ raw = readFileSync33(join44(agentDir, PREMIUM_RECOVERY_FILE), "utf8");
88464
88970
  } catch {
88465
88971
  return null;
88466
88972
  }
@@ -88473,7 +88979,7 @@ function readPremiumRecoveryFile(agentDir) {
88473
88979
  }
88474
88980
  function clearPremiumRecoveryFile(agentDir) {
88475
88981
  try {
88476
- rmSync7(join43(agentDir, PREMIUM_RECOVERY_FILE), { force: true });
88982
+ rmSync7(join44(agentDir, PREMIUM_RECOVERY_FILE), { force: true });
88477
88983
  } catch {}
88478
88984
  }
88479
88985
 
@@ -88867,7 +89373,7 @@ init_merge();
88867
89373
  init_timezone();
88868
89374
 
88869
89375
  // ../src/cli/agent-config.ts
88870
- import { join as join45 } from "node:path";
89376
+ import { join as join46 } from "node:path";
88871
89377
  import { homedir as homedir11 } from "node:os";
88872
89378
 
88873
89379
  // ../src/cli/helpers.ts
@@ -88888,12 +89394,12 @@ var WEBKITE_VAULT_KEYS = new Set([
88888
89394
  init_overlay_loader();
88889
89395
 
88890
89396
  // ../src/cli/agent-config.ts
88891
- var AUDIT_ROOT = join45(homedir11(), ".switchroom", "audit");
89397
+ var AUDIT_ROOT = join46(homedir11(), ".switchroom", "audit");
88892
89398
 
88893
89399
  // ../src/agents/profiles.ts
88894
89400
  var import_handlebars = __toESM(require_lib(), 1);
88895
89401
  import { readFileSync as readFileSync36, writeFileSync as writeFileSync32, existsSync as existsSync37, readdirSync as readdirSync9, statSync as statSync14, copyFileSync, mkdirSync as mkdirSync33, realpathSync as realpathSync4 } from "node:fs";
88896
- import { resolve as resolve8, join as join46, sep as pathSep } from "node:path";
89402
+ import { resolve as resolve8, join as join47, sep as pathSep } from "node:path";
88897
89403
  function resolveProfilesRootDetailed() {
88898
89404
  return resolveShippedAsset(PROFILES_ASSET, {
88899
89405
  bundleDir: import.meta.dirname,
@@ -88912,7 +89418,7 @@ import_handlebars.default.registerHelper("isNumber", (value) => {
88912
89418
  var SHARED_FRAGMENTS_DIR = resolve8(PROFILES_ROOT, "_shared");
88913
89419
  var SHARED_FRAGMENTS = ["vault-protocol", "agent-self-service", "execution-discipline", "reply-discipline", "dev-protocol", "local-time"];
88914
89420
  for (const name of SHARED_FRAGMENTS) {
88915
- const fragPath = join46(SHARED_FRAGMENTS_DIR, `${name}.md.hbs`);
89421
+ const fragPath = join47(SHARED_FRAGMENTS_DIR, `${name}.md.hbs`);
88916
89422
  if (existsSync37(fragPath)) {
88917
89423
  import_handlebars.default.registerPartial(name, readFileSync36(fragPath, "utf-8"));
88918
89424
  }
@@ -90864,7 +91370,7 @@ function numField(obj, key) {
90864
91370
 
90865
91371
  // gateway/context-occupancy.ts
90866
91372
  import { mkdirSync as mkdirSync34, writeFileSync as writeFileSync33 } from "node:fs";
90867
- import { join as join47 } from "node:path";
91373
+ import { join as join48 } from "node:path";
90868
91374
  var CONTEXT_OCCUPANCY_FILENAME = "context-occupancy.json";
90869
91375
  var TIGHT_FRACTION = 0.8;
90870
91376
  function buildContextOccupancy(occupancy, cap, now) {
@@ -90887,7 +91393,7 @@ function buildContextOccupancy(occupancy, cap, now) {
90887
91393
  }
90888
91394
  function writeContextOccupancySnapshot(stateDir, snapshot, deps) {
90889
91395
  try {
90890
- const path2 = join47(stateDir, CONTEXT_OCCUPANCY_FILENAME);
91396
+ const path2 = join48(stateDir, CONTEXT_OCCUPANCY_FILENAME);
90891
91397
  (deps?.mkdir ?? ((p, o) => mkdirSync34(p, o)))(stateDir, { recursive: true });
90892
91398
  (deps?.writeFile ?? ((p, d) => writeFileSync33(p, d)))(path2, JSON.stringify(snapshot, null, 2) + `
90893
91399
  `);
@@ -91025,17 +91531,17 @@ function idleDurationToMs(raw) {
91025
91531
  init_state_owner();
91026
91532
  import { readFileSync as readFileSync39, mkdirSync as mkdirSync35 } from "node:fs";
91027
91533
  import { homedir as homedir13 } from "node:os";
91028
- import { join as join48 } from "node:path";
91534
+ import { join as join49 } from "node:path";
91029
91535
  function emptyPrivacyState() {
91030
91536
  return { version: 1, intervals: [] };
91031
91537
  }
91032
91538
  var PRIVATE_ON_REPLY = "\uD83D\uDD12 Private mode ON \u2014 memory writing paused. Nothing said until /public is stored.";
91033
91539
  var PUBLIC_REPLY = "\uD83D\uDD13 Public mode \u2014 memory writing resumed. The private stretch was excluded from memory.";
91034
91540
  function resolvePrivacyStateDir() {
91035
- return process.env.TELEGRAM_STATE_DIR ?? join48(homedir13(), ".claude", "channels", "telegram");
91541
+ return process.env.TELEGRAM_STATE_DIR ?? join49(homedir13(), ".claude", "channels", "telegram");
91036
91542
  }
91037
91543
  function privacyStatePath(stateDir = resolvePrivacyStateDir()) {
91038
- return join48(stateDir, "privacy-state.json");
91544
+ return join49(stateDir, "privacy-state.json");
91039
91545
  }
91040
91546
  function isInterval(v) {
91041
91547
  if (v === null || typeof v !== "object")
@@ -91091,22 +91597,22 @@ function closePrivateInterval(now = new Date, stateDir = resolvePrivacyStateDir(
91091
91597
 
91092
91598
  // gateway/privacy-reset.ts
91093
91599
  import { existsSync as existsSync40 } from "node:fs";
91094
- import { join as join50 } from "node:path";
91600
+ import { join as join51 } from "node:path";
91095
91601
 
91096
91602
  // gateway/privacy-state.ts
91097
91603
  init_state_owner();
91098
91604
  import { readFileSync as readFileSync40, mkdirSync as mkdirSync36 } from "node:fs";
91099
91605
  import { homedir as homedir14 } from "node:os";
91100
- import { join as join49 } from "node:path";
91606
+ import { join as join50 } from "node:path";
91101
91607
  function emptyPrivacyState2() {
91102
91608
  return { version: 1, intervals: [] };
91103
91609
  }
91104
91610
  var SESSION_RESET_ALERT = "\uD83D\uDD13 New session \u2014 memory writing is ON by default. Private mode from the previous session was reset.";
91105
91611
  function resolvePrivacyStateDir2() {
91106
- return process.env.TELEGRAM_STATE_DIR ?? join49(homedir14(), ".claude", "channels", "telegram");
91612
+ return process.env.TELEGRAM_STATE_DIR ?? join50(homedir14(), ".claude", "channels", "telegram");
91107
91613
  }
91108
91614
  function privacyStatePath2(stateDir = resolvePrivacyStateDir2()) {
91109
- return join49(stateDir, "privacy-state.json");
91615
+ return join50(stateDir, "privacy-state.json");
91110
91616
  }
91111
91617
  function isInterval2(v) {
91112
91618
  if (v === null || typeof v !== "object")
@@ -91170,7 +91676,7 @@ function bootRestoresTranscript(opts) {
91170
91676
  return opts.resumeMode === "continue" || opts.resumeMode === "auto";
91171
91677
  }
91172
91678
  function isContinueRestoreBoot(agentDir) {
91173
- const forceFresh = process.env.SWITCHROOM_FORCE_FRESH === "1" || agentDir != null && existsSync40(join50(agentDir, ".force-fresh-session"));
91679
+ const forceFresh = process.env.SWITCHROOM_FORCE_FRESH === "1" || agentDir != null && existsSync40(join51(agentDir, ".force-fresh-session"));
91174
91680
  return bootRestoresTranscript({
91175
91681
  resumeMode: process.env.SWITCHROOM_RESUME_MODE,
91176
91682
  forceFresh
@@ -92261,7 +92767,7 @@ function reseedSweepLedger(path2, fs2, log = (l) => process.stderr.write(l)) {
92261
92767
  // ../src/util/state-owner.ts
92262
92768
  init_atomic();
92263
92769
  import {
92264
- appendFileSync as appendFileSync8,
92770
+ appendFileSync as appendFileSync9,
92265
92771
  closeSync as closeSync11,
92266
92772
  constants as constants5,
92267
92773
  existsSync as existsSync42,
@@ -92273,7 +92779,7 @@ import {
92273
92779
  statSync as statSync15,
92274
92780
  writeFileSync as writeFileSync34
92275
92781
  } from "node:fs";
92276
- import { dirname as dirname21, join as join51, relative as relative2, sep as sep5 } from "node:path";
92782
+ import { dirname as dirname21, join as join52, relative as relative2, sep as sep5 } from "node:path";
92277
92783
  var NOFOLLOW2 = constants5.O_NOFOLLOW ?? 0;
92278
92784
  var ownerCache2 = new Map;
92279
92785
  var loggedFailure2 = false;
@@ -92347,7 +92853,7 @@ function mkdirStateSync2(path2, options = { recursive: true }, log = defaultLog3
92347
92853
  for (const part of tail.split(sep5)) {
92348
92854
  if (part === "")
92349
92855
  continue;
92350
- current = join51(current, part);
92856
+ current = join52(current, part);
92351
92857
  adoptStateOwnership2(current, owner, log);
92352
92858
  }
92353
92859
  }
@@ -92389,11 +92895,11 @@ function writeStateFileSync2(path2, data, options, log = defaultLog3) {
92389
92895
  function appendStateFileSync(path2, data, options, log = defaultLog3) {
92390
92896
  const owner = resolveStateOwner2(dirname21(path2));
92391
92897
  if (!owner) {
92392
- appendFileSync8(path2, data, options);
92898
+ appendFileSync9(path2, data, options);
92393
92899
  return;
92394
92900
  }
92395
92901
  const existed = existsSync42(path2);
92396
- appendFileSync8(path2, data, options);
92902
+ appendFileSync9(path2, data, options);
92397
92903
  if (!existed)
92398
92904
  adoptStateOwnership2(path2, owner, log);
92399
92905
  }
@@ -92449,7 +92955,7 @@ function reconcileStateDirOwnership(dir, opts = {}) {
92449
92955
  result.symlinksSkipped++;
92450
92956
  continue;
92451
92957
  }
92452
- const child = join51(current, entry.name);
92958
+ const child = join52(current, entry.name);
92453
92959
  result.scanned++;
92454
92960
  if (adoptAndReport(child, owner, log))
92455
92961
  result.adopted++;
@@ -92614,13 +93120,13 @@ function startWebhookIngestServer(opts) {
92614
93120
  }
92615
93121
 
92616
93122
  // ../src/web/webhook-gateway-record.ts
92617
- import { appendFileSync as appendFileSync10, mkdirSync as mkdirSync40 } from "fs";
92618
- import { join as join55 } from "path";
93123
+ import { appendFileSync as appendFileSync11, mkdirSync as mkdirSync40 } from "fs";
93124
+ import { join as join56 } from "path";
92619
93125
  import { homedir as homedir16 } from "os";
92620
93126
 
92621
93127
  // ../src/web/webhook-handler.ts
92622
- import { appendFileSync as appendFileSync9, existsSync as existsSync45, mkdirSync as mkdirSync38, readFileSync as readFileSync41, writeFileSync as writeFileSync35 } from "fs";
92623
- import { join as join53 } from "path";
93128
+ import { appendFileSync as appendFileSync10, existsSync as existsSync45, mkdirSync as mkdirSync38, readFileSync as readFileSync41, writeFileSync as writeFileSync35 } from "fs";
93129
+ import { join as join54 } from "path";
92624
93130
 
92625
93131
  // ../src/util/log-rotation.ts
92626
93132
  import * as fs2 from "node:fs";
@@ -92982,8 +93488,8 @@ var agentDedupCache = new Map;
92982
93488
  function createFileDedupStore(resolveAgentDir) {
92983
93489
  return {
92984
93490
  check(agent, deliveryId, now) {
92985
- const telegramDir = join53(resolveAgentDir(agent), "telegram");
92986
- const filePath = join53(telegramDir, "webhook-dedup.json");
93491
+ const telegramDir = join54(resolveAgentDir(agent), "telegram");
93492
+ const filePath = join54(telegramDir, "webhook-dedup.json");
92987
93493
  if (!agentDedupCache.has(agent)) {
92988
93494
  agentDedupCache.set(agent, loadDedupFile(filePath));
92989
93495
  }
@@ -93005,7 +93511,7 @@ var throttleIssueWindow = new Map;
93005
93511
 
93006
93512
  // ../src/web/webhook-dispatch.ts
93007
93513
  import { existsSync as existsSync46, mkdirSync as mkdirSync39, readFileSync as readFileSync42, writeFileSync as writeFileSync36 } from "fs";
93008
- import { join as join54 } from "path";
93514
+ import { join as join55 } from "path";
93009
93515
  import { homedir as homedir15 } from "os";
93010
93516
 
93011
93517
  // ../src/agent-scheduler/ipc-client.ts
@@ -93325,8 +93831,8 @@ function createFileCooldownStore(resolveAgentDir) {
93325
93831
  isCoolingDown(agent, key, cooldownMs, now) {
93326
93832
  if (cooldownMs <= 0)
93327
93833
  return false;
93328
- const telegramDir = join54(resolveAgentDir(agent), "telegram");
93329
- const filePath = join54(telegramDir, "webhook-cooldown.json");
93834
+ const telegramDir = join55(resolveAgentDir(agent), "telegram");
93835
+ const filePath = join55(telegramDir, "webhook-cooldown.json");
93330
93836
  if (!cache.has(agent)) {
93331
93837
  cache.set(agent, loadCooldownFile(filePath));
93332
93838
  }
@@ -93383,9 +93889,9 @@ async function defaultInject(socketPath, agentName3, inbound) {
93383
93889
  }
93384
93890
  function injectWebhookInbound(agent, prompt, ctx, deps = {}) {
93385
93891
  const log = deps.log ?? ((s) => process.stderr.write(s));
93386
- const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join54(homedir15(), ".switchroom", "agents", a));
93892
+ const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join55(homedir15(), ".switchroom", "agents", a));
93387
93893
  const now = (deps.now ?? Date.now)();
93388
- const socketPath = join54(resolveAgentDir(agent), "telegram", "gateway.sock");
93894
+ const socketPath = join55(resolveAgentDir(agent), "telegram", "gateway.sock");
93389
93895
  const inbound = {
93390
93896
  type: "inbound",
93391
93897
  chatId: ctx.chatId,
@@ -93457,7 +93963,7 @@ function evaluateDispatch(args, deps = {}) {
93457
93963
  const log = deps.log ?? ((s) => process.stderr.write(s));
93458
93964
  const now = (deps.now ?? Date.now)();
93459
93965
  const nowDate = deps.nowDate ?? (() => new Date(now));
93460
- const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join54(homedir15(), ".switchroom", "agents", a));
93966
+ const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join55(homedir15(), ".switchroom", "agents", a));
93461
93967
  const cooldownStore = deps.cooldownStore ?? createFileCooldownStore(resolveAgentDir);
93462
93968
  if (!DISPATCH_SOURCES.includes(args.source))
93463
93969
  return 0;
@@ -93535,10 +94041,10 @@ var CONSOLIDATION_COMPLETED_EVENT = "consolidation.completed";
93535
94041
  function recordWebhookEvent(rec, deps = {}) {
93536
94042
  const log = deps.log ?? ((s) => process.stderr.write(s));
93537
94043
  const now = rec.ts || (deps.now ?? Date.now)();
93538
- const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join55(homedir16(), ".switchroom", "agents", a));
94044
+ const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join56(homedir16(), ".switchroom", "agents", a));
93539
94045
  const dedupStore = deps.dedupStore ?? createFileDedupStore(resolveAgentDir);
93540
94046
  const agent = rec.agent;
93541
- const telegramDir = join55(resolveAgentDir(agent), "telegram");
94047
+ const telegramDir = join56(resolveAgentDir(agent), "telegram");
93542
94048
  if (rec.source === "github" && rec.delivery_id) {
93543
94049
  const originalTs = dedupStore.check(agent, rec.delivery_id, now);
93544
94050
  if (originalTs !== undefined) {
@@ -93547,7 +94053,7 @@ function recordWebhookEvent(rec, deps = {}) {
93547
94053
  return { status: "deduped", ts: originalTs };
93548
94054
  }
93549
94055
  }
93550
- const logPath = join55(telegramDir, "webhook-events.jsonl");
94056
+ const logPath = join56(telegramDir, "webhook-events.jsonl");
93551
94057
  try {
93552
94058
  mkdirSync40(telegramDir, { recursive: true });
93553
94059
  rotateWebhookLogIfNeeded(logPath);
@@ -93558,7 +94064,7 @@ function recordWebhookEvent(rec, deps = {}) {
93558
94064
  rendered_text: rec.rendered_text,
93559
94065
  payload: rec.payload
93560
94066
  };
93561
- appendFileSync10(logPath, JSON.stringify(record) + `
94067
+ appendFileSync11(logPath, JSON.stringify(record) + `
93562
94068
  `, { mode: 384 });
93563
94069
  } catch (err) {
93564
94070
  log(`webhook-gateway: agent='${agent}' source='${rec.source}' write failed: ${err.message}
@@ -98213,14 +98719,14 @@ function purgeStaleTurnsForChat(chatId, keys, purger, isStale = () => true) {
98213
98719
  // gateway/compaction-marker.ts
98214
98720
  import { statSync as statSync17, unlinkSync as unlinkSync22 } from "node:fs";
98215
98721
  import { homedir as homedir17 } from "node:os";
98216
- import { join as join56 } from "node:path";
98722
+ import { join as join57 } from "node:path";
98217
98723
  var COMPACTION_MARKER_FILE = "compaction-in-flight.json";
98218
98724
  function resolveTelegramStateDir() {
98219
- return process.env.TELEGRAM_STATE_DIR ?? join56(homedir17(), ".claude", "channels", "telegram");
98725
+ return process.env.TELEGRAM_STATE_DIR ?? join57(homedir17(), ".claude", "channels", "telegram");
98220
98726
  }
98221
98727
  function readCompactionMarkerAgeMs(stateDir, now) {
98222
98728
  try {
98223
- const st = statSync17(join56(stateDir, COMPACTION_MARKER_FILE));
98729
+ const st = statSync17(join57(stateDir, COMPACTION_MARKER_FILE));
98224
98730
  return (now ?? Date.now()) - st.mtimeMs;
98225
98731
  } catch {
98226
98732
  return null;
@@ -98228,7 +98734,7 @@ function readCompactionMarkerAgeMs(stateDir, now) {
98228
98734
  }
98229
98735
  function removeCompactionMarker(stateDir) {
98230
98736
  try {
98231
- unlinkSync22(join56(stateDir, COMPACTION_MARKER_FILE));
98737
+ unlinkSync22(join57(stateDir, COMPACTION_MARKER_FILE));
98232
98738
  } catch {}
98233
98739
  }
98234
98740
 
@@ -100293,7 +100799,7 @@ import {
100293
100799
  readdirSync as readdirSync12,
100294
100800
  readFileSync as readFileSync47
100295
100801
  } from "fs";
100296
- import { join as join57 } from "path";
100802
+ import { join as join58 } from "path";
100297
100803
 
100298
100804
  // session-tail.ts
100299
100805
  function sanitizeCwdToProjectName2(cwd) {
@@ -101616,8 +102122,8 @@ function startSubagentWatcher(config) {
101616
102122
  if (stopped)
101617
102123
  return;
101618
102124
  pruneVanishedDirWatchers();
101619
- const claudeHome = join57(agentDir, ".claude");
101620
- const projectsRoot = join57(claudeHome, "projects");
102125
+ const claudeHome = join58(agentDir, ".claude");
102126
+ const projectsRoot = join58(claudeHome, "projects");
101621
102127
  if (!fs3.existsSync(projectsRoot))
101622
102128
  return;
101623
102129
  let projectDirs;
@@ -101651,7 +102157,7 @@ function startSubagentWatcher(config) {
101651
102157
  continue;
101652
102158
  }
101653
102159
  warnedForeignSlugs.delete(pDir);
101654
- const projectPath = join57(projectsRoot, pDir);
102160
+ const projectPath = join58(projectsRoot, pDir);
101655
102161
  let sessionDirs;
101656
102162
  try {
101657
102163
  sessionDirs = fs3.readdirSync(projectPath);
@@ -101661,7 +102167,7 @@ function startSubagentWatcher(config) {
101661
102167
  for (const sDir of sessionDirs) {
101662
102168
  if (sDir.endsWith(".jsonl"))
101663
102169
  continue;
101664
- const subagentsPath = join57(projectPath, sDir, "subagents");
102170
+ const subagentsPath = join58(projectPath, sDir, "subagents");
101665
102171
  if (!fs3.existsSync(subagentsPath))
101666
102172
  continue;
101667
102173
  const watchAndScan = (dirPath) => {
@@ -101670,7 +102176,7 @@ function startSubagentWatcher(config) {
101670
102176
  const w = fs3.watch(dirPath, (_event, filename) => {
101671
102177
  if (!filename || !filename.toString().startsWith("agent-") || !filename.toString().endsWith(".jsonl"))
101672
102178
  return;
101673
- const filePath = join57(dirPath, filename.toString());
102179
+ const filePath = join58(dirPath, filename.toString());
101674
102180
  if (!knownFiles.has(filePath)) {
101675
102181
  scanSubagentsDir(dirPath);
101676
102182
  }
@@ -101684,7 +102190,7 @@ function startSubagentWatcher(config) {
101684
102190
  scanSubagentsDir(dirPath);
101685
102191
  };
101686
102192
  watchAndScan(subagentsPath);
101687
- const workflowsPath = join57(subagentsPath, "workflows");
102193
+ const workflowsPath = join58(subagentsPath, "workflows");
101688
102194
  if (fs3.existsSync(workflowsPath)) {
101689
102195
  let wfDirs;
101690
102196
  try {
@@ -101694,7 +102200,7 @@ function startSubagentWatcher(config) {
101694
102200
  }
101695
102201
  for (const wfDir of wfDirs) {
101696
102202
  try {
101697
- const wfPath = join57(workflowsPath, wfDir);
102203
+ const wfPath = join58(workflowsPath, wfDir);
101698
102204
  if (!fs3.statSync(wfPath).isDirectory())
101699
102205
  continue;
101700
102206
  watchAndScan(wfPath);
@@ -101714,7 +102220,7 @@ function startSubagentWatcher(config) {
101714
102220
  for (const e of entries) {
101715
102221
  if (!e.startsWith("agent-") || !e.endsWith(".jsonl"))
101716
102222
  continue;
101717
- const filePath = join57(subagentsPath, e);
102223
+ const filePath = join58(subagentsPath, e);
101718
102224
  if (knownFiles.has(filePath))
101719
102225
  continue;
101720
102226
  const agentId = e.slice("agent-".length, -".jsonl".length);
@@ -101850,13 +102356,13 @@ import {
101850
102356
  existsSync as existsSync48,
101851
102357
  renameSync as renameSync24
101852
102358
  } from "node:fs";
101853
- import { join as join58, resolve as resolve10 } from "node:path";
102359
+ import { join as join59, resolve as resolve10 } from "node:path";
101854
102360
  import { homedir as homedir18 } from "node:os";
101855
102361
  function registryDir2() {
101856
- return resolve10(process.env.SWITCHROOM_WORKTREE_DIR ?? join58(homedir18(), ".switchroom", "worktrees"));
102362
+ return resolve10(process.env.SWITCHROOM_WORKTREE_DIR ?? join59(homedir18(), ".switchroom", "worktrees"));
101857
102363
  }
101858
102364
  function recordPath(id) {
101859
- return join58(registryDir2(), `${id}.json`);
102365
+ return join59(registryDir2(), `${id}.json`);
101860
102366
  }
101861
102367
  function ensureDir4() {
101862
102368
  mkdirSync41(registryDir2(), { recursive: true });
@@ -102040,19 +102546,19 @@ function determineBridgeReconnectReason(opts) {
102040
102546
 
102041
102547
  // gateway/update-announce.ts
102042
102548
  import { existsSync as existsSync53, mkdirSync as mkdirSync45, openSync as openSync14, closeSync as closeSync14, readFileSync as readFileSync55 } from "node:fs";
102043
- import { join as join63 } from "node:path";
102549
+ import { join as join64 } from "node:path";
102044
102550
  import { homedir as homedir20 } from "node:os";
102045
102551
 
102046
102552
  // ../src/host-control/audit-reader.ts
102047
102553
  import { homedir as homedir19 } from "node:os";
102048
- import { join as join62 } from "node:path";
102554
+ import { join as join63 } from "node:path";
102049
102555
 
102050
102556
  // ../src/host-control/audit-rotation-config.ts
102051
102557
  var DEFAULT_HOSTD_AUDIT_MAX_BYTES = 32 * 1024 * 1024;
102052
102558
 
102053
102559
  // ../src/host-control/audit-reader.ts
102054
102560
  function defaultAuditLogPath(home2 = homedir19()) {
102055
- return join62(home2, ".switchroom", "host-control-audit.log");
102561
+ return join63(home2, ".switchroom", "host-control-audit.log");
102056
102562
  }
102057
102563
  var AUDIT_READ_WINDOW_BYTES = 4 * 1024 * 1024;
102058
102564
  function parseAuditLine(line) {
@@ -102251,15 +102757,15 @@ function renderUpdateOutcomeLine(entry) {
102251
102757
  `);
102252
102758
  }
102253
102759
  function claimUpdateAnnouncement(requestId, opts = {}) {
102254
- const stateDir = opts.stateDir ?? process.env.TELEGRAM_STATE_DIR ?? join63(homedir20(), ".switchroom");
102255
- const dir = join63(stateDir, "update-announced");
102760
+ const stateDir = opts.stateDir ?? process.env.TELEGRAM_STATE_DIR ?? join64(homedir20(), ".switchroom");
102761
+ const dir = join64(stateDir, "update-announced");
102256
102762
  try {
102257
102763
  mkdirSync45(dir, { recursive: true });
102258
102764
  } catch {
102259
102765
  return false;
102260
102766
  }
102261
102767
  const safeId = requestId.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 200);
102262
- const path3 = join63(dir, safeId);
102768
+ const path3 = join64(dir, safeId);
102263
102769
  try {
102264
102770
  const fd = openSync14(path3, "wx");
102265
102771
  closeSync14(fd);
@@ -102481,7 +102987,7 @@ function createIssuesCardHandle(opts) {
102481
102987
 
102482
102988
  // issues-watcher.ts
102483
102989
  import { existsSync as existsSync55, statSync as statSync21 } from "node:fs";
102484
- import { join as join65 } from "node:path";
102990
+ import { join as join66 } from "node:path";
102485
102991
 
102486
102992
  // ../src/issues/store.ts
102487
102993
  import {
@@ -102497,7 +103003,7 @@ import {
102497
103003
  writeFileSync as writeFileSync46,
102498
103004
  writeSync as writeSync8
102499
103005
  } from "node:fs";
102500
- import { join as join64 } from "node:path";
103006
+ import { join as join65 } from "node:path";
102501
103007
  import { randomBytes as randomBytes10 } from "node:crypto";
102502
103008
  import { execSync } from "node:child_process";
102503
103009
 
@@ -102516,7 +103022,7 @@ init_redact();
102516
103022
  var ISSUES_FILE = "issues.jsonl";
102517
103023
  var ISSUES_LOCK = "issues.lock";
102518
103024
  function readAll(stateDir) {
102519
- const path3 = join64(stateDir, ISSUES_FILE);
103025
+ const path3 = join65(stateDir, ISSUES_FILE);
102520
103026
  if (!existsSync54(path3))
102521
103027
  return [];
102522
103028
  let raw;
@@ -102553,7 +103059,7 @@ function list2(stateDir, opts = {}) {
102553
103059
  });
102554
103060
  }
102555
103061
  function resolve11(stateDir, fingerprint, nowFn = Date.now) {
102556
- if (!existsSync54(join64(stateDir, ISSUES_FILE)))
103062
+ if (!existsSync54(join65(stateDir, ISSUES_FILE)))
102557
103063
  return 0;
102558
103064
  return withLock(stateDir, () => {
102559
103065
  const all2 = readAll(stateDir);
@@ -102571,7 +103077,7 @@ function resolve11(stateDir, fingerprint, nowFn = Date.now) {
102571
103077
  });
102572
103078
  }
102573
103079
  function writeAll(stateDir, events) {
102574
- const path3 = join64(stateDir, ISSUES_FILE);
103080
+ const path3 = join65(stateDir, ISSUES_FILE);
102575
103081
  sweepOrphanTmpFiles(stateDir);
102576
103082
  const tmp = `${path3}.tmp-${process.pid}-${randomBytes10(4).toString("hex")}`;
102577
103083
  const body = events.length === 0 ? "" : events.map((e) => JSON.stringify(e)).join(`
@@ -102593,7 +103099,7 @@ function sweepOrphanTmpFiles(stateDir) {
102593
103099
  for (const entry of entries) {
102594
103100
  if (!entry.startsWith(TMP_PREFIX))
102595
103101
  continue;
102596
- const tmpPath2 = join64(stateDir, entry);
103102
+ const tmpPath2 = join65(stateDir, entry);
102597
103103
  try {
102598
103104
  const stat = statSync20(tmpPath2);
102599
103105
  if (stat.mtimeMs < cutoff) {
@@ -102605,7 +103111,7 @@ function sweepOrphanTmpFiles(stateDir) {
102605
103111
  var LOCK_RETRY_MS = 25;
102606
103112
  var LOCK_TIMEOUT_MS = 1e4;
102607
103113
  function withLock(stateDir, fn) {
102608
- const lockPath = join64(stateDir, ISSUES_LOCK);
103114
+ const lockPath = join65(stateDir, ISSUES_LOCK);
102609
103115
  const startedAt = Date.now();
102610
103116
  let fd = null;
102611
103117
  while (fd === null) {
@@ -102690,7 +103196,7 @@ function isIssueEvent(v) {
102690
103196
  // issues-watcher.ts
102691
103197
  var DEFAULT_POLL_INTERVAL_MS2 = 2000;
102692
103198
  function startIssuesWatcher(opts) {
102693
- const path3 = join65(opts.stateDir, ISSUES_FILE);
103199
+ const path3 = join66(opts.stateDir, ISSUES_FILE);
102694
103200
  const log = opts.log ?? (() => {});
102695
103201
  const intervalMs = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
102696
103202
  const setIntervalFn = opts.setInterval ?? setInterval;
@@ -103450,7 +103956,7 @@ function readBashCommand(inputPreview) {
103450
103956
 
103451
103957
  // gateway/scoped-grant-store.ts
103452
103958
  init_state_owner();
103453
- import { join as join66 } from "node:path";
103959
+ import { join as join67 } from "node:path";
103454
103960
 
103455
103961
  // scoped-approval.ts
103456
103962
  var SCOPED_APPROVAL_DEFAULT_TTL_MS2 = 30 * 60 * 1000;
@@ -103492,7 +103998,7 @@ function scopedGrantPersistEnabled(env = process.env) {
103492
103998
  return env.SWITCHROOM_SCOPED_GRANT_PERSIST !== "0";
103493
103999
  }
103494
104000
  function createScopedGrantStore(stateDir, env = process.env, log = (l) => process.stderr.write(l)) {
103495
- const filePath = join66(stateDir, "scoped-grants.json");
104001
+ const filePath = join67(stateDir, "scoped-grants.json");
103496
104002
  const enabled7 = scopedGrantPersistEnabled(env);
103497
104003
  let unreadable = false;
103498
104004
  function read() {
@@ -103871,7 +104377,7 @@ function isDiffPreApproved(agentName3, unifiedDiff, deps) {
103871
104377
  // credits-watch.ts
103872
104378
  init_card_format();
103873
104379
  import { readFileSync as readFileSync58, writeFileSync as writeFileSync47, existsSync as existsSync56, mkdirSync as mkdirSync47 } from "fs";
103874
- import { join as join67 } from "path";
104380
+ import { join as join68 } from "path";
103875
104381
  var STATE_FILE = "credits-watch.json";
103876
104382
  var DEFAULT_CREDIT_FATAL_REASONS = new Set;
103877
104383
  var KNOWN_CREDIT_REASONS = [
@@ -103893,7 +104399,7 @@ function emptyCreditState() {
103893
104399
  return { lastNotifiedReason: null, lastNotifiedAt: 0 };
103894
104400
  }
103895
104401
  function readClaudeJsonOverage(claudeConfigDir) {
103896
- const path3 = join67(claudeConfigDir, ".claude.json");
104402
+ const path3 = join68(claudeConfigDir, ".claude.json");
103897
104403
  if (!existsSync56(path3))
103898
104404
  return null;
103899
104405
  let raw;
@@ -103976,7 +104482,7 @@ function humanizeReason(reason) {
103976
104482
  }
103977
104483
  }
103978
104484
  function loadCreditState(stateDir) {
103979
- const path3 = join67(stateDir, STATE_FILE);
104485
+ const path3 = join68(stateDir, STATE_FILE);
103980
104486
  if (!existsSync56(path3))
103981
104487
  return emptyCreditState();
103982
104488
  try {
@@ -103993,7 +104499,7 @@ function loadCreditState(stateDir) {
103993
104499
  }
103994
104500
  function saveCreditState(stateDir, state7) {
103995
104501
  mkdirSync47(stateDir, { recursive: true });
103996
- const path3 = join67(stateDir, STATE_FILE);
104502
+ const path3 = join68(stateDir, STATE_FILE);
103997
104503
  writeFileSync47(path3, JSON.stringify(state7, null, 2) + `
103998
104504
  `, { mode: 384 });
103999
104505
  }
@@ -104002,7 +104508,7 @@ function saveCreditState(stateDir, state7) {
104002
104508
  init_auth_snapshot_format();
104003
104509
  init_card_format();
104004
104510
  import { readFileSync as readFileSync59, writeFileSync as writeFileSync48, existsSync as existsSync57, mkdirSync as mkdirSync48 } from "fs";
104005
- import { join as join68 } from "path";
104511
+ import { join as join69 } from "path";
104006
104512
  var STATE_FILE2 = "quota-watch.json";
104007
104513
  function emptyQuotaWatchState() {
104008
104514
  return {};
@@ -104240,7 +104746,7 @@ function buildRecoveryMessage(agentName3, snap) {
104240
104746
  `);
104241
104747
  }
104242
104748
  function loadQuotaWatchState(stateDir) {
104243
- const path3 = join68(stateDir, STATE_FILE2);
104749
+ const path3 = join69(stateDir, STATE_FILE2);
104244
104750
  if (!existsSync57(path3))
104245
104751
  return emptyQuotaWatchState();
104246
104752
  try {
@@ -104262,7 +104768,7 @@ function loadQuotaWatchState(stateDir) {
104262
104768
  }
104263
104769
  function saveQuotaWatchState(stateDir, state7) {
104264
104770
  mkdirSync48(stateDir, { recursive: true });
104265
- const path3 = join68(stateDir, STATE_FILE2);
104771
+ const path3 = join69(stateDir, STATE_FILE2);
104266
104772
  writeFileSync48(path3, JSON.stringify(state7, null, 2) + `
104267
104773
  `, { mode: 384 });
104268
104774
  }
@@ -104319,17 +104825,17 @@ import {
104319
104825
  unlinkSync as unlinkSync28,
104320
104826
  utimesSync as utimesSync2
104321
104827
  } from "node:fs";
104322
- import { join as join69 } from "node:path";
104828
+ import { join as join70 } from "node:path";
104323
104829
  var TURN_ACTIVE_MARKER_FILE2 = "turn-active.json";
104324
104830
  var TURN_ACTIVE_HARD_TTL_MS2 = 10 * 60000;
104325
104831
  var TURN_ACTIVE_IDLE_SWEEP_MS = 60000;
104326
104832
  function removeTurnActiveMarker2(stateDir) {
104327
104833
  try {
104328
- unlinkSync28(join69(stateDir, TURN_ACTIVE_MARKER_FILE2));
104834
+ unlinkSync28(join70(stateDir, TURN_ACTIVE_MARKER_FILE2));
104329
104835
  } catch {}
104330
104836
  }
104331
104837
  function sweepStaleTurnActiveMarker(stateDir, opts) {
104332
- const path3 = join69(stateDir, TURN_ACTIVE_MARKER_FILE2);
104838
+ const path3 = join70(stateDir, TURN_ACTIVE_MARKER_FILE2);
104333
104839
  if (!existsSync58(path3))
104334
104840
  return false;
104335
104841
  const now = opts.now ?? Date.now();
@@ -104360,7 +104866,7 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
104360
104866
  }
104361
104867
  }
104362
104868
  function readTurnActiveMarkerAgeMs2(stateDir, now) {
104363
- const path3 = join69(stateDir, TURN_ACTIVE_MARKER_FILE2);
104869
+ const path3 = join70(stateDir, TURN_ACTIVE_MARKER_FILE2);
104364
104870
  try {
104365
104871
  const st = statSync22(path3);
104366
104872
  return (now ?? Date.now()) - st.mtimeMs;
@@ -104375,11 +104881,11 @@ function effectiveTurnAgeMs(markerAgeMs, turnStartedAt, now) {
104375
104881
  // gateway/gateway-heartbeat.ts
104376
104882
  init_state_owner();
104377
104883
  import { utimesSync as utimesSync3 } from "node:fs";
104378
- import { join as join70 } from "node:path";
104884
+ import { join as join71 } from "node:path";
104379
104885
  var GATEWAY_HEARTBEAT_FILE = "gateway-heartbeat";
104380
104886
  var GATEWAY_HEARTBEAT_INTERVAL_MS = 15000;
104381
104887
  function touchGatewayHeartbeat(stateDir) {
104382
- const path3 = join70(stateDir, GATEWAY_HEARTBEAT_FILE);
104888
+ const path3 = join71(stateDir, GATEWAY_HEARTBEAT_FILE);
104383
104889
  const now = new Date;
104384
104890
  try {
104385
104891
  utimesSync3(path3, now, now);
@@ -104410,7 +104916,7 @@ import {
104410
104916
  unlinkSync as unlinkSync29,
104411
104917
  writeFileSync as writeFileSync49
104412
104918
  } from "node:fs";
104413
- import { join as join71 } from "node:path";
104919
+ import { join as join72 } from "node:path";
104414
104920
  var BOOT_BEACON_FILE = "gateway-beacon.json";
104415
104921
  var HOST_BOOT_ID_PATH = "/proc/sys/kernel/random/boot_id";
104416
104922
  var CGROUP_MEMORY_EVENTS_PATH = "/sys/fs/cgroup/memory.events";
@@ -104509,7 +105015,7 @@ function sampleBeaconHost(paths = {}) {
104509
105015
  return sample3;
104510
105016
  }
104511
105017
  function writeBootBeaconFile(stateDir, beacon) {
104512
- const path3 = join71(stateDir, BOOT_BEACON_FILE);
105018
+ const path3 = join72(stateDir, BOOT_BEACON_FILE);
104513
105019
  const tmp = `${path3}.tmp-${process.pid}`;
104514
105020
  let fd;
104515
105021
  try {
@@ -104901,10 +105407,10 @@ function startOutboxSweep(deps) {
104901
105407
  }
104902
105408
 
104903
105409
  // ../src/build-info.ts
104904
- var VERSION2 = "0.21.9";
104905
- var COMMIT_SHA = "08262924";
104906
- var COMMIT_DATE = "2026-08-13T12:13:46Z";
104907
- var LATEST_PR = 4686;
105410
+ var VERSION2 = "0.21.10";
105411
+ var COMMIT_SHA = "fd1650e7";
105412
+ var COMMIT_DATE = "2026-08-14T03:50:00Z";
105413
+ var LATEST_PR = 4698;
104908
105414
  var COMMITS_AHEAD_OF_TAG = 0;
104909
105415
 
104910
105416
  // gateway/boot-version.ts
@@ -104982,11 +105488,11 @@ init_peercred();
104982
105488
  import * as net5 from "node:net";
104983
105489
  import * as fs3 from "node:fs";
104984
105490
  import { homedir as homedir21 } from "node:os";
104985
- import { join as join72 } from "node:path";
105491
+ import { join as join73 } from "node:path";
104986
105492
  var DEFAULT_TIMEOUT_MS4 = 2000;
104987
105493
  var UNLOCK_TIMEOUT_MS = 30000;
104988
- var LEGACY_SOCKET_PATH2 = join72(homedir21(), ".switchroom", "vault-broker.sock");
104989
- var OPERATOR_SOCKET_PATH2 = join72(homedir21(), ".switchroom", "broker-operator", "sock");
105494
+ var LEGACY_SOCKET_PATH2 = join73(homedir21(), ".switchroom", "vault-broker.sock");
105495
+ var OPERATOR_SOCKET_PATH2 = join73(homedir21(), ".switchroom", "broker-operator", "sock");
104990
105496
  function defaultBrokerSocketPath2() {
104991
105497
  if (fs3.existsSync(OPERATOR_SOCKET_PATH2))
104992
105498
  return OPERATOR_SOCKET_PATH2;
@@ -105870,7 +106376,7 @@ function resolveVaultApprovalPosture(broker) {
105870
106376
  // registry/turns-schema.ts
105871
106377
  init_state_owner();
105872
106378
  import { chmodSync as chmodSync12 } from "fs";
105873
- import { join as join73 } from "path";
106379
+ import { join as join74 } from "path";
105874
106380
  var DatabaseClass3 = null;
105875
106381
  function loadDatabaseClass3() {
105876
106382
  if (DatabaseClass3 != null)
@@ -105942,9 +106448,9 @@ function applySchema(db3) {
105942
106448
  }
105943
106449
  function openTurnsDb(agentDir) {
105944
106450
  const Database = loadDatabaseClass3();
105945
- const dir = join73(agentDir, "telegram");
106451
+ const dir = join74(agentDir, "telegram");
105946
106452
  mkdirStateSync(dir, { recursive: true, mode: 448 });
105947
- const path3 = join73(dir, "registry.db");
106453
+ const path3 = join74(dir, "registry.db");
105948
106454
  const db3 = new Database(path3, { create: true });
105949
106455
  applySchema(db3);
105950
106456
  try {
@@ -106287,7 +106793,7 @@ function selectResumeBuilder(endedVia, opts) {
106287
106793
 
106288
106794
  // gateway/boot-briefing-wiring.ts
106289
106795
  import { existsSync as existsSync60, readFileSync as readFileSync63, writeFileSync as writeFileSync50 } from "node:fs";
106290
- import { join as join74 } from "node:path";
106796
+ import { join as join75 } from "node:path";
106291
106797
  init_history();
106292
106798
 
106293
106799
  // gateway/resume-inbound-builder.ts
@@ -106594,8 +107100,8 @@ function readDailyMemory(agentDir, env, nowMs3, readFile = (p) => readFileSync63
106594
107100
  const date = agentLocalDate(nowMs3, env.SWITCHROOM_TIMEZONE || env.TZ || undefined);
106595
107101
  if (!date)
106596
107102
  return null;
106597
- const workspaceDir = env.WORKSPACE_DIR && env.WORKSPACE_DIR.trim() ? env.WORKSPACE_DIR : join74(agentDir, "workspace");
106598
- const file = join74(workspaceDir, "memory", `${date}.md`);
107103
+ const workspaceDir = env.WORKSPACE_DIR && env.WORKSPACE_DIR.trim() ? env.WORKSPACE_DIR : join75(agentDir, "workspace");
107104
+ const file = join75(workspaceDir, "memory", `${date}.md`);
106599
107105
  try {
106600
107106
  const content3 = readFile(file);
106601
107107
  if (!content3 || !content3.trim())
@@ -106624,7 +107130,7 @@ async function maybeQueueBootBriefing(opts) {
106624
107130
  try {
106625
107131
  const agentDir = opts.stateDir.endsWith("/telegram") ? opts.stateDir.slice(0, -"/telegram".length) : opts.stateDir;
106626
107132
  const bootId = opts.env.SWITCHROOM_GATEWAY_BOOT_ID;
106627
- const genMarkerPath = join74(agentDir, ".boot-briefing-generation");
107133
+ const genMarkerPath = join75(agentDir, ".boot-briefing-generation");
106628
107134
  if (bootId) {
106629
107135
  let prevGen = null;
106630
107136
  try {
@@ -106646,7 +107152,7 @@ async function maybeQueueBootBriefing(opts) {
106646
107152
  `);
106647
107153
  } catch {}
106648
107154
  };
106649
- const forceFresh = opts.env.SWITCHROOM_FORCE_FRESH === "1" || existsSync60(join74(agentDir, ".force-fresh-session"));
107155
+ const forceFresh = opts.env.SWITCHROOM_FORCE_FRESH === "1" || existsSync60(join75(agentDir, ".force-fresh-session"));
106650
107156
  const decision = decideBootBriefing({
106651
107157
  briefingMode: opts.env.SWITCHROOM_SESSION_BRIEFING,
106652
107158
  resumeMode: opts.env.SWITCHROOM_RESUME_MODE,
@@ -106680,7 +107186,7 @@ async function maybeQueueBootBriefing(opts) {
106680
107186
  return null;
106681
107187
  }
106682
107188
  const restartReason = readRestartBreadcrumb({
106683
- restartReasonPath: join74(agentDir, ".restart-reason"),
107189
+ restartReasonPath: join75(agentDir, ".restart-reason"),
106684
107190
  env: opts.env,
106685
107191
  readFile: (p) => readFileSync63(p, "utf8")
106686
107192
  });
@@ -106717,9 +107223,9 @@ async function maybeQueueBootBriefing(opts) {
106717
107223
 
106718
107224
  // gateway/pending-turn-env.ts
106719
107225
  import { existsSync as existsSync61, renameSync as renameSync29, rmSync as rmSync8, writeFileSync as writeFileSync51 } from "node:fs";
106720
- import { join as join75 } from "node:path";
107226
+ import { join as join76 } from "node:path";
106721
107227
  function writePendingTurnEnv(agentDir, pending, log = (l) => process.stderr.write(l)) {
106722
- const pendingEnvPath = join75(agentDir, ".pending-turn.env");
107228
+ const pendingEnvPath = join76(agentDir, ".pending-turn.env");
106723
107229
  try {
106724
107230
  if (pending != null) {
106725
107231
  const lines = [
@@ -106752,7 +107258,7 @@ function writePendingTurnEnv(agentDir, pending, log = (l) => process.stderr.writ
106752
107258
 
106753
107259
  // gateway/agent-process-liveness.ts
106754
107260
  import { existsSync as existsSync62, readFileSync as readFileSync64, writeFileSync as writeFileSync52, renameSync as renameSync30, unlinkSync as unlinkSync30, readdirSync as readdirSync16 } from "node:fs";
106755
- import { join as join76, dirname as dirname28, basename as basename18 } from "node:path";
107261
+ import { join as join77, dirname as dirname28, basename as basename18 } from "node:path";
106756
107262
  var AGENT_PROCESS_RECORD_FILE = "agent-process.json";
106757
107263
  var BOOT_RESUME_DONE_FILE = ".boot-resume-done";
106758
107264
  function parseProcStat(raw) {
@@ -106775,7 +107281,7 @@ function readProcIdentity(pid, procRoot = "/proc") {
106775
107281
  return null;
106776
107282
  let identity;
106777
107283
  try {
106778
- identity = parseProcStat(readFileSync64(join76(procRoot, String(pid), "stat"), "utf8"));
107284
+ identity = parseProcStat(readFileSync64(join77(procRoot, String(pid), "stat"), "utf8"));
106779
107285
  } catch {
106780
107286
  return null;
106781
107287
  }
@@ -106807,7 +107313,7 @@ function readAgentProcessRecord(path3) {
106807
107313
  return rec;
106808
107314
  }
106809
107315
  function bootResumeDonePath(stateDir) {
106810
- return join76(stateDir, BOOT_RESUME_DONE_FILE);
107316
+ return join77(stateDir, BOOT_RESUME_DONE_FILE);
106811
107317
  }
106812
107318
  function containerBootIdentity(procRoot = "/proc") {
106813
107319
  return readProcIdentity(1, procRoot)?.starttime ?? null;
@@ -106840,7 +107346,7 @@ function sweepStrayTmps(path3) {
106840
107346
  if (!name.startsWith(prefix))
106841
107347
  continue;
106842
107348
  try {
106843
- unlinkSync30(join76(dirname28(path3), name));
107349
+ unlinkSync30(join77(dirname28(path3), name));
106844
107350
  } catch {}
106845
107351
  }
106846
107352
  } catch {}
@@ -106892,7 +107398,7 @@ function detectGatewayOnlyRespawn(opts) {
106892
107398
  return { gatewayOnly: false, reason: "guard-disabled", pid: null };
106893
107399
  const procRoot = opts.procRoot ?? "/proc";
106894
107400
  const sentinel = readBootResumeSentinel(opts.sentinelPath ?? bootResumeDonePath(opts.stateDir), { procRoot });
106895
- const recordPath2 = opts.recordPath ?? join76(opts.stateDir, AGENT_PROCESS_RECORD_FILE);
107401
+ const recordPath2 = opts.recordPath ?? join77(opts.stateDir, AGENT_PROCESS_RECORD_FILE);
106896
107402
  const record2 = readAgentProcessRecord(recordPath2);
106897
107403
  const live = record2 == null ? null : readProcIdentity(record2.pid, procRoot);
106898
107404
  return decideGatewayOnlyRespawn({
@@ -107450,7 +107956,7 @@ if (isGatewayMain) {
107450
107956
  shutdownAnalytics();
107451
107957
  });
107452
107958
  }
107453
- var STATE_DIR = process.env.TELEGRAM_STATE_DIR ?? join77(homedir22(), ".claude", "channels", "telegram");
107959
+ var STATE_DIR = process.env.TELEGRAM_STATE_DIR ?? join78(homedir22(), ".claude", "channels", "telegram");
107454
107960
  var permCardStore = createPermissionCardStore(STATE_DIR);
107455
107961
  var BLOCKED_APPROVALS_DIR = process.env.SWITCHROOM_BLOCKED_APPROVALS_DIR ?? "/state/blocked-approvals";
107456
107962
  var AGENT_NAME = process.env.SWITCHROOM_AGENT_NAME ?? "agent";
@@ -107550,11 +108056,11 @@ function scheduleAlwaysAllowPersistDrain() {
107550
108056
  }, ALWAYS_ALLOW_DRAIN_INTERVAL_MS);
107551
108057
  timer3.unref?.();
107552
108058
  }
107553
- var ACCESS_FILE = join77(STATE_DIR, "access.json");
107554
- var APPROVED_DIR = join77(STATE_DIR, "approved");
107555
- var ENV_FILE = join77(STATE_DIR, ".env");
107556
- var INBOX_DIR = join77(STATE_DIR, "inbox");
107557
- var PEOPLE_FILE = join77(STATE_DIR, "people.json");
108059
+ var ACCESS_FILE = join78(STATE_DIR, "access.json");
108060
+ var APPROVED_DIR = join78(STATE_DIR, "approved");
108061
+ var ENV_FILE = join78(STATE_DIR, ".env");
108062
+ var INBOX_DIR = join78(STATE_DIR, "inbox");
108063
+ var PEOPLE_FILE = join78(STATE_DIR, "people.json");
107558
108064
  function triggerSelfRestart(targetAgent, reason, delayMs = 300) {
107559
108065
  const isDocker = process.env.SWITCHROOM_RUNTIME === "docker";
107560
108066
  const selfAgent = process.env.SWITCHROOM_AGENT_NAME;
@@ -107681,7 +108187,7 @@ function assertSendable(f) {
107681
108187
  } catch {
107682
108188
  throw new Error(`refusing to send file \u2014 cannot resolve real path: ${f}`);
107683
108189
  }
107684
- const inbox = join77(stateReal, "inbox");
108190
+ const inbox = join78(stateReal, "inbox");
107685
108191
  if (real.startsWith(stateReal + sep6) && !real.startsWith(inbox + sep6)) {
107686
108192
  throw new Error(`refusing to send channel state: ${f}`);
107687
108193
  }
@@ -107710,7 +108216,7 @@ var HISTORY_ENABLED = HISTORY_ACCESS.historyEnabled !== false;
107710
108216
  if (isGatewayMain && HISTORY_ENABLED) {
107711
108217
  try {
107712
108218
  initHistory(STATE_DIR, HISTORY_ACCESS.historyRetentionDays ?? 30);
107713
- process.stderr.write(`telegram gateway: history capture enabled at ${join77(STATE_DIR, "history.db")}
108219
+ process.stderr.write(`telegram gateway: history capture enabled at ${join78(STATE_DIR, "history.db")}
107714
108220
  `);
107715
108221
  } catch (err) {
107716
108222
  process.stderr.write(`telegram gateway: history init failed (${err.message}) \u2014 capture disabled
@@ -107733,7 +108239,7 @@ bootResumeInit:
107733
108239
  let markerTurnKey = null;
107734
108240
  let markerAgeMs = null;
107735
108241
  try {
107736
- const markerPath = join77(STATE_DIR, TURN_ACTIVE_MARKER_FILE2);
108242
+ const markerPath = join78(STATE_DIR, TURN_ACTIVE_MARKER_FILE2);
107737
108243
  if (existsSync65(markerPath)) {
107738
108244
  const st = statSync25(markerPath);
107739
108245
  markerAgeMs = Date.now() - st.mtimeMs;
@@ -107758,10 +108264,10 @@ bootResumeInit:
107758
108264
  process.stderr.write(`telegram gateway: turn-registry boot-reaper stamped ${reaped} orphaned turn(s)` + `${timeoutTurnKey ? ` (turnKey=${timeoutTurnKey} as 'timeout', markerAgeMs=${markerAgeMs})` : " as 'restart'"}
107759
108265
  `);
107760
108266
  } else {
107761
- process.stderr.write(`telegram gateway: turn-registry initialized at ${join77(agentDir, "telegram", "registry.db")}
108267
+ process.stderr.write(`telegram gateway: turn-registry initialized at ${join78(agentDir, "telegram", "registry.db")}
107762
108268
  `);
107763
108269
  }
107764
- const bridgeDeadMarker = consumeBridgeDeadEscalationMarker(join77(STATE_DIR, "bridge-dead-escalation.json"));
108270
+ const bridgeDeadMarker = consumeBridgeDeadEscalationMarker(join78(STATE_DIR, "bridge-dead-escalation.json"));
107765
108271
  if (bridgeDeadMarker != null) {
107766
108272
  bridgeDeadPriorStreak = bridgeDeadMarker.count ?? 1;
107767
108273
  process.stderr.write(`telegram gateway: boot: prior restart was a bridge-dead escalation (reason=${bridgeDeadMarker.reason}` + `, consecutive=${bridgeDeadPriorStreak}` + `${bridgeDeadMarker.crashTail ? `, crashTail=${bridgeDeadMarker.crashTail}` : ""})
@@ -107774,7 +108280,7 @@ bootResumeInit:
107774
108280
  const pending2 = findLatestTurnIfInterrupted(turnsDb);
107775
108281
  const selfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
107776
108282
  if (pending2 != null && selfAgent) {
107777
- const bootResumeMarkerPath = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join77(STATE_DIR, "clean-shutdown.json");
108283
+ const bootResumeMarkerPath = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join78(STATE_DIR, "clean-shutdown.json");
107778
108284
  const bootResumeCleanMarker = readCleanShutdownMarker(bootResumeMarkerPath);
107779
108285
  const bootResumeForceAlways = process.env.SWITCHROOM_BOOT_RESUME_ALWAYS === "1";
107780
108286
  const bootResumeMode = parseBootResumeMode(process.env.SWITCHROOM_BOOT_RESUME);
@@ -107981,7 +108487,7 @@ function checkApprovals() {
107981
108487
  return;
107982
108488
  }
107983
108489
  for (const senderId of files) {
107984
- const file = join77(APPROVED_DIR, senderId);
108490
+ const file = join78(APPROVED_DIR, senderId);
107985
108491
  bot.api.sendMessage(senderId, "Paired! Say hi to Claude.").then(() => rmSync9(file, { force: true }), (err) => {
107986
108492
  process.stderr.write(`telegram gateway: failed to send approval confirm: ${err}
107987
108493
  `);
@@ -108159,7 +108665,7 @@ function noteAgentOutputAt(key, ts) {
108159
108665
  lastAgentOutputAt.delete(oldest);
108160
108666
  }
108161
108667
  }
108162
- var OBLIGATION_STORE_PATH = join77(STATE_DIR, "obligations.json");
108668
+ var OBLIGATION_STORE_PATH = join78(STATE_DIR, "obligations.json");
108163
108669
  var obligationStoreFs = {
108164
108670
  readFileSync: (p) => readFileSync67(p, "utf8"),
108165
108671
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -108928,7 +109434,7 @@ function emitTurnRecord(turn, endedAt) {
108928
109434
  },
108929
109435
  rename: (from, to) => renameSync32(from, to)
108930
109436
  });
108931
- appendFileSync11(turnsPath, rec);
109437
+ appendFileSync12(turnsPath, rec);
108932
109438
  } catch {}
108933
109439
  }
108934
109440
  function maybeProactiveCompact() {
@@ -110497,7 +111003,7 @@ var PIN_STATUS_WHILE_WORKING = (() => {
110497
111003
  })();
110498
111004
  var statusPinClaims = new Map;
110499
111005
  var statusPinRightsCache = new PinRightsCache2;
110500
- var STATUS_PIN_STORE_PATH = join77(STATE_DIR, "status-pins.json");
111006
+ var STATUS_PIN_STORE_PATH = join78(STATE_DIR, "status-pins.json");
110501
111007
  var statusPinStoreFs = {
110502
111008
  readFileSync: (p) => readFileSync67(p, "utf8"),
110503
111009
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -110505,7 +111011,7 @@ var statusPinStoreFs = {
110505
111011
  existsSync: (p) => existsSync65(p)
110506
111012
  };
110507
111013
  var statusPinPersistEnabled = !STATIC && PIN_STATUS_WHILE_WORKING;
110508
- var ACTIVITY_CARD_STORE_PATH = join77(STATE_DIR, "activity-cards-pending.json");
111014
+ var ACTIVITY_CARD_STORE_PATH = join78(STATE_DIR, "activity-cards-pending.json");
110509
111015
  var activityCardStoreFs = {
110510
111016
  readFileSync: (p) => readFileSync67(p, "utf8"),
110511
111017
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -110513,7 +111019,7 @@ var activityCardStoreFs = {
110513
111019
  existsSync: (p) => existsSync65(p)
110514
111020
  };
110515
111021
  var activityCardPersistEnabled = !STATIC;
110516
- var QUEUED_CARD_STORE_PATH = join77(STATE_DIR, "queued-cards-pending.json");
111022
+ var QUEUED_CARD_STORE_PATH = join78(STATE_DIR, "queued-cards-pending.json");
110517
111023
  var queuedCardStoreFs = {
110518
111024
  readFileSync: (p) => readFileSync67(p, "utf8"),
110519
111025
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -110801,7 +111307,7 @@ async function unpinAllStatusPins() {
110801
111307
  }
110802
111308
  }
110803
111309
  var stalePinSweepEligible = false;
110804
- var STALE_PIN_SWEEP_STORE_PATH = join77(STATE_DIR, "stale-pin-sweep.json");
111310
+ var STALE_PIN_SWEEP_STORE_PATH = join78(STATE_DIR, "stale-pin-sweep.json");
110805
111311
  var sweepStoreFs = {
110806
111312
  readFileSync: (p) => readFileSync67(p, "utf-8"),
110807
111313
  writeFileSync: (p, data) => atomicWriteStateFileSync2(p, data, 384),
@@ -110842,12 +111348,12 @@ var getPinnedProgressCardMessageId = null;
110842
111348
  var completeProgressCardTurn = null;
110843
111349
  var subagentWatcher = null;
110844
111350
  var workerActivityFeed = null;
110845
- var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join77(STATE_DIR, "gateway.sock");
111351
+ var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join78(STATE_DIR, "gateway.sock");
110846
111352
  if (isGatewayMain)
110847
111353
  mkdirStateSync2(STATE_DIR, { recursive: true, mode: 448 });
110848
- var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ?? join77(STATE_DIR, "gateway.pid.json");
110849
- var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ?? join77(STATE_DIR, "gateway-session.json");
110850
- var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join77(STATE_DIR, "clean-shutdown.json");
111354
+ var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ?? join78(STATE_DIR, "gateway.pid.json");
111355
+ var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ?? join78(STATE_DIR, "gateway-session.json");
111356
+ var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join78(STATE_DIR, "clean-shutdown.json");
110851
111357
  var GATEWAY_STARTED_AT_MS = Date.now();
110852
111358
  var BOOT_CARD_ENABLED = process.env.SWITCHROOM_BOOT_CARD !== "false";
110853
111359
  var activeBootCard = null;
@@ -110877,7 +111383,7 @@ function ensureIssuesCard(chatId, threadId) {
110877
111383
  bot: botApi,
110878
111384
  log: (msg) => process.stderr.write(`telegram gateway: ${msg}
110879
111385
  `),
110880
- persistPath: join77(stateDir, "issues-card.json")
111386
+ persistPath: join78(stateDir, "issues-card.json")
110881
111387
  });
110882
111388
  activeIssuesWatcher = startIssuesWatcher({
110883
111389
  stateDir,
@@ -111082,7 +111588,7 @@ if (isGatewayMain)
111082
111588
  var inboundSpool;
111083
111589
  if (isGatewayMain)
111084
111590
  inboundSpool = STATIC ? undefined : createInboundSpool({
111085
- path: join77(STATE_DIR, "inbound-spool.jsonl"),
111591
+ path: join78(STATE_DIR, "inbound-spool.jsonl"),
111086
111592
  fs: {
111087
111593
  appendFileSync: (p, d) => appendStateFileSync(p, d),
111088
111594
  readFileSync: (p) => readFileSync67(p, "utf8"),
@@ -111153,7 +111659,7 @@ async function maybeRedeliverUndeliveredAnswer() {
111153
111659
  let transcriptText;
111154
111660
  try {
111155
111661
  const projectsDir = getProjectsDirForCwd();
111156
- const path3 = join77(projectsDir, `${sessionId}.jsonl`);
111662
+ const path3 = join78(projectsDir, `${sessionId}.jsonl`);
111157
111663
  if (!existsSync65(path3)) {
111158
111664
  process.stderr.write(`telegram gateway: crash-redelivery \u2014 transcript not found for turnKey=${turn.turn_key} session=${sessionId} (${path3}); skipping
111159
111665
  `);
@@ -111328,8 +111834,8 @@ var bridgeDeadWatchdog = createBridgeDeadWatchdog({
111328
111834
  isSessionAlive: () => findAgentProcessInContainer2()?.comm === "claude",
111329
111835
  isShuttingDown: () => shuttingDown,
111330
111836
  escalate: (reason) => triggerSelfRestart(process.env.SWITCHROOM_AGENT_NAME ?? "", reason, 1500),
111331
- crashLogPath: join77(STATE_DIR, "bridge-crash.log"),
111332
- markerPath: join77(STATE_DIR, "bridge-dead-escalation.json"),
111837
+ crashLogPath: join78(STATE_DIR, "bridge-crash.log"),
111838
+ markerPath: join78(STATE_DIR, "bridge-dead-escalation.json"),
111333
111839
  log: (line) => process.stderr.write(`${line}
111334
111840
  `),
111335
111841
  priorStreak: bridgeDeadPriorStreak,
@@ -111436,8 +111942,8 @@ if (isGatewayMain)
111436
111942
  probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
111437
111943
  tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
111438
111944
  dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
111439
- configSnapshotPath: join77(resolvedAgentDirForCard, ".config-snapshot.json"),
111440
- bootCardStatePath: join77(resolvedAgentDirForCard, ".boot-card-msgid.json"),
111945
+ configSnapshotPath: join78(resolvedAgentDirForCard, ".config-snapshot.json"),
111946
+ bootCardStatePath: join78(resolvedAgentDirForCard, ".boot-card-msgid.json"),
111441
111947
  floodStatePath: FLOOD_STATE_PATH,
111442
111948
  ...updateOutcomeLine ? { updateOutcomeLine } : {}
111443
111949
  }, ackMsgId).then((handle) => {
@@ -112071,7 +112577,7 @@ if (isGatewayMain)
112071
112577
  const receiverUid = receiverUidRaw ? Number(receiverUidRaw) : NaN;
112072
112578
  if (Number.isInteger(receiverUid))
112073
112579
  allowedUids.push(receiverUid);
112074
- const socketPath = join77(STATE_DIR, "webhook.sock");
112580
+ const socketPath = join78(STATE_DIR, "webhook.sock");
112075
112581
  const webhookInject = (agentName3, inbound) => {
112076
112582
  const msg = inbound;
112077
112583
  const delivered = ipcServer.sendToAgent(agentName3, msg);
@@ -112323,9 +112829,9 @@ function redactOutboundText(text5, site) {
112323
112829
  var VOICE_OUT_DEFAULT_CHUNK_CHARS = 600;
112324
112830
  var VOICE_OUT_HARD_CHUNK_CAP = 4096;
112325
112831
  var voiceOnDemandCache = new VoiceOnDemandCache({
112326
- persistPath: join77(STATE_DIR, "voice-ondemand.json")
112832
+ persistPath: join78(STATE_DIR, "voice-ondemand.json")
112327
112833
  });
112328
- var VOICE_CACHE_DIR = join77(STATE_DIR, "voice-cache");
112834
+ var VOICE_CACHE_DIR = join78(STATE_DIR, "voice-cache");
112329
112835
  var voicePreSynthQueue = new PreSynthQueue({
112330
112836
  runJob: async (job) => {
112331
112837
  const sidecarToken = await materializeSidecarToken2();
@@ -112733,7 +113239,7 @@ async function executeSendGif(rawArgs) {
112733
113239
  };
112734
113240
  }
112735
113241
  async function publishToTelegraph(text5, shortName, authorName) {
112736
- const accountPath = join77(STATE_DIR, "telegraph-account.json");
113242
+ const accountPath = join78(STATE_DIR, "telegraph-account.json");
112737
113243
  let account = null;
112738
113244
  try {
112739
113245
  if (existsSync65(accountPath)) {
@@ -114283,7 +114789,7 @@ function restartMarkerPath() {
114283
114789
  const agentDir = resolveAgentDirFromEnv();
114284
114790
  if (!agentDir)
114285
114791
  return null;
114286
- return join77(agentDir, "restart-pending.json");
114792
+ return join78(agentDir, "restart-pending.json");
114287
114793
  }
114288
114794
  function writeRestartMarker(marker) {
114289
114795
  const p = restartMarkerPath();
@@ -114475,7 +114981,7 @@ function _resetDockerReachableCache() {
114475
114981
  }
114476
114982
  function spawnSwitchroomDetached(args, onFailure) {
114477
114983
  const fullArgs = SWITCHROOM_CONFIG ? ["--config", SWITCHROOM_CONFIG, ...args] : args;
114478
- const logPath = join77(STATE_DIR, "detached-spawn.log");
114984
+ const logPath = join78(STATE_DIR, "detached-spawn.log");
114479
114985
  let outFd = null;
114480
114986
  try {
114481
114987
  mkdirStateSync2(STATE_DIR, { recursive: true });
@@ -114768,7 +115274,7 @@ ${preBlock(formatSwitchroomOutput(detail))}`, { html: true });
114768
115274
  }
114769
115275
  function readRecentDenialsForAgent(agentName3, windowMs, limit) {
114770
115276
  try {
114771
- const auditPath = join77(homedir22(), ".switchroom", "vault-audit.log");
115277
+ const auditPath = join78(homedir22(), ".switchroom", "vault-audit.log");
114772
115278
  if (!existsSync65(auditPath))
114773
115279
  return [];
114774
115280
  const raw = readFileSync67(auditPath, "utf8");
@@ -114822,7 +115328,7 @@ async function buildAgentMetadata(agentName3) {
114822
115328
  try {
114823
115329
  const agentDir = resolveAgentDirFromEnv();
114824
115330
  if (agentDir) {
114825
- const raw = readFileSync67(join77(agentDir, ".claude", ".claude.json"), "utf8");
115331
+ const raw = readFileSync67(join78(agentDir, ".claude", ".claude.json"), "utf8");
114826
115332
  claudeJson = JSON.parse(raw);
114827
115333
  }
114828
115334
  } catch {}
@@ -114951,7 +115457,7 @@ function buildModelDeps(restartCtx) {
114951
115457
  try {
114952
115458
  const agentDir = resolveAgentDirFromEnv();
114953
115459
  if (agentDir) {
114954
- const local = await fetchQuota2({ claudeConfigDir: join77(agentDir, ".claude") });
115460
+ const local = await fetchQuota2({ claudeConfigDir: join78(agentDir, ".claude") });
114955
115461
  if (local.ok)
114956
115462
  return formatQuotaLine2(local.data);
114957
115463
  }
@@ -115198,7 +115704,7 @@ function effortMenuReplyMarkup(reply) {
115198
115704
  function flushAgentHandoff(agentDir) {
115199
115705
  let removed = 0;
115200
115706
  for (const fname of [".handoff.md", ".handoff-topic"]) {
115201
- const p = join77(agentDir, fname);
115707
+ const p = join78(agentDir, fname);
115202
115708
  try {
115203
115709
  if (existsSync65(p)) {
115204
115710
  unlinkSync33(p);
@@ -115256,7 +115762,7 @@ async function handleNewCommand(ctx) {
115256
115762
  writeRestartMarker({ chat_id: chatId, thread_id: threadId ?? null, ack_message_id: ackId, ts: Date.now() });
115257
115763
  if (agentDir != null) {
115258
115764
  try {
115259
- writeFileSync55(join77(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
115765
+ writeFileSync55(join78(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
115260
115766
  `, "utf8");
115261
115767
  } catch (err) {
115262
115768
  process.stderr.write(`telegram gateway: failed to write force-fresh marker: ${err}
@@ -115373,7 +115879,7 @@ var lockoutOps = {
115373
115879
  writeFileSync: (p, data, opts) => writeStateFileSync2(p, data, opts),
115374
115880
  existsSync: (p) => existsSync65(p),
115375
115881
  mkdirSync: (p, opts) => mkdirStateSync2(p, opts),
115376
- joinPath: (...parts) => join77(...parts)
115882
+ joinPath: (...parts) => join78(...parts)
115377
115883
  };
115378
115884
  var FLEET_FALLBACK_DEDUP_MS = 30000;
115379
115885
  function isAuthBrokerSocketReachable() {
@@ -115634,7 +116140,7 @@ async function runCreditWatch() {
115634
116140
  if (!agentDir)
115635
116141
  return;
115636
116142
  const agentName3 = getMyAgentName();
115637
- const claudeConfigDir = join77(agentDir, ".claude");
116143
+ const claudeConfigDir = join78(agentDir, ".claude");
115638
116144
  const stateDir = STATE_DIR;
115639
116145
  const reason = readClaudeJsonOverage(claudeConfigDir);
115640
116146
  const prev = loadCreditState(stateDir);
@@ -117404,7 +117910,7 @@ Send \`/auth ${parsed.provider} cancel\` to abort.`, { html: true });
117404
117910
  await switchroomReply(ctx, "**/usage:** cannot resolve agent dir.", { html: true });
117405
117911
  return;
117406
117912
  }
117407
- const result = await fetchQuota2({ claudeConfigDir: join77(agentDir, ".claude") });
117913
+ const result = await fetchQuota2({ claudeConfigDir: join78(agentDir, ".claude") });
117408
117914
  if (!result.ok) {
117409
117915
  await switchroomReply(ctx, `**/usage:** ${escapeHtmlForTg2(result.reason)}`, { html: true });
117410
117916
  return;
@@ -118670,7 +119176,7 @@ async function startGateway() {
118670
119176
  return;
118671
119177
  }
118672
119178
  })();
118673
- const resolvedAgentDirForBootCard = agentDir ?? join77(homedir22(), ".switchroom", "agents", agentSlug);
119179
+ const resolvedAgentDirForBootCard = agentDir ?? join78(homedir22(), ".switchroom", "agents", agentSlug);
118674
119180
  const handle = await startBootCard(chatId, threadId, botApiForCard, {
118675
119181
  agentName: agentDisplayName,
118676
119182
  agentSlug,
@@ -118684,8 +119190,8 @@ async function startGateway() {
118684
119190
  probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
118685
119191
  tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
118686
119192
  dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
118687
- configSnapshotPath: join77(resolvedAgentDirForBootCard, ".config-snapshot.json"),
118688
- bootCardStatePath: join77(resolvedAgentDirForBootCard, ".boot-card-msgid.json"),
119193
+ configSnapshotPath: join78(resolvedAgentDirForBootCard, ".config-snapshot.json"),
119194
+ bootCardStatePath: join78(resolvedAgentDirForBootCard, ".boot-card-msgid.json"),
118689
119195
  floodStatePath: FLOOD_STATE_PATH,
118690
119196
  ...updateOutcomeLine ? { updateOutcomeLine } : {}
118691
119197
  }, ackMsgId);
@@ -118718,7 +119224,7 @@ async function startGateway() {
118718
119224
  if (smAgentDir) {
118719
119225
  const resolutionTimeoutMs = resolveSessionModelResolutionTimeoutMs(process.env.SWITCHROOM_SESSION_MODEL_RESOLUTION_TIMEOUT_MS);
118720
119226
  const resolved = await waitForSessionModelResolution({
118721
- barrierExists: () => existsSync65(join77(smAgentDir, ".session-model-resolved")),
119227
+ barrierExists: () => existsSync65(join78(smAgentDir, ".session-model-resolved")),
118722
119228
  timeoutMs: resolutionTimeoutMs
118723
119229
  });
118724
119230
  if (!resolved) {
@@ -118726,7 +119232,7 @@ async function startGateway() {
118726
119232
  process.stderr.write(`telegram gateway: gw /model relaunch UNRESOLVED agent=${getMyAgentName()} target=${target} (barrier timeout after ${resolutionTimeoutMs}ms)
118727
119233
  `);
118728
119234
  } else {
118729
- const activePath = join77(smAgentDir, ".active-session-model");
119235
+ const activePath = join78(smAgentDir, ".active-session-model");
118730
119236
  if (existsSync65(activePath)) {
118731
119237
  try {
118732
119238
  const launched = readFileSync67(activePath, "utf8").trim();
@@ -118762,12 +119268,12 @@ async function startGateway() {
118762
119268
  deliverModelSwitchBootNotice({
118763
119269
  ...modelBootCardDeps,
118764
119270
  confirmation,
118765
- hasSessionModelAlert: existsSync65(join77(smAgentDir, ".session-model-alert"))
119271
+ hasSessionModelAlert: existsSync65(join78(smAgentDir, ".session-model-alert"))
118766
119272
  });
118767
119273
  }
118768
119274
  } catch {}
118769
119275
  }
118770
- const activeEffortPath = join77(smAgentDir, ".active-session-effort");
119276
+ const activeEffortPath = join78(smAgentDir, ".active-session-effort");
118771
119277
  if (existsSync65(activeEffortPath)) {
118772
119278
  try {
118773
119279
  const launchedEffort = readFileSync67(activeEffortPath, "utf8").trim();
@@ -118775,7 +119281,7 @@ async function startGateway() {
118775
119281
  sessionEffortOverride = launchedEffort.length > 0 && launchedEffort !== configuredEffort ? launchedEffort : null;
118776
119282
  } catch {}
118777
119283
  }
118778
- const alertPath = join77(smAgentDir, ".session-model-alert");
119284
+ const alertPath = join78(smAgentDir, ".session-model-alert");
118779
119285
  if (existsSync65(alertPath)) {
118780
119286
  let alertText = null;
118781
119287
  try {