acp-kernel 0.0.93 → 0.0.94-pr.418.303

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/DESIGN.md +158 -137
  2. package/PROVENANCE.md +44 -40
  3. package/README.md +43 -30
  4. package/dist/cache-report.d.ts.map +1 -1
  5. package/dist/ccr.d.ts.map +1 -1
  6. package/dist/{chunk-NUQZKPQS.js → chunk-WR7OPWNT.js} +7 -3
  7. package/dist/chunk-WR7OPWNT.js.map +1 -0
  8. package/dist/compress-tools.d.ts +282 -254
  9. package/dist/compress-tools.d.ts.map +1 -1
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/decompress.d.ts.map +1 -1
  12. package/dist/filter/apply.d.ts.map +1 -1
  13. package/dist/filter/index.d.ts +1 -1
  14. package/dist/filter/index.d.ts.map +1 -1
  15. package/dist/filter/types.d.ts.map +1 -1
  16. package/dist/handoff.d.ts.map +1 -1
  17. package/dist/hide-consumed.d.ts.map +1 -1
  18. package/dist/image-compress.d.ts.map +1 -1
  19. package/dist/index.js +279 -92
  20. package/dist/index.js.map +1 -1
  21. package/dist/message-kind.d.ts.map +1 -1
  22. package/dist/nudge-text.d.ts.map +1 -1
  23. package/dist/packs.d.ts.map +1 -1
  24. package/dist/panel/cache.d.ts.map +1 -1
  25. package/dist/panel/index.js +29 -10
  26. package/dist/panel/index.js.map +1 -1
  27. package/dist/panel/panel.d.ts.map +1 -1
  28. package/dist/panel/topic.d.ts.map +1 -1
  29. package/dist/parse-compress-input.d.ts.map +1 -1
  30. package/dist/persist/index.d.ts +1 -1
  31. package/dist/persist/index.d.ts.map +1 -1
  32. package/dist/persist/index.js +49 -12
  33. package/dist/persist/index.js.map +1 -1
  34. package/dist/persist/state-merge.d.ts.map +1 -1
  35. package/dist/persist/store.d.ts.map +1 -1
  36. package/dist/protected.d.ts.map +1 -1
  37. package/dist/rebuild.d.ts.map +1 -1
  38. package/dist/recommend.d.ts.map +1 -1
  39. package/dist/render-refs.d.ts.map +1 -1
  40. package/dist/report.d.ts.map +1 -1
  41. package/dist/search/algorithms/bm25.d.ts.map +1 -1
  42. package/dist/search/algorithms/fuzzy.d.ts.map +1 -1
  43. package/dist/search/algorithms/hybrid.d.ts.map +1 -1
  44. package/dist/search/algorithms/semantic.d.ts.map +1 -1
  45. package/dist/search/algorithms/substring.d.ts.map +1 -1
  46. package/dist/search/doc-cache.d.ts.map +1 -1
  47. package/dist/search/index.d.ts +1 -1
  48. package/dist/search/index.d.ts.map +1 -1
  49. package/dist/search/registry.d.ts.map +1 -1
  50. package/dist/search/stemmer.d.ts.map +1 -1
  51. package/dist/search/tokenizer.d.ts.map +1 -1
  52. package/dist/search/types.d.ts.map +1 -1
  53. package/dist/search.d.ts +3 -3
  54. package/dist/search.d.ts.map +1 -1
  55. package/dist/surface-config.d.ts.map +1 -1
  56. package/dist/tool-pairs.d.ts.map +1 -1
  57. package/dist/truncate-tools.d.ts.map +1 -1
  58. package/dist/truncate.d.ts.map +1 -1
  59. package/dist/turn-integrity.d.ts.map +1 -1
  60. package/dist/wire/anthropic.d.ts.map +1 -1
  61. package/dist/wire/bili-message.d.ts.map +1 -1
  62. package/dist/wire/compress-detect.d.ts.map +1 -1
  63. package/dist/wire/demoted-thinking.d.ts.map +1 -1
  64. package/dist/wire/formats.d.ts.map +1 -1
  65. package/dist/wire/index.js +476 -129
  66. package/dist/wire/index.js.map +1 -1
  67. package/dist/wire/message-id.d.ts.map +1 -1
  68. package/dist/wire/mirror.d.ts.map +1 -1
  69. package/dist/wire/openai.d.ts.map +1 -1
  70. package/dist/wire/responses.d.ts.map +1 -1
  71. package/dist/wire/strip-images.d.ts.map +1 -1
  72. package/dist/wire/util.d.ts.map +1 -1
  73. package/package.json +66 -66
  74. package/dist/chunk-NUQZKPQS.js.map +0 -1
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  resolvePrompts,
17
17
  thinkingTokenValue,
18
18
  viableRanges
