@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
@@ -6,19 +6,34 @@ import {
6
6
  visibleWidth,
7
7
  type Component,
8
8
  } from "@earendil-works/pi-tui";
9
+ import { config } from "../../config/config.ts";
9
10
  import { TOOL_LOADING_INTERVAL_MS, toolLoadingIcon } from "../../utils/tool-loading-icon.ts";
10
- import { sanitizeToolResultText } from "../../utils/tool-result-sanitize.ts";
11
+ import {
12
+ CODEMODE_TOOL_NAME,
13
+ codemodeCalls,
14
+ codemodeOutputLineCount,
15
+ codemodeSummaryParts,
16
+ } from "./codemode.ts";
17
+ import { getToolMouseTui } from "../mouse/scroll.ts";
18
+ import { mcpToolTitle } from "./mcp-title.ts";
19
+ import { collapseHintText, isToolTuiFullscreen, showMoreHintText } from "./show-more-hint.ts";
20
+ import { stripAnsi, stripBackgroundAnsi, stripLeadingStatusIcon } from "../../utils/ansi-text.ts";
21
+ import { walkComponentTree } from "../../utils/component-tree.ts";
11
22
  import {
12
23
  fitToolCallSummary,
13
- pathSummary,
14
- toolViewportWidth,
24
+ humanizeToolLabel,
25
+ renderToolSummary,
26
+ toolCallSummary,
15
27
  type ToolCallSummary,
16
- } from "./result.ts";
17
- import { isToolTuiFullscreen, showMoreHintText } from "../show-more-hint.ts";
28
+ } from "./names.ts";
29
+ import { toolViewportWidth } from "./result.ts";
30
+ import {
31
+ patchRegistry,
32
+ TOOL_GROUPING_GENERATION_KEY as GENERATION_KEY,
33
+ TOOL_GROUPING_PARENT_KEY as PARENT_KEY,
34
+ TOOL_GROUPING_PATCH_KEY as PATCH_KEY,
35
+ } from "../../utils/patch-keys.ts";
18
36
 
19
- const PATCH_KEY = Symbol.for("pi.ccstyle.tool-grouping-patch");
20
- const PARENT_KEY = Symbol.for("pi.ccstyle.tool-grouping-parent");
21
- const GENERATION_KEY = Symbol.for("pi.ccstyle.tool-grouping-generation");
22
37
  const NON_GROUPABLE = new Set(["edit", "write", "apply_patch"]);
23
38
 
