@herbertgao/pi-extensions 2026.9.19 → 2026.10.0

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 (444) hide show
  1. package/README.md +14 -16
  2. package/THIRD_PARTY_NOTICES.md +29 -3
  3. package/node_modules/@herbertgao/pi-bark/README.md +39 -3
  4. package/node_modules/@herbertgao/pi-bark/package.json +1 -1
  5. package/node_modules/@herbertgao/pi-bark/src/index.ts +275 -15
  6. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +85 -68
  7. package/node_modules/@herbertgao/pi-cc-extensions/README.md +79 -62
  8. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/preview.webp +0 -0
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +116 -34
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +370 -118
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +6 -36
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/index.ts +2 -2
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +31 -33
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +330 -360
  15. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/index.ts +56 -108
  16. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/session.ts +97 -15
  17. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/subagent.ts +80 -45
  18. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/flush-docked-bash.ts +36 -0
  19. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer-layout.ts +229 -0
  20. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer.ts +521 -0
  21. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/mcp-chip.ts +136 -0
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/startup-header.ts +92 -61
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/working-message.ts +58 -38
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +19 -3
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +1127 -231
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +267 -262
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +38 -48
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +8 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +2 -7
  30. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +287 -114
  31. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +15 -6
  32. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +18 -72
  33. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/scroll.ts +61 -26
  34. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +303 -0
  35. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/ansi-utils.ts +25 -57
  36. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-component.ts +125 -0
  37. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-edit-render.ts +227 -0
  38. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-header.ts +136 -0
  39. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-highlight.ts +151 -0
  40. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-inline.ts +324 -0
  41. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-layout.ts +762 -0
  42. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-limits.ts +152 -0
  43. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-palette.ts +410 -0
  44. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-parse.ts +535 -0
  45. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-presentation.ts +4 -4
  46. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +21 -3219
  47. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-text.ts +44 -0
  48. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-write-render.ts +568 -0
  49. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/index.ts +103 -48
  50. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/line-width-safety.ts +8 -7
  51. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-execution.ts +2 -1
  52. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +171 -196
  53. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/mcp-title.ts +39 -0
  54. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{message-display.ts → tool/message-display.ts} +27 -93
  55. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/names.ts +429 -0
  56. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +259 -164
  57. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{show-more-hint.ts → tool/show-more-hint.ts} +10 -0
  58. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/transcript-refresh.ts +8 -26
  59. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-color.ts +44 -0
  60. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-text.ts +77 -0
  61. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/component-tree.ts +34 -0
  62. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/format.ts +28 -0
  63. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +51 -0
  64. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/patch-keys.ts +124 -0
  65. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/sgr-mouse.ts +70 -0
  66. package/node_modules/@herbertgao/pi-cc-extensions/package.json +10 -8
  67. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  68. package/node_modules/@herbertgao/pi-subagents/package.json +1 -1
  69. package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +3 -2
  70. package/node_modules/@herbertgao/sol-pi/CONTRIBUTING.md +22 -0
  71. package/node_modules/@herbertgao/sol-pi/README.md +36 -17
  72. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +10 -6
  73. package/node_modules/@herbertgao/sol-pi/agents-install.md +15 -12
  74. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +24 -8
  75. package/node_modules/@herbertgao/sol-pi/docs/configuration.md +2 -2
  76. package/node_modules/@herbertgao/sol-pi/docs/star-history.md +18 -0
  77. package/node_modules/@herbertgao/sol-pi/package.json +4 -2
  78. package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +1 -1
  79. package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +1 -1
  80. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +23 -4
  81. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +32 -1
  82. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +3 -2
  83. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +1 -1
  84. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +27 -7
  85. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +137 -41
  86. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +1 -0
  87. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +2 -1
  88. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/projection.ts +58 -0
  89. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +28 -6
  90. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +2 -1
  91. package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +15 -2
  92. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  93. package/node_modules/@pi-plugins/fast-mode/README.md +7 -1
  94. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  95. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +7 -1
  96. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  97. package/node_modules/@pi-plugins/fast-mode/package.json +5 -5
  98. package/node_modules/pi-antigravity/README.md +3 -0
  99. package/node_modules/pi-antigravity/package.json +8 -8
  100. package/node_modules/pi-antigravity/src/auth/oauth.ts +6 -3
  101. package/node_modules/pi-antigravity/src/index.ts +114 -110
  102. package/node_modules/pi-antigravity/src/stream/stream.ts +1 -1
  103. package/node_modules/pi-antigravity/src/utils/util.ts +18 -1
  104. package/node_modules/pi-multi-account/CHANGELOG.md +20 -0
  105. package/node_modules/pi-multi-account/README.md +46 -8
  106. package/node_modules/pi-multi-account/config-file-transaction.ts +42 -0
  107. package/node_modules/pi-multi-account/index.ts +255 -269
  108. package/node_modules/pi-multi-account/model-pins.ts +36 -0
  109. package/node_modules/pi-multi-account/package.json +9 -7
  110. package/node_modules/pi-multi-account/slot-proxy-auth.ts +12 -2
  111. package/node_modules/pi-multi-account/slot-proxy.ts +27 -5
  112. package/node_modules/pi-web-access/CHANGELOG.md +17 -0
  113. package/node_modules/pi-web-access/README.md +6 -3
  114. package/node_modules/pi-web-access/brave-rate-limit.ts +170 -0
  115. package/node_modules/pi-web-access/brave.ts +28 -11
  116. package/node_modules/pi-web-access/dist/index.js +202 -33
  117. package/node_modules/pi-web-access/gemini-search.ts +2 -5
  118. package/node_modules/pi-web-access/index.ts +13 -7
  119. package/node_modules/pi-web-access/openai-search.ts +24 -10
  120. package/node_modules/pi-web-access/package.json +1 -1
  121. package/node_modules/pi-web-access/summary-review.ts +8 -2
  122. package/node_modules/{@herbertgao/resume-from → resume-from}/README.md +16 -12
  123. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.d.ts +0 -5
  124. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.js +2 -3
  125. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.d.ts +2 -2
  126. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.d.ts +3 -0
  127. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.js +27 -15
  128. package/node_modules/{@herbertgao/resume-from/dist/adapters/codex → resume-from/dist/adapters/claude-code}/redaction.js +16 -3
  129. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.d.ts +2 -4
  130. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.js +1 -1
  131. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.d.ts +2 -4
  132. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.js +1 -2
  133. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/read.d.ts +16 -0
  134. package/node_modules/resume-from/dist/adapters/codex/read.js +723 -0
  135. package/node_modules/{@herbertgao/resume-from/dist/adapters/pi → resume-from/dist/adapters/codex}/redaction.js +16 -3
  136. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.d.ts +44 -4
  137. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.js +88 -4
  138. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.d.ts +2 -2
  139. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.js +2 -2
  140. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.d.ts +5 -1
  141. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.js +10 -6
  142. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.d.ts +2 -2
  143. package/node_modules/{@herbertgao/resume-from/dist/adapters/claude-code → resume-from/dist/adapters/pi}/redaction.js +16 -3
  144. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.d.ts +2 -4
  145. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.js +2 -2
  146. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.d.ts +1 -1
  147. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.js +4 -4
  148. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.js +2 -2
  149. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.d.ts +2 -2
  150. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.js +31 -8
  151. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.d.ts +1 -1
  152. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.js +1 -2
  153. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.d.ts +4 -1
  154. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.js +2 -2
  155. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.d.ts +8 -6
  156. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.d.ts +10 -5
  157. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/finder.d.ts +2 -1
  158. package/node_modules/resume-from/dist/import/discovery/finder.js +269 -0
  159. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.d.ts +3 -3
  160. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.js +3 -3
  161. package/node_modules/resume-from/dist/import/pipeline.d.ts +28 -0
  162. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/pipeline.js +31 -11
  163. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.d.ts +2 -2
  164. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.js +9 -5
  165. package/node_modules/resume-from/dist/import/preview/warnings.d.ts +14 -0
  166. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/warnings.js +26 -20
  167. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.js +12 -2
  168. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.d.ts +9 -3
  169. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.d.ts +4 -4
  170. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.js +7 -4
  171. package/node_modules/resume-from/dist/platform/repo/reader.d.ts +3 -0
  172. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/reader.js +60 -20
  173. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.d.ts +8 -1
  174. package/node_modules/{@herbertgao/resume-from → resume-from}/package.json +19 -32
  175. package/node_modules/{@herbertgao/resume-from → resume-from}/shims/pi/extensions/resume-from.js +2 -2
  176. package/package.json +18 -22
  177. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +0 -101
  178. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.svg +0 -101
  179. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/welcome.webp +0 -0
  180. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/render-utils.ts +0 -5
  181. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +0 -30
  182. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +0 -12
  183. package/node_modules/@herbertgao/resume-from/dist/adapters/codex/read.js +0 -270
  184. package/node_modules/@herbertgao/resume-from/dist/import/discovery/finder.js +0 -129
  185. package/node_modules/@herbertgao/resume-from/dist/import/pipeline.d.ts +0 -17
  186. package/node_modules/@herbertgao/resume-from/dist/import/preview/warnings.d.ts +0 -11
  187. package/node_modules/@herbertgao/resume-from/dist/platform/repo/reader.d.ts +0 -8
  188. package/node_modules/pi-footer/CHANGELOG.md +0 -145
  189. package/node_modules/pi-footer/LICENSE +0 -21
  190. package/node_modules/pi-footer/README.md +0 -354
  191. package/node_modules/pi-footer/package.json +0 -68
  192. package/node_modules/pi-footer/src/cache.ts +0 -106
  193. package/node_modules/pi-footer/src/colors.ts +0 -237
  194. package/node_modules/pi-footer/src/config.ts +0 -202
  195. package/node_modules/pi-footer/src/event-widgets.ts +0 -41
  196. package/node_modules/pi-footer/src/extension-statuses.ts +0 -102
  197. package/node_modules/pi-footer/src/git.ts +0 -135
  198. package/node_modules/pi-footer/src/index.ts +0 -268
  199. package/node_modules/pi-footer/src/metrics.ts +0 -141
  200. package/node_modules/pi-footer/src/presets.ts +0 -383
  201. package/node_modules/pi-footer/src/render.ts +0 -114
  202. package/node_modules/pi-footer/src/separators.ts +0 -52
  203. package/node_modules/pi-footer/src/types.ts +0 -122
  204. package/node_modules/pi-footer/src/ui/color-level-confirm.ts +0 -22
  205. package/node_modules/pi-footer/src/ui/color-options.ts +0 -195
  206. package/node_modules/pi-footer/src/ui/config-lifecycle.ts +0 -61
  207. package/node_modules/pi-footer/src/ui/edit-colors.ts +0 -13
  208. package/node_modules/pi-footer/src/ui/events.ts +0 -35
  209. package/node_modules/pi-footer/src/ui/extension-status-picker.ts +0 -60
  210. package/node_modules/pi-footer/src/ui/extension-statuses.ts +0 -73
  211. package/node_modules/pi-footer/src/ui/fields.ts +0 -252
  212. package/node_modules/pi-footer/src/ui/global-menu.ts +0 -126
  213. package/node_modules/pi-footer/src/ui/helpers.ts +0 -44
  214. package/node_modules/pi-footer/src/ui/layout.ts +0 -17
  215. package/node_modules/pi-footer/src/ui/line-list.ts +0 -19
  216. package/node_modules/pi-footer/src/ui/model.ts +0 -64
  217. package/node_modules/pi-footer/src/ui/navigation.ts +0 -29
  218. package/node_modules/pi-footer/src/ui/option-edit.ts +0 -93
  219. package/node_modules/pi-footer/src/ui/overlay-render.ts +0 -103
  220. package/node_modules/pi-footer/src/ui/screen-context.ts +0 -18
  221. package/node_modules/pi-footer/src/ui/screen-controller.ts +0 -27
  222. package/node_modules/pi-footer/src/ui/screen-render.ts +0 -32
  223. package/node_modules/pi-footer/src/ui/screen-state.ts +0 -20
  224. package/node_modules/pi-footer/src/ui/screen.ts +0 -243
  225. package/node_modules/pi-footer/src/ui/screens/add-widget.ts +0 -92
  226. package/node_modules/pi-footer/src/ui/screens/confirm-exit.ts +0 -52
  227. package/node_modules/pi-footer/src/ui/screens/controller.ts +0 -12
  228. package/node_modules/pi-footer/src/ui/screens/edit-colors.ts +0 -68
  229. package/node_modules/pi-footer/src/ui/screens/edit-widget.ts +0 -115
  230. package/node_modules/pi-footer/src/ui/screens/extension-status-row.ts +0 -61
  231. package/node_modules/pi-footer/src/ui/screens/global.ts +0 -75
  232. package/node_modules/pi-footer/src/ui/screens/line-list.ts +0 -108
  233. package/node_modules/pi-footer/src/ui/screens/main.ts +0 -99
  234. package/node_modules/pi-footer/src/ui/screens/terminal.ts +0 -121
  235. package/node_modules/pi-footer/src/ui/screens/widget-list.ts +0 -154
  236. package/node_modules/pi-footer/src/ui/terminal-menu.ts +0 -32
  237. package/node_modules/pi-footer/src/ui/theme.ts +0 -48
  238. package/node_modules/pi-footer/src/ui/title-bar.ts +0 -100
  239. package/node_modules/pi-footer/src/ui/widget-actions.ts +0 -76
  240. package/node_modules/pi-footer/src/ui.ts +0 -66
  241. package/node_modules/pi-footer/src/widgets/context.ts +0 -28
  242. package/node_modules/pi-footer/src/widgets/core/active-tools.ts +0 -17
  243. package/node_modules/pi-footer/src/widgets/core/context-window.ts +0 -24
  244. package/node_modules/pi-footer/src/widgets/core/cwd-basename.ts +0 -19
  245. package/node_modules/pi-footer/src/widgets/core/cwd.ts +0 -108
  246. package/node_modules/pi-footer/src/widgets/core/event.ts +0 -34
  247. package/node_modules/pi-footer/src/widgets/core/external-status.ts +0 -102
  248. package/node_modules/pi-footer/src/widgets/core/model-provider.ts +0 -20
  249. package/node_modules/pi-footer/src/widgets/core/model.ts +0 -35
  250. package/node_modules/pi-footer/src/widgets/core/provider.ts +0 -17
  251. package/node_modules/pi-footer/src/widgets/core/session-name.ts +0 -17
  252. package/node_modules/pi-footer/src/widgets/core/text-verbosity.ts +0 -17
  253. package/node_modules/pi-footer/src/widgets/core/thinking-level.ts +0 -17
  254. package/node_modules/pi-footer/src/widgets/git/ahead-behind.ts +0 -17
  255. package/node_modules/pi-footer/src/widgets/git/branch.ts +0 -81
  256. package/node_modules/pi-footer/src/widgets/git/clean.ts +0 -19
  257. package/node_modules/pi-footer/src/widgets/git/deletions.ts +0 -17
  258. package/node_modules/pi-footer/src/widgets/git/diff.ts +0 -38
  259. package/node_modules/pi-footer/src/widgets/git/insertions.ts +0 -17
  260. package/node_modules/pi-footer/src/widgets/git/remote.ts +0 -17
  261. package/node_modules/pi-footer/src/widgets/git/root.ts +0 -17
  262. package/node_modules/pi-footer/src/widgets/git/sha.ts +0 -17
  263. package/node_modules/pi-footer/src/widgets/git/staged.ts +0 -17
  264. package/node_modules/pi-footer/src/widgets/git/status.ts +0 -19
  265. package/node_modules/pi-footer/src/widgets/git/unstaged.ts +0 -17
  266. package/node_modules/pi-footer/src/widgets/git/untracked.ts +0 -17
  267. package/node_modules/pi-footer/src/widgets/instance.ts +0 -118
  268. package/node_modules/pi-footer/src/widgets/layout/custom-text.ts +0 -18
  269. package/node_modules/pi-footer/src/widgets/layout/flex-separator.ts +0 -32
  270. package/node_modules/pi-footer/src/widgets/layout/separator.ts +0 -57
  271. package/node_modules/pi-footer/src/widgets/layout/spacer.ts +0 -31
  272. package/node_modules/pi-footer/src/widgets/options.ts +0 -122
  273. package/node_modules/pi-footer/src/widgets/project/runtime.ts +0 -361
  274. package/node_modules/pi-footer/src/widgets/registry.ts +0 -223
  275. package/node_modules/pi-footer/src/widgets/session/assistant-messages.ts +0 -17
  276. package/node_modules/pi-footer/src/widgets/session/compactions.ts +0 -17
  277. package/node_modules/pi-footer/src/widgets/session/elapsed.ts +0 -18
  278. package/node_modules/pi-footer/src/widgets/session/last-activity.ts +0 -18
  279. package/node_modules/pi-footer/src/widgets/session/messages.ts +0 -19
  280. package/node_modules/pi-footer/src/widgets/session/session-id.ts +0 -17
  281. package/node_modules/pi-footer/src/widgets/session/session-start.ts +0 -18
  282. package/node_modules/pi-footer/src/widgets/session/tool-results.ts +0 -17
  283. package/node_modules/pi-footer/src/widgets/session/total-messages.ts +0 -19
  284. package/node_modules/pi-footer/src/widgets/session/total-time.ts +0 -18
  285. package/node_modules/pi-footer/src/widgets/session/user-messages.ts +0 -17
  286. package/node_modules/pi-footer/src/widgets/store.ts +0 -26
  287. package/node_modules/pi-footer/src/widgets/tokens/cache-hit-rate.ts +0 -55
  288. package/node_modules/pi-footer/src/widgets/tokens/cache-read.ts +0 -18
  289. package/node_modules/pi-footer/src/widgets/tokens/cache-write.ts +0 -18
  290. package/node_modules/pi-footer/src/widgets/tokens/context-bar.ts +0 -108
  291. package/node_modules/pi-footer/src/widgets/tokens/context-length.ts +0 -26
  292. package/node_modules/pi-footer/src/widgets/tokens/context-remaining.ts +0 -29
  293. package/node_modules/pi-footer/src/widgets/tokens/context.ts +0 -29
  294. package/node_modules/pi-footer/src/widgets/tokens/cost.ts +0 -51
  295. package/node_modules/pi-footer/src/widgets/tokens/input-speed.ts +0 -25
  296. package/node_modules/pi-footer/src/widgets/tokens/input-tokens.ts +0 -18
  297. package/node_modules/pi-footer/src/widgets/tokens/output-speed.ts +0 -25
  298. package/node_modules/pi-footer/src/widgets/tokens/output-tokens.ts +0 -18
  299. package/node_modules/pi-footer/src/widgets/tokens/tokens.ts +0 -20
  300. package/node_modules/pi-footer/src/widgets/tokens/total-speed.ts +0 -25
  301. package/node_modules/pi-footer/src/widgets/tokens/total-tokens.ts +0 -18
  302. package/node_modules/pi-footer/src/widgets/types.ts +0 -181
  303. package/node_modules/pi-footer/src/widgets/utils/colors.ts +0 -11
  304. package/node_modules/pi-footer/src/widgets/utils/context.ts +0 -112
  305. package/node_modules/pi-footer/src/widgets/utils/session.ts +0 -19
  306. package/node_modules/pi-footer/src/widgets/utils/token-format.ts +0 -78
  307. /package/node_modules/{@herbertgao/resume-from → resume-from}/LICENSE +0 -0
  308. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.js +0 -0
  309. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.d.ts +0 -0
  310. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.js +0 -0
  311. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.d.ts +0 -0
  312. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.js +0 -0
  313. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.d.ts +0 -0
  314. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.js +0 -0
  315. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.d.ts +0 -0
  316. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.js +0 -0
  317. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/redaction.d.ts +0 -0
  318. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.d.ts +0 -0
  319. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.js +0 -0
  320. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.js +0 -0
  321. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.d.ts +0 -0
  322. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.d.ts +0 -0
  323. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.js +0 -0
  324. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/redaction.d.ts +0 -0
  325. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.d.ts +0 -0
  326. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.js +0 -0
  327. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.js +0 -0
  328. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.d.ts +0 -0
  329. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.js +0 -0
  330. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.d.ts +0 -0
  331. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.js +0 -0
  332. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.d.ts +0 -0
  333. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.js +0 -0
  334. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.d.ts +0 -0
  335. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.js +0 -0
  336. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/redaction.d.ts +0 -0
  337. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.d.ts +0 -0
  338. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.js +0 -0
  339. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.d.ts +0 -0
  340. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.js +0 -0
  341. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.d.ts +0 -0
  342. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.js +0 -0
  343. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.d.ts +0 -0
  344. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.js +0 -0
  345. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.d.ts +0 -0
  346. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.js +0 -0
  347. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.d.ts +0 -0
  348. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.js +0 -0
  349. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.d.ts +0 -0
  350. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.js +0 -0
  351. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.d.ts +0 -0
  352. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.js +0 -0
  353. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.d.ts +0 -0
  354. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.js +0 -0
  355. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.d.ts +0 -0
  356. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.js +0 -0
  357. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.d.ts +0 -0
  358. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.js +0 -0
  359. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.d.ts +0 -0
  360. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.d.ts +0 -0
  361. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.js +0 -0
  362. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.d.ts +0 -0
  363. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.js +0 -0
  364. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.d.ts +0 -0
  365. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.js +0 -0
  366. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.d.ts +0 -0
  367. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.js +0 -0
  368. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.d.ts +0 -0
  369. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.js +0 -0
  370. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.d.ts +0 -0
  371. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.js +0 -0
  372. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.d.ts +0 -0
  373. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.js +0 -0
  374. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.d.ts +0 -0
  375. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.js +0 -0
  376. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.js +0 -0
  377. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.js +0 -0
  378. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.d.ts +0 -0
  379. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.js +0 -0
  380. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.d.ts +0 -0
  381. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.js +0 -0
  382. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.d.ts +0 -0
  383. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.js +0 -0
  384. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.d.ts +0 -0
  385. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.js +0 -0
  386. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.d.ts +0 -0
  387. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.js +0 -0
  388. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.d.ts +0 -0
  389. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.js +0 -0
  390. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.js +0 -0
  391. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.d.ts +0 -0
  392. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.js +0 -0
  393. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.d.ts +0 -0
  394. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.js +0 -0
  395. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.d.ts +0 -0
  396. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.js +0 -0
  397. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.d.ts +0 -0
  398. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.d.ts +0 -0
  399. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.js +0 -0
  400. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.d.ts +0 -0
  401. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.js +0 -0
  402. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.d.ts +0 -0
  403. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.js +0 -0
  404. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.d.ts +0 -0
  405. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.js +0 -0
  406. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.d.ts +0 -0
  407. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.js +0 -0
  408. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.d.ts +0 -0
  409. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.js +0 -0
  410. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.d.ts +0 -0
  411. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.js +0 -0
  412. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.d.ts +0 -0
  413. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.d.ts +0 -0
  414. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.js +0 -0
  415. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.d.ts +0 -0
  416. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.js +0 -0
  417. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.d.ts +0 -0
  418. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.js +0 -0
  419. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.d.ts +0 -0
  420. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.js +0 -0
  421. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.d.ts +0 -0
  422. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.js +0 -0
  423. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.d.ts +0 -0
  424. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.js +0 -0
  425. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.d.ts +0 -0
  426. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.js +0 -0
  427. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.d.ts +0 -0
  428. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.js +0 -0
  429. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.js +0 -0
  430. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.d.ts +0 -0
  431. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.js +0 -0
  432. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.d.ts +0 -0
  433. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.js +0 -0
  434. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.d.ts +0 -0
  435. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.js +0 -0
  436. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.d.ts +0 -0
  437. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.js +0 -0
  438. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.d.ts +0 -0
  439. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.js +0 -0
  440. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.d.ts +0 -0
  441. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.js +0 -0
  442. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.d.ts +0 -0
  443. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.js +0 -0
  444. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.js +0 -0
