pi-ui-extend 0.1.1

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 (420) hide show
  1. package/README.md +307 -0
  2. package/bin/pix.mjs +219 -0
  3. package/dist/app/app.d.ts +96 -0
  4. package/dist/app/app.js +871 -0
  5. package/dist/app/blink-controller.d.ts +23 -0
  6. package/dist/app/blink-controller.js +82 -0
  7. package/dist/app/cli.d.ts +8 -0
  8. package/dist/app/cli.js +83 -0
  9. package/dist/app/clipboard.d.ts +1 -0
  10. package/dist/app/clipboard.js +24 -0
  11. package/dist/app/command-controller.d.ts +18 -0
  12. package/dist/app/command-controller.js +58 -0
  13. package/dist/app/command-host.d.ts +44 -0
  14. package/dist/app/command-host.js +1 -0
  15. package/dist/app/command-model-actions.d.ts +12 -0
  16. package/dist/app/command-model-actions.js +176 -0
  17. package/dist/app/command-navigation-actions.d.ts +19 -0
  18. package/dist/app/command-navigation-actions.js +267 -0
  19. package/dist/app/command-registry.d.ts +32 -0
  20. package/dist/app/command-registry.js +225 -0
  21. package/dist/app/command-runtime.d.ts +5 -0
  22. package/dist/app/command-runtime.js +32 -0
  23. package/dist/app/command-session-actions.d.ts +20 -0
  24. package/dist/app/command-session-actions.js +295 -0
  25. package/dist/app/constants.d.ts +52 -0
  26. package/dist/app/constants.js +103 -0
  27. package/dist/app/conversation-entry-renderer.d.ts +21 -0
  28. package/dist/app/conversation-entry-renderer.js +81 -0
  29. package/dist/app/conversation-shell-renderer.d.ts +5 -0
  30. package/dist/app/conversation-shell-renderer.js +43 -0
  31. package/dist/app/conversation-tool-renderer.d.ts +16 -0
  32. package/dist/app/conversation-tool-renderer.js +216 -0
  33. package/dist/app/conversation-viewport.d.ts +55 -0
  34. package/dist/app/conversation-viewport.js +252 -0
  35. package/dist/app/dcp-stats.d.ts +2 -0
  36. package/dist/app/dcp-stats.js +116 -0
  37. package/dist/app/editor-layout-renderer.d.ts +31 -0
  38. package/dist/app/editor-layout-renderer.js +211 -0
  39. package/dist/app/editor-panels.d.ts +4 -0
  40. package/dist/app/editor-panels.js +130 -0
  41. package/dist/app/extension-actions-controller.d.ts +22 -0
  42. package/dist/app/extension-actions-controller.js +60 -0
  43. package/dist/app/extension-event-bus.d.ts +3 -0
  44. package/dist/app/extension-event-bus.js +23 -0
  45. package/dist/app/extension-ui-controller.d.ts +57 -0
  46. package/dist/app/extension-ui-controller.js +532 -0
  47. package/dist/app/file-link-opener.d.ts +2 -0
  48. package/dist/app/file-link-opener.js +66 -0
  49. package/dist/app/file-links.d.ts +10 -0
  50. package/dist/app/file-links.js +117 -0
  51. package/dist/app/guards.d.ts +3 -0
  52. package/dist/app/guards.js +9 -0
  53. package/dist/app/icons.d.ts +37 -0
  54. package/dist/app/icons.js +97 -0
  55. package/dist/app/id.d.ts +1 -0
  56. package/dist/app/id.js +4 -0
  57. package/dist/app/image-click-targets.d.ts +5 -0
  58. package/dist/app/image-click-targets.js +32 -0
  59. package/dist/app/image-opener.d.ts +2 -0
  60. package/dist/app/image-opener.js +64 -0
  61. package/dist/app/input-action-controller.d.ts +47 -0
  62. package/dist/app/input-action-controller.js +209 -0
  63. package/dist/app/input-controller.d.ts +60 -0
  64. package/dist/app/input-controller.js +425 -0
  65. package/dist/app/input-paste-handler.d.ts +27 -0
  66. package/dist/app/input-paste-handler.js +146 -0
  67. package/dist/app/menu-items-controller.d.ts +32 -0
  68. package/dist/app/menu-items-controller.js +182 -0
  69. package/dist/app/message-content.d.ts +8 -0
  70. package/dist/app/message-content.js +115 -0
  71. package/dist/app/model-ref.d.ts +13 -0
  72. package/dist/app/model-ref.js +50 -0
  73. package/dist/app/model-usage-controller.d.ts +35 -0
  74. package/dist/app/model-usage-controller.js +99 -0
  75. package/dist/app/model-usage-status.d.ts +125 -0
  76. package/dist/app/model-usage-status.js +749 -0
  77. package/dist/app/mouse-controller.d.ts +182 -0
  78. package/dist/app/mouse-controller.js +968 -0
  79. package/dist/app/native-modifiers.d.ts +3 -0
  80. package/dist/app/native-modifiers.js +60 -0
  81. package/dist/app/nerd-font-controller.d.ts +11 -0
  82. package/dist/app/nerd-font-controller.js +90 -0
  83. package/dist/app/popup-action-controller.d.ts +44 -0
  84. package/dist/app/popup-action-controller.js +278 -0
  85. package/dist/app/popup-menu-controller.d.ts +183 -0
  86. package/dist/app/popup-menu-controller.js +1070 -0
  87. package/dist/app/prompt-enhancer-controller.d.ts +40 -0
  88. package/dist/app/prompt-enhancer-controller.js +215 -0
  89. package/dist/app/queued-message-controller.d.ts +62 -0
  90. package/dist/app/queued-message-controller.js +377 -0
  91. package/dist/app/render-controller.d.ts +41 -0
  92. package/dist/app/render-controller.js +378 -0
  93. package/dist/app/render-text.d.ts +19 -0
  94. package/dist/app/render-text.js +67 -0
  95. package/dist/app/request-history.d.ts +23 -0
  96. package/dist/app/request-history.js +131 -0
  97. package/dist/app/runtime.d.ts +39 -0
  98. package/dist/app/runtime.js +195 -0
  99. package/dist/app/screen-selection.d.ts +6 -0
  100. package/dist/app/screen-selection.js +9 -0
  101. package/dist/app/screen-styler.d.ts +34 -0
  102. package/dist/app/screen-styler.js +168 -0
  103. package/dist/app/scroll-controller.d.ts +51 -0
  104. package/dist/app/scroll-controller.js +207 -0
  105. package/dist/app/session-event-controller.d.ts +69 -0
  106. package/dist/app/session-event-controller.js +338 -0
  107. package/dist/app/session-history.d.ts +23 -0
  108. package/dist/app/session-history.js +164 -0
  109. package/dist/app/session-lifecycle-controller.d.ts +55 -0
  110. package/dist/app/session-lifecycle-controller.js +116 -0
  111. package/dist/app/session-search.d.ts +24 -0
  112. package/dist/app/session-search.js +215 -0
  113. package/dist/app/shell-command.d.ts +27 -0
  114. package/dist/app/shell-command.js +176 -0
  115. package/dist/app/shell-controller.d.ts +28 -0
  116. package/dist/app/shell-controller.js +124 -0
  117. package/dist/app/slash-commands.d.ts +6 -0
  118. package/dist/app/slash-commands.js +75 -0
  119. package/dist/app/startup-checks.d.ts +8 -0
  120. package/dist/app/startup-checks.js +59 -0
  121. package/dist/app/startup-info.d.ts +3 -0
  122. package/dist/app/startup-info.js +176 -0
  123. package/dist/app/status-controller.d.ts +35 -0
  124. package/dist/app/status-controller.js +105 -0
  125. package/dist/app/status-line-renderer.d.ts +68 -0
  126. package/dist/app/status-line-renderer.js +453 -0
  127. package/dist/app/subagents-files.d.ts +10 -0
  128. package/dist/app/subagents-files.js +193 -0
  129. package/dist/app/subagents-model.d.ts +23 -0
  130. package/dist/app/subagents-model.js +224 -0
  131. package/dist/app/subagents-widget-controller.d.ts +43 -0
  132. package/dist/app/subagents-widget-controller.js +311 -0
  133. package/dist/app/tab-line-renderer.d.ts +26 -0
  134. package/dist/app/tab-line-renderer.js +222 -0
  135. package/dist/app/tabs-controller.d.ts +100 -0
  136. package/dist/app/tabs-controller.js +885 -0
  137. package/dist/app/terminal-controller.d.ts +40 -0
  138. package/dist/app/terminal-controller.js +135 -0
  139. package/dist/app/terminal-edit-shortcuts.d.ts +23 -0
  140. package/dist/app/terminal-edit-shortcuts.js +138 -0
  141. package/dist/app/terminal-output-buffer.d.ts +20 -0
  142. package/dist/app/terminal-output-buffer.js +52 -0
  143. package/dist/app/toast-controller.d.ts +13 -0
  144. package/dist/app/toast-controller.js +40 -0
  145. package/dist/app/toast-renderer.d.ts +9 -0
  146. package/dist/app/toast-renderer.js +79 -0
  147. package/dist/app/todo-model.d.ts +22 -0
  148. package/dist/app/todo-model.js +179 -0
  149. package/dist/app/todo-widget-controller.d.ts +21 -0
  150. package/dist/app/todo-widget-controller.js +59 -0
  151. package/dist/app/tool-block-renderer.d.ts +26 -0
  152. package/dist/app/tool-block-renderer.js +439 -0
  153. package/dist/app/types.d.ts +550 -0
  154. package/dist/app/types.js +1 -0
  155. package/dist/app/update.d.ts +36 -0
  156. package/dist/app/update.js +315 -0
  157. package/dist/app/voice-controller.d.ts +52 -0
  158. package/dist/app/voice-controller.js +600 -0
  159. package/dist/app/workspace-actions-controller.d.ts +40 -0
  160. package/dist/app/workspace-actions-controller.js +215 -0
  161. package/dist/app/workspace-undo.d.ts +44 -0
  162. package/dist/app/workspace-undo.js +215 -0
  163. package/dist/config.d.ts +62 -0
  164. package/dist/config.js +527 -0
  165. package/dist/context-progress-bar.d.ts +17 -0
  166. package/dist/context-progress-bar.js +48 -0
  167. package/dist/default-pix-config.d.ts +1 -0
  168. package/dist/default-pix-config.js +375 -0
  169. package/dist/fuzzy.d.ts +23 -0
  170. package/dist/fuzzy.js +165 -0
  171. package/dist/input-editor-files.d.ts +15 -0
  172. package/dist/input-editor-files.js +62 -0
  173. package/dist/input-editor.d.ts +186 -0
  174. package/dist/input-editor.js +835 -0
  175. package/dist/main.d.ts +1 -0
  176. package/dist/main.js +12 -0
  177. package/dist/markdown-format.d.ts +22 -0
  178. package/dist/markdown-format.js +542 -0
  179. package/dist/sdk.d.ts +3 -0
  180. package/dist/sdk.js +1 -0
  181. package/dist/syntax-highlight.d.ts +22 -0
  182. package/dist/syntax-highlight.js +528 -0
  183. package/dist/terminal-width.d.ts +6 -0
  184. package/dist/terminal-width.js +245 -0
  185. package/dist/theme.d.ts +56 -0
  186. package/dist/theme.js +118 -0
  187. package/dist/tool-renderers/apply-patch.d.ts +2 -0
  188. package/dist/tool-renderers/apply-patch.js +36 -0
  189. package/dist/tool-renderers/ast.d.ts +2 -0
  190. package/dist/tool-renderers/ast.js +5 -0
  191. package/dist/tool-renderers/compress.d.ts +2 -0
  192. package/dist/tool-renderers/compress.js +126 -0
  193. package/dist/tool-renderers/index.d.ts +3 -0
  194. package/dist/tool-renderers/index.js +44 -0
  195. package/dist/tool-renderers/question.d.ts +2 -0
  196. package/dist/tool-renderers/question.js +88 -0
  197. package/dist/tool-renderers/read.d.ts +2 -0
  198. package/dist/tool-renderers/read.js +36 -0
  199. package/dist/tool-renderers/repo.d.ts +2 -0
  200. package/dist/tool-renderers/repo.js +13 -0
  201. package/dist/tool-renderers/shell.d.ts +3 -0
  202. package/dist/tool-renderers/shell.js +27 -0
  203. package/dist/tool-renderers/skill.d.ts +2 -0
  204. package/dist/tool-renderers/skill.js +132 -0
  205. package/dist/tool-renderers/subagents.d.ts +2 -0
  206. package/dist/tool-renderers/subagents.js +51 -0
  207. package/dist/tool-renderers/todo.d.ts +2 -0
  208. package/dist/tool-renderers/todo.js +9 -0
  209. package/dist/tool-renderers/types.d.ts +42 -0
  210. package/dist/tool-renderers/types.js +1 -0
  211. package/dist/tool-renderers/utils.d.ts +31 -0
  212. package/dist/tool-renderers/utils.js +230 -0
  213. package/dist/tool-renderers/web.d.ts +3 -0
  214. package/dist/tool-renderers/web.js +9 -0
  215. package/dist/tool-renderers/write.d.ts +2 -0
  216. package/dist/tool-renderers/write.js +42 -0
  217. package/dist/ui.d.ts +56 -0
  218. package/dist/ui.js +94 -0
  219. package/docs/release.md +81 -0
  220. package/extensions/question/contract.ts +100 -0
  221. package/extensions/question/index.ts +34 -0
  222. package/extensions/question/render.ts +28 -0
  223. package/extensions/question/result.ts +86 -0
  224. package/extensions/question/tool-description.ts +11 -0
  225. package/extensions/question/tui.ts +629 -0
  226. package/extensions/question/types.ts +123 -0
  227. package/extensions/session-title/config.ts +169 -0
  228. package/extensions/session-title/index.ts +459 -0
  229. package/extensions/terminal-bell/index.ts +315 -0
  230. package/external/pi-tools-suite/README.md +242 -0
  231. package/external/pi-tools-suite/index.ts +1 -0
  232. package/external/pi-tools-suite/licenses/ollama-pi-web-search.MIT +21 -0
  233. package/external/pi-tools-suite/licenses/opencode-mystatus-MIT.txt +21 -0
  234. package/external/pi-tools-suite/package.json +53 -0
  235. package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +194 -0
  236. package/external/pi-tools-suite/src/antigravity-auth/commands.ts +80 -0
  237. package/external/pi-tools-suite/src/antigravity-auth/constants.ts +26 -0
  238. package/external/pi-tools-suite/src/antigravity-auth/headers.ts +20 -0
  239. package/external/pi-tools-suite/src/antigravity-auth/index.ts +104 -0
  240. package/external/pi-tools-suite/src/antigravity-auth/models.ts +86 -0
  241. package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +305 -0
  242. package/external/pi-tools-suite/src/antigravity-auth/payload.ts +423 -0
  243. package/external/pi-tools-suite/src/antigravity-auth/status.ts +78 -0
  244. package/external/pi-tools-suite/src/antigravity-auth/stream.ts +302 -0
  245. package/external/pi-tools-suite/src/antigravity-auth/types.ts +113 -0
  246. package/external/pi-tools-suite/src/ast-grep/index.ts +6 -0
  247. package/external/pi-tools-suite/src/ast-grep/render.ts +70 -0
  248. package/external/pi-tools-suite/src/ast-grep/schema.ts +109 -0
  249. package/external/pi-tools-suite/src/ast-grep/tool.ts +345 -0
  250. package/external/pi-tools-suite/src/ast-grep/types.ts +55 -0
  251. package/external/pi-tools-suite/src/ast-grep/utils.ts +65 -0
  252. package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +222 -0
  253. package/external/pi-tools-suite/src/async-subagents/commands.ts +518 -0
  254. package/external/pi-tools-suite/src/async-subagents/constants.ts +11 -0
  255. package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +74 -0
  256. package/external/pi-tools-suite/src/async-subagents/core/attachment-bridge.ts +133 -0
  257. package/external/pi-tools-suite/src/async-subagents/core/cleanup.ts +66 -0
  258. package/external/pi-tools-suite/src/async-subagents/core/concurrency.ts +90 -0
  259. package/external/pi-tools-suite/src/async-subagents/core/config.ts +819 -0
  260. package/external/pi-tools-suite/src/async-subagents/core/log-limits.ts +166 -0
  261. package/external/pi-tools-suite/src/async-subagents/core/model-fallback.ts +133 -0
  262. package/external/pi-tools-suite/src/async-subagents/core/paths.ts +47 -0
  263. package/external/pi-tools-suite/src/async-subagents/core/pi-invocation.ts +35 -0
  264. package/external/pi-tools-suite/src/async-subagents/core/presets.ts +67 -0
  265. package/external/pi-tools-suite/src/async-subagents/core/process.ts +15 -0
  266. package/external/pi-tools-suite/src/async-subagents/core/prompt.ts +66 -0
  267. package/external/pi-tools-suite/src/async-subagents/core/registry.ts +224 -0
  268. package/external/pi-tools-suite/src/async-subagents/core/retry.ts +191 -0
  269. package/external/pi-tools-suite/src/async-subagents/core/routing.ts +259 -0
  270. package/external/pi-tools-suite/src/async-subagents/core/sessions.ts +138 -0
  271. package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +688 -0
  272. package/external/pi-tools-suite/src/async-subagents/core/state.ts +281 -0
  273. package/external/pi-tools-suite/src/async-subagents/core/stop.ts +131 -0
  274. package/external/pi-tools-suite/src/async-subagents/core/structured-result.ts +237 -0
  275. package/external/pi-tools-suite/src/async-subagents/core/tool-guard.ts +34 -0
  276. package/external/pi-tools-suite/src/async-subagents/core/types.ts +150 -0
  277. package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +184 -0
  278. package/external/pi-tools-suite/src/async-subagents/core/utils.ts +11 -0
  279. package/external/pi-tools-suite/src/async-subagents/format.ts +41 -0
  280. package/external/pi-tools-suite/src/async-subagents/index.ts +422 -0
  281. package/external/pi-tools-suite/src/async-subagents/lib.ts +88 -0
  282. package/external/pi-tools-suite/src/async-subagents/live.ts +10 -0
  283. package/external/pi-tools-suite/src/async-subagents/polling.ts +83 -0
  284. package/external/pi-tools-suite/src/async-subagents/render.ts +230 -0
  285. package/external/pi-tools-suite/src/async-subagents/subagent-overlay.ts +77 -0
  286. package/external/pi-tools-suite/src/async-subagents/tasks.ts +120 -0
  287. package/external/pi-tools-suite/src/async-subagents/tools/cleanup.ts +99 -0
  288. package/external/pi-tools-suite/src/async-subagents/tools/result.ts +179 -0
  289. package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +372 -0
  290. package/external/pi-tools-suite/src/async-subagents/tools/status.ts +60 -0
  291. package/external/pi-tools-suite/src/async-subagents/tools/stop.ts +79 -0
  292. package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +152 -0
  293. package/external/pi-tools-suite/src/async-subagents/tools/wait.ts +67 -0
  294. package/external/pi-tools-suite/src/async-subagents/types.ts +45 -0
  295. package/external/pi-tools-suite/src/async-subagents/ui.ts +5 -0
  296. package/external/pi-tools-suite/src/compress/commands.ts +440 -0
  297. package/external/pi-tools-suite/src/compress/compress-tool.ts +368 -0
  298. package/external/pi-tools-suite/src/compress/compression-blocks.ts +524 -0
  299. package/external/pi-tools-suite/src/compress/config.ts +310 -0
  300. package/external/pi-tools-suite/src/compress/dcp-tui-filter.ts +498 -0
  301. package/external/pi-tools-suite/src/compress/index.ts +397 -0
  302. package/external/pi-tools-suite/src/compress/prompts.ts +269 -0
  303. package/external/pi-tools-suite/src/compress/pruner-candidates.ts +176 -0
  304. package/external/pi-tools-suite/src/compress/pruner-compression-blocks.ts +260 -0
  305. package/external/pi-tools-suite/src/compress/pruner-message-ids.ts +147 -0
  306. package/external/pi-tools-suite/src/compress/pruner-metadata.ts +268 -0
  307. package/external/pi-tools-suite/src/compress/pruner-nudge.ts +315 -0
  308. package/external/pi-tools-suite/src/compress/pruner-tools.ts +263 -0
  309. package/external/pi-tools-suite/src/compress/pruner-types.ts +25 -0
  310. package/external/pi-tools-suite/src/compress/pruner.ts +92 -0
  311. package/external/pi-tools-suite/src/compress/state.ts +486 -0
  312. package/external/pi-tools-suite/src/compress/ui.ts +308 -0
  313. package/external/pi-tools-suite/src/config.ts +176 -0
  314. package/external/pi-tools-suite/src/context-usage.ts +31 -0
  315. package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +355 -0
  316. package/external/pi-tools-suite/src/index.ts +46 -0
  317. package/external/pi-tools-suite/src/lib/lsp.ts +62 -0
  318. package/external/pi-tools-suite/src/lib/project.ts +42 -0
  319. package/external/pi-tools-suite/src/lib/tool-args.ts +137 -0
  320. package/external/pi-tools-suite/src/lsp/_shared/config.ts +156 -0
  321. package/external/pi-tools-suite/src/lsp/_shared/glob.ts +60 -0
  322. package/external/pi-tools-suite/src/lsp/_shared/output.ts +102 -0
  323. package/external/pi-tools-suite/src/lsp/_shared/paths.ts +138 -0
  324. package/external/pi-tools-suite/src/lsp/_shared/runner.ts +64 -0
  325. package/external/pi-tools-suite/src/lsp/_shared/template.ts +23 -0
  326. package/external/pi-tools-suite/src/lsp/_shared/trust.ts +116 -0
  327. package/external/pi-tools-suite/src/lsp/_shared/types.ts +98 -0
  328. package/external/pi-tools-suite/src/lsp/async.ts +29 -0
  329. package/external/pi-tools-suite/src/lsp/child-process.ts +81 -0
  330. package/external/pi-tools-suite/src/lsp/client.ts +340 -0
  331. package/external/pi-tools-suite/src/lsp/constants.ts +9 -0
  332. package/external/pi-tools-suite/src/lsp/diagnostics-store.ts +64 -0
  333. package/external/pi-tools-suite/src/lsp/documents.ts +24 -0
  334. package/external/pi-tools-suite/src/lsp/index.ts +31 -0
  335. package/external/pi-tools-suite/src/lsp/lsp-utils.ts +37 -0
  336. package/external/pi-tools-suite/src/lsp/manager.ts +190 -0
  337. package/external/pi-tools-suite/src/lsp/mutation-events.ts +78 -0
  338. package/external/pi-tools-suite/src/lsp/renderer.ts +1 -0
  339. package/external/pi-tools-suite/src/lsp/tool-result.ts +6 -0
  340. package/external/pi-tools-suite/src/lsp/tsserver.ts +107 -0
  341. package/external/pi-tools-suite/src/lsp/types.ts +15 -0
  342. package/external/pi-tools-suite/src/model-tools/apply-patch.ts +590 -0
  343. package/external/pi-tools-suite/src/model-tools/index.ts +430 -0
  344. package/external/pi-tools-suite/src/model-tools/path-utils.ts +6 -0
  345. package/external/pi-tools-suite/src/model-tools/tool-args.ts +11 -0
  346. package/external/pi-tools-suite/src/prompt-commands/index.ts +349 -0
  347. package/external/pi-tools-suite/src/repo-discovery/index.ts +384 -0
  348. package/external/pi-tools-suite/src/repo-discovery/project.ts +7 -0
  349. package/external/pi-tools-suite/src/startup-section.ts +13 -0
  350. package/external/pi-tools-suite/src/terminal-bell/index.ts +309 -0
  351. package/external/pi-tools-suite/src/todo/index.ts +201 -0
  352. package/external/pi-tools-suite/src/todo/state/auto-clear.ts +13 -0
  353. package/external/pi-tools-suite/src/todo/state/invariants.ts +21 -0
  354. package/external/pi-tools-suite/src/todo/state/persistence.ts +94 -0
  355. package/external/pi-tools-suite/src/todo/state/replay.ts +38 -0
  356. package/external/pi-tools-suite/src/todo/state/selectors.ts +49 -0
  357. package/external/pi-tools-suite/src/todo/state/state-reducer.ts +362 -0
  358. package/external/pi-tools-suite/src/todo/state/state.ts +18 -0
  359. package/external/pi-tools-suite/src/todo/state/store.ts +52 -0
  360. package/external/pi-tools-suite/src/todo/state/task-graph.ts +57 -0
  361. package/external/pi-tools-suite/src/todo/todo.ts +487 -0
  362. package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +143 -0
  363. package/external/pi-tools-suite/src/todo/tool/types.ts +188 -0
  364. package/external/pi-tools-suite/src/todo/view/format.ts +18 -0
  365. package/external/pi-tools-suite/src/todo/view/labels.ts +13 -0
  366. package/external/pi-tools-suite/src/tool-descriptions.ts +369 -0
  367. package/external/pi-tools-suite/src/usage/index.ts +152 -0
  368. package/external/pi-tools-suite/src/usage/lib/copilot.ts +535 -0
  369. package/external/pi-tools-suite/src/usage/lib/google.ts +478 -0
  370. package/external/pi-tools-suite/src/usage/lib/openai.ts +268 -0
  371. package/external/pi-tools-suite/src/usage/lib/types.ts +114 -0
  372. package/external/pi-tools-suite/src/usage/lib/utils.ts +134 -0
  373. package/external/pi-tools-suite/src/usage/lib/zhipu.ts +228 -0
  374. package/external/pi-tools-suite/src/web-search/index.ts +397 -0
  375. package/package.json +89 -0
  376. package/skills/context7/SKILL.md +69 -0
  377. package/skills/context7/scripts/context7.sh +73 -0
  378. package/skills/handoff/SKILL.md +15 -0
  379. package/skills/pdf/LICENSE.txt +30 -0
  380. package/skills/pdf/SKILL.md +314 -0
  381. package/skills/pdf/forms.md +294 -0
  382. package/skills/pdf/reference.md +612 -0
  383. package/skills/pdf/scripts/check_bounding_boxes.py +65 -0
  384. package/skills/pdf/scripts/check_fillable_fields.py +11 -0
  385. package/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  386. package/skills/pdf/scripts/create_validation_image.py +37 -0
  387. package/skills/pdf/scripts/extract_form_field_info.py +122 -0
  388. package/skills/pdf/scripts/extract_form_structure.py +115 -0
  389. package/skills/pdf/scripts/fill_fillable_fields.py +98 -0
  390. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  391. package/skills/playwright-cli/SKILL.md +388 -0
  392. package/skills/playwright-cli/references/element-attributes.md +23 -0
  393. package/skills/playwright-cli/references/playwright-tests.md +39 -0
  394. package/skills/playwright-cli/references/request-mocking.md +87 -0
  395. package/skills/playwright-cli/references/running-code.md +241 -0
  396. package/skills/playwright-cli/references/session-management.md +225 -0
  397. package/skills/playwright-cli/references/spec-driven-testing.md +305 -0
  398. package/skills/playwright-cli/references/storage-state.md +275 -0
  399. package/skills/playwright-cli/references/test-generation.md +134 -0
  400. package/skills/playwright-cli/references/tracing.md +139 -0
  401. package/skills/playwright-cli/references/video-recording.md +143 -0
  402. package/skills/simplify/SKILL.md +51 -0
  403. package/skills/skill-creator/LICENSE.txt +202 -0
  404. package/skills/skill-creator/SKILL.md +485 -0
  405. package/skills/skill-creator/agents/analyzer.md +274 -0
  406. package/skills/skill-creator/agents/comparator.md +202 -0
  407. package/skills/skill-creator/agents/grader.md +223 -0
  408. package/skills/skill-creator/assets/eval_review.html +146 -0
  409. package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  410. package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  411. package/skills/skill-creator/references/schemas.md +430 -0
  412. package/skills/skill-creator/scripts/__init__.py +0 -0
  413. package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  414. package/skills/skill-creator/scripts/generate_report.py +326 -0
  415. package/skills/skill-creator/scripts/improve_description.py +247 -0
  416. package/skills/skill-creator/scripts/package_skill.py +136 -0
  417. package/skills/skill-creator/scripts/quick_validate.py +103 -0
  418. package/skills/skill-creator/scripts/run_eval.py +310 -0
  419. package/skills/skill-creator/scripts/run_loop.py +328 -0
  420. package/skills/skill-creator/scripts/utils.py +47 -0