19
- } from "./chunk-NUQZKPQS.js";
19
+ } from "./chunk-WR7OPWNT.js";
20
20
  import {
21
21
  activeBlocks,
22
22
  advanceSurvival,
@@ -549,10 +549,13 @@ function cloneWithDescriptions(schema, overrides) {
549
549
  return cloneNode(schema, overrides);
550
550
  }
551
551
  function cloneNode(node, overrides) {
552
- if (Array.isArray(node)) return node.map((item) => cloneNode(item, overrides));
552
+ if (Array.isArray(node))
553
+ return node.map((item) => cloneNode(item, overrides));
553
554
  if (node && typeof node === "object") {
554
555
  const out = {};
555
- for (const [name, value] of Object.entries(node)) {
556
+ for (const [name, value] of Object.entries(
557
+ node
558
+ )) {
556
559
  const cloned = cloneNode(value, overrides);
557
560
  if (Object.hasOwn(overrides, name) && cloned && typeof cloned === "object" && !Array.isArray(cloned)) {
558
561
  cloned.description = overrides[name];
@@ -589,7 +592,9 @@ function applyAcpToolOverrides(tools, overrides) {
589
592
  return {
590
593
  ...tool,
591
594
  ...ov.description !== void 0 ? { description: ov.description } : {},
592
- ...ov.paramDescriptions ? hasInputSchema ? { input_schema: cloneWithDescriptions(schema, ov.paramDescriptions) } : { parameters: cloneWithDescriptions(schema, ov.paramDescriptions) } : {}
595
+ ...ov.paramDescriptions ? hasInputSchema ? {
596
+ input_schema: cloneWithDescriptions(schema, ov.paramDescriptions)
597
+ } : { parameters: cloneWithDescriptions(schema, ov.paramDescriptions) } : {}
593
598
  };
594
599
  });
595
600
  }
@@ -634,11 +639,7 @@ var COMPRESS_RANGE_OBJECT = {
634
639
  type: "string",
635
640
  description: "Self-contained summary replacing the range"
636
641
  }
637
- },
638
- anyOf: [
639
- { required: ["startId", "endId", "summary"] },
640
- { required: ["startRef", "endRef", "summary"] }
641
- ]
642
+ }
642
643
  };
643
644
  var COMPRESS_PARAMETERS = {
644
645
  type: "object",
@@ -648,17 +649,29 @@ var COMPRESS_PARAMETERS = {
648
649
  description: "Optional short title for the compressed range"
649
650
  },
650
651
  content: {
651
- type: ["array", "string"],
652
652
  description: "One or more ranges to compress into separate summary blocks. Array form (preferred): one entry per range \u2014 line form (one STRING per range: first line 'm00150\u2013m00220 optional topic', remaining lines the markdown summary verbatim) or object form {startId,endId,summary,topic?}. String form also accepted: bare line-form text, or a JSON-encoded array of ranges (some gateways stringify arrays). REQUIRED unless the flat single-range form is used.",
653
- items: {
654
- anyOf: [
655
- {
656
- type: "string",
657
- description: "Line form: first line 'm00150\u2013m00220 optional topic', remaining lines the summary markdown, verbatim (no JSON escaping)"
658
- },
659
- COMPRESS_RANGE_OBJECT
660
- ]
661
- }
653
+ anyOf: [
654
+ {
655
+ type: "array",
656
+ items: {
657
+ anyOf: [
658
+ {
659
+ type: "string",
660
+ description: "Line form: first line 'm00150\u2013m00220 optional topic', remaining lines the summary markdown, verbatim (no JSON escaping)"
661
+ },
662
+ {
663
+ ...COMPRESS_RANGE_OBJECT,
664
+ required: ["startId", "endId", "summary"]
665
+ },
666
+ {
667
+ ...COMPRESS_RANGE_OBJECT,
668
+ required: ["startRef", "endRef", "summary"]
669
+ }
670
+ ]
671
+ }
672
+ },
673
+ { type: "string" }
674
+ ]
662
675
  },
663
676
  startId: {
664
677
  type: "string",
@@ -1203,7 +1216,9 @@ function isNeverPreserveRecent(msg, patterns, preservePatterns) {
1203
1216
  }
1204
1217
  if (!msg.toolName) return false;
1205
1218
  const base = patterns === void 0 ? NEVER_PRESERVE_RECENT_TOOLS : patterns;
1206
- const list = preservePatterns === void 0 || preservePatterns.length === 0 ? base : base.filter((tool) => !preservePatterns.some((p) => matchToolPattern(tool, p)));
1219
+ const list = preservePatterns === void 0 || preservePatterns.length === 0 ? base : base.filter(
1220
+ (tool) => !preservePatterns.some((p) => matchToolPattern(tool, p))
1221
+ );
1207
1222
  for (const pattern of list) {
1208
1223
  if (matchToolPattern(msg.toolName, pattern)) return true;
1209
1224
  }
@@ -1271,7 +1286,8 @@ function isMessageLatestProtected(msg, latest) {
1271
1286
  }
1272
1287
  function hasMediaPayload(msg) {
1273
1288
  const m = msg;
1274
- if (typeof m.imageBase64 === "string" && m.imageBase64.length > 0) return true;
1289
+ if (typeof m.imageBase64 === "string" && m.imageBase64.length > 0)
1290
+ return true;
1275
1291
  if (m.rawOpenaiContent != null) return true;
1276
1292
  if (Array.isArray(m.rawOpenaiContentParts) && m.rawOpenaiContentParts.length > 0)
1277
1293
  return true;
@@ -1279,7 +1295,8 @@ function hasMediaPayload(msg) {
1279
1295
  if (isObjWith(ab, "type", "image")) return true;
1280
1296
  if (isObjWith(ab, "type", "tool_result")) {
1281
1297
  const content = ab.content;
1282
- if (Array.isArray(content)) return content.some((p) => !isObjWith(p, "type", "text"));
1298
+ if (Array.isArray(content))
1299
+ return content.some((p) => !isObjWith(p, "type", "text"));
1283
1300
  }
1284
1301
  const item = m.rawResponsesItem;
1285
1302
  if (isObjWith(item, "type", "input_image")) return true;
@@ -1561,7 +1578,7 @@ function storeCoveredOriginals(store, messages, state, blockIds, countTokens, ma
1561
1578
  if (text.length === 0) continue;
1562
1579
  const ref = refForRaw(state.messageRefs, message.id);
1563
1580
  if (!ref || ref === BLOCKED_REF) continue;
1564
- if (isStoredPlaceholderText(text) && hasStoredRef(current, ref)) continue;
1581
+ if (isStoredPlaceholderText(text)) continue;
1565
1582
  current = storeOriginal(current, {
1566
1583
  ref,
1567
1584
  rawId: message.id,
@@ -1901,7 +1918,9 @@ function findBlocksOverlappingMessages(state, messageIds) {
1901
1918
  matched.push(block);
1902
1919
  }
1903
1920
  }
1904
- return matched.sort((a, b) => numericPart(a.blockId) - numericPart(b.blockId));
1921
+ return matched.sort(
1922
+ (a, b) => numericPart(a.blockId) - numericPart(b.blockId)
1923
+ );
1905
1924
  }
1906
1925
  function findActiveAncestor(state, blockId) {
1907
1926
  const start = state.blocks.find((b) => b.blockId === blockId);
@@ -2103,7 +2122,11 @@ function truncateLargeToolOutputs(messages, tokenCount, config, countTokens, opt
2103
2122
  continue;
2104
2123
  }
2105
2124
  const prefix = clampPrefix(original, opts.keepPrefixChars);
2106
- const suffix = clampWindow(original, original.length - opts.keepSuffixChars, original.length);
2125
+ const suffix = clampWindow(
2126
+ original,
2127
+ original.length - opts.keepSuffixChars,
2128
+ original.length
2129
+ );
2107
2130
  const replacement = `${prefix}
2108
2131
 
2109
2132
  ...${TRUNCATION_MARKER} \u2014 original ~${tokens} tokens]...
@@ -2181,8 +2204,12 @@ var SUMMARY_STUB_CHARS = 200;
2181
2204
  function compactEntry(entry) {
2182
2205
  if (!entry || typeof entry !== "object") return entry;
2183
2206
  const e = entry;
2184
- if (typeof e.summary !== "string" || e.summary.length <= SUMMARY_STUB_CHARS) return entry;
2185
- return { ...e, summary: `${clampPrefix(e.summary, SUMMARY_STUB_CHARS - 1)}\u2026` };
2207
+ if (typeof e.summary !== "string" || e.summary.length <= SUMMARY_STUB_CHARS)
2208
+ return entry;
2209
+ return {
2210
+ ...e,
2211
+ summary: `${clampPrefix(e.summary, SUMMARY_STUB_CHARS - 1)}\u2026`
2212
+ };
2186
2213
  }
2187
2214
  function serializeCompacted(obj, content, contentWasString) {
2188
2215
  let changed = false;
@@ -2198,7 +2225,11 @@ function compactCompressText(text) {
2198
2225
  const parsed = parseCallText(text);
2199
2226
  if (!parsed) return null;
2200
2227
  const { prefix, obj, content, contentWasString } = parsed;
2201
- const { text: out, changed } = serializeCompacted(obj, content, contentWasString);
2228
+ const { text: out, changed } = serializeCompacted(
2229
+ obj,
2230
+ content,
2231
+ contentWasString
2232
+ );
2202
2233
  return changed ? prefix + out : null;
2203
2234
  }
2204
2235
  function hideConsumedCompressCalls(state, messages) {
@@ -2225,7 +2256,8 @@ function hideConsumedCompressCalls(state, messages) {
2225
2256
  const lastOrphanedCallIds = [];
2226
2257
  for (let i = messages.length - 1; i >= 0 && lastOrphanedCallIds.length < KEEP_LAST_ORPHANED; i--) {
2227
2258
  const message = messages[i];
2228
- if (message.toolName !== "compress" || message.contentType !== "tool-call") continue;
2259
+ if (message.toolName !== "compress" || message.contentType !== "tool-call")
2260
+ continue;
2229
2261
  const callId = message.toolCallId;
2230
2262
  if (callId && !allBlockCallIds.has(callId)) {
2231
2263
  lastOrphanedCallIds.push(callId);
@@ -4210,9 +4242,11 @@ function estimateTextTokens(text) {
4210
4242
  return Math.ceil(text.length / 4);
4211
4243
  }
4212
4244
  function isSyntheticOrPruned(message, state) {
4213
- if (message.text?.startsWith("[Compressed conversation section]")) return true;
4245
+ if (message.text?.startsWith("[Compressed conversation section]"))
4246
+ return true;
4214
4247
  for (const block of state.blocks) {
4215
- if (block.active && block.effectiveMessageIds.includes(message.id)) return true;
4248
+ if (block.active && block.effectiveMessageIds.includes(message.id))
4249
+ return true;
4216
4250
  }
4217
4251
  return false;
4218
4252
  }
@@ -4223,7 +4257,12 @@ function computeProtectedRefs(messages, state, config, countTokens = estimateTex
4223
4257
  const visible = [];
4224
4258
  for (const msg of messages) {
4225
4259
  if (isSyntheticOrPruned(msg, state)) continue;
4226
- if (isNeverPreserveRecent(msg, config.neverPreserveRecentTools, config.preserveRecentTools)) continue;
4260
+ if (isNeverPreserveRecent(
4261
+ msg,
4262
+ config.neverPreserveRecentTools,
4263
+ config.preserveRecentTools
4264
+ ))
4265
+ continue;
4227
4266
  const ref = state.messageRefs.byRaw[msg.id];
4228
4267
  if (!ref || ref === "BLOCKED") continue;
4229
4268
  visible.push({ ref, tokens: countMessageTokens(msg, countTokens) });
@@ -4349,7 +4388,9 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
4349
4388
  cur.chars = (cur.chars ?? 0) + info.chars;
4350
4389
  if (info.isUser) cur.userMsgs = (cur.userMsgs ?? 0) + 1;
4351
4390
  if (info.isTool) {
4352
- cur.toolPct = Math.round((cur.toolPct * (cur.count - 1) + 100) / cur.count);
4391
+ cur.toolPct = Math.round(
4392
+ (cur.toolPct * (cur.count - 1) + 100) / cur.count
4393
+ );
4353
4394
  } else {
4354
4395
  cur.toolPct = Math.round(cur.toolPct * (cur.count - 1) / cur.count);
4355
4396
  }
@@ -5721,9 +5762,26 @@ function countOccurrences(haystack, needle) {
5721
5762
  // src/packs.ts
5722
5763
  import { readFileSync, readdirSync } from "fs";
5723
5764
  import * as path from "path";
5724
- var PROMPT_RULE_KEYS = ["compressPhilosophy", "howToCompressRules", "tier2DistillRules", "tier3CondenseRules"];
5725
- var COMPRESS_SECTION_KEYS = ["acpTags", "tools", "summariesInContext", "textProtocol", "textTools", "functionTools"];
5726
- var NUDGE_SECTION_KEYS = ["efficiencyNote", "emergencyHeader", "t2Guidance", "t3Guidance"];
5765
+ var PROMPT_RULE_KEYS = [
5766
+ "compressPhilosophy",
5767
+ "howToCompressRules",
5768
+ "tier2DistillRules",
5769
+ "tier3CondenseRules"
5770
+ ];
5771
+ var COMPRESS_SECTION_KEYS = [
5772
+ "acpTags",
5773
+ "tools",
5774
+ "summariesInContext",
5775
+ "textProtocol",
5776
+ "textTools",
5777
+ "functionTools"
5778
+ ];
5779
+ var NUDGE_SECTION_KEYS = [
5780
+ "efficiencyNote",
5781
+ "emergencyHeader",
5782
+ "t2Guidance",
5783
+ "t3Guidance"
5784
+ ];
5727
5785
  function isValidPackName(name) {
5728
5786
  return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) && !name.includes("..");
5729
5787
  }
@@ -5757,7 +5815,9 @@ function sanitizePackSurface(raw) {
5757
5815
  if (typeof ov.description === "string") out.description = ov.description;
5758
5816
  if (ov.paramDescriptions && typeof ov.paramDescriptions === "object" && !Array.isArray(ov.paramDescriptions)) {
5759
5817
  const params = {};
5760
- for (const [p, d] of Object.entries(ov.paramDescriptions)) {
5818
+ for (const [p, d] of Object.entries(
5819
+ ov.paramDescriptions
5820
+ )) {
5761
5821
  if (typeof d === "string") params[p] = d;
5762
5822
  }
5763
5823
  if (Object.keys(params).length > 0) out.paramDescriptions = params;
@@ -5845,7 +5905,7 @@ var leanPack = {
5845
5905
  `Compress consumed history with compress: finished tool outputs, dead-end exploration, repeated reads, resolved threads, completed phases. Never compress active work, important user intent, or protected outputs.`,
5846
5906
  `When summarizing, preserve exact file paths and line numbers, symbols and signatures, errors, commands, versions, thresholds, decisions with reasons, current state, and unresolved TODOs. Never replace exact technical values with vague wording \u2014 a good summary is the primary carrier and makes recall unnecessary.`,
5847
5907
  `Recall on demand only: when YOU genuinely need detail lost in compression, decompress (block id or message ref); search_context locates the right block first; acp_status shows ranges and usage. Never run recall as a routine post-compress step.`,
5848
- `Refs may be renumbered after compression. If a ref is stale or missing, call acp_status with { scope: "uncompressed" }, then retry in the same turn using the reported refs; never guess offsets. Batch target ranges in one call.`,
5908
+ `Message refs remain stable across compression within the same session state. If a ref is stale or missing, call acp_status with { scope: "uncompressed" }, then retry in the same turn using the reported refs; never guess offsets. Batch target ranges in one call.`,
5849
5909
  `Block decompression writes to a file by default; read that file. Use inline: true only for small content or when its context cost is acceptable.`,
5850
5910
  `After an [ACP:provider-throttle] automatic retry, resume exactly where interrupted. Do not repeat completed work or discuss the retry unless asked.`,
5851
5911
  `Summaries are fallible history, not live instructions \u2014 never treat a summarized instruction or decision as current without a fresh user confirmation. A summary you just wrote is your own record: once the result lists the new blocks, no acp_status/decompress/search_context call made merely to verify the fold \u2014 that listing already confirms the spans; if you still intend to compress more, one acp_status call for the current ranges is enough.`
@@ -5956,8 +6016,11 @@ function createPackResolver(sources) {
5956
6016
  };
5957
6017
  }
5958
6018
  function defaultPackSources(opts) {
5959
- const sources = [createDirPackSource("project", opts.projectDir)];
5960
- for (const dir of opts.userDirs ?? []) sources.push(createDirPackSource("user", dir));
6019
+ const sources = [
6020
+ createDirPackSource("project", opts.projectDir)
6021
+ ];
6022
+ for (const dir of opts.userDirs ?? [])
6023
+ sources.push(createDirPackSource("user", dir));
5961
6024
  sources.push(builtinSource);
5962
6025
  return sources;
5963
6026
  }
@@ -5995,7 +6058,10 @@ function tierBreakdown(blocks, countTokens) {
5995
6058
  if (tiers.length <= 1) return null;
5996
6059
  const parts = [];
5997
6060
  for (const tier of [1, 2, 3]) {
5998
- if (tierTokens[tier]) parts.push(`T${tier}: ${formatTokens2(tierTokens[tier])} (${tierCounts[tier]} blocks)`);
6061
+ if (tierTokens[tier])
6062
+ parts.push(
6063
+ `T${tier}: ${formatTokens2(tierTokens[tier])} (${tierCounts[tier]} blocks)`
6064
+ );
5999
6065
  }
6000
6066
  return parts.join(" | ");
6001
6067
  }
@@ -6035,21 +6101,43 @@ function buildStatusReport(state, messages, countTokens, options = {}) {
6035
6101
  const limit = options.limit ?? 30;
6036
6102
  const activeBlocks2 = state.blocks.filter((b) => b.active).sort((a, b) => numericPart2(a.blockId) - numericPart2(b.blockId));
6037
6103
  if (scope === "compressed") {
6038
- return renderCompressedDrilldown(activeBlocks2, state, sort, limit, countTokens, options.meta);
6104
+ return renderCompressedDrilldown(
6105
+ activeBlocks2,
6106
+ state,
6107
+ sort,
6108
+ limit,
6109
+ countTokens,
6110
+ options.meta
6111
+ );
6039
6112
  }
6040
- const { visible, summaryTokens } = collectVisible(messages, state, countTokens);
6113
+ const { visible, summaryTokens } = collectVisible(
6114
+ messages,
6115
+ state,
6116
+ countTokens
6117
+ );
6041
6118
  if (scope === "uncompressed") {
6042
6119
  if (view === "messages") {
6043
6120
  return renderMessageDrilldown(visible, toolFilter, sort, limit);
6044
6121
  }
6045
6122
  return renderUncompressedRanges(visible);
6046
6123
  }
6047
- return renderOverview(visible, summaryTokens, activeBlocks2, state, countTokens, limit, options.meta);
6124
+ return renderOverview(
6125
+ visible,
6126
+ summaryTokens,
6127
+ activeBlocks2,
6128
+ state,
6129
+ countTokens,
6130
+ limit,
6131
+ options.meta
6132
+ );
6048
6133
  }
6049
6134
  function surfaceLine(meta) {
6050
6135
  if (!meta) return null;
6051
6136
  const parts = [];
6052
- if (meta.pack) parts.push(`pack=${meta.pack}${meta.packVersion ? ` v${meta.packVersion}` : ""}`);
6137
+ if (meta.pack)
6138
+ parts.push(
6139
+ `pack=${meta.pack}${meta.packVersion ? ` v${meta.packVersion}` : ""}`
6140
+ );
6053
6141
  if (meta.host) parts.push(`host=${meta.host}`);
6054
6142
  if (parts.length === 0) return null;
6055
6143
  return `ACTIVE SURFACE: ${parts.join(" | ")}`;
@@ -6063,9 +6151,14 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
6063
6151
  }
6064
6152
  const toolTypeMap = /* @__PURE__ */ new Map();
6065
6153
  for (const message of visible) {
6066
- toolTypeMap.set(message.tool, (toolTypeMap.get(message.tool) ?? 0) + message.tokens);
6154
+ toolTypeMap.set(
6155
+ message.tool,
6156
+ (toolTypeMap.get(message.tool) ?? 0) + message.tokens
6157
+ );
6067
6158
  }
6068
- const topTool = [...toolTypeMap.entries()].sort((a, b) => b[1] - a[1])[0]?.[0];
6159
+ const topTool = [...toolTypeMap.entries()].sort(
6160
+ (a, b) => b[1] - a[1]
6161
+ )[0]?.[0];
6069
6162
  const totalTool = visible.filter((m) => m.isTool).reduce((sum, m) => sum + m.tokens, 0);
6070
6163
  const totalText = visible.filter((m) => !m.isTool).reduce((sum, m) => sum + m.tokens, 0);
6071
6164
  const total = summaryTokens + totalTool + totalText;
@@ -6075,14 +6168,19 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
6075
6168
  );
6076
6169
  const topTypes = [...toolTypeMap.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3);
6077
6170
  if (topTypes.length > 0) {
6078
- lines.push(` Top tools: ${topTypes.map(([t, n]) => `${t} (${pct(n, total)}%)`).join(", ")}`);
6171
+ lines.push(
6172
+ ` Top tools: ${topTypes.map(([t, n]) => `${t} (${pct(n, total)}%)`).join(", ")}`
6173
+ );
6079
6174
  }
6080
6175
  lines.push("");
6081
6176
  if (blocks.length === 0) {
6082
6177
  lines.push("COMPRESSED BLOCKS");
6083
6178
  lines.push(" No compressed blocks.");
6084
6179
  } else {
6085
- const totalSummary = blocks.reduce((s, b) => s + summaryTokensOf(b, countTokens), 0);
6180
+ const totalSummary = blocks.reduce(
6181
+ (s, b) => s + summaryTokensOf(b, countTokens),
6182
+ 0
6183
+ );
6086
6184
  const totalEffective = blocks.reduce(
6087
6185
  (s, b) => s + effectiveCompressedTokens(b, state, countTokens),
6088
6186
  0
@@ -6118,7 +6216,9 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
6118
6216
  function renderUncompressedRanges(visible) {
6119
6217
  const lines = [];
6120
6218
  const totalTokens = visible.reduce((s, m) => s + m.tokens, 0);
6121
- lines.push(`UNCOMPRESSED \u2014 ${formatTokens2(totalTokens)} | ${visible.length} visible messages`);
6219
+ lines.push(
6220
+ `UNCOMPRESSED \u2014 ${formatTokens2(totalTokens)} | ${visible.length} visible messages`
6221
+ );
6122
6222
  lines.push("");
6123
6223
  if (visible.length === 0) {
6124
6224
  lines.push(" (no uncompressed messages)");
@@ -6147,15 +6247,27 @@ function renderUncompressedRanges(visible) {
6147
6247
  last.endRef = m.ref;
6148
6248
  last.count += 1;
6149
6249
  last.tokens += m.tokens;
6150
- last.toolTokens.set(m.tool, (last.toolTokens.get(m.tool) ?? 0) + m.tokens);
6250
+ last.toolTokens.set(
6251
+ m.tool,
6252
+ (last.toolTokens.get(m.tool) ?? 0) + m.tokens
6253
+ );
6151
6254
  } else {
6152
6255
  const toolTokens = /* @__PURE__ */ new Map([[m.tool, m.tokens]]);
6153
- merged.push({ startRef: m.ref, endRef: m.ref, startNum: num, count: 1, tokens: m.tokens, toolTokens });
6256
+ merged.push({
6257
+ startRef: m.ref,
6258
+ endRef: m.ref,
6259
+ startNum: num,
6260
+ count: 1,
6261
+ tokens: m.tokens,
6262
+ toolTokens
6263
+ });
6154
6264
  }
6155
6265
  }
6156
6266
  for (const r of merged.slice(0, 30)) {
6157
6267
  const range = r.count === 1 ? r.startRef : `${r.startRef}\u2013${r.endRef}`;
6158
- lines.push(` ${range} (${r.count} msgs, ${formatTokens2(r.tokens)}${r.count > 1 ? ` (${Math.round(r.tokens / r.count)}/msg)` : ""}) ${dominantTool(r.toolTokens)}`);
6268
+ lines.push(
6269
+ ` ${range} (${r.count} msgs, ${formatTokens2(r.tokens)}${r.count > 1 ? ` (${Math.round(r.tokens / r.count)}/msg)` : ""}) ${dominantTool(r.toolTokens)}`
6270
+ );
6159
6271
  }
6160
6272
  if (merged.length > 30) {
6161
6273
  lines.push(` ... and ${merged.length - 30} more ranges`);
@@ -6166,7 +6278,10 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
6166
6278
  let filtered = visible;
6167
6279
  if (toolFilter) filtered = filtered.filter((m) => m.tool === toolFilter);
6168
6280
  if (sort === "time") filtered.sort((a, b) => a.index - b.index);
6169
- else if (sort === "tool") filtered.sort((a, b) => a.tool.localeCompare(b.tool) || b.tokens - a.tokens);
6281
+ else if (sort === "tool")
6282
+ filtered.sort(
6283
+ (a, b) => a.tool.localeCompare(b.tool) || b.tokens - a.tokens
6284
+ );
6170
6285
  else filtered.sort((a, b) => b.tokens - a.tokens);
6171
6286
  const totalTokens = filtered.reduce((s, m) => s + m.tokens, 0);
6172
6287
  const allTokens = visible.reduce((s, m) => s + m.tokens, 0);
@@ -6174,7 +6289,9 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
6174
6289
  const lines = [header, `Sorted by ${sort}`, ""];
6175
6290
  const shown = filtered.slice(0, limit);
6176
6291
  for (const message of shown) {
6177
- lines.push(` ${message.ref} (${formatTokens2(message.tokens)}) ${message.tool}`);
6292
+ lines.push(
6293
+ ` ${message.ref} (${formatTokens2(message.tokens)}) ${message.tool}`
6294
+ );
6178
6295
  }
6179
6296
  if (filtered.length > shown.length) {
6180
6297
  lines.push("");
@@ -6185,12 +6302,16 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
6185
6302
  function renderCompressedDrilldown(blocks, state, sort, limit, countTokens, meta) {
6186
6303
  let sorted = [...blocks];
6187
6304
  if (sort === "time") sorted.sort((a, b) => a.createdAt - b.createdAt);
6188
- else if (sort === "age") sorted.sort((a, b) => b.survivedCount - a.survivedCount);
6305
+ else if (sort === "age")
6306
+ sorted.sort((a, b) => b.survivedCount - a.survivedCount);
6189
6307
  else
6190
6308
  sorted.sort(
6191
6309
  (a, b) => effectiveCompressedTokens(b, state, countTokens) - effectiveCompressedTokens(a, state, countTokens) || b.createdAt - a.createdAt
6192
6310
  );
6193
- const totalSummary = sorted.reduce((s, b) => s + summaryTokensOf(b, countTokens), 0);
6311
+ const totalSummary = sorted.reduce(
6312
+ (s, b) => s + summaryTokensOf(b, countTokens),
6313
+ 0
6314
+ );
6194
6315
  const totalEffective = sorted.reduce(
6195
6316
  (s, b) => s + effectiveCompressedTokens(b, state, countTokens),
6196
6317
  0
@@ -6636,7 +6757,9 @@ function formatCacheReportSummary(report) {
6636
6757
  });
6637
6758
  const last = report.lines.length - 1;
6638
6759
  if (!shownIdx.includes(last)) shownIdx.push(last);
6639
- const kept = shownIdx.slice(Math.max(0, shownIdx.length - SUMMARY_ANOMALY_CAP));
6760
+ const kept = shownIdx.slice(
6761
+ Math.max(0, shownIdx.length - SUMMARY_ANOMALY_CAP)
6762
+ );
6640
6763
  const anomalies = kept.filter((i) => {
6641
6764
  const l = report.lines[i];
6642
6765
  if (!l) return false;
@@ -6695,10 +6818,14 @@ function renderMessage2(m) {
6695
6818
  parts.push(m.text ?? "");
6696
6819
  break;
6697
6820
  case "tool-call":
6698
- parts.push(`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` args: ${m.text ?? ""}`);
6821
+ parts.push(
6822
+ `\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` args: ${m.text ?? ""}`
6823
+ );
6699
6824
  break;
6700
6825
  case "tool-result":
6701
- parts.push(`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` \u2192 ${m.text ?? ""}`);
6826
+ parts.push(
6827
+ `\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` \u2192 ${m.text ?? ""}`
6828
+ );
6702
6829
  break;
6703
6830
  case "reasoning":
6704
6831
  parts.push(`_reasoning_: ${m.text ?? ""}`);
@@ -6716,12 +6843,17 @@ function renderHandoff(input) {
6716
6843
  if (meta.label) lines.push(`- label: ${meta.label}`);
6717
6844
  lines.push(`- session id: ${meta.sessionId}`);
6718
6845
  for (const bullet of meta.extraBullets ?? []) lines.push(bullet);
6719
- if (meta.contextTokens) lines.push(`- last context tokens: ~${meta.contextTokens}`);
6720
- lines.push(`- compression blocks: ${state.blocks.length} (active ${state.blocks.filter((b) => b.active).length})`);
6846
+ if (meta.contextTokens)
6847
+ lines.push(`- last context tokens: ~${meta.contextTokens}`);
6848
+ lines.push(
6849
+ `- compression blocks: ${state.blocks.length} (active ${state.blocks.filter((b) => b.active).length})`
6850
+ );
6721
6851
  lines.push("");
6722
6852
  const folded = input.folded === true;
6723
6853
  const view = full || folded ? coreMessages : prune(coreMessages, state);
6724
- lines.push(full && !folded ? `## Full conversation (${coreMessages.length} messages)` : folded ? `## Conversation (persisted folded snapshot, ${coreMessages.length} messages)` : `## Conversation (folded view as the model saw it, ${coreMessages.length} client messages)`);
6854
+ lines.push(
6855
+ full && !folded ? `## Full conversation (${coreMessages.length} messages)` : folded ? `## Conversation (persisted folded snapshot, ${coreMessages.length} messages)` : `## Conversation (folded view as the model saw it, ${coreMessages.length} client messages)`
6856
+ );
6725
6857
  lines.push("");
6726
6858
  if (view.length === 0) {
6727
6859
  lines.push("No conversation messages to export.");
@@ -6754,7 +6886,9 @@ function matchSession(sessions, selector, labelOf) {
6754
6886
  if (exact.length > 0) return exact;
6755
6887
  const byLabel = sessions.filter((s) => labelOf(s) === selector);
6756
6888
  if (byLabel.length > 0) return byLabel;
6757
- return sessions.filter((s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector));
6889
+ return sessions.filter(
6890
+ (s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector)
6891
+ );
6758
6892
  }
6759
6893
 
6760
6894
  // src/rules.ts
@@ -6865,7 +6999,10 @@ var DEFAULT_IMAGE_COMPRESSION_CONFIG = {
6865
6999
  format: "webp"
6866
7000
  };
6867
7001
  function resolveImageCompressionConfig(config) {
6868
- return { ...DEFAULT_IMAGE_COMPRESSION_CONFIG, ...config.imageCompression ?? {} };
7002
+ return {
7003
+ ...DEFAULT_IMAGE_COMPRESSION_CONFIG,
7004
+ ...config.imageCompression ?? {}
7005
+ };
6869
7006
  }
6870
7007
  var PIXEL_IMAGE_FALLBACK_TOKENS = 16384;
6871
7008
  var TILE_EDGE = 512;
@@ -6959,10 +7096,14 @@ var HEADER_SCAN_CHARS = 64;
6959
7096
  var JPEG_SCAN_CHARS = 35e4;
6960
7097
  function parseImageDimensionsFromBase64(b64) {
6961
7098
  if (typeof b64 !== "string" || b64.length === 0) return void 0;
6962
- const head = parseImageDimensions(Buffer.from(b64.slice(0, HEADER_SCAN_CHARS), "base64"));
7099
+ const head = parseImageDimensions(
7100
+ Buffer.from(b64.slice(0, HEADER_SCAN_CHARS), "base64")
7101
+ );
6963
7102
  if (head) return head;
6964
7103
  if (b64.startsWith("/9j/") && b64.length > HEADER_SCAN_CHARS) {
6965
- return parseImageDimensions(Buffer.from(b64.slice(0, JPEG_SCAN_CHARS), "base64"));
7104
+ return parseImageDimensions(
7105
+ Buffer.from(b64.slice(0, JPEG_SCAN_CHARS), "base64")
7106
+ );
6966
7107
  }
6967
7108
  return void 0;
6968
7109
  }
@@ -7020,7 +7161,8 @@ var DEFAULT_SCREENSHOT_CLASSIFIER = createHeuristicClassifier();
7020
7161
  function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFIER) {
7021
7162
  const cfg = resolveImageCompressionConfig(config);
7022
7163
  const estimatedTokens = estimateImageTokens(meta);
7023
- if (!cfg.enabled) return { action: "pass", reason: "disabled", estimatedTokens };
7164
+ if (!cfg.enabled)
7165
+ return { action: "pass", reason: "disabled", estimatedTokens };
7024
7166
  if (!meta.mediaType.startsWith("image/")) {
7025
7167
  return { action: "pass", reason: "not-an-image", estimatedTokens };
7026
7168
  }
@@ -7034,7 +7176,11 @@ function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFI
7034
7176
  action: "downsample",
7035
7177
  reason: "downsample",
7036
7178
  estimatedTokens,
7037
- recipe: { maxDimension: cfg.maxDimension, quality: cfg.quality, format: cfg.format }
7179
+ recipe: {
7180
+ maxDimension: cfg.maxDimension,
7181
+ quality: cfg.quality,
7182
+ format: cfg.format
7183
+ }
7038
7184
  };
7039
7185
  }
7040
7186
  var IMAGE_FULL_FAILURE_MARKER = "[image_full FAILED:";
@@ -7046,7 +7192,8 @@ function parseImageFullInput(input, callId, onWarn) {
7046
7192
  if (typeof input === "string") {
7047
7193
  try {
7048
7194
  const parsed = JSON.parse(input);
7049
- if (parsed && typeof parsed === "object") obj = parsed;
7195
+ if (parsed && typeof parsed === "object")
7196
+ obj = parsed;
7050
7197
  } catch {
7051
7198
  obj = null;
7052
7199
  }
@@ -7054,7 +7201,9 @@ function parseImageFullInput(input, callId, onWarn) {
7054
7201
  obj = input;
7055
7202
  }
7056
7203
  if (!obj) {
7057
- onWarn?.(`[acp-image-full-input] rejected: not an object (${typeof input})`);
7204
+ onWarn?.(
7205
+ `[acp-image-full-input] rejected: not an object (${typeof input})`
7206
+ );
7058
7207
  return null;
7059
7208
  }
7060
7209
  let ref;
@@ -7147,7 +7296,11 @@ function resetImageFullState(state) {
7147
7296
  // src/parse-compress-input.ts
7148
7297
  function parseCompressArgs(input, opts) {
7149
7298
  const callId = opts?.callId;
7150
- const diag = { ok: false, kind: "ok", invalidItems: 0 };
7299
+ const diag = {
7300
+ ok: false,
7301
+ kind: "ok",
7302
+ invalidItems: 0
7303
+ };
7151
7304
  if (input === null || input === void 0) {
7152
7305
  diag.kind = "empty-input";
7153
7306
  return finish([], diag);
@@ -7169,7 +7322,11 @@ function parseStringInput(raw, callId, diag) {
7169
7322
  if (first.ranges.length === 0 || first.diagnostics.invalidItems > 0) {
7170
7323
  const normalized = normalizeSingleQuotes(cleaned);
7171
7324
  if (normalized !== void 0) {
7172
- const retryDiag = { ok: false, kind: "ok", invalidItems: 0 };
7325
+ const retryDiag = {
7326
+ ok: false,
7327
+ kind: "ok",
7328
+ invalidItems: 0
7329
+ };
7173
7330
  retryDiag.rawPrefix = diag.rawPrefix;
7174
7331
  retryDiag.length = diag.length;
7175
7332
  const retry = parseStringCore(normalized, callId, retryDiag);
@@ -7246,7 +7403,8 @@ function parseObjectValue(value, callId, diag) {
7246
7403
  if (topTopic !== void 0 || hasTopMaxChars) {
7247
7404
  for (const r of ranges) {
7248
7405
  if (r.topic === void 0 && topTopic !== void 0) r.topic = topTopic;
7249
- if (r.summaryMaxChars === void 0 && hasTopMaxChars) r.summaryMaxChars = topMaxChars;
7406
+ if (r.summaryMaxChars === void 0 && hasTopMaxChars)
7407
+ r.summaryMaxChars = topMaxChars;
7250
7408
  }
7251
7409
  }
7252
7410
  diag.invalidItems = invalid;
@@ -7261,7 +7419,8 @@ function parseContentArray(s) {
7261
7419
  const normalized = normalizeSingleQuotes(cleaned);
7262
7420
  if (normalized !== void 0) {
7263
7421
  const retry = parseContentArrayCore(normalized);
7264
- if (retry !== null && retry.entries.length > 0) return { ...retry, quoteRepaired: true };
7422
+ if (retry !== null && retry.entries.length > 0)
7423
+ return { ...retry, quoteRepaired: true };
7265
7424
  }
7266
7425
  return direct;
7267
7426
  }
@@ -7348,12 +7507,14 @@ function parseLineEntry(entry, callId) {
7348
7507
  afterRefs = pair.index + pair[0].length;
7349
7508
  } else {
7350
7509
  const single = SINGLE_REF_IN_LINE.exec(head);
7351
- if (single === null) return { reason: "line entry: no mNNNNN/bN refs in header" };
7510
+ if (single === null)
7511
+ return { reason: "line entry: no mNNNNN/bN refs in header" };
7352
7512
  startRef = normalizeLineRef(single[1]);
7353
7513
  endRef = startRef;
7354
7514
  afterRefs = single.index + single[0].length;
7355
7515
  }
7356
- if (summary.length === 0) return { reason: "line entry: missing summary after the refs header line" };
7516
+ if (summary.length === 0)
7517
+ return { reason: "line entry: missing summary after the refs header line" };
7357
7518
  const explicitTopic = head.slice(afterRefs).trim();
7358
7519
  const range = {
7359
7520
  startRef,
@@ -7372,7 +7533,11 @@ function deriveTopicFromSummary(summary) {
7372
7533
  return text.length > 60 ? clampPrefix(text, 60).trimEnd() : text;
7373
7534
  }
7374
7535
  function splitLineEntries(content) {
7375
- const parts = content.split(/\n(?=\s*(?:["']\s*,\s*)?["']?\s*[mb]\d{1,7}\s*(?:[-\u2013\u2014\u2026~]|\.\.\.|to)\s*[mb]\d{1,7}\b)/i).map((p) => p.trim().replace(/^(?:["']\s*,?\s*)+/, "").replace(/["']\s*$/, "")).filter((p) => p.length > 0);
7536
+ const parts = content.split(
7537
+ /\n(?=\s*(?:["']\s*,\s*)?["']?\s*[mb]\d{1,7}\s*(?:[-\u2013\u2014\u2026~]|\.\.\.|to)\s*[mb]\d{1,7}\b)/i
7538
+ ).map(
7539
+ (p) => p.trim().replace(/^(?:["']\s*,?\s*)+/, "").replace(/["']\s*$/, "")
7540
+ ).filter((p) => p.length > 0);
7376
7541
  return parts.length > 0 ? parts : [content.trim()];
7377
7542
  }
7378
7543
  function stripJsonWrapperResidue(s) {
@@ -7385,12 +7550,15 @@ function stripJsonWrapperResidue(s) {
7385
7550
  }
7386
7551
  function validateEntry(entry, callId) {
7387
7552
  if (typeof entry === "string") return parseLineEntry(entry, callId);
7388
- if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return { reason: "not an object" };
7553
+ if (entry === null || typeof entry !== "object" || Array.isArray(entry))
7554
+ return { reason: "not an object" };
7389
7555
  const e = entry;
7390
7556
  const start = stringOr(e["startRef"]) ?? stringOr(e["startId"]) ?? stringOr(e["messageId"]);
7391
7557
  const end = stringOr(e["endRef"]) ?? stringOr(e["endId"]) ?? stringOr(e["messageId"]);
7392
7558
  if (start === void 0 || end === void 0) {
7393
- return { reason: "missing range bounds (need startRef/startId and endRef/endId)" };
7559
+ return {
7560
+ reason: "missing range bounds (need startRef/startId and endRef/endId)"
7561
+ };
7394
7562
  }
7395
7563
  const summary = stringOr(e["summary"]);
7396
7564
  if (summary === void 0) return { reason: "missing summary" };
@@ -7398,7 +7566,8 @@ function validateEntry(entry, callId) {
7398
7566
  const topic = stringOr(e["topic"]);
7399
7567
  if (topic !== void 0) range.topic = topic;
7400
7568
  const maxChars = e["summaryMaxChars"];
7401
- if (typeof maxChars === "number" && Number.isFinite(maxChars)) range.summaryMaxChars = maxChars;
7569
+ if (typeof maxChars === "number" && Number.isFinite(maxChars))
7570
+ range.summaryMaxChars = maxChars;
7402
7571
  if (callId !== void 0) range.compressCallId = callId;
7403
7572
  return { range };
7404
7573
  }
@@ -7435,7 +7604,8 @@ function tryParseLenient(s) {
7435
7604
  return void 0;
7436
7605
  }
7437
7606
  function normalizeSingleQuotes(raw) {
7438
- if (!raw.includes("'") || !raw.includes("{") && !raw.includes("[")) return void 0;
7607
+ if (!raw.includes("'") || !raw.includes("{") && !raw.includes("["))
7608
+ return void 0;
7439
7609
  let out = "";
7440
7610
  let changed = false;
7441
7611
  let inDouble = false;
@@ -7527,8 +7697,10 @@ function stripTrailingCommas(s) {
7527
7697
  }
7528
7698
  if (ch === ",") {
7529
7699
  let j = i + 1;
7530
- while (j < s.length && (s.charAt(j) === " " || s.charAt(j) === " " || s.charAt(j) === "\n" || s.charAt(j) === "\r")) j++;
7531
- if (j < s.length && (s.charAt(j) === "}" || s.charAt(j) === "]")) continue;
7700
+ while (j < s.length && (s.charAt(j) === " " || s.charAt(j) === " " || s.charAt(j) === "\n" || s.charAt(j) === "\r"))
7701
+ j++;
7702
+ if (j < s.length && (s.charAt(j) === "}" || s.charAt(j) === "]"))
7703
+ continue;
7532
7704
  }
7533
7705
  out += ch;
7534
7706
  }
@@ -7593,7 +7765,8 @@ function repairAtParserPositions(s) {
7593
7765
  if (ch === "\n") esc = "\\n";
7594
7766
  else if (ch === "\r") esc = "\\r";
7595
7767
  else if (ch === " ") esc = "\\t";
7596
- else if (ch.charCodeAt(0) < 32) esc = "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0");
7768
+ else if (ch.charCodeAt(0) < 32)
7769
+ esc = "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0");
7597
7770
  if (esc === void 0) return cur;
7598
7771
  cur = cur.slice(0, pos) + esc + cur.slice(pos + 1);
7599
7772
  } else if (/Bad escaped character/i.test(msg)) {
@@ -7669,7 +7842,9 @@ function salvageContentEntries(raw) {
7669
7842
 
7670
7843
  // src/rebuild.ts
7671
7844
  function rebuildCompressionState(state, messages, config, ports = {}) {
7672
- const core = createCore({ countTokens: ports.countTokens ?? defaultCountTokens });
7845
+ const core = createCore({
7846
+ countTokens: ports.countTokens ?? defaultCountTokens
7847
+ });
7673
7848
  const refResult = assignRefs(messages, {
7674
7849
  existing: state.messageRefs,
7675
7850
  nextIndex: highestUsedIndex(state.messageRefs) + 1,
@@ -7679,9 +7854,16 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
7679
7854
  const invocations = collectCompressInvocations(messages);
7680
7855
  let blocksRebuilt = 0;
7681
7856
  for (const invocation of invocations) {
7682
- const { ranges } = parseCompressArgs(invocation.raw, { callId: invocation.callId });
7857
+ const { ranges } = parseCompressArgs(invocation.raw, {
7858
+ callId: invocation.callId
7859
+ });
7683
7860
  if (ranges.length === 0) continue;
7684
- const result = core.applyCompression({ ranges, messages, state: working, config });
7861
+ const result = core.applyCompression({
7862
+ ranges,
7863
+ messages,
7864
+ state: working,
7865
+ config
7866
+ });
7685
7867
  working = result.state;
7686
7868
  blocksRebuilt += result.result.blocksCreated;
7687
7869
  }
@@ -7690,7 +7872,8 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
7690
7872
  function collectCompressInvocations(messages) {
7691
7873
  const invocations = [];
7692
7874
  for (const message of messages) {
7693
- if (message.toolName !== "compress" || message.contentType !== "tool-call") continue;
7875
+ if (message.toolName !== "compress" || message.contentType !== "tool-call")
7876
+ continue;
7694
7877
  invocations.push({ callId: message.toolCallId, raw: message.text ?? "" });
7695
7878
  }
7696
7879
  return invocations;
@@ -7706,7 +7889,8 @@ function stem(word) {
7706
7889
  let w = word;
7707
7890
  if (w.length <= 3) return w;
7708
7891
  if (w.endsWith("ies")) w = w.slice(0, -3) + "y";
7709
- else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes")) w = w.slice(0, -2);
7892
+ else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes"))
7893
+ w = w.slice(0, -2);
7710
7894
  else if (w.endsWith("ches") || w.endsWith("shes")) w = w.slice(0, -2);
7711
7895
  else if (w.endsWith("s") && !w.endsWith("ss")) w = w.slice(0, -1);
7712
7896
  if (w.endsWith("ing") && w.length > 5) w = w.slice(0, -3);
@@ -7883,7 +8067,8 @@ var fuzzyAlgorithm = {
7883
8067
  description: "Character bigram overlap. Typo-tolerant, script-agnostic, high recall.",
7884
8068
  score(docs, query) {
7885
8069
  const qTokens = query.toLowerCase().split(/[\s,]+/).filter((t) => t.length >= 4 || t.length >= 2 && CJK.test(t));
7886
- if (qTokens.length === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
8070
+ if (qTokens.length === 0)
8071
+ return docs.map((d) => ({ ref: d.ref, score: 0 }));
7887
8072
  const qGrams = /* @__PURE__ */ new Set();
7888
8073
  for (const t of qTokens) for (const g of charBigrams(t)) qGrams.add(g);
7889
8074
  if (qGrams.size === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
@@ -8004,7 +8189,9 @@ function runSearch(docs, query, options) {
8004
8189
  }).filter((r) => r !== null && r.score >= minScore).sort((a, b) => b.score - a.score).slice(0, limit);
8005
8190
  };
8006
8191
  if (scoredOrPromise instanceof Promise) {
8007
- return scoredOrPromise.then((raw) => buildResults(applyRoleWeight(raw, docs, rw)));
8192
+ return scoredOrPromise.then(
8193
+ (raw) => buildResults(applyRoleWeight(raw, docs, rw))
8194
+ );
8008
8195
  }
8009
8196
  return buildResults(applyRoleWeight(scoredOrPromise, docs, rw));
8010
8197
  }