acp-kernel 0.0.94 → 0.0.95-pr.235.306

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 (84) hide show
  1. package/DESIGN.md +158 -137
  2. package/PROVENANCE.md +44 -40
  3. package/README.md +45 -32
  4. package/dist/boundaries.d.ts +3 -3
  5. package/dist/boundaries.d.ts.map +1 -1
  6. package/dist/cache-report.d.ts.map +1 -1
  7. package/dist/ccr.d.ts.map +1 -1
  8. package/dist/{chunk-NUQZKPQS.js → chunk-TQ6I62XC.js} +13 -6
  9. package/dist/chunk-TQ6I62XC.js.map +1 -0
  10. package/dist/compress-tools.d.ts +282 -254
  11. package/dist/compress-tools.d.ts.map +1 -1
  12. package/dist/compress.d.ts.map +1 -1
  13. package/dist/compression-rules.d.ts +9 -3
  14. package/dist/compression-rules.d.ts.map +1 -1
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/decompress.d.ts.map +1 -1
  17. package/dist/filter/apply.d.ts.map +1 -1
  18. package/dist/filter/index.d.ts +1 -1
  19. package/dist/filter/index.d.ts.map +1 -1
  20. package/dist/filter/types.d.ts.map +1 -1
  21. package/dist/handoff.d.ts.map +1 -1
  22. package/dist/hide-consumed.d.ts.map +1 -1
  23. package/dist/image-compress.d.ts.map +1 -1
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +477 -193
  27. package/dist/index.js.map +1 -1
  28. package/dist/message-kind.d.ts.map +1 -1
  29. package/dist/nudge-text.d.ts.map +1 -1
  30. package/dist/packs.d.ts +1 -1
  31. package/dist/packs.d.ts.map +1 -1
  32. package/dist/panel/cache.d.ts.map +1 -1
  33. package/dist/panel/index.js +29 -10
  34. package/dist/panel/index.js.map +1 -1
  35. package/dist/panel/panel.d.ts.map +1 -1
  36. package/dist/panel/topic.d.ts.map +1 -1
  37. package/dist/parse-compress-input.d.ts.map +1 -1
  38. package/dist/persist/index.d.ts +1 -1
  39. package/dist/persist/index.d.ts.map +1 -1
  40. package/dist/persist/index.js +49 -12
  41. package/dist/persist/index.js.map +1 -1
  42. package/dist/persist/state-merge.d.ts.map +1 -1
  43. package/dist/persist/store.d.ts.map +1 -1
  44. package/dist/protected.d.ts.map +1 -1
  45. package/dist/rebuild.d.ts.map +1 -1
  46. package/dist/recommend.d.ts.map +1 -1
  47. package/dist/render-refs.d.ts.map +1 -1
  48. package/dist/report.d.ts.map +1 -1
  49. package/dist/search/algorithms/bm25.d.ts.map +1 -1
  50. package/dist/search/algorithms/fuzzy.d.ts.map +1 -1
  51. package/dist/search/algorithms/hybrid.d.ts.map +1 -1
  52. package/dist/search/algorithms/semantic.d.ts.map +1 -1
  53. package/dist/search/algorithms/substring.d.ts.map +1 -1
  54. package/dist/search/doc-cache.d.ts.map +1 -1
  55. package/dist/search/index.d.ts +1 -1
  56. package/dist/search/index.d.ts.map +1 -1
  57. package/dist/search/registry.d.ts.map +1 -1
  58. package/dist/search/stemmer.d.ts.map +1 -1
  59. package/dist/search/tokenizer.d.ts.map +1 -1
  60. package/dist/search/types.d.ts.map +1 -1
  61. package/dist/search.d.ts +3 -3
  62. package/dist/search.d.ts.map +1 -1
  63. package/dist/segment.d.ts +33 -0
  64. package/dist/segment.d.ts.map +1 -0
  65. package/dist/surface-config.d.ts.map +1 -1
  66. package/dist/tool-pairs.d.ts.map +1 -1
  67. package/dist/truncate-tools.d.ts.map +1 -1
  68. package/dist/truncate.d.ts.map +1 -1
  69. package/dist/turn-integrity.d.ts.map +1 -1
  70. package/dist/wire/anthropic.d.ts.map +1 -1
  71. package/dist/wire/bili-message.d.ts.map +1 -1
  72. package/dist/wire/compress-detect.d.ts.map +1 -1
  73. package/dist/wire/demoted-thinking.d.ts.map +1 -1
  74. package/dist/wire/formats.d.ts.map +1 -1
  75. package/dist/wire/index.js +476 -129
  76. package/dist/wire/index.js.map +1 -1
  77. package/dist/wire/message-id.d.ts.map +1 -1
  78. package/dist/wire/mirror.d.ts.map +1 -1
  79. package/dist/wire/openai.d.ts.map +1 -1
  80. package/dist/wire/responses.d.ts.map +1 -1
  81. package/dist/wire/strip-images.d.ts.map +1 -1
  82. package/dist/wire/util.d.ts.map +1 -1
  83. package/package.json +66 -66
  84. package/dist/chunk-NUQZKPQS.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"message-kind.d.ts","sourceRoot":"","sources":["../src/message-kind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAE3D"}