@@ -1,20 +1,29 @@
1
1
  import {
2
+ type BuildSystemPromptOptions,
2
3
  type ExtensionAPI,
3
4
  type ExtensionCommandContext,
4
- type Skill,
5
+ type ToolInfo,
5
6
  estimateTokens,
6
7
  formatSkillsForPrompt,
7
8
  getMarkdownTheme,
8
9
  } from "@earendil-works/pi-coding-agent";
9
- import { Key, Markdown, matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
10
+ import { Key, Markdown, matchesKey, visibleWidth } from "@earendil-works/pi-tui";
11
+ import { mouseBaseButton, parseSgrMousePacket } from "../utils/sgr-mouse.ts";
12
+ import { padLine } from "../utils/format.ts";
10
13
 
11
14
  export type ContextPart = {
12
15
  label: string;
13
16
  tokens: number;
14
- color: "accent" | "success" | "warning" | "muted" | "dim" | "error";
17
+ color: "accent" | "success" | "warning" | "customMessageLabel" | "muted" | "dim" | "error";
15
18
  };
16
19
 
17
- type PreviewKey = "systemPrompt" | "tools" | "toolResults" | "contextFiles" | "skills";
20
+ type PreviewKey =
21
+ | "systemPrompt"
22
+ | "memoryFiles"
23
+ | "skills"
24
+ | "tools"
25
+ | "toolResults"
26
+ | "contextFiles";
18
27
 
19
28
  type ContextPreview = {
20
29
  key: PreviewKey;
@@ -47,12 +56,12 @@ export function escCloseHitbox(bounds: DialogBounds): {
47
56
 
48
57
  let activeContextOverlays = 0;
49
58
 
50
- /** fullscreen 输入包装用于把鼠标事件继续传给当前 context overlay。 */
59
+ /** fullscreen 输入包装用于把鼠标事件继续传给当前 context 主弹框或文本预览 overlay。 */
51
60
  export function hasActiveTextPreview(): boolean {
52
61
  return activeContextOverlays > 0;
53
62
  }
54
63
 
55
- /** fullscreen overlays fall back to 1002; restore motion events for hover states. */
64
+ /** 官方 fullscreen 打开 overlay 时会退回 1002;重新启用 1003 才能收到无按键 hover。 */
56
65
  function ensureFullscreenMouseMotion(tui: any): void {
57
66
  if (tui.mode === "fullscreen") tui.terminal?.write?.("\x1b[?1003h\x1b[?1006h");
58
67
  }
@@ -175,6 +184,7 @@ export async function showTextPreview(
175
184
  else if (button === 65) scrollTo(scrollOffset + 3);
176
185
  }
177
186
  },
187
+
178
188
  render(width: number) {
179
189
  const inner = Math.max(1, width - 2);
180
190
  const escWidth = visibleWidth("[esc]");
@@ -197,10 +207,6 @@ export async function showTextPreview(
197
207
  escHitbox = escCloseHitbox({ left: overlayLeft, top: overlayTop, width });
198
208
  const visible = wrapped.slice(scrollOffset, scrollOffset + pageSize);
199
209
  const border = (text: string) => theme.fg("border", text);
200
- const padLine = (text: string, lineWidth = inner): string => {
201
- const truncated = truncateToWidth(text, lineWidth, "…");
202
- return truncated + " ".repeat(Math.max(0, lineWidth - visibleWidth(truncated)));
203
- };
204
210
  const scrollable = totalLines > pageSize;
205
211
  const thumbSize = scrollable
206
212
  ? Math.max(1, Math.floor((pageSize * pageSize) / totalLines))
@@ -239,7 +245,7 @@ export async function showTextPreview(
239
245
  `${border("├")}${border("─".repeat(inner))}${border("┤")}`,
240
246
  ...bodyRows,
241
247
  `${border("├")}${border("─".repeat(inner))}${border("┤")}`,
242
- `${border("│")}${padLine(theme.fg("dim", ` ${status}`))}${border("│")}`,
248
+ `${border("│")}${padLine(theme.fg("dim", ` ${status}`), inner)}${border("│")}`,
243
249
  border(`╰${"─".repeat(inner)}╯`),
244
250
  ];
245
251
  },
@@ -261,80 +267,18 @@ export async function showTextPreview(
261
267
  }
262
268
  }
263
269
 
264
- type SgrMousePacket = {
265
- code: number;
266
- col: number;
267
- row: number;
268
- final: "M" | "m";
269
- };
270
-
271
- function parseSgrMousePacket(data: string): SgrMousePacket | null {
272
- const match = data.match(/^\x1b\[<(\d+);(\d+);(\d+)([Mm])$/);
273
- if (!match) return null;
274
- return {
275
- code: Number(match[1]),
276
- col: Number(match[2]),
277
- row: Number(match[3]),
278
- final: match[4] as "M" | "m",
279
- };
280
- }
281
-
282
- function mouseBaseButton(code: number): number {
283
- return code & ~(4 | 8 | 16 | 32);
284
- }
285
-
286
270
  const tokenEstimate = (value: unknown): number => {
287
271
  if (!value) return 0;
288
272
  const text = typeof value === "string" ? value : JSON.stringify(value);
289
273
  return Math.max(0, Math.ceil(text.length / 4));
290
274
  };
291
275
 
276
+ /** 只统计确实嵌进 system prompt 的片段,避免源文件预览把占用加两遍。 */
292
277
  function embeddedTokens(prompt: string, chunk: string): number {
293
278
  if (!chunk || !prompt.includes(chunk)) return 0;
294
279
  return tokenEstimate(chunk);
295
280
  }
296
281
 
297
- type ToolPreviewInfo = {
298
- name: string;
299
- description?: string;
300
- promptGuidelines?: string[];
301
- };
302
-
303
- export function scaleParts(parts: ContextPart[], target: number): ContextPart[] {
304
- const estimated = parts.reduce((sum, part) => sum + part.tokens, 0);
305
- if (estimated === 0 || target <= 0) return parts;
306
- const scaled = parts.map((part) => ({
307
- ...part,
308
- tokens: Math.round((part.tokens / estimated) * target),
309
- }));
310
- const delta = target - scaled.reduce((sum, part) => sum + part.tokens, 0);
311
- const largest = scaled.reduce(
312
- (best, part, index) => (part.tokens > scaled[best]!.tokens ? index : best),
313
- 0,
314
- );
315
- scaled[largest]!.tokens += delta;
316
- return scaled;
317
- }
318
-
319
- export function resolveUsedTokens(
320
- usage: { tokens: number | null; percent: number | null } | undefined,
321
- estimated: number,
322
- contextWindow: number,
323
- ): number {
324
- const reported = usage?.tokens;
325
- const fromPercent =
326
- usage?.percent !== null && usage?.percent !== undefined && contextWindow > 0
327
- ? Math.round((usage.percent / 100) * contextWindow)
328
- : undefined;
329
- let resolved = reported ?? fromPercent ?? estimated;
330
- if (reported !== null && reported !== undefined && fromPercent !== undefined) {
331
- const tolerance = Math.max(32, Math.round(contextWindow * 0.001));
332
- if (Math.abs(reported - fromPercent) > tolerance) resolved = fromPercent;
333
- }
334
- if (estimated > 0 && resolved < estimated * 0.25) return estimated;
335
- return resolved;
336
- }
337
-
338
282
  export function capParts(parts: ContextPart[], target: number, fixedPrefix = 0): ContextPart[] {
339
283
  const fixed = parts.slice(0, fixedPrefix);
340
284
  const variable = parts.slice(fixedPrefix);
@@ -342,7 +286,10 @@ export function capParts(parts: ContextPart[], target: number, fixedPrefix = 0):
342
286
  const variableTarget = Math.max(0, target - fixedTokens);
343
287
  const estimated = variable.reduce((sum, part) => sum + part.tokens, 0);
344
288
  if (estimated <= variableTarget || estimated === 0) return parts;
345
- if (variableTarget === 0) return [...fixed, ...variable.map((part) => ({ ...part, tokens: 0 }))];
289
+ if (variableTarget === 0) {
290
+ return [...fixed, ...variable.map((part) => ({ ...part, tokens: 0 }))];
291
+ }
292
+
346
293
  let previous = 0;
347
294
  let cumulative = 0;
348
295
  const capped = variable.map((part, index) => {
@@ -364,78 +311,137 @@ export function formatTokens(tokens: number): string {
364
311
  return `${Math.round(tokens / 1_000)}k`;
365
312
  }
366
313
 
367
- type SystemPromptOptions = {
368
- contextFiles?: Array<{ path: string; content: string }>;
369
- skills?: Skill[];
370
- selectedTools?: string[];
371
- toolSnippets?: Record<string, string>;
372
- promptGuidelines?: string[];
373
- };
314
+ export function resolveUsedTokens(
315
+ usage: { tokens: number | null; percent: number | null } | undefined,
316
+ estimated: number,
317
+ contextWindow: number,
318
+ ): number {
319
+ const reported = usage?.tokens;
320
+ const fromPercent =
321
+ usage?.percent !== null && usage?.percent !== undefined && contextWindow > 0
322
+ ? Math.round((usage.percent / 100) * contextWindow)
323
+ : undefined;
324
+ let resolved = reported ?? fromPercent ?? estimated;
325
+ if (reported !== null && reported !== undefined && fromPercent !== undefined) {
326
+ // 某些 Provider 会返回异常 totalTokens;百分比与底部状态栏不一致时优先采用百分比。
327
+ const tolerance = Math.max(32, Math.round(contextWindow * 0.001));
328
+ if (Math.abs(reported - fromPercent) > tolerance) resolved = fromPercent;
329
+ }
330
+ // tokens 与 percent 可能同时源自异常 usage;数量级明显偏小时回退到实际内容估算。
331
+ if (estimated > 0 && resolved < estimated * 0.25) return estimated;
332
+ return resolved;
333
+ }
374
334
 
375
335
  type ContextBreakdown = {
376
336
  parts: ContextPart[];
377
- options: SystemPromptOptions;
378
- systemPrompt: string;
379
- toolResults: string;
337
+ previews: Record<PreviewKey, string>;
380
338
  };
381
339
 
382
- /**
383
- * Single pass over prompt options + session entries. Returns options/systemPrompt
384
- * so the /context UI does not re-fetch or re-stringify the same sources.
385
- */
386
- export function collectContextBreakdown(ctx: ExtensionCommandContext): ContextBreakdown {
387
- const options = (ctx.getSystemPromptOptions?.() ?? {}) as SystemPromptOptions;
340
+ function previewValue(value: unknown): string {
341
+ if (typeof value === "string") return value;
342
+ return `\`\`\`json\n${JSON.stringify(value, null, 2)}\n\`\`\``;
343
+ }
344
+
345
+ /** 按真实请求的 systemPrompt、tools、messages 三部分同步组装计数与预览。 */
346
+ export function collectContextBreakdown(
347
+ ctx: ExtensionCommandContext,
348
+ allTools: ToolInfo[],
349
+ ): ContextBreakdown {
350
+ const options = (ctx.getSystemPromptOptions?.() ?? {}) as BuildSystemPromptOptions;
388
351
  const systemPrompt = typeof ctx.getSystemPrompt === "function" ? ctx.getSystemPrompt() : "";
352
+ const selectedTools = new Set(options.selectedTools ?? ["read", "bash", "edit", "write"]);
353
+ const toolDefinitionPreview: string[] = [];
354
+ const toolResultPreview: string[] = [];
355
+ const contextPreview: string[] = [];
356
+ let toolDefinitionTokens = 0;
357
+ let toolResultTokens = 0;
358
+ let contextTokens = 0;
359
+
360
+ const memoryPreview: string[] = [];
361
+ let memoryTokens = 0;
362
+ for (const file of options.contextFiles ?? []) {
363
+ memoryTokens += embeddedTokens(systemPrompt, file.content);
364
+ memoryPreview.push(`## ${file.path}\n\n${previewValue(file.content)}`);
365
+ }
389
366
 
390
- const contextFileTokens = (options.contextFiles ?? []).reduce(
391
- (sum, file) => sum + embeddedTokens(systemPrompt, file.content),
392
- 0,
393
- );
394
367
  const skillsText = formatSkillsForPrompt(options.skills ?? []).trim();
395
- const skillTokens = embeddedTokens(systemPrompt, skillsText);
396
- const tools = options.selectedTools ?? [];
397
- const snippets = options.toolSnippets;
398
- let toolTokens = tokenEstimate(options.promptGuidelines);
399
- for (const name of tools) {
400
- toolTokens += tokenEstimate(name) + tokenEstimate(snippets?.[name]);
368
+ const skillsTokens = embeddedTokens(systemPrompt, skillsText);
369
+
370
+ for (const tool of allTools) {
371
+ if (!selectedTools.has(tool.name)) continue;
372
+ const definition = {
373
+ name: tool.name,
374
+ description: tool.description,
375
+ parameters: tool.parameters,
376
+ };
377
+ toolDefinitionTokens += tokenEstimate(definition);
378
+ toolDefinitionPreview.push(`## Definition: ${tool.name}\n\n${previewValue(definition)}`);
401
379
  }
402
380
 
403
- let user = 0;
404
- let assistant = 0;
405
- let toolResults = 0;
406
- let summaries = 0;
407
- const toolResultPreview: string[] = [];
408
381
  for (const entry of ctx.sessionManager.buildContextEntries()) {
409
382
  if (entry.type === "message") {
410
- const tokens = estimateTokens(entry.message);
411
- if (entry.message.role === "user") user += tokens;
412
- else if (entry.message.role === "assistant") assistant += tokens;
413
- else toolResults += tokens;
414
- if (entry.message.role === "toolResult") {
415
- toolResultPreview.push(`## Tool result\n\n${JSON.stringify(entry.message, null, 2)}`);
383
+ const message = entry.message;
384
+ if (message.role === "assistant") {
385
+ for (const block of message.content) {
386
+ if (block.type === "toolCall") {
387
+ contextTokens += tokenEstimate(block.name) + tokenEstimate(block.arguments);
388
+ contextPreview.push(
389
+ `## Assistant tool call: ${block.name}\n\n${previewValue(block.arguments)}`,
390
+ );
391
+ } else if (block.type === "text") {
392
+ contextTokens += tokenEstimate(block.text);
393
+ contextPreview.push(`## Assistant\n\n${block.text}`);
394
+ } else if (block.type === "thinking") {
395
+ contextTokens += tokenEstimate(block.thinking);
396
+ contextPreview.push(`## Assistant thinking\n\n${block.thinking}`);
397
+ }
398
+ }
399
+ } else if (message.role === "toolResult") {
400
+ toolResultTokens += estimateTokens(message);
401
+ toolResultPreview.push(
402
+ `## Result: ${message.toolName}\n\n${previewValue(message.content)}`,
403
+ );
404
+ } else if (message.role === "bashExecution") {
405
+ toolResultTokens += estimateTokens(message);
406
+ toolResultPreview.push(
407
+ `## Bash\n\nCommand:\n\n${previewValue(message.command)}\n\nOutput:\n\n${previewValue(message.output)}`,
408
+ );
409
+ } else if (message.role === "branchSummary" || message.role === "compactionSummary") {
410
+ contextTokens += estimateTokens(message);
411
+ contextPreview.push(`## ${message.role}\n\n${message.summary}`);
412
+ } else {
413
+ contextTokens += estimateTokens(message);
414
+ contextPreview.push(`## ${message.role}\n\n${previewValue(message.content)}`);
416
415
  }
417
416
  } else if (entry.type === "compaction" || entry.type === "branch_summary") {
418
- summaries += tokenEstimate(entry);
417
+ contextTokens += tokenEstimate(entry.summary);
418
+ contextPreview.push(
419
+ `## ${entry.type === "compaction" ? "Compaction" : "Branch summary"}\n\n${entry.summary}`,
420
+ );
421
+ } else if (entry.type === "custom_message") {
422
+ contextTokens += tokenEstimate(entry.content);
423
+ contextPreview.push(`## Custom: ${entry.customType}\n\n${previewValue(entry.content)}`);
419
424
  }
420
425
  }
421
426
 
422
- const systemTotal = tokenEstimate(systemPrompt);
423
- const baseSystem = Math.max(0, systemTotal - contextFileTokens - skillTokens - toolTokens);
424
- const parts: ContextPart[] = [
425
- { label: "System prompt", tokens: baseSystem, color: "accent" },
426
- { label: "Tools", tokens: toolTokens, color: "success" },
427
- { label: "Memory", tokens: contextFileTokens, color: "error" },
428
- { label: "Skills", tokens: skillTokens, color: "warning" },
429
- { label: "User messages", tokens: user, color: "muted" },
430
- { label: "Assistant messages", tokens: assistant, color: "accent" },
431
- { label: "Tool results", tokens: toolResults, color: "dim" },
432
- { label: "Compaction summaries", tokens: summaries, color: "success" },
433
- ];
427
+ const systemTokens = Math.max(0, tokenEstimate(systemPrompt) - memoryTokens - skillsTokens);
434
428
  return {
435
- parts: parts.filter((part) => part.tokens > 0),
436
- options,
437
- systemPrompt,
438
- toolResults: toolResultPreview.join("\n\n") || "No tool results in the current context.",
429
+ parts: [
430
+ { label: "System prompt", tokens: systemTokens, color: "accent" },
431
+ { label: "Memory", tokens: memoryTokens, color: "error" },
432
+ { label: "Skills", tokens: skillsTokens, color: "warning" },
433
+ { label: "Tools definition", tokens: toolDefinitionTokens, color: "success" },
434
+ { label: "Tool results", tokens: toolResultTokens, color: "customMessageLabel" },
435
+ { label: "Context", tokens: contextTokens, color: "warning" },
436
+ ] satisfies ContextPart[],
437
+ previews: {
438
+ systemPrompt: systemPrompt || "No system prompt.",
439
+ memoryFiles: memoryPreview.join("\n\n") || "No memory files in context.",
440
+ skills: skillsText || "No skills in context.",
441
+ tools: toolDefinitionPreview.join("\n\n") || "No active tool definitions.",
442
+ toolResults: toolResultPreview.join("\n\n") || "No tool results in the current context.",
443
+ contextFiles: contextPreview.join("\n\n") || "No conversation context.",
444
+ },
439
445
  };
440
446
  }
441
447
 
@@ -445,26 +451,13 @@ export default function contextUsageExtension(pi: ExtensionAPI) {
445
451
  handler: async (_args, ctx) => {
446
452
  const usage = ctx.getContextUsage();
447
453
  const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? 0;
448
- const breakdown = collectContextBreakdown(ctx);
454
+ const tools = pi.getAllTools();
455
+ const breakdown = collectContextBreakdown(ctx, tools);
449
456
  const estimated = breakdown.parts.reduce((sum, part) => sum + part.tokens, 0);
450
- const fixedParts = breakdown.parts.filter(
451
- (part) =>
452
- part.label === "System prompt" ||
453
- part.label === "Memory" ||
454
- part.label === "Skills" ||
455
- part.label === "Tools",
456
- );
457
- const variableParts = breakdown.parts.filter(
458
- (part) =>
459
- part.label !== "System prompt" &&
460
- part.label !== "Memory" &&
461
- part.label !== "Skills" &&
462
- part.label !== "Tools",
463
- );
464
- const orderedParts = [...fixedParts, ...variableParts];
465
- const fixedTokens = fixedParts.reduce((sum, part) => sum + part.tokens, 0);
457
+ // System / Memory / Skills / Tools definition 为固定项,capParts 时保持原值不压缩。
458
+ const fixedTokens = breakdown.parts.slice(0, 4).reduce((sum, part) => sum + part.tokens, 0);
466
459
  const used = Math.max(resolveUsedTokens(usage, estimated, contextWindow), fixedTokens);
467
- const parts = capParts(orderedParts, used, fixedParts.length);
460
+ const parts = capParts(breakdown.parts, used, 4);
468
461
  const attributed = parts.reduce((sum, part) => sum + part.tokens, 0);
469
462
  const other = Math.max(0, used - attributed);
470
463
  const free = Math.max(0, contextWindow - used);
@@ -480,70 +473,42 @@ export default function contextUsageExtension(pi: ExtensionAPI) {
480
473
  return;
481
474
  }
482
475
 
483
- const options = breakdown.options;
484
- const toolByName = new Map<string, ToolPreviewInfo>(
485
- (pi.getAllTools() as ToolPreviewInfo[]).map((tool) => [tool.name, tool] as const),
486
- );
487
- const toolContent = (options.selectedTools ?? []).map((name) => {
488
- const tool = toolByName.get(name);
489
- const lines = [`## ${name}`];
490
- if (tool?.description) lines.push(tool.description);
491
- if (options.toolSnippets?.[name]) lines.push(`Prompt: ${options.toolSnippets[name]}`);
492
- if (tool?.promptGuidelines?.length) {
493
- lines.push("Guidelines:", ...tool.promptGuidelines.map((guideline) => `- ${guideline}`));
494
- }
495
- return lines.join("\n");
496
- });
497
- if (options.promptGuidelines?.length) {
498
- toolContent.push(
499
- `## Shared prompt guidelines\n${options.promptGuidelines.map((guideline) => `- ${guideline}`).join("\n")}`,
500
- );
501
- }
502
- const contextFilesContent = (options.contextFiles ?? [])
503
- .map((file) => `===== ${file.path} =====\n${file.content}`)
504
- .join("\n\n");
505
- const skillsContent = (options.skills ?? [])
506
- .map((skill) =>
507
- [
508
- `## ${skill.name}`,
509
- skill.description,
510
- `Path: ${skill.filePath}`,
511
- `Model invocation: ${skill.disableModelInvocation ? "disabled" : "enabled"}`,
512
- ]
513
- .filter(Boolean)
514
- .join("\n"),
515
- )
516
- .join("\n\n");
517
476
  const rawPreviews: ContextPreview[] = [
518
477
  {
519
478
  key: "systemPrompt",
520
479
  label: "System prompt",
521
480
  title: "System Prompt",
522
- content: breakdown.systemPrompt,
481
+ content: breakdown.previews.systemPrompt,
482
+ },
483
+ {
484
+ key: "memoryFiles",
485
+ label: "Memory",
486
+ title: "Memory Files",
487
+ content: breakdown.previews.memoryFiles,
488
+ },
489
+ {
490
+ key: "skills",
491
+ label: "Skills",
492
+ title: "Skills",
493
+ content: breakdown.previews.skills,
523
494
  },
524
495
  {
525
496
  key: "tools",
526
- label: "Tools",
527
- title: "Tools",
528
- content: toolContent.join("\n\n") || "No active tools.",
497
+ label: "Tools definition",
498
+ title: "Tools definition",
499
+ content: breakdown.previews.tools,
529
500
  },
530
501
  {
531
502
  key: "toolResults",
532
503
  label: "Tool results",
533
504
  title: "Tool Results",
534
- content: breakdown.toolResults,
505
+ content: breakdown.previews.toolResults,
535
506
  },
536
507
  {
537
508
  key: "contextFiles",
538
- label: "Memory",
539
- title: "Memory Files",
540
- content: contextFilesContent || "No memory files loaded.",
541
- },
542
- {
543
- key: "skills",
544
- label: "Skills",
545
- title: "Skills",
546
- content: skillsContent || "No skills loaded.",
509
+ label: "Context",
510
+ title: "Context",
511
+ content: breakdown.previews.contextFiles,
547
512
  },
548
513
  ];
549
514
  const previews = rawPreviews.map((preview) => ({
@@ -557,179 +522,184 @@ export default function contextUsageExtension(pi: ExtensionAPI) {
557
522
  let selectedPreviewIndex = 0;
558
523
 
559
524
  while (true) {
525
+ // 主弹框也计入活动 overlay,fullscreen 下官方输入链才会把鼠标包放行给行点击。
560
526
  activeContextOverlays++;
561
- const actionPromise = ctx.ui.custom(
562
- (tui, theme, _keybindings, done) => {
563
- ensureFullscreenMouseMotion(tui);
564
- let previewHitboxes: Array<{
565
- key: PreviewKey;
566
- row: number;
567
- startCol: number;
568
- endCol: number;
569
- }> = [];
570
- let escHitbox: { row: number; startCol: number; endCol: number } | undefined;
571
- let escHovered = false;
572
- let hoveredKey: PreviewKey | undefined;
573
-
574
- const padLine = (text: string, width: number): string => {
575
- const truncated = truncateToWidth(text, width, "…");
576
- return truncated + " ".repeat(Math.max(0, width - visibleWidth(truncated)));
577
- };
578
-
579
- return {
580
- invalidate() {},
581
- handleInput(data: string) {
582
- if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c"))) {
583
- done(undefined);
584
- return;
585
- }
586
- if (matchesKey(data, Key.up) && visiblePreviews.length > 0) {
587
- selectedPreviewIndex =
588
- (selectedPreviewIndex - 1 + visiblePreviews.length) % visiblePreviews.length;
589
- tui.requestRender();
590
- return;
591
- }
592
- if (matchesKey(data, Key.down) && visiblePreviews.length > 0) {
593
- selectedPreviewIndex = (selectedPreviewIndex + 1) % visiblePreviews.length;
594
- tui.requestRender();
595
- return;
596
- }
597
- if (matchesKey(data, Key.enter)) {
598
- done(visiblePreviews[selectedPreviewIndex]?.key);
599
- return;
600
- }
527
+ let action;
528
+ try {
529
+ action = await ctx.ui.custom(
530
+ (tui, theme, _keybindings, done) => {
531
+ ensureFullscreenMouseMotion(tui);
532
+ let previewHitboxes: Array<{
533
+ key: PreviewKey;
534
+ row: number;
535
+ startCol: number;
536
+ endCol: number;
537
+ }> = [];
538
+ let escHitbox: { row: number; startCol: number; endCol: number } | undefined;
539
+ let escHovered = false;
540
+ let hoveredKey: PreviewKey | undefined;
541
+
542
+ return {
543
+ invalidate() {},
544
+ handleInput(data: string) {
545
+ if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c"))) {
546
+ done(undefined);
547
+ return;
548
+ }
549
+ if (matchesKey(data, Key.up) && visiblePreviews.length > 0) {
550
+ selectedPreviewIndex =
551
+ (selectedPreviewIndex - 1 + visiblePreviews.length) % visiblePreviews.length;
552
+ tui.requestRender();
553
+ return;
554
+ }
555
+ if (matchesKey(data, Key.down) && visiblePreviews.length > 0) {
556
+ selectedPreviewIndex = (selectedPreviewIndex + 1) % visiblePreviews.length;
557
+ tui.requestRender();
558
+ return;
559
+ }
560
+ if (matchesKey(data, Key.enter)) {
561
+ done(visiblePreviews[selectedPreviewIndex]?.key);
562
+ return;
563
+ }
601
564
 
602
- const mouse = parseSgrMousePacket(data);
603
- if (!mouse || mouse.final !== "M") return;
604
- const overEsc = Boolean(
605
- escHitbox &&
565
+ const mouse = parseSgrMousePacket(data);
566
+ if (!mouse || mouse.final !== "M") return;
567
+ if ((mouse.code & 32) !== 0) {
568
+ // SGR 1003 的无按键 hover code 为 35,不能按左键事件过滤。
569
+ const overEsc = Boolean(
570
+ escHitbox &&
571
+ mouse.row === escHitbox.row &&
572
+ mouse.col >= escHitbox.startCol &&
573
+ mouse.col <= escHitbox.endCol,
574
+ );
575
+ const hovered = previewHitboxes.find(
576
+ (candidate) =>
577
+ mouse.row === candidate.row &&
578
+ mouse.col >= candidate.startCol &&
579
+ mouse.col <= candidate.endCol,
580
+ );
581
+ if (overEsc !== escHovered || hovered?.key !== hoveredKey) {
582
+ escHovered = overEsc;
583
+ hoveredKey = hovered?.key;
584
+ tui.requestRender();
585
+ }
586
+ return;
587
+ }
588
+ if (mouseBaseButton(mouse.code) !== 0) return;
589
+ if (
590
+ escHitbox &&
606
591
  mouse.row === escHitbox.row &&
607
592
  mouse.col >= escHitbox.startCol &&
608
- mouse.col <= escHitbox.endCol,
609
- );
610
- const hitbox = previewHitboxes.find(
611
- (candidate) =>
612
- mouse.row === candidate.row &&
613
- mouse.col >= candidate.startCol &&
614
- mouse.col <= candidate.endCol,
615
- );
616
- if ((mouse.code & 32) !== 0) {
617
- if (overEsc !== escHovered || hitbox?.key !== hoveredKey) {
618
- escHovered = overEsc;
619
- hoveredKey = hitbox?.key;
620
- tui.requestRender();
593
+ mouse.col <= escHitbox.endCol
594
+ ) {
595
+ done(undefined);
596
+ return;
621
597
  }
622
- return;
623
- }
624
- if (mouseBaseButton(mouse.code) !== 0) return;
625
- if (overEsc) {
626
- done(undefined);
627
- return;
628
- }
629
- if (hitbox) {
630
- selectedPreviewIndex = Math.max(
631
- 0,
632
- visiblePreviews.findIndex((preview) => preview.key === hitbox.key),
598
+ const hitbox = previewHitboxes.find(
599
+ (candidate) =>
600
+ mouse.row === candidate.row &&
601
+ mouse.col >= candidate.startCol &&
602
+ mouse.col <= candidate.endCol,
633
603
  );
634
- done(hitbox.key);
635
- }
636
- },
637
- render(width: number) {
638
- const inner = Math.max(1, width - 2);
639
- const escWidth = visibleWidth("[esc]");
640
- const percent = contextWindow > 0 ? (used / contextWindow) * 100 : 0;
641
- const title = theme.bold(theme.fg("accent", "Context Usage"));
642
- const subtitle = `${formatTokens(used)} / ${formatTokens(contextWindow)} tokens (${percent.toFixed(1)}%)`;
643
- const barWidth = Math.max(1, Math.min(60, inner - 2));
644
- let remaining = barWidth;
645
- const segments = allParts
646
- .map((part, index) => {
647
- const cells =
648
- index === allParts.length - 1
649
- ? remaining
650
- : Math.min(
651
- remaining,
652
- Math.round((part.tokens / Math.max(1, contextWindow)) * barWidth),
653
- );
654
- remaining -= cells;
655
- return theme.fg(part.color, "█".repeat(Math.max(0, cells)));
656
- })
657
- .join("");
658
- const labelWidth = Math.min(
659
- 24,
660
- Math.max(...allParts.map((part) => part.label.length)),
661
- );
662
- const selectedLabel = visiblePreviews[selectedPreviewIndex]?.label;
663
- const hoverLabel = visiblePreviews.find(
664
- (preview) => preview.key === hoveredKey,
665
- )?.label;
666
- const partRows = allParts.map((part) => {
667
- const pct = contextWindow > 0 ? (part.tokens / contextWindow) * 100 : 0;
668
- const swatch = theme.fg(part.color, "■");
669
- const label = part.label.padEnd(labelWidth);
670
- const amount = `${formatTokens(part.tokens).padStart(7)} ${pct.toFixed(1).padStart(5)}%`;
671
- const selected = part.label === selectedLabel;
672
- const prefix = selected ? "› " : " ";
673
- const row = padLine(`${prefix}${swatch} ${label} ${amount}`, inner);
674
- if (selected) return theme.bg("selectedBg", row);
675
- return part.label === hoverLabel ? theme.bg("customMessageBg", row) : row;
676
- });
677
- const border = (text: string) => theme.fg("border", text);
678
- const lines = [
679
- border(`╭${"─".repeat(inner)}╮`),
680
- `${border("│")}${padLine(` ${title} ${theme.fg("muted", subtitle)}`, inner - escWidth)}${theme.fg(escHovered ? "text" : "muted", "[esc]")}${border("│")}`,
681
- `${border("├")}${border("─".repeat(inner))}${border("┤")}`,
682
- `${border("│")}${padLine(` ${segments}`, inner)}${border("│")}`,
683
- `${border("│")}${" ".repeat(inner)}${border("│")}`,
684
- ...partRows.map((row) => `${border("│")}${row}${border("│")}`),
685
- `${border("├")}${border("─".repeat(inner))}${border("┤")}`,
686
- `${border("│")}${padLine(theme.fg("dim", " ↑↓ select · Click / Enter to preview · [esc] close"), inner)}${border("│")}`,
687
- border(`╰${"─".repeat(inner)}╯`),
688
- ];
689
-
690
- const terminalHeight = Math.max(1, tui.terminal.rows);
691
- const maxHeight = Math.min(
692
- Math.max(1, Math.floor(terminalHeight * 0.9)),
693
- Math.max(1, terminalHeight - 2),
694
- );
695
- const visibleHeight = Math.min(lines.length, maxHeight);
696
- const overlayTop =
697
- 1 + Math.floor((Math.max(1, terminalHeight - 2) - visibleHeight) / 2);
698
- const overlayLeft = Math.floor((Math.max(1, tui.terminal.columns) - width) / 2);
699
- escHitbox = escCloseHitbox({ left: overlayLeft, top: overlayTop, width });
700
- previewHitboxes = visiblePreviews.flatMap((preview) => {
701
- const partIndex = allParts.findIndex((part) => part.label === preview.label);
702
- const line = 5 + partIndex;
703
- return partIndex >= 0 && line < visibleHeight
704
- ? [
705
- {
706
- key: preview.key,
707
- row: overlayTop + line + 1,
708
- startCol: overlayLeft + 1,
709
- endCol: overlayLeft + width,
710
- },
711
- ]
712
- : [];
713
- });
714
-
715
- return lines;
604
+ if (hitbox) {
605
+ selectedPreviewIndex = Math.max(
606
+ 0,
607
+ visiblePreviews.findIndex((preview) => preview.key === hitbox.key),
608
+ );
609
+ done(hitbox.key);
610
+ }
611
+ },
612
+ render(width: number) {
613
+ const inner = Math.max(1, width - 2);
614
+ const escWidth = visibleWidth("[esc]");
615
+ const percent = contextWindow > 0 ? (used / contextWindow) * 100 : 0;
616
+ const title = theme.bold(theme.fg("accent", "Context Usage"));
617
+ const subtitle = `${formatTokens(used)} / ${formatTokens(contextWindow)} tokens (${percent.toFixed(1)}%)`;
618
+ const barWidth = Math.max(1, Math.min(60, inner - 2));
619
+ let remaining = barWidth;
620
+ const segments = allParts
621
+ .map((part, index) => {
622
+ const cells =
623
+ index === allParts.length - 1
624
+ ? remaining
625
+ : Math.min(
626
+ remaining,
627
+ Math.round((part.tokens / Math.max(1, contextWindow)) * barWidth),
628
+ );
629
+ remaining -= cells;
630
+ return theme.fg(part.color, "█".repeat(Math.max(0, cells)));
631
+ })
632
+ .join("");
633
+ const labelWidth = Math.min(
634
+ 24,
635
+ Math.max(...allParts.map((part) => part.label.length)),
636
+ );
637
+ const selectedLabel = visiblePreviews[selectedPreviewIndex]?.label;
638
+ const partRows = allParts.map((part) => {
639
+ const pct = contextWindow > 0 ? (part.tokens / contextWindow) * 100 : 0;
640
+ const swatch = theme.fg(part.color, "■");
641
+ const label = part.label.padEnd(labelWidth);
642
+ const amount = `${formatTokens(part.tokens).padStart(7)} ${pct.toFixed(1).padStart(5)}%`;
643
+ const selected = part.label === selectedLabel;
644
+ const hoverLabel = visiblePreviews.find((p) => p.key === hoveredKey)?.label;
645
+ const prefix = selected ? "› " : " ";
646
+ const row = padLine(`${prefix}${swatch} ${label} ${amount}`, inner);
647
+ if (selected) return theme.bg("selectedBg", row);
648
+ return part.label === hoverLabel ? theme.bg("customMessageBg", row) : row;
649
+ });
650
+ const border = (text: string) => theme.fg("border", text);
651
+ const lines = [
652
+ border(`╭${"─".repeat(inner)}╮`),
653
+ `${border("│")}${padLine(` ${title} ${theme.fg("muted", subtitle)}`, inner - escWidth)}${theme.fg(escHovered ? "text" : "muted", "[esc]")}${border("│")}`,
654
+ `${border("├")}${border("─".repeat(inner))}${border("┤")}`,
655
+ `${border("│")}${padLine(` ${segments}`, inner)}${border("│")}`,
656
+ `${border("│")}${" ".repeat(inner)}${border("│")}`,
657
+ ...partRows.map((row) => `${border("│")}${row}${border("│")}`),
658
+ `${border("├")}${border("─".repeat(inner))}${border("┤")}`,
659
+ `${border("│")}${padLine(theme.fg("dim", " ↑↓ select · Click / Enter to preview · [esc] close"), inner)}${border("│")}`,
660
+ border(`╰${"─".repeat(inner)}╯`),
661
+ ];
662
+
663
+ const terminalHeight = Math.max(1, tui.terminal.rows);
664
+ const maxHeight = Math.min(
665
+ Math.max(1, Math.floor(terminalHeight * 0.9)),
666
+ Math.max(1, terminalHeight - 2),
667
+ );
668
+ const visibleHeight = Math.min(lines.length, maxHeight);
669
+ const overlayTop =
670
+ 1 + Math.floor((Math.max(1, terminalHeight - 2) - visibleHeight) / 2);
671
+ const overlayLeft = Math.floor((Math.max(1, tui.terminal.columns) - width) / 2);
672
+ escHitbox = escCloseHitbox({ left: overlayLeft, top: overlayTop, width });
673
+ previewHitboxes = visiblePreviews.flatMap((preview) => {
674
+ const partIndex = allParts.findIndex((part) => part.label === preview.label);
675
+ const line = 5 + partIndex;
676
+ return partIndex >= 0 && line < visibleHeight
677
+ ? [
678
+ {
679
+ key: preview.key,
680
+ row: overlayTop + line + 1,
681
+ startCol: overlayLeft + 1,
682
+ endCol: overlayLeft + width,
683
+ },
684
+ ]
685
+ : [];
686
+ });
687
+
688
+ return lines;
689
+ },
690
+ };
691
+ },
692
+ {
693
+ overlay: true,
694
+ overlayOptions: {
695
+ anchor: "center",
696
+ width: 64,
697
+ minWidth: 44,
698
+ maxHeight: "90%",
699
+ margin: 1,
716
700
  },
717
- };
718
- },
719
- {
720
- overlay: true,
721
- overlayOptions: {
722
- anchor: "center",
723
- width: 64,
724
- minWidth: 44,
725
- maxHeight: "90%",
726
- margin: 1,
727
701
  },
728
- },
729
- );
730
- let action;
731
- try {
732
- action = await actionPromise;
702
+ );
733
703
  } finally {
734
704
  activeContextOverlays--;
735
705
  }