acp-kernel 0.0.94-pr.438.290 → 0.0.94

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 (72) hide show
  1. package/DESIGN.md +137 -158
  2. package/PROVENANCE.md +40 -44
  3. package/README.md +30 -43
  4. package/dist/cache-report.d.ts.map +1 -1
  5. package/dist/{chunk-WR7OPWNT.js → chunk-NUQZKPQS.js} +3 -7
  6. package/dist/chunk-NUQZKPQS.js.map +1 -0
  7. package/dist/compress-tools.d.ts.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/decompress.d.ts.map +1 -1
  10. package/dist/filter/apply.d.ts.map +1 -1
  11. package/dist/filter/index.d.ts +1 -1
  12. package/dist/filter/index.d.ts.map +1 -1
  13. package/dist/filter/types.d.ts.map +1 -1
  14. package/dist/handoff.d.ts.map +1 -1
  15. package/dist/hide-consumed.d.ts.map +1 -1
  16. package/dist/image-compress.d.ts.map +1 -1
  17. package/dist/index.js +75 -254
  18. package/dist/index.js.map +1 -1
  19. package/dist/message-kind.d.ts.map +1 -1
  20. package/dist/nudge-text.d.ts.map +1 -1
  21. package/dist/packs.d.ts.map +1 -1
  22. package/dist/panel/cache.d.ts.map +1 -1
  23. package/dist/panel/index.js +10 -29
  24. package/dist/panel/index.js.map +1 -1
  25. package/dist/panel/panel.d.ts.map +1 -1
  26. package/dist/panel/topic.d.ts.map +1 -1
  27. package/dist/parse-compress-input.d.ts.map +1 -1
  28. package/dist/persist/index.d.ts +1 -1
  29. package/dist/persist/index.d.ts.map +1 -1
  30. package/dist/persist/index.js +12 -49
  31. package/dist/persist/index.js.map +1 -1
  32. package/dist/persist/state-merge.d.ts.map +1 -1
  33. package/dist/persist/store.d.ts.map +1 -1
  34. package/dist/protected.d.ts.map +1 -1
  35. package/dist/rebuild.d.ts.map +1 -1
  36. package/dist/recommend.d.ts.map +1 -1
  37. package/dist/render-refs.d.ts.map +1 -1
  38. package/dist/report.d.ts.map +1 -1
  39. package/dist/search/algorithms/bm25.d.ts.map +1 -1
  40. package/dist/search/algorithms/fuzzy.d.ts.map +1 -1
  41. package/dist/search/algorithms/hybrid.d.ts.map +1 -1
  42. package/dist/search/algorithms/semantic.d.ts.map +1 -1
  43. package/dist/search/algorithms/substring.d.ts.map +1 -1
  44. package/dist/search/doc-cache.d.ts.map +1 -1
  45. package/dist/search/index.d.ts +1 -1
  46. package/dist/search/index.d.ts.map +1 -1
  47. package/dist/search/registry.d.ts.map +1 -1
  48. package/dist/search/stemmer.d.ts.map +1 -1
  49. package/dist/search/tokenizer.d.ts.map +1 -1
  50. package/dist/search/types.d.ts.map +1 -1
  51. package/dist/search.d.ts +3 -3
  52. package/dist/search.d.ts.map +1 -1
  53. package/dist/surface-config.d.ts.map +1 -1
  54. package/dist/tool-pairs.d.ts.map +1 -1
  55. package/dist/truncate-tools.d.ts.map +1 -1
  56. package/dist/truncate.d.ts.map +1 -1
  57. package/dist/turn-integrity.d.ts.map +1 -1
  58. package/dist/wire/anthropic.d.ts.map +1 -1
  59. package/dist/wire/bili-message.d.ts.map +1 -1
  60. package/dist/wire/compress-detect.d.ts.map +1 -1
  61. package/dist/wire/demoted-thinking.d.ts.map +1 -1
  62. package/dist/wire/formats.d.ts.map +1 -1
  63. package/dist/wire/index.js +97 -403
  64. package/dist/wire/index.js.map +1 -1
  65. package/dist/wire/message-id.d.ts.map +1 -1
  66. package/dist/wire/mirror.d.ts.map +1 -1
  67. package/dist/wire/openai.d.ts.map +1 -1
  68. package/dist/wire/responses.d.ts.map +1 -1
  69. package/dist/wire/strip-images.d.ts.map +1 -1
  70. package/dist/wire/util.d.ts.map +1 -1
  71. package/package.json +66 -66
  72. package/dist/chunk-WR7OPWNT.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-WR7OPWNT.js";