1
+ {"version":3,"file":"message-kind.d.ts","sourceRoot":"","sources":["../src/message-kind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAI3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"nudge-text.d.ts","sourceRoot":"","sources":["../src/nudge-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAiD,MAAM,YAAY,CAAC;AAElI,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAwDD,wBAAgB,YAAY,CAAC,YAAY,EAAE,iBAAiB,EAAE,EAAE,eAAe,EAAE,cAAc,EAAE,GAAG,MAAM,CAgFzG;AAiBD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,GAAE,OAAwB,EAAE,QAAQ,GAAE,mBAAwB,GAAG,aAAa,CAyE7I"}
1
+ {"version":3,"file":"nudge-text.d.ts","sourceRoot":"","sources":["../src/nudge-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EAIf,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AA8DD,wBAAgB,YAAY,CAC1B,YAAY,EAAE,iBAAiB,EAAE,EACjC,eAAe,EAAE,cAAc,EAAE,GAChC,MAAM,CAsHR;AAoBD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,OAAwB,EACjC,QAAQ,GAAE,mBAAwB,GACjC,aAAa,CA6Ef"}
package/dist/packs.d.ts CHANGED
@@ -64,7 +64,7 @@ export declare const defaultPack: Pack;
64
64
  * reply as sent, then pattern-completed the list into a fabricated user turn.
65
65
  * Summaries are the only record; this contract is the floor that keeps them honest.
66
66
  */
67
- export declare const LEAN_HOW_TO_COMPRESS = "HOW TO COMPRESS\n\nYour summary is the ONLY record of the replaced conversation \u2014 a later reader must continue without the original. It records the PAST: label task state as history (\"TASK AS OF THIS BLOCK: ...\"), never as a live instruction. Real unicode only, never \\uXXXX escapes.\n\nINTEGRITY \u2014 record facts and state only, never a simulated transcript of the dialogue: no Q&A lists, no \"(answered)\" claims. An answer not actually sent is PENDING; user questions are recorded as asked (with ref), never as answered.\n\nKEEP VERBATIM \u2014 never paraphrase or abbreviate:\n- File paths with line numbers and directory prefix on every mention (lib/hooks.ts:347); never a bare filename \u2014 ambiguous, un-greppable.\n- Function/class/type signatures AND the critical code lines that encode logic (the line that IS the finding).\n- Error messages and stack traces (exact text \u2014 needed to grep later).\n- Report details: comparison numbers plus mechanism, not \"X is worse\" (\"1.76\u00D7 PPL gap because KV store is static\").\n- Decisions with rationale (\"chose X over Y because Z\"); discovered constraints (\"must support Node 22\").\n- Exact values: versions, config keys, thresholds, magic numbers.\n- User intent: short quotes verbatim ONLY WITH message ref (User said (m00132): \"ship it tonight\"); without a ref, paraphrase. Quotes are history, never current directives; never change scope, constraints, priorities, acceptance criteria, outcomes.\n- Overall goal and its evolution, including pivots (\"initially: fix X \u2192 pivoted to: refactor Y\").\n- Purpose behind significant actions (hypothesis, question, goal \u2014 not just what was done).\n- Open questions and unresolved TODOs.\n- Message refs of key anchors (m00420, m00510\u2013m00520) for decompress.\n\nDROP \u2014 keep the signal, discard the vessel: verbose logs once the error/result is captured; duplicate reads; consumed exploration (search hits, agent returns, successful outputs); dead ends (one lesson line: \"tried X, failed because Y\"); back-and-forth once the final position is kept; repeated status checks. For each dropped item add one line of CONTENT: what it covers (\"probe.py: tests n-gram baseline...\"), not where it lives.\n\nPRIORITY when compacting: 1. user goal/evolution/intent/hard constraints \u00B7 2. decisions + rationale \u00B7 3. exact artifacts (paths, signatures, errors, values) \u00B7 4. conclusions \u00B7 5. lessons learned (what failed and why).\n\nFormat: dense scannable bullets under short thematic headers, not narrative prose; every line earns its place. Do not mimic the style of existing summaries in context; follow these rules.";
67
+ export declare const LEAN_HOW_TO_COMPRESS = "HOW TO COMPRESS\n\nYour summary is the ONLY record of the replaced conversation \u2014 a later reader must continue without the original. It records the PAST: label task state as history (\"TASK AS OF THIS BLOCK: ...\"), never as a live instruction. Real unicode only, never \\uXXXX escapes.\n\nINTEGRITY \u2014 record facts and state only, never a simulated transcript of the dialogue: no Q&A lists, no \"(answered)\" claims. An answer not actually sent is PENDING; user questions are recorded as asked (with ref), never as answered.\n\nKEEP VERBATIM \u2014 never paraphrase or abbreviate:\n- File paths with line numbers and directory prefix on every mention (lib/hooks.ts:347); never a bare filename \u2014 ambiguous, un-greppable.\n- Function/class/type signatures AND the critical code lines that encode logic (the line that IS the finding).\n- Error messages and stack traces (exact text \u2014 needed to grep later).\n- Report details: comparison numbers plus mechanism, not \"X is worse\" (\"1.76\u00D7 PPL gap because KV store is static\").\n- Decisions with rationale (\"chose X over Y because Z\"); discovered constraints (\"must support Node 22\").\n- Exact values: versions, config keys, thresholds, magic numbers.\n- User intent: short quotes verbatim ONLY WITH message ref (User said (m00132): \"ship it tonight\"); without a ref, paraphrase. Quotes are history, not live instructions \u2014 but open-objective STATUS is current (see Open objectives below); never change scope, constraints, priorities, acceptance criteria, outcomes.\n- Overall goal and its evolution, including pivots (\"initially: fix X \u2192 pivoted to: refactor Y\").\n- Purpose behind significant actions (hypothesis, question, goal \u2014 not just what was done).\n- Open questions and unresolved TODOs.\n- Open objectives: user-requested work neither completed nor superseded gets a one-line \"Open objectives:\" entry with message refs; scan absorbed block summaries too. Last to drop, first to restore at every tier \u2014 carrying is not a directive to re-execute unconfirmed.\n- Message refs of key anchors (m00420, m00510\u2013m00520) for decompress.\n\nDROP \u2014 keep the signal, discard the vessel: verbose logs once the error/result is captured; duplicate reads; consumed exploration (search hits, agent returns, successful outputs); dead ends (one lesson line: \"tried X, failed because Y\"); back-and-forth once the final position is kept; repeated status checks. For each dropped item add one line of CONTENT: what it covers (\"probe.py: tests n-gram baseline...\"), not where it lives.\n\nPRIORITY when compacting: 1. user goal/evolution/intent/hard constraints \u00B7 2. decisions + rationale \u00B7 3. exact artifacts (paths, signatures, errors, values) \u00B7 4. conclusions \u00B7 5. lessons learned (what failed and why).\n\nFormat: dense scannable bullets under short thematic headers, not narrative prose; every line earns its place. Do not mimic the style of existing summaries in context; follow these rules.";
68
68
  /** Token-lean surface: one-line tool descriptions, no snippets or guidelines.
69
69
  * Host-specific trims (e.g. the Pi adapter's compact system-prompt block)
70
70
  * ride under `adapters` and are validated by that host. The pi
@@ -1 +1 @@
1
- {"version":3,"file":"packs.d.ts","sourceRoot":"","sources":["../src/packs.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;sEACsE;AACtE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;4EACwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3B,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;oEACoE;AACpE,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;gBAEgB;AAChB,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACnC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACnC,SAAS,IAAI,IAAI,EAAE,CAAC;CACrB;AAMD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAaD;;4EAE4E;AAC5E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,GAAG,WAAW,CAuCvF;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,IAMzB,CAAC;AA0BF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,wnFAuB2J,CAAC;AAE7L;;;;;2CAK2C;AAC3C,eAAO,MAAM,QAAQ,EAAE,IA6CtB,CAAC;AASF,eAAO,MAAM,aAAa,EAAE,UAQ3B,CAAC;AAWF;0EAC0E;AAC1E,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAoCvE;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,YAAY,CAyB/E;AAED;;0BAE0B;AAC1B,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,UAAU,EAAE,CAK3G"}
1
+ {"version":3,"file":"packs.d.ts","sourceRoot":"","sources":["../src/packs.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;sEACsE;AACtE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;4EACwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3B,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;oEACoE;AACpE,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;gBAEgB;AAChB,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACnC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACnC,SAAS,IAAI,IAAI,EAAE,CAAC;CACrB;AAuBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAgBD;;4EAE4E;AAC5E,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,GACrC,WAAW,CAoDb;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,IAMzB,CAAC;AA8BF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,k9FAwB2J,CAAC;AAE7L;;;;;2CAK2C;AAC3C,eAAO,MAAM,QAAQ,EAAE,IA6CtB,CAAC;AASF,eAAO,MAAM,aAAa,EAAE,UAQ3B,CAAC;AAaF;0EAC0E;AAC1E,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAqCvE;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,UAAU,EAAE,GAC7B,YAAY,CAyBd;AAED;;0BAE0B;AAC1B,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,GAAG,UAAU,EAAE,CAQf"}
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/panel/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;kCAOkC;AAElC,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B;6DACyD;IACzD,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;4DACwD;IACxD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAAG,eAAe,CAyBlF;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/panel/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;kCAOkC;AAElC,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B;6DACyD;IACzD,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;4DACwD;IACxD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,oEAAoE;AACpE,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAClC,eAAe,CAyBjB;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD"}
@@ -3,7 +3,7 @@ import {
3
3
  defaultCountTokens,
4
4
  formatRanges,
5
5
  viableRanges
6
- } from "../chunk-NUQZKPQS.js";
6
+ } from "../chunk-TQ6I62XC.js";
7
7
 
8
8
  // src/panel/topic.ts
9
9
  function topicFallback(summary) {
@@ -57,7 +57,10 @@ function formatHitRate(rate) {
57
57
  // src/panel/panel.ts
58
58
  function bar(value, total, width = 20) {
59
59
  if (total === 0) return "";
60
- const filled = Math.max(0, Math.min(width, Math.round(value / total * width)));
60
+ const filled = Math.max(
61
+ 0,
62
+ Math.min(width, Math.round(value / total * width))
63
+ );
61
64
  return "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
62
65
  }
63
66
  function buildStatusPanel(input) {
@@ -80,16 +83,22 @@ function buildStatusPanel(input) {
80
83
  lines.push("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F");
81
84
  if (input.version) lines.push(input.version);
82
85
  lines.push("");
83
- lines.push(`Context (session accounting, host footer scale): ${displayPct}% (${fmt(displayTotal)} / ${fmt(limit)}) \u2014 includes compressed originals; shrinks slower than the sent view`);
86
+ lines.push(
87
+ `Context (session accounting, host footer scale): ${displayPct}% (${fmt(displayTotal)} / ${fmt(limit)}) \u2014 includes compressed originals; shrinks slower than the sent view`
88
+ );
84
89
  if (nudge && bd) {
85
90
  const growth = bd.growth;
86
91
  if (growth > 0 && displayTotal > 0) {
87
92
  lines.push(`Growth: +${fmt(growth)} since last nudge`);
88
93
  }
89
94
  lines.push("");
90
- lines.push(`Sent to LLM (after compression, est.): ${fmt(sentTotal)}${limit > 0 ? ` (${sentPct}% of limit)` : ""}`);
95
+ lines.push(
96
+ `Sent to LLM (after compression, est.): ${fmt(sentTotal)}${limit > 0 ? ` (${sentPct}% of limit)` : ""}`
97
+ );
91
98
  if (input.unprunedTokens !== void 0 && sessionOnly > 0) {
92
- lines.push(`Session-only (compressed originals, est.): ${fmt(sessionOnly)} \u2014 pruned from every request; the footer/nudge still count them`);
99
+ lines.push(
100
+ `Session-only (compressed originals, est.): ${fmt(sessionOnly)} \u2014 pruned from every request; the footer/nudge still count them`
101
+ );
93
102
  }
94
103
  lines.push("");
95
104
  lines.push("Token Breakdown (sent view):");
@@ -104,7 +113,9 @@ function buildStatusPanel(input) {
104
113
  if (cat.value <= 0) continue;
105
114
  const pct = sentTotal > 0 ? Math.round(cat.value / sentTotal * 100) : 0;
106
115
  const b = bar(cat.value, sentTotal);
107
- lines.push(` ${cat.label.padEnd(10)} ${b} ${String(pct).padStart(3)}% ${fmt(cat.value)}`);
116
+ lines.push(
117
+ ` ${cat.label.padEnd(10)} ${b} ${String(pct).padStart(3)}% ${fmt(cat.value)}`
118
+ );
108
119
  }
109
120
  }
110
121
  if (input.cacheUsages) {
@@ -133,22 +144,30 @@ function buildStatusPanel(input) {
133
144
  }
134
145
  if (activeBlocksList.length > 0) {
135
146
  lines.push("");
136
- lines.push(`Blocks: ${activeBlocksList.length} active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`);
147
+ lines.push(
148
+ `Blocks: ${activeBlocksList.length} active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`
149
+ );
137
150
  for (const b of activeBlocksList) {
138
151
  const topic = b.topic ? `: ${b.topic}` : `: ${topicFallback(b.summary || "")}`;
139
152
  const summaryTok = defaultCountTokens(b.summary || "");
140
153
  const origTok = b.compressedTokens > 0 ? b.compressedTokens : summaryTok;
141
- lines.push(` [${b.blockId}] T${b.tier} ${fmt(origTok)}\u2192${fmt(summaryTok)}${topic}`);
154
+ lines.push(
155
+ ` [${b.blockId}] T${b.tier} ${fmt(origTok)}\u2192${fmt(summaryTok)}${topic}`
156
+ );
142
157
  }
143
158
  } else if (totalBlocksList.length > 0) {
144
159
  lines.push("");
145
- lines.push(`Blocks: 0 active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`);
160
+ lines.push(
161
+ `Blocks: 0 active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`
162
+ );
146
163
  } else {
147
164
  lines.push("");
148
165
  lines.push("Blocks: none (nothing compressed yet)");
149
166
  }
150
167
  lines.push("");
151
- lines.push("Tag visibility: tags injected to LLM only (deep copy), not persisted in session, not shown in terminal.");
168
+ lines.push(
169
+ "Tag visibility: tags injected to LLM only (deep copy), not persisted in session, not shown in terminal."
170
+ );
152
171
  return lines.join("\n");
153
172
  }
154
173
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/panel/topic.ts","../../src/panel/format.ts","../../src/panel/cache.ts","../../src/panel/panel.ts"],"sourcesContent":["/** Short topic for a block when the model did not provide one: first sentence\n * segment, leading quotes stripped, truncated to 30 chars with an ellipsis.\n * Used wherever block lists are rendered (panels, search results). */\nimport { clampPrefix } from \"../truncate.js\";\n\nexport function topicFallback(summary: string): string {\n const first = summary.split(/[.\\n]/)[0] ?? \"\";\n const t = first.trim().replace(/^[\"'`]+/, \"\").trim();\n return t.length <= 30 ? t : `${clampPrefix(t, 30).trimEnd()}…`;\n}\n","/** Compact token formatting for user-facing panels: lowercase k/M with the\n * same thresholds as the hosts' footers (<1000 → raw, <10000 → one decimal\n * k, <1e6 → rounded k, <1e7 → one decimal M). */\nexport function formatCompactTokens(count: number): string {\n if (count < 1000) return count.toString();\n if (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n if (count < 1000000) return `${Math.round(count / 1000)}k`;\n if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n return `${Math.round(count / 1000000)}M`;\n}\n","/** Cache hit-rate math for the /acp status panel.\n *\n * Hosts feed per-request prompt-cache usage samples (from assistant\n * messages' provider-reported `usage`); the kernel derives the display\n * numbers. A request COUNTS only when the provider reported cache\n * activity for it (`cacheRead + cacheWrite > 0`): providers without\n * prompt-cache reporting (0/0 with plain `input`) must not drag the\n * average to a fabricated 0%. */\n\nexport interface CacheUsageSample {\n /** Non-cached conversation input tokens billed for the request. */\n input: number;\n /** Conversation tokens served from the prompt cache. */\n cacheRead: number;\n /** Conversation tokens written to the prompt cache (cache creation). */\n cacheWrite: number;\n}\n\nexport interface CacheHitSummary {\n /** Session hit rate (0..1), weighted by billed prompt tokens.\n * Undefined when no request reported cache activity. */\n session: number | undefined;\n /** Hit rate (0..1) of the most recent request that reported cache\n * activity. Undefined when no request reported any. */\n last: number | undefined;\n /** Counted requests (provider reported cache activity). */\n requests: number;\n /** Cumulative tokens served from cache. */\n cacheRead: number;\n /** Cumulative billed prompt tokens (input + cacheRead + cacheWrite). */\n billedPrompt: number;\n}\n\nfunction num(v: unknown): number {\n return typeof v === \"number\" && Number.isFinite(v) && v > 0 ? v : 0;\n}\n\n/** Aggregate per-request cache usage into panel display numbers. */\nexport function cacheHitStats(usages: readonly CacheUsageSample[]): CacheHitSummary {\n let cacheRead = 0;\n let billedPrompt = 0;\n let requests = 0;\n let last: number | undefined;\n for (const u of usages) {\n const read = num(u?.cacheRead);\n const write = num(u?.cacheWrite);\n const input = num(u?.input);\n // No cache signal on this request → excluded entirely (see header).\n if (read + write <= 0) continue;\n const total = read + write + input;\n if (total <= 0) continue;\n cacheRead += read;\n billedPrompt += total;\n requests += 1;\n last = read / total;\n }\n return {\n session: requests > 0 ? cacheRead / billedPrompt : undefined,\n last,\n requests,\n cacheRead,\n billedPrompt,\n };\n}\n\n/** Format a 0..1 rate as a percentage with one decimal (\"92.3%\"). */\nexport function formatHitRate(rate: number): string {\n return `${(Math.max(0, Math.min(1, rate)) * 100).toFixed(1)}%`;\n}\n","import { defaultCountTokens } from \"../tokenize.js\";\nimport { formatRanges } from \"../nudge-text.js\";\nimport type { CompressionState, NudgeDecision } from \"../types.js\";\nimport { formatCompactTokens } from \"./format.js\";\nimport { topicFallback } from \"./topic.js\";\nimport { viableRanges } from \"../viable.js\";\nimport { cacheHitStats, formatHitRate, type CacheUsageSample } from \"./cache.js\";\n\nexport interface StatusPanelInput {\n /** Adapter identifier for the header, e.g. \"billion-context-omp@0.1.6\".\n * Omit to hide the version line. */\n version?: string;\n /** Host session accounting — the SAME number the host footer displays.\n * It includes compressed originals (summaries stay in the window), so it\n * shrinks slower than the sent view when compression prunes the\n * per-request projection. */\n tokenCount: number;\n /** Measured token count of the host system prompt (host-specific to\n * obtain; the kernel breakdown does not see it). */\n systemPromptTokens: number;\n /** Kernel state (blocks drive the Blocks section). */\n state: CompressionState;\n /** The nudge decision from core.processTurn for this turn, if any. The\n * panel applies the viability filter to compressibleRanges itself. */\n nudge: NudgeDecision | undefined;\n /** Configured model context window, in tokens. */\n modelContextLimit: number;\n /** Estimate of the FULL (unpruned) core-message projection, computed\n * with the SAME countTokens the core uses (kernel default = CJK-aware\n * defaultCountTokens) — the same estimation scale as the kernel\n * breakdown. When provided, the panel derives `Session-only` on that\n * scale (unpruned − sent). Without it the line is omitted: subtracting\n * the host's provider-scale number from an estimate-scale number\n * invents a third, meaningless scale (issue #18 \"看板统计的和拆分的有差异\"). */\n unprunedTokens?: number;\n /** Per-request prompt-cache usage (from assistant messages' provider-\n * reported `usage`). Requests without cache reporting are excluded by\n * cacheHitStats; when no counted request remains, the section is\n * omitted entirely. Omit the field to hide the section. */\n cacheUsages?: ReadonlyArray<CacheUsageSample>;\n /** Token formatter override (defaults to formatCompactTokens). */\n fmtTokens?: (n: number) => string;\n}\n\nfunction bar(value: number, total: number, width: number = 20): string {\n if (total === 0) return \"\";\n const filled = Math.max(0, Math.min(width, Math.round((value / total) * width)));\n return \"█\".repeat(filled) + \"░\".repeat(width - filled);\n}\n\n/** Render the /acp status panel. Three token numbers, each labeled with\n * its own scale, never mixed in arithmetic:\n * - Session accounting (host footer scale): the host's reported context\n * size INCLUDING compressed originals (summaries stay in the window), so\n * it shrinks slower than the sent view when compression prunes the\n * per-request projection.\n * - Sent view (estimated, kernel countTokens scale): what actually\n * reaches the LLM after compression (kernel's classification over the\n * pruned projection + measured system prompt). This is the number\n * compression controls.\n * - Session-only (estimated, kernel countTokens scale): unpruned\n * projection − sent view; the compressed originals pruned from every\n * request.\n * Subtracting the host number from an estimate produced numbers that\n * reconciled with neither scale (\"Framework 390K\", \"session-only 29k vs\n * 112k compressed\") — that is what issue #18 reported. */\nexport function buildStatusPanel(input: StatusPanelInput): string {\n const { tokenCount, state, nudge, modelContextLimit } = input;\n const fmt = input.fmtTokens ?? formatCompactTokens;\n const bd = nudge?.contextBreakdown;\n const limit = modelContextLimit;\n const classified = bd ? bd.system + bd.tool + bd.summaries + bd.code + bd.text : 0;\n const systemPromptTokens = input.systemPromptTokens;\n const sentTotal = classified + systemPromptTokens;\n // Same-scale derivation only: both sides use the core's countTokens\n // estimate (kernel default = CJK-aware defaultCountTokens). The host\n // footer's tokenCount (provider-anchored, session-tree) is displayed as\n // its own line and never fed into an arithmetic difference with these.\n const sessionOnly = input.unprunedTokens !== undefined ? Math.max(0, input.unprunedTokens - sentTotal) : 0;\n const displayTotal = tokenCount;\n const displayPct = limit > 0 ? Math.round((displayTotal / limit) * 100) : 0;\n const sentPct = limit > 0 ? Math.round((sentTotal / limit) * 100) : 0;\n const activeBlocksList = state.blocks.filter((b) => b.active);\n const totalBlocksList = state.blocks;\n\n const lines: string[] = [];\n\n lines.push(\"╭─────────────────────────────────────────────╮\");\n lines.push(\"│ ACP Context Analysis │\");\n lines.push(\"╰─────────────────────────────────────────────╯\");\n if (input.version) lines.push(input.version);\n lines.push(\"\");\n lines.push(`Context (session accounting, host footer scale): ${displayPct}% (${fmt(displayTotal)} / ${fmt(limit)}) — includes compressed originals; shrinks slower than the sent view`);\n\n if (nudge && bd) {\n const growth = bd.growth;\n if (growth > 0 && displayTotal > 0) {\n lines.push(`Growth: +${fmt(growth)} since last nudge`);\n }\n lines.push(\"\");\n lines.push(`Sent to LLM (after compression, est.): ${fmt(sentTotal)}${limit > 0 ? ` (${sentPct}% of limit)` : \"\"}`);\n if (input.unprunedTokens !== undefined && sessionOnly > 0) {\n lines.push(`Session-only (compressed originals, est.): ${fmt(sessionOnly)} — pruned from every request; the footer/nudge still count them`);\n }\n lines.push(\"\");\n lines.push(\"Token Breakdown (sent view):\");\n\n const categories: Array<{ label: string; value: number }> = [\n { label: \"Tool\", value: bd.tool },\n { label: \"SysPrompt\", value: systemPromptTokens },\n { label: \"Text\", value: bd.text },\n { label: \"Code\", value: bd.code },\n { label: \"Summaries\", value: bd.summaries },\n ];\n\n for (const cat of categories) {\n if (cat.value <= 0) continue;\n const pct = sentTotal > 0 ? Math.round((cat.value / sentTotal) * 100) : 0;\n const b = bar(cat.value, sentTotal);\n lines.push(` ${cat.label.padEnd(10)} ${b} ${String(pct).padStart(3)}% ${fmt(cat.value)}`);\n }\n }\n\n if (input.cacheUsages) {\n const cache = cacheHitStats(input.cacheUsages);\n if (cache.requests > 0 && cache.session !== undefined && cache.last !== undefined) {\n lines.push(\"\");\n lines.push(\n `Prompt cache (provider-reported): ${formatHitRate(cache.last)} last · ${formatHitRate(cache.session)} session avg — ${fmt(cache.cacheRead)} of ${fmt(cache.billedPrompt)} billed prompt tokens served from cache (${cache.requests} req)`,\n );\n }\n }\n\n lines.push(\"\");\n\n if (nudge) {\n if (nudge.shouldInject) {\n const tierInfo = nudge.tier ? ` [T${nudge.tier} distillation]` : \"\";\n lines.push(`Nudge: ACTIVE${tierInfo} — ${nudge.reason}`);\n } else {\n lines.push(`Nudge: idle — ${nudge.reason}`);\n }\n }\n\n const ranges = viableRanges(nudge?.compressibleRanges ?? []);\n const protectedRanges = nudge?.protectedRanges ?? [];\n if (ranges.length > 0 || protectedRanges.length > 0) {\n lines.push(\"\");\n lines.push(formatRanges(ranges, protectedRanges));\n }\n\n if (activeBlocksList.length > 0) {\n lines.push(\"\");\n lines.push(`Blocks: ${activeBlocksList.length} active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`);\n for (const b of activeBlocksList) {\n const topic = b.topic ? `: ${b.topic}` : `: ${topicFallback(b.summary || \"\")}`;\n const summaryTok = defaultCountTokens(b.summary || \"\");\n const origTok = b.compressedTokens > 0 ? b.compressedTokens : summaryTok;\n lines.push(` [${b.blockId}] T${b.tier} ${fmt(origTok)}→${fmt(summaryTok)}${topic}`);\n }\n } else if (totalBlocksList.length > 0) {\n lines.push(\"\");\n lines.push(`Blocks: 0 active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`);\n } else {\n lines.push(\"\");\n lines.push(\"Blocks: none (nothing compressed yet)\");\n }\n\n lines.push(\"\");\n lines.push(\"Tag visibility: tags injected to LLM only (deep copy), not persisted in session, not shown in terminal.\");\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/panel/topic.ts","../../src/panel/format.ts","../../src/panel/cache.ts","../../src/panel/panel.ts"],"sourcesContent":["/** Short topic for a block when the model did not provide one: first sentence\n * segment, leading quotes stripped, truncated to 30 chars with an ellipsis.\n * Used wherever block lists are rendered (panels, search results). */\nimport { clampPrefix } from \"../truncate.js\";\n\nexport function topicFallback(summary: string): string {\n const first = summary.split(/[.\\n]/)[0] ?? \"\";\n const t = first\n .trim()\n .replace(/^[\"'`]+/, \"\")\n .trim();\n return t.length <= 30 ? t : `${clampPrefix(t, 30).trimEnd()}…`;\n}\n","/** Compact token formatting for user-facing panels: lowercase k/M with the\n * same thresholds as the hosts' footers (<1000 → raw, <10000 → one decimal\n * k, <1e6 → rounded k, <1e7 → one decimal M). */\nexport function formatCompactTokens(count: number): string {\n if (count < 1000) return count.toString();\n if (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n if (count < 1000000) return `${Math.round(count / 1000)}k`;\n if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;\n return `${Math.round(count / 1000000)}M`;\n}\n","/** Cache hit-rate math for the /acp status panel.\n *\n * Hosts feed per-request prompt-cache usage samples (from assistant\n * messages' provider-reported `usage`); the kernel derives the display\n * numbers. A request COUNTS only when the provider reported cache\n * activity for it (`cacheRead + cacheWrite > 0`): providers without\n * prompt-cache reporting (0/0 with plain `input`) must not drag the\n * average to a fabricated 0%. */\n\nexport interface CacheUsageSample {\n /** Non-cached conversation input tokens billed for the request. */\n input: number;\n /** Conversation tokens served from the prompt cache. */\n cacheRead: number;\n /** Conversation tokens written to the prompt cache (cache creation). */\n cacheWrite: number;\n}\n\nexport interface CacheHitSummary {\n /** Session hit rate (0..1), weighted by billed prompt tokens.\n * Undefined when no request reported cache activity. */\n session: number | undefined;\n /** Hit rate (0..1) of the most recent request that reported cache\n * activity. Undefined when no request reported any. */\n last: number | undefined;\n /** Counted requests (provider reported cache activity). */\n requests: number;\n /** Cumulative tokens served from cache. */\n cacheRead: number;\n /** Cumulative billed prompt tokens (input + cacheRead + cacheWrite). */\n billedPrompt: number;\n}\n\nfunction num(v: unknown): number {\n return typeof v === \"number\" && Number.isFinite(v) && v > 0 ? v : 0;\n}\n\n/** Aggregate per-request cache usage into panel display numbers. */\nexport function cacheHitStats(\n usages: readonly CacheUsageSample[],\n): CacheHitSummary {\n let cacheRead = 0;\n let billedPrompt = 0;\n let requests = 0;\n let last: number | undefined;\n for (const u of usages) {\n const read = num(u?.cacheRead);\n const write = num(u?.cacheWrite);\n const input = num(u?.input);\n // No cache signal on this request → excluded entirely (see header).\n if (read + write <= 0) continue;\n const total = read + write + input;\n if (total <= 0) continue;\n cacheRead += read;\n billedPrompt += total;\n requests += 1;\n last = read / total;\n }\n return {\n session: requests > 0 ? cacheRead / billedPrompt : undefined,\n last,\n requests,\n cacheRead,\n billedPrompt,\n };\n}\n\n/** Format a 0..1 rate as a percentage with one decimal (\"92.3%\"). */\nexport function formatHitRate(rate: number): string {\n return `${(Math.max(0, Math.min(1, rate)) * 100).toFixed(1)}%`;\n}\n","import { defaultCountTokens } from \"../tokenize.js\";\nimport { formatRanges } from \"../nudge-text.js\";\nimport type { CompressionState, NudgeDecision } from \"../types.js\";\nimport { formatCompactTokens } from \"./format.js\";\nimport { topicFallback } from \"./topic.js\";\nimport { viableRanges } from \"../viable.js\";\nimport {\n cacheHitStats,\n formatHitRate,\n type CacheUsageSample,\n} from \"./cache.js\";\n\nexport interface StatusPanelInput {\n /** Adapter identifier for the header, e.g. \"billion-context-omp@0.1.6\".\n * Omit to hide the version line. */\n version?: string;\n /** Host session accounting — the SAME number the host footer displays.\n * It includes compressed originals (summaries stay in the window), so it\n * shrinks slower than the sent view when compression prunes the\n * per-request projection. */\n tokenCount: number;\n /** Measured token count of the host system prompt (host-specific to\n * obtain; the kernel breakdown does not see it). */\n systemPromptTokens: number;\n /** Kernel state (blocks drive the Blocks section). */\n state: CompressionState;\n /** The nudge decision from core.processTurn for this turn, if any. The\n * panel applies the viability filter to compressibleRanges itself. */\n nudge: NudgeDecision | undefined;\n /** Configured model context window, in tokens. */\n modelContextLimit: number;\n /** Estimate of the FULL (unpruned) core-message projection, computed\n * with the SAME countTokens the core uses (kernel default = CJK-aware\n * defaultCountTokens) — the same estimation scale as the kernel\n * breakdown. When provided, the panel derives `Session-only` on that\n * scale (unpruned − sent). Without it the line is omitted: subtracting\n * the host's provider-scale number from an estimate-scale number\n * invents a third, meaningless scale (issue #18 \"看板统计的和拆分的有差异\"). */\n unprunedTokens?: number;\n /** Per-request prompt-cache usage (from assistant messages' provider-\n * reported `usage`). Requests without cache reporting are excluded by\n * cacheHitStats; when no counted request remains, the section is\n * omitted entirely. Omit the field to hide the section. */\n cacheUsages?: ReadonlyArray<CacheUsageSample>;\n /** Token formatter override (defaults to formatCompactTokens). */\n fmtTokens?: (n: number) => string;\n}\n\nfunction bar(value: number, total: number, width: number = 20): string {\n if (total === 0) return \"\";\n const filled = Math.max(\n 0,\n Math.min(width, Math.round((value / total) * width)),\n );\n return \"█\".repeat(filled) + \"░\".repeat(width - filled);\n}\n\n/** Render the /acp status panel. Three token numbers, each labeled with\n * its own scale, never mixed in arithmetic:\n * - Session accounting (host footer scale): the host's reported context\n * size INCLUDING compressed originals (summaries stay in the window), so\n * it shrinks slower than the sent view when compression prunes the\n * per-request projection.\n * - Sent view (estimated, kernel countTokens scale): what actually\n * reaches the LLM after compression (kernel's classification over the\n * pruned projection + measured system prompt). This is the number\n * compression controls.\n * - Session-only (estimated, kernel countTokens scale): unpruned\n * projection − sent view; the compressed originals pruned from every\n * request.\n * Subtracting the host number from an estimate produced numbers that\n * reconciled with neither scale (\"Framework 390K\", \"session-only 29k vs\n * 112k compressed\") — that is what issue #18 reported. */\nexport function buildStatusPanel(input: StatusPanelInput): string {\n const { tokenCount, state, nudge, modelContextLimit } = input;\n const fmt = input.fmtTokens ?? formatCompactTokens;\n const bd = nudge?.contextBreakdown;\n const limit = modelContextLimit;\n const classified = bd\n ? bd.system + bd.tool + bd.summaries + bd.code + bd.text\n : 0;\n const systemPromptTokens = input.systemPromptTokens;\n const sentTotal = classified + systemPromptTokens;\n // Same-scale derivation only: both sides use the core's countTokens\n // estimate (kernel default = CJK-aware defaultCountTokens). The host\n // footer's tokenCount (provider-anchored, session-tree) is displayed as\n // its own line and never fed into an arithmetic difference with these.\n const sessionOnly =\n input.unprunedTokens !== undefined\n ? Math.max(0, input.unprunedTokens - sentTotal)\n : 0;\n const displayTotal = tokenCount;\n const displayPct = limit > 0 ? Math.round((displayTotal / limit) * 100) : 0;\n const sentPct = limit > 0 ? Math.round((sentTotal / limit) * 100) : 0;\n const activeBlocksList = state.blocks.filter((b) => b.active);\n const totalBlocksList = state.blocks;\n\n const lines: string[] = [];\n\n lines.push(\"╭─────────────────────────────────────────────╮\");\n lines.push(\"│ ACP Context Analysis │\");\n lines.push(\"╰─────────────────────────────────────────────╯\");\n if (input.version) lines.push(input.version);\n lines.push(\"\");\n lines.push(\n `Context (session accounting, host footer scale): ${displayPct}% (${fmt(displayTotal)} / ${fmt(limit)}) — includes compressed originals; shrinks slower than the sent view`,\n );\n\n if (nudge && bd) {\n const growth = bd.growth;\n if (growth > 0 && displayTotal > 0) {\n lines.push(`Growth: +${fmt(growth)} since last nudge`);\n }\n lines.push(\"\");\n lines.push(\n `Sent to LLM (after compression, est.): ${fmt(sentTotal)}${limit > 0 ? ` (${sentPct}% of limit)` : \"\"}`,\n );\n if (input.unprunedTokens !== undefined && sessionOnly > 0) {\n lines.push(\n `Session-only (compressed originals, est.): ${fmt(sessionOnly)} — pruned from every request; the footer/nudge still count them`,\n );\n }\n lines.push(\"\");\n lines.push(\"Token Breakdown (sent view):\");\n\n const categories: Array<{ label: string; value: number }> = [\n { label: \"Tool\", value: bd.tool },\n { label: \"SysPrompt\", value: systemPromptTokens },\n { label: \"Text\", value: bd.text },\n { label: \"Code\", value: bd.code },\n { label: \"Summaries\", value: bd.summaries },\n ];\n\n for (const cat of categories) {\n if (cat.value <= 0) continue;\n const pct = sentTotal > 0 ? Math.round((cat.value / sentTotal) * 100) : 0;\n const b = bar(cat.value, sentTotal);\n lines.push(\n ` ${cat.label.padEnd(10)} ${b} ${String(pct).padStart(3)}% ${fmt(cat.value)}`,\n );\n }\n }\n\n if (input.cacheUsages) {\n const cache = cacheHitStats(input.cacheUsages);\n if (\n cache.requests > 0 &&\n cache.session !== undefined &&\n cache.last !== undefined\n ) {\n lines.push(\"\");\n lines.push(\n `Prompt cache (provider-reported): ${formatHitRate(cache.last)} last · ${formatHitRate(cache.session)} session avg — ${fmt(cache.cacheRead)} of ${fmt(cache.billedPrompt)} billed prompt tokens served from cache (${cache.requests} req)`,\n );\n }\n }\n\n lines.push(\"\");\n\n if (nudge) {\n if (nudge.shouldInject) {\n const tierInfo = nudge.tier ? ` [T${nudge.tier} distillation]` : \"\";\n lines.push(`Nudge: ACTIVE${tierInfo} — ${nudge.reason}`);\n } else {\n lines.push(`Nudge: idle — ${nudge.reason}`);\n }\n }\n\n const ranges = viableRanges(nudge?.compressibleRanges ?? []);\n const protectedRanges = nudge?.protectedRanges ?? [];\n if (ranges.length > 0 || protectedRanges.length > 0) {\n lines.push(\"\");\n lines.push(formatRanges(ranges, protectedRanges));\n }\n\n if (activeBlocksList.length > 0) {\n lines.push(\"\");\n lines.push(\n `Blocks: ${activeBlocksList.length} active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`,\n );\n for (const b of activeBlocksList) {\n const topic = b.topic\n ? `: ${b.topic}`\n : `: ${topicFallback(b.summary || \"\")}`;\n const summaryTok = defaultCountTokens(b.summary || \"\");\n const origTok = b.compressedTokens > 0 ? b.compressedTokens : summaryTok;\n lines.push(\n ` [${b.blockId}] T${b.tier} ${fmt(origTok)}→${fmt(summaryTok)}${topic}`,\n );\n }\n } else if (totalBlocksList.length > 0) {\n lines.push(\"\");\n lines.push(\n `Blocks: 0 active / ${totalBlocksList.length} total (${fmt(state.stats.tokensCompressed)} tokens compressed, cumulative)`,\n );\n } else {\n lines.push(\"\");\n lines.push(\"Blocks: none (nothing compressed yet)\");\n }\n\n lines.push(\"\");\n lines.push(\n \"Tag visibility: tags injected to LLM only (deep copy), not persisted in session, not shown in terminal.\",\n );\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;AAKO,SAAS,cAAc,SAAyB;AACrD,QAAM,QAAQ,QAAQ,MAAM,OAAO,EAAE,CAAC,KAAK;AAC3C,QAAM,IAAI,MACP,KAAK,EACL,QAAQ,WAAW,EAAE,EACrB,KAAK;AACR,SAAO,EAAE,UAAU,KAAK,IAAI,GAAG,YAAY,GAAG,EAAE,EAAE,QAAQ,CAAC;AAC7D;;;ACTO,SAAS,oBAAoB,OAAuB;AACzD,MAAI,QAAQ,IAAM,QAAO,MAAM,SAAS;AACxC,MAAI,QAAQ,IAAO,QAAO,IAAI,QAAQ,KAAM,QAAQ,CAAC,CAAC;AACtD,MAAI,QAAQ,IAAS,QAAO,GAAG,KAAK,MAAM,QAAQ,GAAI,CAAC;AACvD,MAAI,QAAQ,IAAU,QAAO,IAAI,QAAQ,KAAS,QAAQ,CAAC,CAAC;AAC5D,SAAO,GAAG,KAAK,MAAM,QAAQ,GAAO,CAAC;AACvC;;;ACwBA,SAAS,IAAI,GAAoB;AAC/B,SAAO,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,KAAK,IAAI,IAAI,IAAI;AACpE;AAGO,SAAS,cACd,QACiB;AACjB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,WAAW;AACf,MAAI;AACJ,aAAW,KAAK,QAAQ;AACtB,UAAM,OAAO,IAAI,GAAG,SAAS;AAC7B,UAAM,QAAQ,IAAI,GAAG,UAAU;AAC/B,UAAM,QAAQ,IAAI,GAAG,KAAK;AAE1B,QAAI,OAAO,SAAS,EAAG;AACvB,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,SAAS,EAAG;AAChB,iBAAa;AACb,oBAAgB;AAChB,gBAAY;AACZ,WAAO,OAAO;AAAA,EAChB;AACA,SAAO;AAAA,IACL,SAAS,WAAW,IAAI,YAAY,eAAe;AAAA,IACnD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,cAAc,MAAsB;AAClD,SAAO,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AAC7D;;;ACtBA,SAAS,IAAI,OAAe,OAAe,QAAgB,IAAY;AACrE,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,SAAS,KAAK;AAAA,IAClB;AAAA,IACA,KAAK,IAAI,OAAO,KAAK,MAAO,QAAQ,QAAS,KAAK,CAAC;AAAA,EACrD;AACA,SAAO,SAAI,OAAO,MAAM,IAAI,SAAI,OAAO,QAAQ,MAAM;AACvD;AAkBO,SAAS,iBAAiB,OAAiC;AAChE,QAAM,EAAE,YAAY,OAAO,OAAO,kBAAkB,IAAI;AACxD,QAAM,MAAM,MAAM,aAAa;AAC/B,QAAM,KAAK,OAAO;AAClB,QAAM,QAAQ;AACd,QAAM,aAAa,KACf,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,OAClD;AACJ,QAAM,qBAAqB,MAAM;AACjC,QAAM,YAAY,aAAa;AAK/B,QAAM,cACJ,MAAM,mBAAmB,SACrB,KAAK,IAAI,GAAG,MAAM,iBAAiB,SAAS,IAC5C;AACN,QAAM,eAAe;AACrB,QAAM,aAAa,QAAQ,IAAI,KAAK,MAAO,eAAe,QAAS,GAAG,IAAI;AAC1E,QAAM,UAAU,QAAQ,IAAI,KAAK,MAAO,YAAY,QAAS,GAAG,IAAI;AACpE,QAAM,mBAAmB,MAAM,OAAO,OAAO,CAAC,MAAM,EAAE,MAAM;AAC5D,QAAM,kBAAkB,MAAM;AAE9B,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,4RAAiD;AAC5D,QAAM,KAAK,2DAAiD;AAC5D,QAAM,KAAK,4RAAiD;AAC5D,MAAI,MAAM,QAAS,OAAM,KAAK,MAAM,OAAO;AAC3C,QAAM,KAAK,EAAE;AACb,QAAM;AAAA,IACJ,oDAAoD,UAAU,MAAM,IAAI,YAAY,CAAC,MAAM,IAAI,KAAK,CAAC;AAAA,EACvG;AAEA,MAAI,SAAS,IAAI;AACf,UAAM,SAAS,GAAG;AAClB,QAAI,SAAS,KAAK,eAAe,GAAG;AAClC,YAAM,KAAK,YAAY,IAAI,MAAM,CAAC,mBAAmB;AAAA,IACvD;AACA,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJ,0CAA0C,IAAI,SAAS,CAAC,GAAG,QAAQ,IAAI,KAAK,OAAO,gBAAgB,EAAE;AAAA,IACvG;AACA,QAAI,MAAM,mBAAmB,UAAa,cAAc,GAAG;AACzD,YAAM;AAAA,QACJ,8CAA8C,IAAI,WAAW,CAAC;AAAA,MAChE;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,8BAA8B;AAEzC,UAAM,aAAsD;AAAA,MAC1D,EAAE,OAAO,QAAQ,OAAO,GAAG,KAAK;AAAA,MAChC,EAAE,OAAO,aAAa,OAAO,mBAAmB;AAAA,MAChD,EAAE,OAAO,QAAQ,OAAO,GAAG,KAAK;AAAA,MAChC,EAAE,OAAO,QAAQ,OAAO,GAAG,KAAK;AAAA,MAChC,EAAE,OAAO,aAAa,OAAO,GAAG,UAAU;AAAA,IAC5C;AAEA,eAAW,OAAO,YAAY;AAC5B,UAAI,IAAI,SAAS,EAAG;AACpB,YAAM,MAAM,YAAY,IAAI,KAAK,MAAO,IAAI,QAAQ,YAAa,GAAG,IAAI;AACxE,YAAM,IAAI,IAAI,IAAI,OAAO,SAAS;AAClC,YAAM;AAAA,QACJ,KAAK,IAAI,MAAM,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,OAAO,GAAG,EAAE,SAAS,CAAC,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,aAAa;AACrB,UAAM,QAAQ,cAAc,MAAM,WAAW;AAC7C,QACE,MAAM,WAAW,KACjB,MAAM,YAAY,UAClB,MAAM,SAAS,QACf;AACA,YAAM,KAAK,EAAE;AACb,YAAM;AAAA,QACJ,qCAAqC,cAAc,MAAM,IAAI,CAAC,cAAW,cAAc,MAAM,OAAO,CAAC,uBAAkB,IAAI,MAAM,SAAS,CAAC,OAAO,IAAI,MAAM,YAAY,CAAC,4CAA4C,MAAM,QAAQ;AAAA,MACrO;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,EAAE;AAEb,MAAI,OAAO;AACT,QAAI,MAAM,cAAc;AACtB,YAAM,WAAW,MAAM,OAAO,MAAM,MAAM,IAAI,mBAAmB;AACjE,YAAM,KAAK,gBAAgB,QAAQ,WAAM,MAAM,MAAM,EAAE;AAAA,IACzD,OAAO;AACL,YAAM,KAAK,sBAAiB,MAAM,MAAM,EAAE;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM,SAAS,aAAa,OAAO,sBAAsB,CAAC,CAAC;AAC3D,QAAM,kBAAkB,OAAO,mBAAmB,CAAC;AACnD,MAAI,OAAO,SAAS,KAAK,gBAAgB,SAAS,GAAG;AACnD,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,aAAa,QAAQ,eAAe,CAAC;AAAA,EAClD;AAEA,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJ,WAAW,iBAAiB,MAAM,aAAa,gBAAgB,MAAM,WAAW,IAAI,MAAM,MAAM,gBAAgB,CAAC;AAAA,IACnH;AACA,eAAW,KAAK,kBAAkB;AAChC,YAAM,QAAQ,EAAE,QACZ,KAAK,EAAE,KAAK,KACZ,KAAK,cAAc,EAAE,WAAW,EAAE,CAAC;AACvC,YAAM,aAAa,mBAAmB,EAAE,WAAW,EAAE;AACrD,YAAM,UAAU,EAAE,mBAAmB,IAAI,EAAE,mBAAmB;AAC9D,YAAM;AAAA,QACJ,MAAM,EAAE,OAAO,MAAM,EAAE,IAAI,IAAI,IAAI,OAAO,CAAC,SAAI,IAAI,UAAU,CAAC,GAAG,KAAK;AAAA,MACxE;AAAA,IACF;AAAA,EACF,WAAW,gBAAgB,SAAS,GAAG;AACrC,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJ,sBAAsB,gBAAgB,MAAM,WAAW,IAAI,MAAM,MAAM,gBAAgB,CAAC;AAAA,IAC1F;AAAA,EACF,OAAO;AACL,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,uCAAuC;AAAA,EACpD;AAEA,QAAM,KAAK,EAAE;AACb,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/panel/panel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAInE,OAAO,EAAgC,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEjF,MAAM,WAAW,gBAAgB;IAC/B;yCACqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;kCAG8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;yDACqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,KAAK,EAAE,gBAAgB,CAAC;IACxB;2EACuE;IACvE,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;;;yEAMqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;gEAG4D;IAC5D,WAAW,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC9C,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACnC;AAQD;;;;;;;;;;;;;;;2DAe2D;AAC3D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CA0GhE"}
1
+ {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/panel/panel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAInE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B;yCACqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;kCAG8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;yDACqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,KAAK,EAAE,gBAAgB,CAAC;IACxB;2EACuE;IACvE,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;;;yEAMqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;gEAG4D;IAC5D,WAAW,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC9C,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACnC;AAWD;;;;;;;;;;;;;;;2DAe2D;AAC3D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAqIhE"}
@@ -1 +1 @@
1
- {"version":3,"file":"topic.d.ts","sourceRoot":"","sources":["../../src/panel/topic.ts"],"names":[],"mappings":"AAKA,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIrD"}
1
+ {"version":3,"file":"topic.d.ts","sourceRoot":"","sources":["../../src/panel/topic.ts"],"names":[],"mappings":"AAKA,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse-compress-input.d.ts","sourceRoot":"","sources":["../src/parse-compress-input.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GACvB,IAAI,GACJ,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,WAAW,GACX,iBAAiB,CAAC;AAExB,MAAM,WAAW,wBAAwB;IACrC,uDAAuD;IACvD,EAAE,EAAE,OAAO,CAAC;IACZ,2CAA2C;IAC3C,IAAI,EAAE,iBAAiB,CAAC;IACxB,wEAAwE;IACxE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,WAAW,EAAE,wBAAwB,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,mBAAmB,CAmBjG;AAsQD;;;0CAG0C;AAC1C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM1E"}
1
+ {"version":3,"file":"parse-compress-input.d.ts","sourceRoot":"","sources":["../src/parse-compress-input.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GACzB,IAAI,GACJ,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,WAAW,GACX,iBAAiB,CAAC;AAEtB,MAAM,WAAW,wBAAwB;IACvC,uDAAuD;IACvD,EAAE,EAAE,OAAO,CAAC;IACZ,2CAA2C;IAC3C,IAAI,EAAE,iBAAiB,CAAC;IACxB,wEAAwE;IACxE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzB,mBAAmB,CAuBrB;AA0TD;;;0CAG0C;AAC1C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS1E"}
@@ -14,6 +14,6 @@
14
14
  * - the store never deletes files; cleanup is a downstream decision
15
15
  */
16
16
  export { StateStore, flatFileNameFor } from "./store.js";
17
- export type { PersistedEnvelope, PersistLogger, StateStoreCodec, StateStoreOptions } from "./store.js";
17
+ export type { PersistedEnvelope, PersistLogger, StateStoreCodec, StateStoreOptions, } from "./store.js";
18
18
  export { mergeCompressionState } from "./state-merge.js";
19
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persist/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACvG,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persist/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -121,7 +121,12 @@ var StateStore = class {
121
121
  } catch {
122
122
  }
123
123
  if (!isTransientFsError(e) || attempt === this.retryAttempts - 1) break;
124
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, this.backoffMs(attempt));
124
+ Atomics.wait(
125
+ new Int32Array(new SharedArrayBuffer(4)),
126
+ 0,
127
+ 0,
128
+ this.backoffMs(attempt)
129
+ );
125
130
  }
126
131
  }
127
132
  if (!lastErr) {
@@ -140,7 +145,12 @@ var StateStore = class {
140
145
  spillPath = spill;
141
146
  } catch (e) {
142
147
  if (!isTransientFsError(e) || attempt === this.retryAttempts - 1) break;
143
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, this.backoffMs(attempt));
148
+ Atomics.wait(
149
+ new Int32Array(new SharedArrayBuffer(4)),
150
+ 0,
151
+ 0,
152
+ this.backoffMs(attempt)
153
+ );
144
154
  }
145
155
  }
146
156
  if (spillPath) this.discovered.set(id, spillPath);
@@ -181,7 +191,9 @@ var StateStore = class {
181
191
  const envelope = this.readEnvelope(file);
182
192
  if (!envelope) continue;
183
193
  const base = path.basename(file);
184
- const relBase = path.basename(this.relPathOf(envelope.id, envelope.payload));
194
+ const relBase = path.basename(
195
+ this.relPathOf(envelope.id, envelope.payload)
196
+ );
185
197
  const flatBase = flatFileNameFor(envelope.id);
186
198
  let owner = null;
187
199
  if (base === relBase || base === flatBase) {
@@ -193,7 +205,10 @@ var StateStore = class {
193
205
  }
194
206
  }
195
207
  if (owner === null) {
196
- this.log("warn", `[persist] skipping ${rel(file, this.dir)}: filename does not match record id`);
208
+ this.log(
209
+ "warn",
210
+ `[persist] skipping ${rel(file, this.dir)}: filename does not match record id`
211
+ );
197
212
  continue;
198
213
  }
199
214
  const existing = out.get(owner);
@@ -227,7 +242,10 @@ var StateStore = class {
227
242
  await Promise.all(
228
243
  [...builders.entries()].map(
229
244
  ([id, build]) => this.writeNow(id, build).catch((e) => {
230
- this.log("error", `[persist] shutdown flush failed for ${id}: ${errText(e)}`);
245
+ this.log(
246
+ "error",
247
+ `[persist] shutdown flush failed for ${id}: ${errText(e)}`
248
+ );
231
249
  })
232
250
  )
233
251
  );
@@ -267,7 +285,8 @@ var StateStore = class {
267
285
  lastErr = e;
268
286
  await fsp.unlink(tmp).catch(() => {
269
287
  });
270
- if (!isTransientFsError(e) || attempt === this.retryAttempts - 1) break;
288
+ if (!isTransientFsError(e) || attempt === this.retryAttempts - 1)
289
+ break;
271
290
  const { promise, resolve } = Promise.withResolvers();
272
291
  setTimeout(resolve, this.backoffMs(attempt));
273
292
  await promise;
@@ -331,7 +350,10 @@ var StateStore = class {
331
350
  if (!custom) return flatFileNameFor(id);
332
351
  const rel2 = path.normalize(custom);
333
352
  if (path.isAbsolute(rel2) || rel2.split(/[\\/]+/).includes("..")) {
334
- this.log("warn", `[persist] relPath for ${id} escapes dir; using flat name`);
353
+ this.log(
354
+ "warn",
355
+ `[persist] relPath for ${id} escapes dir; using flat name`
356
+ );
335
357
  return flatFileNameFor(id);
336
358
  }
337
359
  return rel2;
@@ -340,7 +362,10 @@ var StateStore = class {
340
362
  * rename is atomic). Prefixed `.tmp-` so loadAll skips orphans. */
341
363
  tempPath(dest) {
342
364
  const seq = this.tmpSeq++;
343
- return path.join(path.dirname(dest), `.tmp-${path.basename(dest, ".json")}-${process.pid}-${seq}`);
365
+ return path.join(
366
+ path.dirname(dest),
367
+ `.tmp-${path.basename(dest, ".json")}-${process.pid}-${seq}`
368
+ );
344
369
  }
345
370
  backoffMs(attempt) {
346
371
  return Math.min(this.retryBaseMs * 2 ** attempt, this.retryMaxMs);
@@ -383,7 +408,10 @@ var StateStore = class {
383
408
  const alertAt = count === 1 || count >= 2 && (count & count - 1) === 0;
384
409
  if (!alertAt) return;
385
410
  const where = spillPath ? `; data spilled to ${rel(spillPath, this.dir)}` : "; SPILLOVER ALSO FAILED \u2014 data at risk";
386
- this.log(count === 1 ? "error" : "warn", `[persist] write failed for ${id} (total ${count}x): ${errText(err)}${where}`);
411
+ this.log(
412
+ count === 1 ? "error" : "warn",
413
+ `[persist] write failed for ${id} (total ${count}x): ${errText(err)}${where}`
414
+ );
387
415
  }
388
416
  clearFailure(id) {
389
417
  this.failCounts.delete(id);
@@ -398,20 +426,29 @@ var StateStore = class {
398
426
  parsed = JSON.parse(text);
399
427
  } catch (e) {
400
428
  if (e.code !== "ENOENT") {
401
- this.log("warn", `[persist] skipping corrupt file ${rel(file, this.dir)}: ${errText(e)}`);
429
+ this.log(
430
+ "warn",
431
+ `[persist] skipping corrupt file ${rel(file, this.dir)}: ${errText(e)}`
432
+ );
402
433
  }
403
434
  return null;
404
435
  }
405
436
  if (isEnvelopeLike(parsed)) {
406
437
  if (!this.validateFn(parsed)) {
407
- this.log("warn", `[persist] skipping invalid record ${rel(file, this.dir)}`);
438
+ this.log(
439
+ "warn",
440
+ `[persist] skipping invalid record ${rel(file, this.dir)}`
441
+ );
408
442
  return null;
409
443
  }
410
444
  return parsed;
411
445
  }
412
446
  const adopted = this.adoptLegacy(parsed);
413
447
  if (adopted) return adopted;
414
- this.log("warn", `[persist] skipping invalid record ${rel(file, this.dir)}`);
448
+ this.log(
449
+ "warn",
450
+ `[persist] skipping invalid record ${rel(file, this.dir)}`
451
+ );
415
452
  return null;
416
453
  }
417
454
  /** Wrap a legacy (pre-envelope) record as an envelope via the `legacy`