@@ -0,0 +1,524 @@
1
+ import type { CompressionBlock, DcpState, MessageIdMeta } from "./state.js"
2
+ import type { DcpConfig } from "./config.js"
3
+ import { estimateTokens } from "./pruner-metadata.js"
4
+ import { isToolRecordProtected } from "./pruner-tools.js"
5
+ import * as fs from "node:fs"
6
+ import * as path from "node:path"
7
+
8
+ const MAX_PROTECTED_SUBAGENT_RESULT_CHARS = 50_000
9
+
10
+ export interface CompressionBlockCreationResult {
11
+ block: CompressionBlock
12
+ removedTokenEstimate: number
13
+ summaryTokenEstimate: number
14
+ }
15
+
16
+ export interface CreateRangeCompressionBlockOptions {
17
+ topic: string
18
+ summary: string
19
+ startTimestamp: number
20
+ endTimestamp: number
21
+ startMessageId?: string
22
+ endMessageId?: string
23
+ state: DcpState
24
+ config: DcpConfig
25
+ anchorTimestamp?: number
26
+ anchorMessageId?: string
27
+ createdByToolCallId?: string
28
+ mode?: "range" | "message"
29
+ validatePlaceholders?: boolean
30
+ expandPlaceholders?: boolean
31
+ }
32
+
33
+ export interface ResolvedCompressionBoundary {
34
+ timestamp: number
35
+ stableId?: string
36
+ }
37
+
38
+ export interface ResolvedCompressionAnchor extends ResolvedCompressionBoundary {}
39
+
40
+ const BLOCK_PLACEHOLDER_RE = /\(b(\d+)\)|\{block_(\d+)\}/gi
41
+ const MAX_DIAGNOSTIC_IDS = 24
42
+
43
+ function idSortKey(id: string): [number, string] {
44
+ const match = id.match(/^(\D+)(\d+)$/)
45
+ if (!match) return [Number.MAX_SAFE_INTEGER, id]
46
+ return [Number.parseInt(match[2]!, 10), match[1]!.toLowerCase()]
47
+ }
48
+
49
+ function sortIds(ids: string[]): string[] {
50
+ return [...ids].sort((a, b) => {
51
+ const [aNumber, aPrefix] = idSortKey(a)
52
+ const [bNumber, bPrefix] = idSortKey(b)
53
+ return aNumber - bNumber || aPrefix.localeCompare(bPrefix) || a.localeCompare(b)
54
+ })
55
+ }
56
+
57
+ function compactList(items: string[], maxItems = MAX_DIAGNOSTIC_IDS): string {
58
+ if (items.length === 0) return "none"
59
+ if (items.length <= maxItems) return items.join(", ")
60
+
61
+ const headCount = Math.max(1, Math.floor(maxItems * 0.65))
62
+ const tailCount = Math.max(1, maxItems - headCount)
63
+ return `${items.slice(0, headCount).join(", ")}, …, ${items.slice(-tailCount).join(", ")} (${items.length} total)`
64
+ }
65
+
66
+ function quoteTopic(topic: string): string {
67
+ const singleLine = topic.replace(/\s+/g, " ").trim()
68
+ if (!singleLine) return ""
69
+ const truncated = singleLine.length > 48 ? `${singleLine.slice(0, 47)}…` : singleLine
70
+ return ` "${truncated.replace(/"/g, "'")}"`
71
+ }
72
+
73
+ export function formatCompressionIdDiagnostics(state: DcpState): string {
74
+ const rawIds = sortIds([
75
+ ...new Set([
76
+ ...state.messageIdSnapshot.keys(),
77
+ ...state.messageMetaSnapshot.keys(),
78
+ ]),
79
+ ])
80
+ const blockIds = state.compressionBlocks
81
+ .filter((block) => block.active)
82
+ .sort((a, b) => a.id - b.id)
83
+ .map((block) => `b${block.id}${quoteTopic(block.topic)}`)
84
+
85
+ return [
86
+ `Current raw message IDs: ${compactList(rawIds)}.`,
87
+ `Current active block IDs: ${compactList(blockIds)}.`,
88
+ "Use only IDs from the latest visible context. If a raw range was already compressed, use the corresponding bN block ID instead of stale mNNN IDs.",
89
+ ].join("\n")
90
+ }
91
+
92
+ export function unknownCompressionIdError(rawId: string, state: DcpState): Error {
93
+ const id = rawId.trim()
94
+ return new Error(
95
+ `Unknown message ID: ${id}.\n` +
96
+ "The ID is not present in the current DCP snapshot; it may be stale after compression, pruning, reload, or session switching.\n" +
97
+ formatCompressionIdDiagnostics(state),
98
+ )
99
+ }
100
+
101
+ function formatRestoredBlock(block: CompressionBlock): string {
102
+ return `[Previously compressed: ${block.topic}]\n${block.summary}`
103
+ }
104
+
105
+ /**
106
+ * Replace `(bN)` / legacy `{block_N}` placeholders in a summary with the
107
+ * stored content of the referenced compression block. Unrecognised
108
+ * placeholders are left as-is for backwards compatibility.
109
+ */
110
+ export function expandBlockPlaceholders(summary: string, state: DcpState): string {
111
+ return summary.replace(BLOCK_PLACEHOLDER_RE, (match, idStr, legacyIdStr) => {
112
+ const id = parseInt(idStr ?? legacyIdStr, 10)
113
+ const block = state.compressionBlocks.find((b) => b.id === id)
114
+ return block ? formatRestoredBlock(block) : match
115
+ })
116
+ }
117
+
118
+ function expandBlockPlaceholdersWithRecovery(
119
+ summary: string,
120
+ coveredBlocks: CompressionBlock[],
121
+ state: DcpState,
122
+ ): string {
123
+ const coveredIds = new Set(coveredBlocks.map((block) => block.id))
124
+ const consumed = new Set<number>()
125
+
126
+ const expanded = summary.replace(BLOCK_PLACEHOLDER_RE, (_match, idStr, legacyIdStr) => {
127
+ const id = parseInt(idStr ?? legacyIdStr, 10)
128
+ if (!coveredIds.has(id) || consumed.has(id)) return ""
129
+
130
+ const block = state.compressionBlocks.find((b) => b.id === id)
131
+ if (!block) return ""
132
+
133
+ consumed.add(id)
134
+ return formatRestoredBlock(block)
135
+ })
136
+
137
+ const missing = coveredBlocks.filter((block) => !consumed.has(block.id))
138
+ if (missing.length === 0) return expanded
139
+
140
+ const recoveryHeading =
141
+ "\n\nThe following previously compressed summaries were also part of this conversation section and were preserved automatically:"
142
+ const recovery = missing
143
+ .map((block) => `\n\n### b${block.id}\n${formatRestoredBlock(block)}`)
144
+ .join("")
145
+
146
+ return expanded + recoveryHeading + recovery
147
+ }
148
+
149
+ function preparePlaceholderSummary(
150
+ summary: string,
151
+ coveredBlocks: CompressionBlock[],
152
+ state: DcpState,
153
+ options: { validatePlaceholders: boolean; expandPlaceholders: boolean },
154
+ ): string {
155
+ if (!options.expandPlaceholders) return summary
156
+ if (options.validatePlaceholders) {
157
+ return expandBlockPlaceholdersWithRecovery(summary, coveredBlocks, state)
158
+ }
159
+ return expandBlockPlaceholders(summary, state)
160
+ }
161
+
162
+ export function findCoveredAndPartialBlocks(
163
+ startTimestamp: number,
164
+ endTimestamp: number,
165
+ state: DcpState,
166
+ ): { coveredBlocks: CompressionBlock[]; partialBlocks: CompressionBlock[] } {
167
+ const coveredBlocks: CompressionBlock[] = []
168
+ const partialBlocks: CompressionBlock[] = []
169
+
170
+ for (const existing of state.compressionBlocks) {
171
+ if (!existing.active) continue
172
+ if (!Number.isFinite(existing.startTimestamp) || !Number.isFinite(existing.endTimestamp)) continue
173
+
174
+ const overlaps =
175
+ startTimestamp <= existing.endTimestamp &&
176
+ existing.startTimestamp <= endTimestamp
177
+ if (!overlaps) continue
178
+
179
+ const fullyCovered =
180
+ startTimestamp <= existing.startTimestamp &&
181
+ existing.endTimestamp <= endTimestamp
182
+
183
+ if (fullyCovered) coveredBlocks.push(existing)
184
+ else partialBlocks.push(existing)
185
+ }
186
+
187
+ return { coveredBlocks, partialBlocks }
188
+ }
189
+
190
+ export function getMessageMeta(id: string, state: DcpState): MessageIdMeta | undefined {
191
+ return state.messageMetaSnapshot.get(id.trim())
192
+ }
193
+
194
+ function extractProtectTagTexts(text: string): string[] {
195
+ const protectedTexts: string[] = []
196
+ for (const match of text.matchAll(/<protect>([\s\S]*?)<\/protect>/gi)) {
197
+ const protectedText = match[1]?.trim()
198
+ if (protectedText) protectedTexts.push(protectedText)
199
+ }
200
+ return protectedTexts
201
+ }
202
+
203
+ export function appendProtectedPromptInfo(
204
+ summary: string,
205
+ startTimestamp: number,
206
+ endTimestamp: number,
207
+ state: DcpState,
208
+ config: DcpConfig,
209
+ ): string {
210
+ if (!config.compress.protectTags) return summary
211
+
212
+ const protectedTexts: string[] = []
213
+ const seen = new Set<string>()
214
+
215
+ for (const meta of state.messageMetaSnapshot.values()) {
216
+ if (meta.role !== "user") continue
217
+ if (meta.blockId !== undefined) continue
218
+ if (!Number.isFinite(meta.timestamp)) continue
219
+ if (meta.timestamp < startTimestamp || meta.timestamp > endTimestamp) continue
220
+
221
+ for (const text of extractProtectTagTexts(meta.text ?? "")) {
222
+ if (seen.has(text)) continue
223
+ seen.add(text)
224
+ protectedTexts.push(text)
225
+ }
226
+ }
227
+
228
+ if (protectedTexts.length === 0) return summary
229
+
230
+ const heading = "\n\nThe following protected prompt information appeared in the selected user message(s) and must be preserved verbatim:"
231
+ return summary + heading + protectedTexts.map((text) => `\n${text}`).join("")
232
+ }
233
+
234
+ export function appendProtectedUserMessages(
235
+ summary: string,
236
+ startTimestamp: number,
237
+ endTimestamp: number,
238
+ state: DcpState,
239
+ enabled: boolean,
240
+ ): string {
241
+ if (!enabled) return summary
242
+
243
+ const userTexts: string[] = []
244
+ const seen = new Set<string>()
245
+
246
+ for (const meta of state.messageMetaSnapshot.values()) {
247
+ if (meta.role !== "user") continue
248
+ if (meta.blockId !== undefined) continue
249
+ if (!Number.isFinite(meta.timestamp)) continue
250
+ if (meta.timestamp < startTimestamp || meta.timestamp > endTimestamp) continue
251
+
252
+ const text = meta.text?.trim()
253
+ if (!text || seen.has(text)) continue
254
+ seen.add(text)
255
+ userTexts.push(text)
256
+ }
257
+
258
+ if (userTexts.length === 0) return summary
259
+
260
+ const heading = "\n\nThe following user messages from this compressed range were preserved verbatim:"
261
+ return summary + heading + userTexts.map((text) => `\n${text}`).join("")
262
+ }
263
+
264
+ function truncateProtectedOutput(text: string, maxChars: number): string {
265
+ if (text.length <= maxChars) return text
266
+ const omitted = text.length - maxChars
267
+ return text.slice(0, maxChars) + `\n[Protected output truncated; ${omitted} characters omitted]`
268
+ }
269
+
270
+ function resolveArtifactPath(filePath: string): string {
271
+ return path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath)
272
+ }
273
+
274
+ function readProtectedSubagentResult(details: unknown, fallbackText: string): string | undefined {
275
+ if (!details || typeof details !== "object") return undefined
276
+ const record = details as any
277
+ const artifactPath = record.artifacts?.resultMd
278
+ if (typeof artifactPath !== "string" || artifactPath.trim().length === 0) return undefined
279
+
280
+ const absolutePath = resolveArtifactPath(artifactPath.trim())
281
+ let text: string
282
+ try {
283
+ text = fs.readFileSync(absolutePath, "utf8")
284
+ } catch {
285
+ return undefined
286
+ }
287
+
288
+ const trimmed = text.trim()
289
+ if (!trimmed || fallbackText.includes(trimmed)) return undefined
290
+ return `\n### Expanded subagent result: ${artifactPath}\n${truncateProtectedOutput(trimmed, MAX_PROTECTED_SUBAGENT_RESULT_CHARS)}`
291
+ }
292
+
293
+ function appendProtectedToolOutputs(
294
+ summary: string,
295
+ startTimestamp: number,
296
+ endTimestamp: number,
297
+ state: DcpState,
298
+ config: DcpConfig,
299
+ ): string {
300
+ const protectedOutputs: string[] = []
301
+ const seenToolCallIds = new Set<string>()
302
+
303
+ for (const meta of state.messageMetaSnapshot.values()) {
304
+ if (meta.blockId !== undefined) continue
305
+ if (!Number.isFinite(meta.timestamp)) continue
306
+ if (meta.timestamp < startTimestamp || meta.timestamp > endTimestamp) continue
307
+ if (meta.role !== "toolResult" && meta.role !== "bashExecution") continue
308
+
309
+ const toolCallId = meta.toolCallId
310
+ if (!toolCallId || seenToolCallIds.has(toolCallId)) continue
311
+ const record = state.toolCalls.get(toolCallId)
312
+ if (!record) continue
313
+
314
+ // The compress tool's own JSON accounting output is control-plane data and
315
+ // rarely useful in future summaries; avoid recursively copying it.
316
+ if (record.toolName === "compress") continue
317
+ if (!isToolRecordProtected(record, config)) continue
318
+
319
+ const output = (record.outputText ?? meta.text ?? "").trim()
320
+ if (!output) continue
321
+
322
+ seenToolCallIds.add(toolCallId)
323
+ const expandedSubagentResult =
324
+ record.toolName === "subagents" || record.toolName === "async_subagents_result"
325
+ ? readProtectedSubagentResult(record.outputDetails, output)
326
+ : undefined
327
+ protectedOutputs.push(`\n### Tool: ${record.toolName}\n${output}${expandedSubagentResult ?? ""}`)
328
+ }
329
+
330
+ if (protectedOutputs.length === 0) return summary
331
+ const heading = "\n\nThe following protected tool outputs were included in this conversation section:"
332
+ return summary + heading + protectedOutputs.join("")
333
+ }
334
+
335
+ export function estimateVisibleRangeTokens(
336
+ startTimestamp: number,
337
+ endTimestamp: number,
338
+ coveredBlocks: CompressionBlock[],
339
+ state: DcpState,
340
+ ): number {
341
+ let total = 0
342
+ for (const meta of state.messageMetaSnapshot.values()) {
343
+ if (meta.blockId !== undefined) continue
344
+ if (!Number.isFinite(meta.timestamp)) continue
345
+ if (meta.timestamp < startTimestamp || meta.timestamp > endTimestamp) continue
346
+ total += Math.max(0, Math.round(meta.tokenEstimate ?? 0))
347
+ }
348
+ for (const block of coveredBlocks) {
349
+ total += Math.max(0, Math.round(block.summaryTokenEstimate ?? 0))
350
+ }
351
+ return total
352
+ }
353
+
354
+ /**
355
+ * Resolve a user-supplied ID string (e.g. "m001" or "b3") to an actual
356
+ * message timestamp.
357
+ */
358
+ export function resolveIdToTimestamp(
359
+ rawId: string,
360
+ field: "startTimestamp" | "endTimestamp",
361
+ state: DcpState,
362
+ ): number {
363
+ return resolveIdToBoundary(rawId, field, state).timestamp
364
+ }
365
+
366
+ export function resolveIdToBoundary(
367
+ rawId: string,
368
+ field: "startTimestamp" | "endTimestamp",
369
+ state: DcpState,
370
+ ): ResolvedCompressionBoundary {
371
+ const id = rawId.trim()
372
+
373
+ const blockMatch = id.match(/^b(\d+)$/i)
374
+ if (blockMatch) {
375
+ const blockId = parseInt(blockMatch[1]!, 10)
376
+ const block = state.compressionBlocks.find((b) => b.id === blockId && b.active)
377
+ if (!block) throw unknownCompressionIdError(id, state)
378
+ return {
379
+ timestamp: block[field],
380
+ stableId: field === "startTimestamp" ? block.startMessageId : block.endMessageId,
381
+ }
382
+ }
383
+
384
+ const meta = state.messageMetaSnapshot.get(id)
385
+ if (meta) return { timestamp: meta.timestamp, stableId: meta.stableId }
386
+
387
+ const ts = state.messageIdSnapshot.get(id)
388
+ if (ts === undefined) throw unknownCompressionIdError(id, state)
389
+ return { timestamp: ts }
390
+ }
391
+
392
+ /**
393
+ * Determine the anchor timestamp for a compression block — the timestamp of
394
+ * the first raw message that appears strictly after `endTimestamp`.
395
+ */
396
+ export function resolveAnchorTimestamp(endTimestamp: number, state: DcpState): number {
397
+ return resolveAnchorBoundary(endTimestamp, state).timestamp
398
+ }
399
+
400
+ export function resolveAnchorBoundary(endTimestamp: number, state: DcpState): ResolvedCompressionAnchor {
401
+ let anchor: number | null = null
402
+ let stableId: string | undefined
403
+ for (const meta of state.messageMetaSnapshot.values()) {
404
+ const ts = meta.timestamp
405
+ if (ts > endTimestamp && (anchor === null || ts < anchor)) {
406
+ anchor = ts
407
+ stableId = meta.stableId
408
+ }
409
+ }
410
+ if (anchor === null) {
411
+ for (const ts of state.messageIdSnapshot.values()) {
412
+ if (ts > endTimestamp && (anchor === null || ts < anchor)) anchor = ts
413
+ }
414
+ }
415
+ return { timestamp: anchor ?? endTimestamp + 1, stableId }
416
+ }
417
+
418
+ export function createRangeCompressionBlock(
419
+ options: CreateRangeCompressionBlockOptions,
420
+ ): CompressionBlockCreationResult {
421
+ const {
422
+ topic,
423
+ summary,
424
+ startTimestamp,
425
+ endTimestamp,
426
+ startMessageId,
427
+ endMessageId,
428
+ state,
429
+ config,
430
+ anchorTimestamp = resolveAnchorBoundary(endTimestamp, state).timestamp,
431
+ anchorMessageId,
432
+ createdByToolCallId,
433
+ mode = "range",
434
+ validatePlaceholders = true,
435
+ expandPlaceholders = true,
436
+ } = options
437
+
438
+ if (startTimestamp > endTimestamp) {
439
+ throw new Error("Compression range start must appear before end in the conversation")
440
+ }
441
+
442
+ if (!Number.isFinite(startTimestamp)) {
443
+ throw new Error(`Compression range start resolved to a non-finite timestamp (${startTimestamp})`)
444
+ }
445
+ if (!Number.isFinite(endTimestamp)) {
446
+ throw new Error(`Compression range end resolved to a non-finite timestamp (${endTimestamp})`)
447
+ }
448
+
449
+ const { coveredBlocks, partialBlocks } = findCoveredAndPartialBlocks(
450
+ startTimestamp,
451
+ endTimestamp,
452
+ state,
453
+ )
454
+
455
+ if (partialBlocks.length > 0) {
456
+ const blockList = partialBlocks.map((block) => `b${block.id} "${block.topic}"`).join(", ")
457
+ throw new Error(
458
+ `Compression range partially overlaps existing block(s): ${blockList}. ` +
459
+ "Select the whole block or choose non-overlapping boundaries.",
460
+ )
461
+ }
462
+
463
+ const placeholderSummary = preparePlaceholderSummary(
464
+ summary,
465
+ coveredBlocks,
466
+ state,
467
+ { validatePlaceholders, expandPlaceholders },
468
+ )
469
+
470
+ const userPreservedSummary = mode === "range"
471
+ ? appendProtectedUserMessages(
472
+ placeholderSummary,
473
+ startTimestamp,
474
+ endTimestamp,
475
+ state,
476
+ config.compress.protectUserMessages,
477
+ )
478
+ : placeholderSummary
479
+
480
+ const promptPreservedSummary = appendProtectedPromptInfo(
481
+ userPreservedSummary,
482
+ startTimestamp,
483
+ endTimestamp,
484
+ state,
485
+ config,
486
+ )
487
+
488
+ const expandedSummary = appendProtectedToolOutputs(
489
+ promptPreservedSummary,
490
+ startTimestamp,
491
+ endTimestamp,
492
+ state,
493
+ config,
494
+ )
495
+
496
+ const block: CompressionBlock = {
497
+ id: state.nextBlockId++,
498
+ topic,
499
+ summary: expandedSummary,
500
+ startTimestamp,
501
+ endTimestamp,
502
+ startMessageId,
503
+ endMessageId,
504
+ anchorTimestamp,
505
+ anchorMessageId,
506
+ createdByToolCallId,
507
+ active: true,
508
+ summaryTokenEstimate: estimateTokens(expandedSummary),
509
+ createdAt: Date.now(),
510
+ coveredBlockIds: coveredBlocks.map((covered) => covered.id),
511
+ mode,
512
+ }
513
+
514
+ state.compressionBlocks.push(block)
515
+ for (const covered of coveredBlocks) {
516
+ covered.active = false
517
+ }
518
+
519
+ return {
520
+ block,
521
+ removedTokenEstimate: estimateVisibleRangeTokens(startTimestamp, endTimestamp, coveredBlocks, state),
522
+ summaryTokenEstimate: Math.max(0, Math.round(block.summaryTokenEstimate ?? 0)),
523
+ }
524
+ }