24
39
  type Patch = {
@@ -39,7 +54,20 @@ function toolName(tool: any): string {
39
54
  return String(tool?.toolName ?? tool?.toolDefinition?.name ?? "tool");
40
55
  }
41
56
 
42
- function isGroupable(value: unknown): value is any {
57
+ /**
58
+ * 标题:MCP 工具用 adapter 暴露的真实工具名,其余回退工具名人性化。
59
+ */
60
+ function toolTitle(tool: any): string {
61
+ const name = toolName(tool);
62
+ return (
63
+ mcpToolTitle({
64
+ toolName: name,
65
+ definition: tool?.toolDefinition ?? tool?.builtInToolDefinition,
66
+ }) ?? humanizeToolLabel(name)
67
+ );
68
+ }
69
+
70
+ function isGroupable(value: unknown): boolean {
43
71
  return value instanceof ToolExecutionComponent && !NON_GROUPABLE.has(toolName(value));
44
72
  }
45
73
 
@@ -85,37 +113,42 @@ function scheduleGroupAnimation(patch: Patch): void {
85
113
  patch.animationTimer = setTimeout(() => {
86
114
  patch.animationTimer = null;
87
115
  if (!patch.active) return;
116
+ let needsRender = false;
88
117
  for (const group of patch.groups) {
89
118
  if (
90
119
  (group.children as any[]).some(
91
120
  (tool) => tool?.executionStarted && status(tool) === "pending",
92
121
  )
93
- )
122
+ ) {
94
123
  group.invalidate();
124
+ // 分组卡不是 ToolExecutionComponent:它的 invalidate() 不会请求渲染,
125
+ // 不补这一步 spinner 只在别人渲染时才跳帧(并行工具下表现为卡顿/冻结)。
126
+ needsRender = true;
127
+ }
95
128
  }
129
+ if (needsRender) requestAnimationRender(patch);
96
130
  }, TOOL_LOADING_INTERVAL_MS);
97
131
  patch.animationTimer.unref?.();
98
132
  }
99
133
 
100
- function stripAnsi(line: string): string {
101
- return line.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "");
134
+ /** 借用子工具卡的 ui 请求一帧;子卡缺失时回退到扩展持有的 TUI 槽。 */
135
+ function requestAnimationRender(patch: Patch): void {
136
+ for (const group of patch.groups) {
137
+ const ui = (group.children as any[]).find(
138
+ (tool) => typeof tool?.ui?.requestRender === "function",
139
+ )?.ui;
140
+ if (ui) {
141
+ ui.requestRender();
142
+ return;
143
+ }
144
+ }
145
+ getToolMouseTui()?.requestRender?.();
102
146
  }
103
147
 
104
148
  function visibleLines(lines: string[]): string[] {
105
149
  return lines.filter((line) => stripAnsi(line).trim());
106
150
  }
107
151
 
108
- function stripLeadingStatusIcon(line: string): string {
109
- return line.replace(
110
- /^((?:\x1b\[[0-9;]*m|[ \t]|[├└│─])*)(?:\x1b\[[0-9;]*m)*(?:[✓✗●○■⬤•·⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏])(?:\x1b\[[0-9;]*m)*\s+/,
111
- "$1",
112
- );
113
- }
114
-
115
- export function stripBackgroundAnsi(line: string): string {
116
- return line.replace(/\x1b\[(?:4[0-9]|10[0-7]|48(?:(?:;|:)[0-9]+)+|49)m/g, "");
117
- }
118
-
119
152
  function stripLeadingSpaces(line: string, count: number): string {
120
153
  let offset = 0;
121
154
  let removed = 0;
@@ -138,10 +171,6 @@ function stripLeadingSpaces(line: string, count: number): string {
138
171
  }
139
172
 
140
173
  /** 生成一行铺满 width 的 slot 背景行;bgAnsiOverride 可替换背景 ANSI(用于提亮等)。 */
141
- function panelInnerWidth(width: number): number {
142
- return Math.max(0, Math.floor(width) - 2);
143
- }
144
-
145
174
  export function paddedBackgroundRow(
146
175
  theme: any,
147
176
  slot: string,
@@ -149,12 +178,9 @@ export function paddedBackgroundRow(
149
178
  width: number,
150
179
  bgAnsiOverride?: string,
151
180
  ): string {
152
- const safeWidth = Math.max(0, Math.floor(width));
153
- const leftPadding = safeWidth > 0 ? " " : "";
154
- const rightPadding = safeWidth > 1 ? " " : "";
155
- const innerWidth = panelInnerWidth(width);
181
+ const innerWidth = Math.max(0, width - 2);
156
182
  const clipped = truncateToWidth(stripBackgroundAnsi(content), innerWidth, "");
157
- const row = `${leftPadding}${clipped}${" ".repeat(Math.max(0, innerWidth - visibleWidth(clipped)))}${rightPadding}`;
183
+ const row = ` ${clipped}${" ".repeat(Math.max(0, innerWidth - visibleWidth(clipped)))} `;
158
184
  const bgAnsi =
159
185
  bgAnsiOverride ||
160
186
  (typeof theme?.bg === "function"
@@ -165,113 +191,26 @@ export function paddedBackgroundRow(
165
191
  return `${bgAnsi}${stable}\x1b[49m`;
166
192
  }
167
193
 
168
- function oneLine(value: unknown): string {
169
- return sanitizeToolResultText(String(value ?? ""), 4096)
170
- .replace(/\s+/g, " ")
171
- .trim();
172
- }
173
-
174
- function humanizeToolName(name: string): string {
175
- return name
176
- .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
177
- .replace(/[_-]+/g, " ")
178
- .replace(/\b\w/g, (char) => char.toUpperCase());
194
+ function toolSummary(tool: any): ToolCallSummary {
195
+ return toolCallSummary(toolName(tool), tool?.args ?? {}, {
196
+ title: toolTitle(tool),
197
+ variant: "grouping",
198
+ cwd: tool?.cwd,
199
+ });
179
200
  }
180
201
 
181
- function toolSummary(tool: any): ToolCallSummary {
182
- const name = toolName(tool);
183
- const lowerName = name.toLowerCase();
184
- const args = tool?.args ?? {};
185
- const titled = humanizeToolName(name);
186
- const value = (fallback: string, ...keys: string[]) => {
187
- const found = keys.map((key) => args[key]).find((item) => typeof item === "string" && item);
188
- return `${titled} ${oneLine(found || fallback)}`;
189
- };
190
- if (lowerName === "agent" || lowerName === "agents") {
191
- const displayName = args.subagent_type ?? args.agent_type ?? args.agent;
192
- if (typeof displayName === "string" && displayName) {
193
- return { main: `${titled} ${displayName}`, detail: "" };
194
- }
195
- return {
196
- main: value(
197
- lowerName === "agent" ? "launch agent" : "launch agents",
198
- "description",
199
- "prompt",
200
- ),
201
- detail: "",
202
- };
203
- }
204
- if (lowerName === "get_subagent_result" || lowerName === "steer_subagent") {
205
- return {
206
- main: value(lowerName === "get_subagent_result" ? "agent result" : "steer agent", "agent_id"),
207
- detail: "",
208
- };
209
- }
210
- if (lowerName === "skill") return { main: value("run skill", "name"), detail: "" };
211
- if (lowerName === "enterplanmode" || lowerName === "enter_plan_mode") {
212
- return { main: `${titled} enable read-only planning`, detail: "" };
213
- }
214
- if (lowerName === "exitplanmode" || lowerName === "exit_plan_mode") {
215
- return { main: `${titled} present plan`, detail: "" };
216
- }
217
- if (lowerName === "taskcreate") return { main: value("create task", "subject"), detail: "" };
218
- if (lowerName === "tasklist") return { main: `${titled} task list`, detail: "" };
219
- if (lowerName === "taskget" || lowerName === "taskupdate") {
220
- return { main: value("task", "taskId", "task_id"), detail: "" };
221
- }
222
- if (lowerName === "taskoutput" || lowerName === "taskstop") {
223
- return { main: value("background task", "task_id", "taskId"), detail: "" };
224
- }
225
- if (lowerName === "taskexecute") {
226
- const ids = Array.isArray(args.task_ids)
227
- ? args.task_ids
228
- : Array.isArray(args.taskIds)
229
- ? args.taskIds
230
- : [];
231
- return {
232
- main: `${titled} ${ids.length ? `${ids[0]}${ids.length > 1 ? ` (+${ids.length - 1} tasks)` : ""}` : "start tasks"}`,
233
- detail: "",
234
- };
235
- }
236
- if (name === "read") {
237
- const details = [
238
- args.offset !== undefined ? `offset=${args.offset}` : "",
239
- args.limit !== undefined ? `limit=${args.limit}` : "",
240
- ].filter(Boolean);
241
- const detail = details.length ? ` (${details.join(", ")})` : "";
242
- if (typeof args.path === "string" && args.path) {
243
- return pathSummary("Read", args.path, tool?.cwd, detail);
244
- }
245
- return { main: "Read ...", detail };
246
- }
247
- if (name === "bash") return { main: `Bash ${oneLine(args.command || "...")}`, detail: "" };
248
- if (name === "grep") {
249
- const pattern = oneLine(args.pattern || "...");
250
- return {
251
- main: `Grep ${JSON.stringify(pattern)}${args.path ? ` in ${oneLine(args.path)}` : ""}`,
252
- detail: "",
253
- };
254
- }
255
- if (name === "find") {
256
- const pattern = oneLine(args.pattern || "...");
257
- return {
258
- main: `Find ${JSON.stringify(pattern)}${args.path ? ` in ${oneLine(args.path)}` : ""}`,
259
- detail: "",
260
- };
261
- }
262
- const preferred =
263
- args.agent_id ??
264
- args.path ??
265
- args.file_path ??
266
- args.url ??
267
- args.description ??
268
- args.query ??
269
- args.name ??
270
- args.prompt;
271
- return {
272
- main: `${humanizeToolName(name)}${preferred === undefined ? "" : ` ${oneLine(preferred)}`}`,
273
- detail: "",
274
- };
202
+ /**
203
+ * codemode 的折叠行:有结果就报该次调用的统计(与单卡汇总行同一套口径),
204
+ * 免得一张卡里几行长代码预览互相看不出区别。还没结果时退回代码预览。
205
+ */
206
+ function codemodeResultSummary(tool: any): ToolCallSummary | undefined {
207
+ if (toolName(tool) !== CODEMODE_TOOL_NAME || !tool?.result) return undefined;
208
+ const parts = codemodeSummaryParts(
209
+ codemodeCalls(tool.result),
210
+ codemodeOutputLineCount(tool.result),
211
+ tool?.isPartial === true,
212
+ );
213
+ return { main: `${toolTitle(tool)} ${parts.join(" · ")}`, detail: "" };
275
214
  }
276
215
 
277
216
  function toolNameList(tools: any[]): string {
@@ -282,10 +221,6 @@ function toolNameList(tools: any[]): string {
282
221
 
283
222
  let nextGroupId = 1;
284
223
 
285
- function groupChildWidth(width: number): number {
286
- return Math.max(1, panelInnerWidth(width));
287
- }
288
-
289
224
  type SettledGroupCache = {
290
225
  width: number;
291
226
  hover: boolean;
@@ -297,6 +232,17 @@ type SettledGroupCache = {
297
232
  lines: string[];
298
233
  };
299
234
 
235
+ type ExpandedGroupCache = {
236
+ width: number;
237
+ hover: boolean;
238
+ theme: unknown;
239
+ fullscreen: boolean;
240
+ /** 背景槽位参与命中判断:改配置后已展开的分组不能继续用旧底色。 */
241
+ bgSlot: string;
242
+ paints: readonly unknown[];
243
+ lines: string[];
244
+ };
245
+
300
246
  export class ToolGroupComponent extends Container {
301
247
  readonly toolCallId = `ccstyle-tool-group-${nextGroupId++}`;
302
248
  readonly toolName = "Tool group";
@@ -307,8 +253,10 @@ export class ToolGroupComponent extends Container {
307
253
  }
308
254
  private hintHovered = false;
309
255
  private readonly patch: Patch;
310
- /** 仅缓存已完成且折叠的分组;pending / expanded 每帧现算。 */
256
+ /** 仅缓存已完成且折叠的分组;pending 每帧现算。 */
311
257
  private settledCache: SettledGroupCache | undefined;
258
+ /** 展开分组:子工具 paint 引用未变则复用整卡行。 */
259
+ private expandedPaintCache: ExpandedGroupCache | undefined;
312
260
 
313
261
  constructor(patch: Patch) {
314
262
  super();
@@ -316,14 +264,19 @@ export class ToolGroupComponent extends Container {
316
264
  patch.groups.add(this);
317
265
  }
318
266
 
319
- addTool(tool: any): void {
267
+ private clearPaintCache(): void {
320
268
  this.settledCache = undefined;
269
+ this.expandedPaintCache = undefined;
270
+ }
271
+
272
+ addTool(tool: any): void {
273
+ this.clearPaintCache();
321
274
  this.children.push(tool);
322
275
  tool[PARENT_KEY] = this;
323
276
  }
324
277
 
325
278
  releaseTools(): any[] {
326
- this.settledCache = undefined;
279
+ this.clearPaintCache();
327
280
  const tools = [...this.children];
328
281
  this.children.length = 0;
329
282
  this.patch.groups.delete(this);
@@ -331,27 +284,27 @@ export class ToolGroupComponent extends Container {
331
284
  }
332
285
 
333
286
  removeTool(tool: any): void {
334
- this.settledCache = undefined;
287
+ this.clearPaintCache();
335
288
  const index = this.children.indexOf(tool);
336
289
  if (index >= 0) this.children.splice(index, 1);
337
290
  if (tool?.[PARENT_KEY] === this) delete tool[PARENT_KEY];
338
291
  }
339
292
 
340
293
  setExpanded(expanded: boolean): void {
341
- if (this._expanded !== expanded) this.settledCache = undefined;
294
+ if (this._expanded !== expanded) this.clearPaintCache();
342
295
  this._expanded = expanded;
343
296
  for (const tool of this.children)
344
297
  (tool as Component & { setExpanded?: (expanded: boolean) => void }).setExpanded?.(expanded);
345
298
  }
346
299
 
347
300
  setHintHovered(hovered: boolean): void {
348
- if (this.hintHovered !== hovered) this.settledCache = undefined;
301
+ if (this.hintHovered !== hovered) this.clearPaintCache();
349
302
  this.hintHovered = hovered;
350
303
  }
351
304
 
352
305
  /**
353
306
  * 展开时按局部行定位内部组件(null = 行属于 group 自身:空行/头行/尾行)。
354
- * 行数计算与 render 保持一致:预留背景 padding、分支和状态前缀后再过滤空行。
307
+ * 行数计算与 render 保持一致:宽度 width-2 + 空行过滤。
355
308
  */
356
309
  childAtRow(localRow: number, width: number): { component: any; row: number } | null {
357
310
  if (!this._expanded || localRow < 2) return null;
@@ -359,7 +312,7 @@ export class ToolGroupComponent extends Container {
359
312
  for (const tool of this.children) {
360
313
  let lines: string[] = [];
361
314
  try {
362
- const rendered = tool.render?.(groupChildWidth(width));
315
+ const rendered = tool.render?.(Math.max(1, width - 2));
363
316
  if (Array.isArray(rendered)) lines = visibleLines(rendered.map((line) => String(line)));
364
317
  } catch {
365
318
  lines = [];
@@ -374,7 +327,7 @@ export class ToolGroupComponent extends Container {
374
327
  }
375
328
 
376
329
  invalidate(): void {
377
- this.settledCache = undefined;
330
+ this.clearPaintCache();
378
331
  for (const tool of this.children) tool.invalidate?.();
379
332
  }
380
333
 
@@ -432,28 +385,54 @@ export class ToolGroupComponent extends Container {
432
385
  const color = key === "pending" ? "accent" : key;
433
386
  return `${fg(color, String(counts[key]))} ${label}`;
434
387
  })
435
- .join(` ${fg("dim", "•")} `);
388
+ .join(` ${fg("dim", "·")} `);
436
389
  const names = new Set(this.children.map(toolName));
437
- const label =
438
- names.size === 1 ? humanizeToolName(toolName(this.children[0])) : "Multiple Tools";
390
+ const label = names.size === 1 ? toolTitle(this.children[0]) : "Multiple Tools";
439
391
  const overall: ToolStatus = counts.error ? "error" : counts.pending ? "pending" : "success";
440
392
  if (
441
393
  (this.children as any[]).some((tool) => tool?.executionStarted && status(tool) === "pending")
442
394
  )
443
395
  scheduleGroupAnimation(this.patch);
444
396
  const overallColor = overall === "pending" ? "accent" : overall;
445
- const nameList = names.size > 1 ? ` ${fg("dim", `• ${toolNameList(this.children)}`)}` : "";
397
+ const nameList = names.size > 1 ? ` ${fg("dim", `· ${toolNameList(this.children)}`)}` : "";
446
398
  // 圆点保持 dim;hover 只高亮可点击文字。
447
- const hint = `${fg("dim", "•")} ${fg(this.hintHovered ? "text" : "dim", showMoreHintText())}`;
448
- const lines = [
449
- "",
450
- truncateToWidth(
451
- ` ${fg(overallColor, "●")} ${label}: ${countText}${nameList} ${hint}`,
452
- toolViewportWidth(width),
453
- "…",
454
- ),
455
- ];
399
+ const hintText = this._expanded ? collapseHintText() : showMoreHintText();
400
+ const hint = `${fg("dim", "·")} ${fg(this.hintHovered ? "text" : "dim", hintText)}`;
401
+ // 行尾提示承载折叠分组的可点击区(collapsedHintHitbox 依赖行尾短语)。
402
+ // 空间不足时先省略工具名列表,再截断计数尾部,提示最后让位;
403
+ // 极窄视口连“圆点+标题+计数”都放不下时才回退整行截断。
404
+ const viewport = toolViewportWidth(width);
405
+ const head = ` ${fg(overallColor, "●")} ${label}: ${countText}`;
406
+ const hintWidth = visibleWidth(` ${hint}`);
407
+ const nameBudget = viewport - visibleWidth(head) - hintWidth;
408
+ const elidedName =
409
+ nameList && nameBudget < visibleWidth(nameList)
410
+ ? nameBudget >= 4
411
+ ? ` ${fg("dim", "…")}`
412
+ : ""
413
+ : nameList;
414
+ const headBudget = viewport - hintWidth - visibleWidth(elidedName);
415
+ const titleLine = `${visibleWidth(head) <= headBudget ? head : truncateToWidth(head, headBudget, "…")}${elidedName} ${hint}`;
416
+ const lines = ["", truncateToWidth(titleLine, viewport, "…")];
456
417
  const total = this.children.length;
418
+ const childPaints = this._expanded
419
+ ? (this.children as any[]).map((tool) => tool.render?.(Math.max(1, width - 2)))
420
+ : undefined;
421
+ if (this._expanded && childPaints) {
422
+ const expandedHit = this.expandedPaintCache;
423
+ if (
424
+ expandedHit &&
425
+ expandedHit.width === width &&
426
+ expandedHit.hover === this.hintHovered &&
427
+ expandedHit.theme === this.patch.theme &&
428
+ expandedHit.fullscreen === isToolTuiFullscreen() &&
429
+ expandedHit.bgSlot === config.expandedCardBackground &&
430
+ expandedHit.paints.length === childPaints.length &&
431
+ expandedHit.paints.every((paint, index) => paint === childPaints[index])
432
+ ) {
433
+ return expandedHit.lines;
434
+ }
435
+ }
457
436
  const expandedLines: string[] = [];
458
437
  for (let index = 0; index < total; index++) {
459
438
  const tool = this.children[index];
@@ -462,20 +441,22 @@ export class ToolGroupComponent extends Container {
462
441
  const branch = index === total - 1 ? "└" : "├";
463
442
  const continuation = index === total - 1 ? " " : "│ ";
464
443
  if (!this._expanded) {
465
- const summary = toolSummary(tool);
444
+ const summary = codemodeResultSummary(tool) ?? toolSummary(tool);
466
445
  const prefix = ` ${fg("dim", branch)} ${fg(color, statusIcon(toolStatus))} `;
467
446
  const detail = fg("dim", summary.detail);
468
- const mainWidth = Math.max(0, width - visibleWidth(prefix) - visibleWidth(detail));
447
+ // 与单工具卡标题同宽,宽屏右侧留白一致
448
+ const rowWidth = toolViewportWidth(width);
449
+ const mainWidth = Math.max(0, rowWidth - visibleWidth(prefix) - visibleWidth(detail));
469
450
  lines.push(
470
451
  truncateToWidth(
471
- `${prefix}${fg("toolTitle", fitToolCallSummary(summary, mainWidth))}${detail}`,
472
- width,
452
+ `${prefix}${renderToolSummary(summary, mainWidth, fg)}${detail}`,
453
+ rowWidth,
473
454
  "",
474
455
  ),
475
456
  );
476
457
  continue;
477
458
  }
478
- const rendered = visibleLines(tool.render(groupChildWidth(width)));
459
+ const rendered = visibleLines(Array.isArray(childPaints?.[index]) ? childPaints[index] : []);
479
460
  if (rendered.length) {
480
461
  rendered[0] = stripLeadingStatusIcon(rendered[0])
481
462
  .replace(/^ +/, "")
@@ -484,7 +465,8 @@ export class ToolGroupComponent extends Container {
484
465
  const childLines = rendered.length ? rendered : [toolSummary(tool).main];
485
466
  for (let lineIndex = 0; lineIndex < childLines.length; lineIndex++) {
486
467
  const content =
487
- lineIndex === 0 ? childLines[lineIndex] : stripLeadingSpaces(childLines[lineIndex], 2);
468
+ // 续行只剥外层 Box 的 1 格 left pad,保留 Input/Output 相对缩进
469
+ lineIndex === 0 ? childLines[lineIndex] : stripLeadingSpaces(childLines[lineIndex], 1);
488
470
  const prefix =
489
471
  lineIndex === 0
490
472
  ? `${fg("dim", branch)} ${fg(color, statusIcon(toolStatus))} `
@@ -493,12 +475,21 @@ export class ToolGroupComponent extends Container {
493
475
  }
494
476
  }
495
477
  if (this._expanded) {
496
- // 展开面板统一用 user message 背景色(ccstyle 约定),不按状态区分。
497
- const backgroundSlot = "userMessageBg";
478
+ // 展开面板统一一个背景槽位(ccstyle 约定),不按状态区分。
479
+ const backgroundSlot = config.expandedCardBackground;
498
480
  for (const line of expandedLines) {
499
481
  lines.push(paddedBackgroundRow(theme, backgroundSlot, line, width));
500
482
  }
501
483
  lines.push(paddedBackgroundRow(theme, backgroundSlot, "", width));
484
+ this.expandedPaintCache = {
485
+ width,
486
+ hover: this.hintHovered,
487
+ theme: this.patch.theme,
488
+ fullscreen: isToolTuiFullscreen(),
489
+ bgSlot: backgroundSlot,
490
+ paints: childPaints ?? [],
491
+ lines,
492
+ };
502
493
  } else if (counts.pending === 0) {
503
494
  this.storeSettledCache(width, lines);
504
495
  }
@@ -525,7 +516,7 @@ function ungroup(patch: Patch): void {
525
516
  }
526
517
  }
527
518
 
528
- function normalizeGroup(group: ToolGroupComponent): void {
519
+ function normalizeGroup(patch: Patch, group: ToolGroupComponent): void {
529
520
  if (group.children.length > 1) return;
530
521
  const parent = (group as any)[PARENT_KEY];
531
522
  const index = parent?.children?.indexOf(group) ?? -1;
@@ -574,32 +565,17 @@ function maybeGroup(patch: Patch, parent: any, component: any): void {
574
565
  /** /reload 不会重新 addChild;扫描当前 mounted roots,把已有工具重新送入同一分组规则。 */
575
566
  function regroup(patch: Patch, root: any): void {
576
567
  if (!patch.active || !patch.enabled() || !root) return;
577
- const seen = new Set<any>();
578
- const visit = (value: any): void => {
579
- if (!value || typeof value !== "object" || seen.has(value)) return;
580
- seen.add(value);
581
- if (Array.isArray(value)) {
582
- for (const child of value) visit(child);
583
- return;
584
- }
568
+ walkComponentTree(root, (value: any) => {
569
+ // 分组卡与可分组工具是分组边界:不继续下钻(与原有遍历过滤一致)。
570
+ if (value instanceof ToolGroupComponent || isGroupable(value)) return false;
585
571
  const children = value.children;
586
572
  if (Array.isArray(children)) {
587
573
  for (const child of [...children]) {
588
574
  if (child && typeof child === "object") child[PARENT_KEY] = value;
589
575
  maybeGroup(patch, value, child);
590
576
  }
591
- for (const child of [...children]) {
592
- if (!(child instanceof ToolGroupComponent) && !isGroupable(child)) visit(child);
593
- }
594
577
  }
595
- try {
596
- const mounted = value.getMountedRoots?.();
597
- if (Array.isArray(mounted)) visit(mounted);
598
- } catch {
599
- // renderer 切换中的惰性 Proxy 可能暂时没有 mounted roots。
600
- }
601
- };
602
- visit(root);
578
+ });
603
579
  }
604
580
 
605
581
  export type ToolGroupingHooks = {
@@ -610,8 +586,7 @@ export type ToolGroupingHooks = {
610
586
 
611
587
  export function installToolGrouping(getEnabled: () => boolean): ToolGroupingHooks {
612
588
  const prototype = Container.prototype as any;
613
- const host = globalThis as any;
614
- const previous = host[PATCH_KEY] as Patch | undefined;
589
+ const previous = patchRegistry.get<Patch>(PATCH_KEY);
615
590
  if (previous) {
616
591
  previous.active = false;
617
592
  previous.enabled = () => false;
@@ -656,12 +631,12 @@ export function installToolGrouping(getEnabled: () => boolean): ToolGroupingHook
656
631
  const group = component?.[PARENT_KEY];
657
632
  if (group instanceof ToolGroupComponent && (group as any)[PARENT_KEY] === this) {
658
633
  group.removeTool(component);
659
- normalizeGroup(group);
634
+ normalizeGroup(patch, group);
660
635
  return;
661
636
  }
662
637
  const result = patch.original.removeChild.call(this, component);
663
638
  if (component?.[PARENT_KEY] === this) delete component[PARENT_KEY];
664
- if (this instanceof ToolGroupComponent) normalizeGroup(this);
639
+ if (this instanceof ToolGroupComponent) normalizeGroup(patch, this);
665
640
  if (component instanceof ToolGroupComponent) {
666
641
  for (const tool of component.releaseTools()) delete tool[PARENT_KEY];
667
642
  }
@@ -681,7 +656,7 @@ export function installToolGrouping(getEnabled: () => boolean): ToolGroupingHook
681
656
  prototype.addChild = patch.installed.addChild;
682
657
  prototype.removeChild = patch.installed.removeChild;
683
658
  prototype.clear = patch.installed.clear;
684
- host[PATCH_KEY] = patch;
659
+ patchRegistry.install(PATCH_KEY, patch);
685
660
  return {
686
661
  setTheme(theme: any) {
687
662
  patch.theme = theme;
@@ -0,0 +1,39 @@
1
+ import { humanizeToolLabel } from "./names.ts";
2
+
3
+ /**
4
+ * MCP 工具的识别与标题,单卡(default-mode)与分组行/分组头(grouping)共用。
5
+ *
6
+ * - 判定:工具名带 mcp 片段(`mcp` 网关、`mcpScript`、`mcp__<server>`),或 adapter 注册时
7
+ * 给的 label 以 `MCP:` 开头。默认/none/short 前缀模式下直连工具的名字里没有 mcp 片段
8
+ * (`github_search_code`、`search_code`),只能靠 label 判定。
9
+ * - 标题:具体工具用 adapter 暴露的真实工具名,不做二次格式化;只有 `mcp` / `mcpScript`
10
+ * 这两个入口没有具体工具名,跟普通工具一样人性化(MCP / MCP Script)。
11
+ * - 参数摘要与其它工具共用 toolCallSummary 的字段链,网关额外把 `args.tool` 提到标题后。
12
+ */
13
+
14
+ /** 单次 MCP 调用的识别信息。 */
15
+ export type McpToolCall = {
16
+ toolName: string;
17
+ /** 工具定义;默认/none/short 前缀模式要靠 label 判定,会话重放时可能缺失。 */
18
+ definition?: any;
19
+ };
20
+
21
+ const GATEWAY_TOOL_NAME = "mcp";
22
+ const SCRIPT_TOOL_NAME = "mcpScript";
23
+
24
+ export function isMcpToolDefinition(definition: any, toolName: string): boolean {
25
+ const label = typeof definition?.label === "string" ? definition.label.trim() : "";
26
+ if (/^MCP(?::|$)/i.test(label)) return true;
27
+ if (toolName === GATEWAY_TOOL_NAME || toolName === SCRIPT_TOOL_NAME) return true;
28
+ return /^mcp[_:-]|[_:-]mcp[_:-]/i.test(toolName);
29
+ }
30
+
31
+ /** 标题:MCP 工具返回标题(入口走人性化,其余用真实工具名);非 MCP 返回 undefined。 */
32
+ export function mcpToolTitle(call: McpToolCall): string | undefined {
33
+ const { toolName } = call;
34
+ if (!isMcpToolDefinition(call.definition, toolName)) return undefined;
35
+ if (toolName === GATEWAY_TOOL_NAME || toolName === SCRIPT_TOOL_NAME) {
36
+ return humanizeToolLabel(toolName);
37
+ }
38
+ return toolName;
39
+ }