19
+ } from "./chunk-NUQZKPQS.js";
20
20
  import {
21
21
  activeBlocks,
22
22
  advanceSurvival,
@@ -549,13 +549,10 @@ function cloneWithDescriptions(schema, overrides) {
549
549
  return cloneNode(schema, overrides);
550
550
  }
551
551
  function cloneNode(node, overrides) {
552
- if (Array.isArray(node))
553
- return node.map((item) => cloneNode(item, overrides));
552
+ if (Array.isArray(node)) return node.map((item) => cloneNode(item, overrides));
554
553
  if (node && typeof node === "object") {
555
554
  const out = {};
556
- for (const [name, value] of Object.entries(
557
- node
558
- )) {
555
+ for (const [name, value] of Object.entries(node)) {
559
556
  const cloned = cloneNode(value, overrides);
560
557
  if (Object.hasOwn(overrides, name) && cloned && typeof cloned === "object" && !Array.isArray(cloned)) {
561
558
  cloned.description = overrides[name];
@@ -592,9 +589,7 @@ function applyAcpToolOverrides(tools, overrides) {
592
589
  return {
593
590
  ...tool,
594
591
  ...ov.description !== void 0 ? { description: ov.description } : {},
595
- ...ov.paramDescriptions ? hasInputSchema ? {
596
- input_schema: cloneWithDescriptions(schema, ov.paramDescriptions)
597
- } : { parameters: cloneWithDescriptions(schema, ov.paramDescriptions) } : {}
592
+ ...ov.paramDescriptions ? hasInputSchema ? { input_schema: cloneWithDescriptions(schema, ov.paramDescriptions) } : { parameters: cloneWithDescriptions(schema, ov.paramDescriptions) } : {}
598
593
  };
599
594
  });
600
595
  }
@@ -1208,9 +1203,7 @@ function isNeverPreserveRecent(msg, patterns, preservePatterns) {
1208
1203
  }
1209
1204
  if (!msg.toolName) return false;
1210
1205
  const base = patterns === void 0 ? NEVER_PRESERVE_RECENT_TOOLS : patterns;
1211
- const list = preservePatterns === void 0 || preservePatterns.length === 0 ? base : base.filter(
1212
- (tool) => !preservePatterns.some((p) => matchToolPattern(tool, p))
1213
- );
1206
+ const list = preservePatterns === void 0 || preservePatterns.length === 0 ? base : base.filter((tool) => !preservePatterns.some((p) => matchToolPattern(tool, p)));
1214
1207
  for (const pattern of list) {
1215
1208
  if (matchToolPattern(msg.toolName, pattern)) return true;
1216
1209
  }
@@ -1278,8 +1271,7 @@ function isMessageLatestProtected(msg, latest) {
1278
1271
  }
1279
1272
  function hasMediaPayload(msg) {
1280
1273
  const m = msg;
1281
- if (typeof m.imageBase64 === "string" && m.imageBase64.length > 0)
1282
- return true;
1274
+ if (typeof m.imageBase64 === "string" && m.imageBase64.length > 0) return true;
1283
1275
  if (m.rawOpenaiContent != null) return true;
1284
1276
  if (Array.isArray(m.rawOpenaiContentParts) && m.rawOpenaiContentParts.length > 0)
1285
1277
  return true;
@@ -1287,8 +1279,7 @@ function hasMediaPayload(msg) {
1287
1279
  if (isObjWith(ab, "type", "image")) return true;
1288
1280
  if (isObjWith(ab, "type", "tool_result")) {
1289
1281
  const content = ab.content;
1290
- if (Array.isArray(content))
1291
- return content.some((p) => !isObjWith(p, "type", "text"));
1282
+ if (Array.isArray(content)) return content.some((p) => !isObjWith(p, "type", "text"));
1292
1283
  }
1293
1284
  const item = m.rawResponsesItem;
1294
1285
  if (isObjWith(item, "type", "input_image")) return true;
@@ -1910,9 +1901,7 @@ function findBlocksOverlappingMessages(state, messageIds) {
1910
1901
  matched.push(block);
1911
1902
  }
1912
1903
  }
1913
- return matched.sort(
1914
- (a, b) => numericPart(a.blockId) - numericPart(b.blockId)
1915
- );
1904
+ return matched.sort((a, b) => numericPart(a.blockId) - numericPart(b.blockId));
1916
1905
  }
1917
1906
  function findActiveAncestor(state, blockId) {
1918
1907
  const start = state.blocks.find((b) => b.blockId === blockId);
@@ -2114,11 +2103,7 @@ function truncateLargeToolOutputs(messages, tokenCount, config, countTokens, opt
2114
2103
  continue;
2115
2104
  }
2116
2105
  const prefix = clampPrefix(original, opts.keepPrefixChars);
2117
- const suffix = clampWindow(
2118
- original,
2119
- original.length - opts.keepSuffixChars,
2120
- original.length
2121
- );
2106
+ const suffix = clampWindow(original, original.length - opts.keepSuffixChars, original.length);
2122
2107
  const replacement = `${prefix}
2123
2108
 
2124
2109
  ...${TRUNCATION_MARKER} \u2014 original ~${tokens} tokens]...
@@ -2196,12 +2181,8 @@ var SUMMARY_STUB_CHARS = 200;
2196
2181
  function compactEntry(entry) {
2197
2182
  if (!entry || typeof entry !== "object") return entry;
2198
2183
  const e = entry;
2199
- if (typeof e.summary !== "string" || e.summary.length <= SUMMARY_STUB_CHARS)
2200
- return entry;
2201
- return {
2202
- ...e,
2203
- summary: `${clampPrefix(e.summary, SUMMARY_STUB_CHARS - 1)}\u2026`
2204
- };
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` };
2205
2186
  }
2206
2187
  function serializeCompacted(obj, content, contentWasString) {
2207
2188
  let changed = false;
@@ -2217,11 +2198,7 @@ function compactCompressText(text) {
2217
2198
  const parsed = parseCallText(text);
2218
2199
  if (!parsed) return null;
2219
2200
  const { prefix, obj, content, contentWasString } = parsed;
2220
- const { text: out, changed } = serializeCompacted(
2221
- obj,
2222
- content,
2223
- contentWasString
2224
- );
2201
+ const { text: out, changed } = serializeCompacted(obj, content, contentWasString);
2225
2202
  return changed ? prefix + out : null;
2226
2203
  }
2227
2204
  function hideConsumedCompressCalls(state, messages) {
@@ -2248,8 +2225,7 @@ function hideConsumedCompressCalls(state, messages) {
2248
2225
  const lastOrphanedCallIds = [];
2249
2226
  for (let i = messages.length - 1; i >= 0 && lastOrphanedCallIds.length < KEEP_LAST_ORPHANED; i--) {
2250
2227
  const message = messages[i];
2251
- if (message.toolName !== "compress" || message.contentType !== "tool-call")
2252
- continue;
2228
+ if (message.toolName !== "compress" || message.contentType !== "tool-call") continue;
2253
2229
  const callId = message.toolCallId;
2254
2230
  if (callId && !allBlockCallIds.has(callId)) {
2255
2231
  lastOrphanedCallIds.push(callId);
@@ -4234,11 +4210,9 @@ function estimateTextTokens(text) {
4234
4210
  return Math.ceil(text.length / 4);
4235
4211
  }
4236
4212
  function isSyntheticOrPruned(message, state) {
4237
- if (message.text?.startsWith("[Compressed conversation section]"))
4238
- return true;
4213
+ if (message.text?.startsWith("[Compressed conversation section]")) return true;
4239
4214
  for (const block of state.blocks) {
4240
- if (block.active && block.effectiveMessageIds.includes(message.id))
4241
- return true;
4215
+ if (block.active && block.effectiveMessageIds.includes(message.id)) return true;
4242
4216
  }
4243
4217
  return false;
4244
4218
  }
@@ -4249,12 +4223,7 @@ function computeProtectedRefs(messages, state, config, countTokens = estimateTex
4249
4223
  const visible = [];
4250
4224
  for (const msg of messages) {
4251
4225
  if (isSyntheticOrPruned(msg, state)) continue;
4252
- if (isNeverPreserveRecent(
4253
- msg,
4254
- config.neverPreserveRecentTools,
4255
- config.preserveRecentTools
4256
- ))
4257
- continue;
4226
+ if (isNeverPreserveRecent(msg, config.neverPreserveRecentTools, config.preserveRecentTools)) continue;
4258
4227
  const ref = state.messageRefs.byRaw[msg.id];
4259
4228
  if (!ref || ref === "BLOCKED") continue;
4260
4229
  visible.push({ ref, tokens: countMessageTokens(msg, countTokens) });
@@ -4380,9 +4349,7 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
4380
4349
  cur.chars = (cur.chars ?? 0) + info.chars;
4381
4350
  if (info.isUser) cur.userMsgs = (cur.userMsgs ?? 0) + 1;
4382
4351
  if (info.isTool) {
4383
- cur.toolPct = Math.round(
4384
- (cur.toolPct * (cur.count - 1) + 100) / cur.count
4385
- );
4352
+ cur.toolPct = Math.round((cur.toolPct * (cur.count - 1) + 100) / cur.count);
4386
4353
  } else {
4387
4354
  cur.toolPct = Math.round(cur.toolPct * (cur.count - 1) / cur.count);
4388
4355
  }
@@ -5754,26 +5721,9 @@ function countOccurrences(haystack, needle) {
5754
5721
  // src/packs.ts
5755
5722
  import { readFileSync, readdirSync } from "fs";
5756
5723
  import * as path from "path";
5757
- var PROMPT_RULE_KEYS = [
5758
- "compressPhilosophy",
5759
- "howToCompressRules",
5760
- "tier2DistillRules",
5761
- "tier3CondenseRules"
5762
- ];
5763
- var COMPRESS_SECTION_KEYS = [
5764
- "acpTags",
5765
- "tools",
5766
- "summariesInContext",
5767
- "textProtocol",
5768
- "textTools",
5769
- "functionTools"
5770
- ];
5771
- var NUDGE_SECTION_KEYS = [
5772
- "efficiencyNote",
5773
- "emergencyHeader",
5774
- "t2Guidance",
5775
- "t3Guidance"
5776
- ];
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"];
5777
5727
  function isValidPackName(name) {
5778
5728
  return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) && !name.includes("..");
5779
5729
  }
@@ -5807,9 +5757,7 @@ function sanitizePackSurface(raw) {
5807
5757
  if (typeof ov.description === "string") out.description = ov.description;
5808
5758
  if (ov.paramDescriptions && typeof ov.paramDescriptions === "object" && !Array.isArray(ov.paramDescriptions)) {
5809
5759
  const params = {};
5810
- for (const [p, d] of Object.entries(
5811
- ov.paramDescriptions
5812
- )) {
5760
+ for (const [p, d] of Object.entries(ov.paramDescriptions)) {
5813
5761
  if (typeof d === "string") params[p] = d;
5814
5762
  }
5815
5763
  if (Object.keys(params).length > 0) out.paramDescriptions = params;
@@ -6008,11 +5956,8 @@ function createPackResolver(sources) {
6008
5956
  };
6009
5957
  }
6010
5958
  function defaultPackSources(opts) {
6011
- const sources = [
6012
- createDirPackSource("project", opts.projectDir)
6013
- ];
6014
- for (const dir of opts.userDirs ?? [])
6015
- sources.push(createDirPackSource("user", dir));
5959
+ const sources = [createDirPackSource("project", opts.projectDir)];
5960
+ for (const dir of opts.userDirs ?? []) sources.push(createDirPackSource("user", dir));
6016
5961
  sources.push(builtinSource);
6017
5962
  return sources;
6018
5963
  }
@@ -6050,10 +5995,7 @@ function tierBreakdown(blocks, countTokens) {
6050
5995
  if (tiers.length <= 1) return null;
6051
5996
  const parts = [];
6052
5997
  for (const tier of [1, 2, 3]) {
6053
- if (tierTokens[tier])
6054
- parts.push(
6055
- `T${tier}: ${formatTokens2(tierTokens[tier])} (${tierCounts[tier]} blocks)`
6056
- );
5998
+ if (tierTokens[tier]) parts.push(`T${tier}: ${formatTokens2(tierTokens[tier])} (${tierCounts[tier]} blocks)`);
6057
5999
  }
6058
6000
  return parts.join(" | ");
6059
6001
  }
@@ -6093,43 +6035,21 @@ function buildStatusReport(state, messages, countTokens, options = {}) {
6093
6035
  const limit = options.limit ?? 30;
6094
6036
  const activeBlocks2 = state.blocks.filter((b) => b.active).sort((a, b) => numericPart2(a.blockId) - numericPart2(b.blockId));
6095
6037
  if (scope === "compressed") {
6096
- return renderCompressedDrilldown(
6097
- activeBlocks2,
6098
- state,
6099
- sort,
6100
- limit,
6101
- countTokens,
6102
- options.meta
6103
- );
6038
+ return renderCompressedDrilldown(activeBlocks2, state, sort, limit, countTokens, options.meta);
6104
6039
  }
6105
- const { visible, summaryTokens } = collectVisible(
6106
- messages,
6107
- state,
6108
- countTokens
6109
- );
6040
+ const { visible, summaryTokens } = collectVisible(messages, state, countTokens);
6110
6041
  if (scope === "uncompressed") {
6111
6042
  if (view === "messages") {
6112
6043
  return renderMessageDrilldown(visible, toolFilter, sort, limit);
6113
6044
  }
6114
6045
  return renderUncompressedRanges(visible);
6115
6046
  }
6116
- return renderOverview(
6117
- visible,
6118
- summaryTokens,
6119
- activeBlocks2,
6120
- state,
6121
- countTokens,
6122
- limit,
6123
- options.meta
6124
- );
6047
+ return renderOverview(visible, summaryTokens, activeBlocks2, state, countTokens, limit, options.meta);
6125
6048
  }
6126
6049
  function surfaceLine(meta) {
6127
6050
  if (!meta) return null;
6128
6051
  const parts = [];
6129
- if (meta.pack)
6130
- parts.push(
6131
- `pack=${meta.pack}${meta.packVersion ? ` v${meta.packVersion}` : ""}`
6132
- );
6052
+ if (meta.pack) parts.push(`pack=${meta.pack}${meta.packVersion ? ` v${meta.packVersion}` : ""}`);
6133
6053
  if (meta.host) parts.push(`host=${meta.host}`);
6134
6054
  if (parts.length === 0) return null;
6135
6055
  return `ACTIVE SURFACE: ${parts.join(" | ")}`;
@@ -6143,14 +6063,9 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
6143
6063
  }
6144
6064
  const toolTypeMap = /* @__PURE__ */ new Map();
6145
6065
  for (const message of visible) {
6146
- toolTypeMap.set(
6147
- message.tool,
6148
- (toolTypeMap.get(message.tool) ?? 0) + message.tokens
6149
- );
6066
+ toolTypeMap.set(message.tool, (toolTypeMap.get(message.tool) ?? 0) + message.tokens);
6150
6067
  }
6151
- const topTool = [...toolTypeMap.entries()].sort(
6152
- (a, b) => b[1] - a[1]
6153
- )[0]?.[0];
6068
+ const topTool = [...toolTypeMap.entries()].sort((a, b) => b[1] - a[1])[0]?.[0];
6154
6069
  const totalTool = visible.filter((m) => m.isTool).reduce((sum, m) => sum + m.tokens, 0);
6155
6070
  const totalText = visible.filter((m) => !m.isTool).reduce((sum, m) => sum + m.tokens, 0);
6156
6071
  const total = summaryTokens + totalTool + totalText;
@@ -6160,19 +6075,14 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
6160
6075
  );
6161
6076
  const topTypes = [...toolTypeMap.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3);
6162
6077
  if (topTypes.length > 0) {
6163
- lines.push(
6164
- ` Top tools: ${topTypes.map(([t, n]) => `${t} (${pct(n, total)}%)`).join(", ")}`
6165
- );
6078
+ lines.push(` Top tools: ${topTypes.map(([t, n]) => `${t} (${pct(n, total)}%)`).join(", ")}`);
6166
6079
  }
6167
6080
  lines.push("");
6168
6081
  if (blocks.length === 0) {
6169
6082
  lines.push("COMPRESSED BLOCKS");
6170
6083
  lines.push(" No compressed blocks.");
6171
6084
  } else {
6172
- const totalSummary = blocks.reduce(
6173
- (s, b) => s + summaryTokensOf(b, countTokens),
6174
- 0
6175
- );
6085
+ const totalSummary = blocks.reduce((s, b) => s + summaryTokensOf(b, countTokens), 0);
6176
6086
  const totalEffective = blocks.reduce(
6177
6087
  (s, b) => s + effectiveCompressedTokens(b, state, countTokens),
6178
6088
  0
@@ -6208,9 +6118,7 @@ function renderOverview(visible, summaryTokens, blocks, state, countTokens, limi
6208
6118
  function renderUncompressedRanges(visible) {
6209
6119
  const lines = [];
6210
6120
  const totalTokens = visible.reduce((s, m) => s + m.tokens, 0);
6211
- lines.push(
6212
- `UNCOMPRESSED \u2014 ${formatTokens2(totalTokens)} | ${visible.length} visible messages`
6213
- );
6121
+ lines.push(`UNCOMPRESSED \u2014 ${formatTokens2(totalTokens)} | ${visible.length} visible messages`);
6214
6122
  lines.push("");
6215
6123
  if (visible.length === 0) {
6216
6124
  lines.push(" (no uncompressed messages)");
@@ -6239,27 +6147,15 @@ function renderUncompressedRanges(visible) {
6239
6147
  last.endRef = m.ref;
6240
6148
  last.count += 1;
6241
6149
  last.tokens += m.tokens;
6242
- last.toolTokens.set(
6243
- m.tool,
6244
- (last.toolTokens.get(m.tool) ?? 0) + m.tokens
6245
- );
6150
+ last.toolTokens.set(m.tool, (last.toolTokens.get(m.tool) ?? 0) + m.tokens);
6246
6151
  } else {
6247
6152
  const toolTokens = /* @__PURE__ */ new Map([[m.tool, m.tokens]]);
6248
- merged.push({
6249
- startRef: m.ref,
6250
- endRef: m.ref,
6251
- startNum: num,
6252
- count: 1,
6253
- tokens: m.tokens,
6254
- toolTokens
6255
- });
6153
+ merged.push({ startRef: m.ref, endRef: m.ref, startNum: num, count: 1, tokens: m.tokens, toolTokens });
6256
6154
  }
6257
6155
  }
6258
6156
  for (const r of merged.slice(0, 30)) {
6259
6157
  const range = r.count === 1 ? r.startRef : `${r.startRef}\u2013${r.endRef}`;
6260
- lines.push(
6261
- ` ${range} (${r.count} msgs, ${formatTokens2(r.tokens)}${r.count > 1 ? ` (${Math.round(r.tokens / r.count)}/msg)` : ""}) ${dominantTool(r.toolTokens)}`
6262
- );
6158
+ lines.push(` ${range} (${r.count} msgs, ${formatTokens2(r.tokens)}${r.count > 1 ? ` (${Math.round(r.tokens / r.count)}/msg)` : ""}) ${dominantTool(r.toolTokens)}`);
6263
6159
  }
6264
6160
  if (merged.length > 30) {
6265
6161
  lines.push(` ... and ${merged.length - 30} more ranges`);
@@ -6270,10 +6166,7 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
6270
6166
  let filtered = visible;
6271
6167
  if (toolFilter) filtered = filtered.filter((m) => m.tool === toolFilter);
6272
6168
  if (sort === "time") filtered.sort((a, b) => a.index - b.index);
6273
- else if (sort === "tool")
6274
- filtered.sort(
6275
- (a, b) => a.tool.localeCompare(b.tool) || b.tokens - a.tokens
6276
- );
6169
+ else if (sort === "tool") filtered.sort((a, b) => a.tool.localeCompare(b.tool) || b.tokens - a.tokens);
6277
6170
  else filtered.sort((a, b) => b.tokens - a.tokens);
6278
6171
  const totalTokens = filtered.reduce((s, m) => s + m.tokens, 0);
6279
6172
  const allTokens = visible.reduce((s, m) => s + m.tokens, 0);
@@ -6281,9 +6174,7 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
6281
6174
  const lines = [header, `Sorted by ${sort}`, ""];
6282
6175
  const shown = filtered.slice(0, limit);
6283
6176
  for (const message of shown) {
6284
- lines.push(
6285
- ` ${message.ref} (${formatTokens2(message.tokens)}) ${message.tool}`
6286
- );
6177
+ lines.push(` ${message.ref} (${formatTokens2(message.tokens)}) ${message.tool}`);
6287
6178
  }
6288
6179
  if (filtered.length > shown.length) {
6289
6180
  lines.push("");
@@ -6294,16 +6185,12 @@ function renderMessageDrilldown(visible, toolFilter, sort, limit) {
6294
6185
  function renderCompressedDrilldown(blocks, state, sort, limit, countTokens, meta) {
6295
6186
  let sorted = [...blocks];
6296
6187
  if (sort === "time") sorted.sort((a, b) => a.createdAt - b.createdAt);
6297
- else if (sort === "age")
6298
- sorted.sort((a, b) => b.survivedCount - a.survivedCount);
6188
+ else if (sort === "age") sorted.sort((a, b) => b.survivedCount - a.survivedCount);
6299
6189
  else
6300
6190
  sorted.sort(
6301
6191
  (a, b) => effectiveCompressedTokens(b, state, countTokens) - effectiveCompressedTokens(a, state, countTokens) || b.createdAt - a.createdAt
6302
6192
  );
6303
- const totalSummary = sorted.reduce(
6304
- (s, b) => s + summaryTokensOf(b, countTokens),
6305
- 0
6306
- );
6193
+ const totalSummary = sorted.reduce((s, b) => s + summaryTokensOf(b, countTokens), 0);
6307
6194
  const totalEffective = sorted.reduce(
6308
6195
  (s, b) => s + effectiveCompressedTokens(b, state, countTokens),
6309
6196
  0
@@ -6749,9 +6636,7 @@ function formatCacheReportSummary(report) {
6749
6636
  });
6750
6637
  const last = report.lines.length - 1;
6751
6638
  if (!shownIdx.includes(last)) shownIdx.push(last);
6752
- const kept = shownIdx.slice(
6753
- Math.max(0, shownIdx.length - SUMMARY_ANOMALY_CAP)
6754
- );
6639
+ const kept = shownIdx.slice(Math.max(0, shownIdx.length - SUMMARY_ANOMALY_CAP));
6755
6640
  const anomalies = kept.filter((i) => {
6756
6641
  const l = report.lines[i];
6757
6642
  if (!l) return false;
@@ -6810,14 +6695,10 @@ function renderMessage2(m) {
6810
6695
  parts.push(m.text ?? "");
6811
6696
  break;
6812
6697
  case "tool-call":
6813
- parts.push(
6814
- `\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` args: ${m.text ?? ""}`
6815
- );
6698
+ parts.push(`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` args: ${m.text ?? ""}`);
6816
6699
  break;
6817
6700
  case "tool-result":
6818
- parts.push(
6819
- `\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` \u2192 ${m.text ?? ""}`
6820
- );
6701
+ parts.push(`\`${m.toolName ?? "?"}(${m.toolCallId ?? ""})\` \u2192 ${m.text ?? ""}`);
6821
6702
  break;
6822
6703
  case "reasoning":
6823
6704
  parts.push(`_reasoning_: ${m.text ?? ""}`);
@@ -6835,17 +6716,12 @@ function renderHandoff(input) {
6835
6716
  if (meta.label) lines.push(`- label: ${meta.label}`);
6836
6717
  lines.push(`- session id: ${meta.sessionId}`);
6837
6718
  for (const bullet of meta.extraBullets ?? []) lines.push(bullet);
6838
- if (meta.contextTokens)
6839
- lines.push(`- last context tokens: ~${meta.contextTokens}`);
6840
- lines.push(
6841
- `- compression blocks: ${state.blocks.length} (active ${state.blocks.filter((b) => b.active).length})`
6842
- );
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})`);
6843
6721
  lines.push("");
6844
6722
  const folded = input.folded === true;
6845
6723
  const view = full || folded ? coreMessages : prune(coreMessages, state);
6846
- lines.push(
6847
- 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)`
6848
- );
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)`);
6849
6725
  lines.push("");
6850
6726
  if (view.length === 0) {
6851
6727
  lines.push("No conversation messages to export.");
@@ -6878,9 +6754,7 @@ function matchSession(sessions, selector, labelOf) {
6878
6754
  if (exact.length > 0) return exact;
6879
6755
  const byLabel = sessions.filter((s) => labelOf(s) === selector);
6880
6756
  if (byLabel.length > 0) return byLabel;
6881
- return sessions.filter(
6882
- (s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector)
6883
- );
6757
+ return sessions.filter((s) => s.id.startsWith(selector) || (labelOf(s) ?? "").startsWith(selector));
6884
6758
  }
6885
6759
 
6886
6760
  // src/rules.ts
@@ -6991,10 +6865,7 @@ var DEFAULT_IMAGE_COMPRESSION_CONFIG = {
6991
6865
  format: "webp"
6992
6866
  };
6993
6867
  function resolveImageCompressionConfig(config) {
6994
- return {
6995
- ...DEFAULT_IMAGE_COMPRESSION_CONFIG,
6996
- ...config.imageCompression ?? {}
6997
- };
6868
+ return { ...DEFAULT_IMAGE_COMPRESSION_CONFIG, ...config.imageCompression ?? {} };
6998
6869
  }
6999
6870
  var PIXEL_IMAGE_FALLBACK_TOKENS = 16384;
7000
6871
  var TILE_EDGE = 512;
@@ -7088,14 +6959,10 @@ var HEADER_SCAN_CHARS = 64;
7088
6959
  var JPEG_SCAN_CHARS = 35e4;
7089
6960
  function parseImageDimensionsFromBase64(b64) {
7090
6961
  if (typeof b64 !== "string" || b64.length === 0) return void 0;
7091
- const head = parseImageDimensions(
7092
- Buffer.from(b64.slice(0, HEADER_SCAN_CHARS), "base64")
7093
- );
6962
+ const head = parseImageDimensions(Buffer.from(b64.slice(0, HEADER_SCAN_CHARS), "base64"));
7094
6963
  if (head) return head;
7095
6964
  if (b64.startsWith("/9j/") && b64.length > HEADER_SCAN_CHARS) {
7096
- return parseImageDimensions(
7097
- Buffer.from(b64.slice(0, JPEG_SCAN_CHARS), "base64")
7098
- );
6965
+ return parseImageDimensions(Buffer.from(b64.slice(0, JPEG_SCAN_CHARS), "base64"));
7099
6966
  }
7100
6967
  return void 0;
7101
6968
  }
@@ -7153,8 +7020,7 @@ var DEFAULT_SCREENSHOT_CLASSIFIER = createHeuristicClassifier();
7153
7020
  function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFIER) {
7154
7021
  const cfg = resolveImageCompressionConfig(config);
7155
7022
  const estimatedTokens = estimateImageTokens(meta);
7156
- if (!cfg.enabled)
7157
- return { action: "pass", reason: "disabled", estimatedTokens };
7023
+ if (!cfg.enabled) return { action: "pass", reason: "disabled", estimatedTokens };
7158
7024
  if (!meta.mediaType.startsWith("image/")) {
7159
7025
  return { action: "pass", reason: "not-an-image", estimatedTokens };
7160
7026
  }
@@ -7168,11 +7034,7 @@ function decideImageRoute(meta, config, classifier = DEFAULT_SCREENSHOT_CLASSIFI
7168
7034
  action: "downsample",
7169
7035
  reason: "downsample",
7170
7036
  estimatedTokens,
7171
- recipe: {
7172
- maxDimension: cfg.maxDimension,
7173
- quality: cfg.quality,
7174
- format: cfg.format
7175
- }
7037
+ recipe: { maxDimension: cfg.maxDimension, quality: cfg.quality, format: cfg.format }
7176
7038
  };
7177
7039
  }
7178
7040
  var IMAGE_FULL_FAILURE_MARKER = "[image_full FAILED:";
@@ -7184,8 +7046,7 @@ function parseImageFullInput(input, callId, onWarn) {
7184
7046
  if (typeof input === "string") {
7185
7047
  try {
7186
7048
  const parsed = JSON.parse(input);
7187
- if (parsed && typeof parsed === "object")
7188
- obj = parsed;
7049
+ if (parsed && typeof parsed === "object") obj = parsed;
7189
7050
  } catch {
7190
7051
  obj = null;
7191
7052
  }
@@ -7193,9 +7054,7 @@ function parseImageFullInput(input, callId, onWarn) {
7193
7054
  obj = input;
7194
7055
  }
7195
7056
  if (!obj) {
7196
- onWarn?.(
7197
- `[acp-image-full-input] rejected: not an object (${typeof input})`
7198
- );
7057
+ onWarn?.(`[acp-image-full-input] rejected: not an object (${typeof input})`);
7199
7058
  return null;
7200
7059
  }
7201
7060
  let ref;
@@ -7288,11 +7147,7 @@ function resetImageFullState(state) {
7288
7147
  // src/parse-compress-input.ts
7289
7148
  function parseCompressArgs(input, opts) {
7290
7149
  const callId = opts?.callId;
7291
- const diag = {
7292
- ok: false,
7293
- kind: "ok",
7294
- invalidItems: 0
7295
- };
7150
+ const diag = { ok: false, kind: "ok", invalidItems: 0 };
7296
7151
  if (input === null || input === void 0) {
7297
7152
  diag.kind = "empty-input";
7298
7153
  return finish([], diag);
@@ -7314,11 +7169,7 @@ function parseStringInput(raw, callId, diag) {
7314
7169
  if (first.ranges.length === 0 || first.diagnostics.invalidItems > 0) {
7315
7170
  const normalized = normalizeSingleQuotes(cleaned);
7316
7171
  if (normalized !== void 0) {
7317
- const retryDiag = {
7318
- ok: false,
7319
- kind: "ok",
7320
- invalidItems: 0
7321
- };
7172
+ const retryDiag = { ok: false, kind: "ok", invalidItems: 0 };
7322
7173
  retryDiag.rawPrefix = diag.rawPrefix;
7323
7174
  retryDiag.length = diag.length;
7324
7175
  const retry = parseStringCore(normalized, callId, retryDiag);
@@ -7395,8 +7246,7 @@ function parseObjectValue(value, callId, diag) {
7395
7246
  if (topTopic !== void 0 || hasTopMaxChars) {
7396
7247
  for (const r of ranges) {
7397
7248
  if (r.topic === void 0 && topTopic !== void 0) r.topic = topTopic;
7398
- if (r.summaryMaxChars === void 0 && hasTopMaxChars)
7399
- r.summaryMaxChars = topMaxChars;
7249
+ if (r.summaryMaxChars === void 0 && hasTopMaxChars) r.summaryMaxChars = topMaxChars;
7400
7250
  }
7401
7251
  }
7402
7252
  diag.invalidItems = invalid;
@@ -7411,8 +7261,7 @@ function parseContentArray(s) {
7411
7261
  const normalized = normalizeSingleQuotes(cleaned);
7412
7262
  if (normalized !== void 0) {
7413
7263
  const retry = parseContentArrayCore(normalized);
7414
- if (retry !== null && retry.entries.length > 0)
7415
- return { ...retry, quoteRepaired: true };
7264
+ if (retry !== null && retry.entries.length > 0) return { ...retry, quoteRepaired: true };
7416
7265
  }
7417
7266
  return direct;
7418
7267
  }
@@ -7499,14 +7348,12 @@ function parseLineEntry(entry, callId) {
7499
7348
  afterRefs = pair.index + pair[0].length;
7500
7349
  } else {
7501
7350
  const single = SINGLE_REF_IN_LINE.exec(head);
7502
- if (single === null)
7503
- return { reason: "line entry: no mNNNNN/bN refs in header" };
7351
+ if (single === null) return { reason: "line entry: no mNNNNN/bN refs in header" };
7504
7352
  startRef = normalizeLineRef(single[1]);
7505
7353
  endRef = startRef;
7506
7354
  afterRefs = single.index + single[0].length;
7507
7355
  }
7508
- if (summary.length === 0)
7509
- return { reason: "line entry: missing summary after the refs header line" };
7356
+ if (summary.length === 0) return { reason: "line entry: missing summary after the refs header line" };
7510
7357
  const explicitTopic = head.slice(afterRefs).trim();
7511
7358
  const range = {
7512
7359
  startRef,
@@ -7525,11 +7372,7 @@ function deriveTopicFromSummary(summary) {
7525
7372
  return text.length > 60 ? clampPrefix(text, 60).trimEnd() : text;
7526
7373
  }
7527
7374
  function splitLineEntries(content) {
7528
- const parts = content.split(
7529
- /\n(?=\s*(?:["']\s*,\s*)?["']?\s*[mb]\d{1,7}\s*(?:[-\u2013\u2014\u2026~]|\.\.\.|to)\s*[mb]\d{1,7}\b)/i
7530
- ).map(
7531
- (p) => p.trim().replace(/^(?:["']\s*,?\s*)+/, "").replace(/["']\s*$/, "")
7532
- ).filter((p) => p.length > 0);
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);
7533
7376
  return parts.length > 0 ? parts : [content.trim()];
7534
7377
  }
7535
7378
  function stripJsonWrapperResidue(s) {
@@ -7542,15 +7385,12 @@ function stripJsonWrapperResidue(s) {
7542
7385
  }
7543
7386
  function validateEntry(entry, callId) {
7544
7387
  if (typeof entry === "string") return parseLineEntry(entry, callId);
7545
- if (entry === null || typeof entry !== "object" || Array.isArray(entry))
7546
- return { reason: "not an object" };
7388
+ if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return { reason: "not an object" };
7547
7389
  const e = entry;
7548
7390
  const start = stringOr(e["startRef"]) ?? stringOr(e["startId"]) ?? stringOr(e["messageId"]);
7549
7391
  const end = stringOr(e["endRef"]) ?? stringOr(e["endId"]) ?? stringOr(e["messageId"]);
7550
7392
  if (start === void 0 || end === void 0) {
7551
- return {
7552
- reason: "missing range bounds (need startRef/startId and endRef/endId)"
7553
- };
7393
+ return { reason: "missing range bounds (need startRef/startId and endRef/endId)" };
7554
7394
  }
7555
7395
  const summary = stringOr(e["summary"]);
7556
7396
  if (summary === void 0) return { reason: "missing summary" };
@@ -7558,8 +7398,7 @@ function validateEntry(entry, callId) {
7558
7398
  const topic = stringOr(e["topic"]);
7559
7399
  if (topic !== void 0) range.topic = topic;
7560
7400
  const maxChars = e["summaryMaxChars"];
7561
- if (typeof maxChars === "number" && Number.isFinite(maxChars))
7562
- range.summaryMaxChars = maxChars;
7401
+ if (typeof maxChars === "number" && Number.isFinite(maxChars)) range.summaryMaxChars = maxChars;
7563
7402
  if (callId !== void 0) range.compressCallId = callId;
7564
7403
  return { range };
7565
7404
  }
@@ -7596,8 +7435,7 @@ function tryParseLenient(s) {
7596
7435
  return void 0;
7597
7436
  }
7598
7437
  function normalizeSingleQuotes(raw) {
7599
- if (!raw.includes("'") || !raw.includes("{") && !raw.includes("["))
7600
- return void 0;
7438
+ if (!raw.includes("'") || !raw.includes("{") && !raw.includes("[")) return void 0;
7601
7439
  let out = "";
7602
7440
  let changed = false;
7603
7441
  let inDouble = false;
@@ -7689,10 +7527,8 @@ function stripTrailingCommas(s) {
7689
7527
  }
7690
7528
  if (ch === ",") {
7691
7529
  let j = i + 1;
7692
- while (j < s.length && (s.charAt(j) === " " || s.charAt(j) === " " || s.charAt(j) === "\n" || s.charAt(j) === "\r"))
7693
- j++;
7694
- if (j < s.length && (s.charAt(j) === "}" || s.charAt(j) === "]"))
7695
- continue;
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;
7696
7532
  }
7697
7533
  out += ch;
7698
7534
  }
@@ -7757,8 +7593,7 @@ function repairAtParserPositions(s) {
7757
7593
  if (ch === "\n") esc = "\\n";
7758
7594
  else if (ch === "\r") esc = "\\r";
7759
7595
  else if (ch === " ") esc = "\\t";
7760
- else if (ch.charCodeAt(0) < 32)
7761
- esc = "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0");
7596
+ else if (ch.charCodeAt(0) < 32) esc = "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0");
7762
7597
  if (esc === void 0) return cur;
7763
7598
  cur = cur.slice(0, pos) + esc + cur.slice(pos + 1);
7764
7599
  } else if (/Bad escaped character/i.test(msg)) {
@@ -7834,9 +7669,7 @@ function salvageContentEntries(raw) {
7834
7669
 
7835
7670
  // src/rebuild.ts
7836
7671
  function rebuildCompressionState(state, messages, config, ports = {}) {
7837
- const core = createCore({
7838
- countTokens: ports.countTokens ?? defaultCountTokens
7839
- });
7672
+ const core = createCore({ countTokens: ports.countTokens ?? defaultCountTokens });
7840
7673
  const refResult = assignRefs(messages, {
7841
7674
  existing: state.messageRefs,
7842
7675
  nextIndex: highestUsedIndex(state.messageRefs) + 1,
@@ -7846,16 +7679,9 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
7846
7679
  const invocations = collectCompressInvocations(messages);
7847
7680
  let blocksRebuilt = 0;
7848
7681
  for (const invocation of invocations) {
7849
- const { ranges } = parseCompressArgs(invocation.raw, {
7850
- callId: invocation.callId
7851
- });
7682
+ const { ranges } = parseCompressArgs(invocation.raw, { callId: invocation.callId });
7852
7683
  if (ranges.length === 0) continue;
7853
- const result = core.applyCompression({
7854
- ranges,
7855
- messages,
7856
- state: working,
7857
- config
7858
- });
7684
+ const result = core.applyCompression({ ranges, messages, state: working, config });
7859
7685
  working = result.state;
7860
7686
  blocksRebuilt += result.result.blocksCreated;
7861
7687
  }
@@ -7864,8 +7690,7 @@ function rebuildCompressionState(state, messages, config, ports = {}) {
7864
7690
  function collectCompressInvocations(messages) {
7865
7691
  const invocations = [];
7866
7692
  for (const message of messages) {
7867
- if (message.toolName !== "compress" || message.contentType !== "tool-call")
7868
- continue;
7693
+ if (message.toolName !== "compress" || message.contentType !== "tool-call") continue;
7869
7694
  invocations.push({ callId: message.toolCallId, raw: message.text ?? "" });
7870
7695
  }
7871
7696
  return invocations;
@@ -7881,8 +7706,7 @@ function stem(word) {
7881
7706
  let w = word;
7882
7707
  if (w.length <= 3) return w;
7883
7708
  if (w.endsWith("ies")) w = w.slice(0, -3) + "y";
7884
- else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes"))
7885
- w = w.slice(0, -2);
7709
+ else if (w.endsWith("ses") || w.endsWith("xes") || w.endsWith("zes")) w = w.slice(0, -2);
7886
7710
  else if (w.endsWith("ches") || w.endsWith("shes")) w = w.slice(0, -2);
7887
7711
  else if (w.endsWith("s") && !w.endsWith("ss")) w = w.slice(0, -1);
7888
7712
  if (w.endsWith("ing") && w.length > 5) w = w.slice(0, -3);
@@ -8059,8 +7883,7 @@ var fuzzyAlgorithm = {
8059
7883
  description: "Character bigram overlap. Typo-tolerant, script-agnostic, high recall.",
8060
7884
  score(docs, query) {
8061
7885
  const qTokens = query.toLowerCase().split(/[\s,]+/).filter((t) => t.length >= 4 || t.length >= 2 && CJK.test(t));
8062
- if (qTokens.length === 0)
8063
- return docs.map((d) => ({ ref: d.ref, score: 0 }));
7886
+ if (qTokens.length === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
8064
7887
  const qGrams = /* @__PURE__ */ new Set();
8065
7888
  for (const t of qTokens) for (const g of charBigrams(t)) qGrams.add(g);
8066
7889
  if (qGrams.size === 0) return docs.map((d) => ({ ref: d.ref, score: 0 }));
@@ -8181,9 +8004,7 @@ function runSearch(docs, query, options) {
8181
8004
  }).filter((r) => r !== null && r.score >= minScore).sort((a, b) => b.score - a.score).slice(0, limit);
8182
8005
  };
8183
8006
  if (scoredOrPromise instanceof Promise) {
8184
- return scoredOrPromise.then(
8185
- (raw) => buildResults(applyRoleWeight(raw, docs, rw))
8186
- );
8007
+ return scoredOrPromise.then((raw) => buildResults(applyRoleWeight(raw, docs, rw)));
8187
8008
  }
8188
8009
  return buildResults(applyRoleWeight(scoredOrPromise, docs, rw));
8189
8010
  }