@herbertgao/pi-extensions 2026.8.2 → 2026.8.4

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 (392) hide show
  1. package/README.md +50 -2
  2. package/examples/pi-footer.json +275 -0
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +6 -8
  4. package/node_modules/@herbertgao/pi-cc-extensions/README.md +5 -7
  5. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +101 -0
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +1 -17
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +5 -3
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/{utils/agent-summary.ts → feature/agent-summary/core.ts} +37 -35
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-summary.ts → agent-summary/index.ts} +2 -6
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference.ts → reference/index.ts} +1 -1
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-autocomplete.ts → reference/subagent.ts} +19 -9
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-startup-header.ts → shell/startup-header.ts} +1 -1
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{working-message.ts → shell/working-message.ts} +5 -2
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +32 -28
  15. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +379 -85
  16. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +727 -0
  17. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +65 -775
  18. package/node_modules/@herbertgao/pi-cc-extensions/extensions/{feature → renderer}/markdown-enhance.ts +35 -31
  19. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-hover.ts → mouse/hover.ts} +5 -5
  20. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +34 -35
  21. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-layout.ts → mouse/layout.ts} +5 -21
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-packets.ts → mouse/packets.ts} +1 -1
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-scroll.ts → mouse/scroll.ts} +48 -37
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ansi-utils.ts +56 -1
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-renderer.ts +2 -2
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/line-width-safety.ts +1 -1
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +12 -0
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/write-execution.ts +1 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-grouping.ts → tool/grouping.ts} +18 -8
  30. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-result.ts → tool/result.ts} +4 -13
  31. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +0 -27
  32. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  33. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  34. package/node_modules/@herbertgao/pi-subagents/package.json +2 -2
  35. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +1 -0
  36. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +3 -1
  37. package/node_modules/@herbertgao/pi-subagents/src/index.ts +33 -35
  38. package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +26 -35
  39. package/node_modules/@herbertgao/pi-subagents/src/prompts.ts +15 -1
  40. package/node_modules/pi-footer/CHANGELOG.md +145 -0
  41. package/node_modules/pi-footer/LICENSE +21 -0
  42. package/node_modules/pi-footer/README.md +354 -0
  43. package/node_modules/pi-footer/package.json +68 -0
  44. package/node_modules/pi-footer/src/cache.ts +106 -0
  45. package/node_modules/pi-footer/src/colors.ts +237 -0
  46. package/node_modules/pi-footer/src/config.ts +202 -0
  47. package/node_modules/pi-footer/src/event-widgets.ts +41 -0
  48. package/node_modules/pi-footer/src/extension-statuses.ts +102 -0
  49. package/node_modules/pi-footer/src/git.ts +135 -0
  50. package/node_modules/pi-footer/src/index.ts +268 -0
  51. package/node_modules/pi-footer/src/metrics.ts +141 -0
  52. package/node_modules/pi-footer/src/presets.ts +383 -0
  53. package/node_modules/pi-footer/src/render.ts +114 -0
  54. package/node_modules/pi-footer/src/separators.ts +52 -0
  55. package/node_modules/pi-footer/src/types.ts +122 -0
  56. package/node_modules/pi-footer/src/ui/color-level-confirm.ts +22 -0
  57. package/node_modules/pi-footer/src/ui/color-options.ts +195 -0
  58. package/node_modules/pi-footer/src/ui/config-lifecycle.ts +61 -0
  59. package/node_modules/pi-footer/src/ui/edit-colors.ts +13 -0
  60. package/node_modules/pi-footer/src/ui/events.ts +35 -0
  61. package/node_modules/pi-footer/src/ui/extension-status-picker.ts +60 -0
  62. package/node_modules/pi-footer/src/ui/extension-statuses.ts +73 -0
  63. package/node_modules/pi-footer/src/ui/fields.ts +252 -0
  64. package/node_modules/pi-footer/src/ui/global-menu.ts +126 -0
  65. package/node_modules/pi-footer/src/ui/helpers.ts +44 -0
  66. package/node_modules/pi-footer/src/ui/layout.ts +17 -0
  67. package/node_modules/pi-footer/src/ui/line-list.ts +19 -0
  68. package/node_modules/pi-footer/src/ui/model.ts +64 -0
  69. package/node_modules/pi-footer/src/ui/navigation.ts +29 -0
  70. package/node_modules/pi-footer/src/ui/option-edit.ts +93 -0
  71. package/node_modules/pi-footer/src/ui/overlay-render.ts +103 -0
  72. package/node_modules/pi-footer/src/ui/screen-context.ts +18 -0
  73. package/node_modules/pi-footer/src/ui/screen-controller.ts +27 -0
  74. package/node_modules/pi-footer/src/ui/screen-render.ts +32 -0
  75. package/node_modules/pi-footer/src/ui/screen-state.ts +20 -0
  76. package/node_modules/pi-footer/src/ui/screen.ts +243 -0
  77. package/node_modules/pi-footer/src/ui/screens/add-widget.ts +92 -0
  78. package/node_modules/pi-footer/src/ui/screens/confirm-exit.ts +52 -0
  79. package/node_modules/pi-footer/src/ui/screens/controller.ts +12 -0
  80. package/node_modules/pi-footer/src/ui/screens/edit-colors.ts +68 -0
  81. package/node_modules/pi-footer/src/ui/screens/edit-widget.ts +115 -0
  82. package/node_modules/pi-footer/src/ui/screens/extension-status-row.ts +61 -0
  83. package/node_modules/pi-footer/src/ui/screens/global.ts +75 -0
  84. package/node_modules/pi-footer/src/ui/screens/line-list.ts +108 -0
  85. package/node_modules/pi-footer/src/ui/screens/main.ts +99 -0
  86. package/node_modules/pi-footer/src/ui/screens/terminal.ts +121 -0
  87. package/node_modules/pi-footer/src/ui/screens/widget-list.ts +154 -0
  88. package/node_modules/pi-footer/src/ui/terminal-menu.ts +32 -0
  89. package/node_modules/pi-footer/src/ui/theme.ts +48 -0
  90. package/node_modules/pi-footer/src/ui/title-bar.ts +100 -0
  91. package/node_modules/pi-footer/src/ui/widget-actions.ts +76 -0
  92. package/node_modules/pi-footer/src/ui.ts +66 -0
  93. package/node_modules/pi-footer/src/widgets/context.ts +28 -0
  94. package/node_modules/pi-footer/src/widgets/core/active-tools.ts +17 -0
  95. package/node_modules/pi-footer/src/widgets/core/context-window.ts +24 -0
  96. package/node_modules/pi-footer/src/widgets/core/cwd-basename.ts +19 -0
  97. package/node_modules/pi-footer/src/widgets/core/cwd.ts +108 -0
  98. package/node_modules/pi-footer/src/widgets/core/event.ts +34 -0
  99. package/node_modules/pi-footer/src/widgets/core/external-status.ts +102 -0
  100. package/node_modules/pi-footer/src/widgets/core/model-provider.ts +20 -0
  101. package/node_modules/pi-footer/src/widgets/core/model.ts +35 -0
  102. package/node_modules/pi-footer/src/widgets/core/provider.ts +17 -0
  103. package/node_modules/pi-footer/src/widgets/core/session-name.ts +17 -0
  104. package/node_modules/pi-footer/src/widgets/core/text-verbosity.ts +17 -0
  105. package/node_modules/pi-footer/src/widgets/core/thinking-level.ts +17 -0
  106. package/node_modules/pi-footer/src/widgets/git/ahead-behind.ts +17 -0
  107. package/node_modules/pi-footer/src/widgets/git/branch.ts +81 -0
  108. package/node_modules/pi-footer/src/widgets/git/clean.ts +19 -0
  109. package/node_modules/pi-footer/src/widgets/git/deletions.ts +17 -0
  110. package/node_modules/pi-footer/src/widgets/git/diff.ts +38 -0
  111. package/node_modules/pi-footer/src/widgets/git/insertions.ts +17 -0
  112. package/node_modules/pi-footer/src/widgets/git/remote.ts +17 -0
  113. package/node_modules/pi-footer/src/widgets/git/root.ts +17 -0
  114. package/node_modules/pi-footer/src/widgets/git/sha.ts +17 -0
  115. package/node_modules/pi-footer/src/widgets/git/staged.ts +17 -0
  116. package/node_modules/pi-footer/src/widgets/git/status.ts +19 -0
  117. package/node_modules/pi-footer/src/widgets/git/unstaged.ts +17 -0
  118. package/node_modules/pi-footer/src/widgets/git/untracked.ts +17 -0
  119. package/node_modules/pi-footer/src/widgets/instance.ts +118 -0
  120. package/node_modules/pi-footer/src/widgets/layout/custom-text.ts +18 -0
  121. package/node_modules/pi-footer/src/widgets/layout/flex-separator.ts +32 -0
  122. package/node_modules/pi-footer/src/widgets/layout/separator.ts +57 -0
  123. package/node_modules/pi-footer/src/widgets/layout/spacer.ts +31 -0
  124. package/node_modules/pi-footer/src/widgets/options.ts +122 -0
  125. package/node_modules/pi-footer/src/widgets/project/runtime.ts +361 -0
  126. package/node_modules/pi-footer/src/widgets/registry.ts +223 -0
  127. package/node_modules/pi-footer/src/widgets/session/assistant-messages.ts +17 -0
  128. package/node_modules/pi-footer/src/widgets/session/compactions.ts +17 -0
  129. package/node_modules/pi-footer/src/widgets/session/elapsed.ts +18 -0
  130. package/node_modules/pi-footer/src/widgets/session/last-activity.ts +18 -0
  131. package/node_modules/pi-footer/src/widgets/session/messages.ts +19 -0
  132. package/node_modules/pi-footer/src/widgets/session/session-id.ts +17 -0
  133. package/node_modules/pi-footer/src/widgets/session/session-start.ts +18 -0
  134. package/node_modules/pi-footer/src/widgets/session/tool-results.ts +17 -0
  135. package/node_modules/pi-footer/src/widgets/session/total-messages.ts +19 -0
  136. package/node_modules/pi-footer/src/widgets/session/total-time.ts +18 -0
  137. package/node_modules/pi-footer/src/widgets/session/user-messages.ts +17 -0
  138. package/node_modules/pi-footer/src/widgets/store.ts +26 -0
  139. package/node_modules/pi-footer/src/widgets/tokens/cache-hit-rate.ts +55 -0
  140. package/node_modules/pi-footer/src/widgets/tokens/cache-read.ts +18 -0
  141. package/node_modules/pi-footer/src/widgets/tokens/cache-write.ts +18 -0
  142. package/node_modules/pi-footer/src/widgets/tokens/context-bar.ts +108 -0
  143. package/node_modules/pi-footer/src/widgets/tokens/context-length.ts +26 -0
  144. package/node_modules/pi-footer/src/widgets/tokens/context-remaining.ts +29 -0
  145. package/node_modules/pi-footer/src/widgets/tokens/context.ts +29 -0
  146. package/node_modules/pi-footer/src/widgets/tokens/cost.ts +51 -0
  147. package/node_modules/pi-footer/src/widgets/tokens/input-speed.ts +25 -0
  148. package/node_modules/pi-footer/src/widgets/tokens/input-tokens.ts +18 -0
  149. package/node_modules/pi-footer/src/widgets/tokens/output-speed.ts +25 -0
  150. package/node_modules/pi-footer/src/widgets/tokens/output-tokens.ts +18 -0
  151. package/node_modules/pi-footer/src/widgets/tokens/tokens.ts +20 -0
  152. package/node_modules/pi-footer/src/widgets/tokens/total-speed.ts +25 -0
  153. package/node_modules/pi-footer/src/widgets/tokens/total-tokens.ts +18 -0
  154. package/node_modules/pi-footer/src/widgets/types.ts +181 -0
  155. package/node_modules/pi-footer/src/widgets/utils/colors.ts +11 -0
  156. package/node_modules/pi-footer/src/widgets/utils/context.ts +112 -0
  157. package/node_modules/pi-footer/src/widgets/utils/session.ts +19 -0
  158. package/node_modules/pi-footer/src/widgets/utils/token-format.ts +78 -0
  159. package/node_modules/pi-mcp-adapter/CHANGELOG.md +19 -0
  160. package/node_modules/pi-mcp-adapter/README.md +19 -4
  161. package/node_modules/pi-mcp-adapter/agent-dir.ts +40 -0
  162. package/node_modules/pi-mcp-adapter/commands.ts +12 -2
  163. package/node_modules/pi-mcp-adapter/direct-tools.ts +6 -8
  164. package/node_modules/pi-mcp-adapter/index.ts +15 -3
  165. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +87 -4
  166. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +138 -61
  167. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +43 -4
  168. package/node_modules/pi-mcp-adapter/oauth.ts +48 -0
  169. package/node_modules/pi-mcp-adapter/package.json +8 -2
  170. package/node_modules/pi-mcp-adapter/proxy-modes.ts +8 -10
  171. package/node_modules/pi-mcp-adapter/tool-registrar.ts +187 -3
  172. package/node_modules/pi-mcp-adapter/types.ts +2 -0
  173. package/node_modules/pi-web-access/CHANGELOG.md +45 -0
  174. package/node_modules/pi-web-access/README.md +104 -29
  175. package/node_modules/pi-web-access/bocha.ts +221 -0
  176. package/node_modules/pi-web-access/curator-page.ts +113 -12
  177. package/node_modules/pi-web-access/curator-server.ts +56 -20
  178. package/node_modules/pi-web-access/datalab-pdf-extract.ts +568 -0
  179. package/node_modules/pi-web-access/duckduckgo.ts +123 -0
  180. package/node_modules/pi-web-access/extract.ts +288 -143
  181. package/node_modules/pi-web-access/feature-config.ts +29 -0
  182. package/node_modules/pi-web-access/gemini-api.ts +4 -0
  183. package/node_modules/pi-web-access/gemini-search.ts +45 -12
  184. package/node_modules/pi-web-access/gemini-web.ts +68 -3
  185. package/node_modules/pi-web-access/index.ts +160 -71
  186. package/node_modules/pi-web-access/jina-search.ts +284 -0
  187. package/node_modules/pi-web-access/kagi.ts +12 -12
  188. package/node_modules/pi-web-access/openai-search.ts +12 -2
  189. package/node_modules/pi-web-access/package.json +4 -3
  190. package/node_modules/pi-web-access/pdf-extract.ts +327 -228
  191. package/node_modules/pi-web-access/storage.ts +440 -2
  192. package/node_modules/pi-web-access/summary-model-scope.ts +1 -1
  193. package/node_modules/pi-web-access/summary-review.ts +4 -2
  194. package/node_modules/pi-web-access/video-extract.ts +10 -8
  195. package/node_modules/pi-web-access/xai-search.ts +12 -2
  196. package/node_modules/pi-web-access/youtube-extract.ts +2 -1
  197. package/node_modules/remote-pi/LICENSE +21 -0
  198. package/node_modules/remote-pi/README.md +675 -0
  199. package/node_modules/remote-pi/dist/actions/handlers.d.ts +122 -0
  200. package/node_modules/remote-pi/dist/actions/handlers.js +160 -0
  201. package/node_modules/remote-pi/dist/actions/handlers.js.map +1 -0
  202. package/node_modules/remote-pi/dist/actions/registry.d.ts +39 -0
  203. package/node_modules/remote-pi/dist/actions/registry.js +58 -0
  204. package/node_modules/remote-pi/dist/actions/registry.js.map +1 -0
  205. package/node_modules/remote-pi/dist/bin/supervisord.d.ts +2 -0
  206. package/node_modules/remote-pi/dist/bin/supervisord.js +86 -0
  207. package/node_modules/remote-pi/dist/bin/supervisord.js.map +1 -0
  208. package/node_modules/remote-pi/dist/commands/builtin_mirror.d.ts +58 -0
  209. package/node_modules/remote-pi/dist/commands/builtin_mirror.js +71 -0
  210. package/node_modules/remote-pi/dist/commands/builtin_mirror.js.map +1 -0
  211. package/node_modules/remote-pi/dist/commands/list_commands.d.ts +60 -0
  212. package/node_modules/remote-pi/dist/commands/list_commands.js +73 -0
  213. package/node_modules/remote-pi/dist/commands/list_commands.js.map +1 -0
  214. package/node_modules/remote-pi/dist/config.d.ts +62 -0
  215. package/node_modules/remote-pi/dist/config.js +115 -0
  216. package/node_modules/remote-pi/dist/config.js.map +1 -0
  217. package/node_modules/remote-pi/dist/daemon/client.d.ts +20 -0
  218. package/node_modules/remote-pi/dist/daemon/client.js +131 -0
  219. package/node_modules/remote-pi/dist/daemon/client.js.map +1 -0
  220. package/node_modules/remote-pi/dist/daemon/control_protocol.d.ts +176 -0
  221. package/node_modules/remote-pi/dist/daemon/control_protocol.js +63 -0
  222. package/node_modules/remote-pi/dist/daemon/control_protocol.js.map +1 -0
  223. package/node_modules/remote-pi/dist/daemon/cron_log.d.ts +45 -0
  224. package/node_modules/remote-pi/dist/daemon/cron_log.js +72 -0
  225. package/node_modules/remote-pi/dist/daemon/cron_log.js.map +1 -0
  226. package/node_modules/remote-pi/dist/daemon/cron_registry.d.ts +80 -0
  227. package/node_modules/remote-pi/dist/daemon/cron_registry.js +194 -0
  228. package/node_modules/remote-pi/dist/daemon/cron_registry.js.map +1 -0
  229. package/node_modules/remote-pi/dist/daemon/id.d.ts +24 -0
  230. package/node_modules/remote-pi/dist/daemon/id.js +36 -0
  231. package/node_modules/remote-pi/dist/daemon/id.js.map +1 -0
  232. package/node_modules/remote-pi/dist/daemon/install.d.ts +170 -0
  233. package/node_modules/remote-pi/dist/daemon/install.js +547 -0
  234. package/node_modules/remote-pi/dist/daemon/install.js.map +1 -0
  235. package/node_modules/remote-pi/dist/daemon/registry.d.ts +63 -0
  236. package/node_modules/remote-pi/dist/daemon/registry.js +153 -0
  237. package/node_modules/remote-pi/dist/daemon/registry.js.map +1 -0
  238. package/node_modules/remote-pi/dist/daemon/rpc_child.d.ts +194 -0
  239. package/node_modules/remote-pi/dist/daemon/rpc_child.js +389 -0
  240. package/node_modules/remote-pi/dist/daemon/rpc_child.js.map +1 -0
  241. package/node_modules/remote-pi/dist/daemon/supervisor.d.ts +93 -0
  242. package/node_modules/remote-pi/dist/daemon/supervisor.js +596 -0
  243. package/node_modules/remote-pi/dist/daemon/supervisor.js.map +1 -0
  244. package/node_modules/remote-pi/dist/extension_ui_bridge.d.ts +26 -0
  245. package/node_modules/remote-pi/dist/extension_ui_bridge.js +341 -0
  246. package/node_modules/remote-pi/dist/extension_ui_bridge.js.map +1 -0
  247. package/node_modules/remote-pi/dist/index.d.ts +213 -0
  248. package/node_modules/remote-pi/dist/index.js +4996 -0
  249. package/node_modules/remote-pi/dist/index.js.map +1 -0
  250. package/node_modules/remote-pi/dist/mcp/mesh_result.d.ts +10 -0
  251. package/node_modules/remote-pi/dist/mcp/mesh_result.js +42 -0
  252. package/node_modules/remote-pi/dist/mcp/mesh_result.js.map +1 -0
  253. package/node_modules/remote-pi/dist/mcp/mesh_server.d.ts +16 -0
  254. package/node_modules/remote-pi/dist/mcp/mesh_server.js +327 -0
  255. package/node_modules/remote-pi/dist/mcp/mesh_server.js.map +1 -0
  256. package/node_modules/remote-pi/dist/mesh/canonical.d.ts +30 -0
  257. package/node_modules/remote-pi/dist/mesh/canonical.js +61 -0
  258. package/node_modules/remote-pi/dist/mesh/canonical.js.map +1 -0
  259. package/node_modules/remote-pi/dist/mesh/client.d.ts +18 -0
  260. package/node_modules/remote-pi/dist/mesh/client.js +125 -0
  261. package/node_modules/remote-pi/dist/mesh/client.js.map +1 -0
  262. package/node_modules/remote-pi/dist/mesh/encoding.d.ts +38 -0
  263. package/node_modules/remote-pi/dist/mesh/encoding.js +216 -0
  264. package/node_modules/remote-pi/dist/mesh/encoding.js.map +1 -0
  265. package/node_modules/remote-pi/dist/mesh/self_revoke.d.ts +73 -0
  266. package/node_modules/remote-pi/dist/mesh/self_revoke.js +401 -0
  267. package/node_modules/remote-pi/dist/mesh/self_revoke.js.map +1 -0
  268. package/node_modules/remote-pi/dist/mesh/siblings.d.ts +49 -0
  269. package/node_modules/remote-pi/dist/mesh/siblings.js +159 -0
  270. package/node_modules/remote-pi/dist/mesh/siblings.js.map +1 -0
  271. package/node_modules/remote-pi/dist/mesh/types.d.ts +34 -0
  272. package/node_modules/remote-pi/dist/mesh/types.js +11 -0
  273. package/node_modules/remote-pi/dist/mesh/types.js.map +1 -0
  274. package/node_modules/remote-pi/dist/mesh/verify.d.ts +17 -0
  275. package/node_modules/remote-pi/dist/mesh/verify.js +86 -0
  276. package/node_modules/remote-pi/dist/mesh/verify.js.map +1 -0
  277. package/node_modules/remote-pi/dist/pairing/crypto.d.ts +8 -0
  278. package/node_modules/remote-pi/dist/pairing/crypto.js +22 -0
  279. package/node_modules/remote-pi/dist/pairing/crypto.js.map +1 -0
  280. package/node_modules/remote-pi/dist/pairing/handshake.d.ts +28 -0
  281. package/node_modules/remote-pi/dist/pairing/handshake.js +113 -0
  282. package/node_modules/remote-pi/dist/pairing/handshake.js.map +1 -0
  283. package/node_modules/remote-pi/dist/pairing/noise-sha256.d.ts +16 -0
  284. package/node_modules/remote-pi/dist/pairing/noise-sha256.js +103 -0
  285. package/node_modules/remote-pi/dist/pairing/noise-sha256.js.map +1 -0
  286. package/node_modules/remote-pi/dist/pairing/qr.d.ts +59 -0
  287. package/node_modules/remote-pi/dist/pairing/qr.js +125 -0
  288. package/node_modules/remote-pi/dist/pairing/qr.js.map +1 -0
  289. package/node_modules/remote-pi/dist/pairing/storage.d.ts +120 -0
  290. package/node_modules/remote-pi/dist/pairing/storage.js +604 -0
  291. package/node_modules/remote-pi/dist/pairing/storage.js.map +1 -0
  292. package/node_modules/remote-pi/dist/protocol/codec.d.ts +7 -0
  293. package/node_modules/remote-pi/dist/protocol/codec.js +49 -0
  294. package/node_modules/remote-pi/dist/protocol/codec.js.map +1 -0
  295. package/node_modules/remote-pi/dist/protocol/types.d.ts +393 -0
  296. package/node_modules/remote-pi/dist/protocol/types.js +2 -0
  297. package/node_modules/remote-pi/dist/protocol/types.js.map +1 -0
  298. package/node_modules/remote-pi/dist/rooms.d.ts +29 -0
  299. package/node_modules/remote-pi/dist/rooms.js +57 -0
  300. package/node_modules/remote-pi/dist/rooms.js.map +1 -0
  301. package/node_modules/remote-pi/dist/session/address.d.ts +49 -0
  302. package/node_modules/remote-pi/dist/session/address.js +58 -0
  303. package/node_modules/remote-pi/dist/session/address.js.map +1 -0
  304. package/node_modules/remote-pi/dist/session/agent_bridge.d.ts +55 -0
  305. package/node_modules/remote-pi/dist/session/agent_bridge.js +146 -0
  306. package/node_modules/remote-pi/dist/session/agent_bridge.js.map +1 -0
  307. package/node_modules/remote-pi/dist/session/bridge.d.ts +37 -0
  308. package/node_modules/remote-pi/dist/session/bridge.js +130 -0
  309. package/node_modules/remote-pi/dist/session/bridge.js.map +1 -0
  310. package/node_modules/remote-pi/dist/session/broker.d.ts +189 -0
  311. package/node_modules/remote-pi/dist/session/broker.js +507 -0
  312. package/node_modules/remote-pi/dist/session/broker.js.map +1 -0
  313. package/node_modules/remote-pi/dist/session/broker_remote.d.ts +74 -0
  314. package/node_modules/remote-pi/dist/session/broker_remote.js +583 -0
  315. package/node_modules/remote-pi/dist/session/broker_remote.js.map +1 -0
  316. package/node_modules/remote-pi/dist/session/cwd_lock.d.ts +33 -0
  317. package/node_modules/remote-pi/dist/session/cwd_lock.js +126 -0
  318. package/node_modules/remote-pi/dist/session/cwd_lock.js.map +1 -0
  319. package/node_modules/remote-pi/dist/session/envelope.d.ts +33 -0
  320. package/node_modules/remote-pi/dist/session/envelope.js +117 -0
  321. package/node_modules/remote-pi/dist/session/envelope.js.map +1 -0
  322. package/node_modules/remote-pi/dist/session/global_config.d.ts +33 -0
  323. package/node_modules/remote-pi/dist/session/global_config.js +73 -0
  324. package/node_modules/remote-pi/dist/session/global_config.js.map +1 -0
  325. package/node_modules/remote-pi/dist/session/ipc.d.ts +27 -0
  326. package/node_modules/remote-pi/dist/session/ipc.js +22 -0
  327. package/node_modules/remote-pi/dist/session/ipc.js.map +1 -0
  328. package/node_modules/remote-pi/dist/session/leader_election.d.ts +32 -0
  329. package/node_modules/remote-pi/dist/session/leader_election.js +106 -0
  330. package/node_modules/remote-pi/dist/session/leader_election.js.map +1 -0
  331. package/node_modules/remote-pi/dist/session/local_config.d.ts +55 -0
  332. package/node_modules/remote-pi/dist/session/local_config.js +157 -0
  333. package/node_modules/remote-pi/dist/session/local_config.js.map +1 -0
  334. package/node_modules/remote-pi/dist/session/mesh_message.d.ts +20 -0
  335. package/node_modules/remote-pi/dist/session/mesh_message.js +28 -0
  336. package/node_modules/remote-pi/dist/session/mesh_message.js.map +1 -0
  337. package/node_modules/remote-pi/dist/session/mesh_node.d.ts +116 -0
  338. package/node_modules/remote-pi/dist/session/mesh_node.js +573 -0
  339. package/node_modules/remote-pi/dist/session/mesh_node.js.map +1 -0
  340. package/node_modules/remote-pi/dist/session/peer.d.ts +139 -0
  341. package/node_modules/remote-pi/dist/session/peer.js +451 -0
  342. package/node_modules/remote-pi/dist/session/peer.js.map +1 -0
  343. package/node_modules/remote-pi/dist/session/peer_inventory.d.ts +13 -0
  344. package/node_modules/remote-pi/dist/session/peer_inventory.js +48 -0
  345. package/node_modules/remote-pi/dist/session/peer_inventory.js.map +1 -0
  346. package/node_modules/remote-pi/dist/session/peer_limits.d.ts +9 -0
  347. package/node_modules/remote-pi/dist/session/peer_limits.js +21 -0
  348. package/node_modules/remote-pi/dist/session/peer_limits.js.map +1 -0
  349. package/node_modules/remote-pi/dist/session/setup_wizard.d.ts +39 -0
  350. package/node_modules/remote-pi/dist/session/setup_wizard.js +63 -0
  351. package/node_modules/remote-pi/dist/session/setup_wizard.js.map +1 -0
  352. package/node_modules/remote-pi/dist/session/tool_gate.d.ts +5 -0
  353. package/node_modules/remote-pi/dist/session/tool_gate.js +11 -0
  354. package/node_modules/remote-pi/dist/session/tool_gate.js.map +1 -0
  355. package/node_modules/remote-pi/dist/session/tools.d.ts +24 -0
  356. package/node_modules/remote-pi/dist/session/tools.js +252 -0
  357. package/node_modules/remote-pi/dist/session/tools.js.map +1 -0
  358. package/node_modules/remote-pi/dist/session/wizard.d.ts +13 -0
  359. package/node_modules/remote-pi/dist/session/wizard.js +20 -0
  360. package/node_modules/remote-pi/dist/session/wizard.js.map +1 -0
  361. package/node_modules/remote-pi/dist/settings.d.ts +15 -0
  362. package/node_modules/remote-pi/dist/settings.js +52 -0
  363. package/node_modules/remote-pi/dist/settings.js.map +1 -0
  364. package/node_modules/remote-pi/dist/transport/peer_channel.d.ts +37 -0
  365. package/node_modules/remote-pi/dist/transport/peer_channel.js +98 -0
  366. package/node_modules/remote-pi/dist/transport/peer_channel.js.map +1 -0
  367. package/node_modules/remote-pi/dist/transport/pi_forward_client.d.ts +29 -0
  368. package/node_modules/remote-pi/dist/transport/pi_forward_client.js +62 -0
  369. package/node_modules/remote-pi/dist/transport/pi_forward_client.js.map +1 -0
  370. package/node_modules/remote-pi/dist/transport/relay_client.d.ts +91 -0
  371. package/node_modules/remote-pi/dist/transport/relay_client.js +206 -0
  372. package/node_modules/remote-pi/dist/transport/relay_client.js.map +1 -0
  373. package/node_modules/remote-pi/dist/ui/footer.d.ts +32 -0
  374. package/node_modules/remote-pi/dist/ui/footer.js +34 -0
  375. package/node_modules/remote-pi/dist/ui/footer.js.map +1 -0
  376. package/node_modules/remote-pi/docs/daemon.md +289 -0
  377. package/node_modules/remote-pi/package.json +88 -0
  378. package/node_modules/remote-pi/service-templates/launchd.plist.template +35 -0
  379. package/node_modules/remote-pi/service-templates/systemd.service.template +19 -0
  380. package/node_modules/remote-pi/service-templates/task-launcher.vbs.template +10 -0
  381. package/node_modules/remote-pi/service-templates/task-scheduler.xml.template +38 -0
  382. package/node_modules/remote-pi/skills/agent-network/SKILL.md +310 -0
  383. package/package.json +25 -10
  384. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-diff/write-display-utils.ts +0 -29
  385. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference-core.ts → reference/session.ts} +0 -0
  386. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-aliases.ts → shell/aliases.ts} +0 -0
  387. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ATTRIBUTION.md +0 -0
  388. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-presentation.ts +0 -0
  389. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/index.ts +0 -0
  390. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/render-utils.ts +0 -0
  391. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/shiki-highlight.ts +0 -0
  392. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/types.ts +0 -0
@@ -0,0 +1,727 @@
1
+ /**
2
+ * default mode(config.mode === "on"):Claude Code 风格工具卡渲染。
3
+ *
4
+ * 经 ToolExecutionComponent 原型补丁接管 call/result;edit/write 走 rich diff。
5
+ * 生命周期对齐 compact-mode:installDefaultMode → hooks.shutdown。
6
+ */
7
+ import { ToolExecutionComponent } from "@earendil-works/pi-coding-agent";
8
+ import { Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
9
+ import { config, getToolDisplayConfig, type CompactStyleMode } from "../config/config.ts";
10
+ import { isToolCallHovered } from "./mouse/interaction.ts";
11
+ import {
12
+ countLines,
13
+ hasExpandableDetail,
14
+ headTruncateToWidth,
15
+ insetComponent,
16
+ isToolExpanded,
17
+ oneLine,
18
+ outputLineCount,
19
+ pendingIcon,
20
+ renderCollapsedToolResultToWidth,
21
+ renderExpandedToolResult,
22
+ resolveToolVisualState,
23
+ scheduleAnimation,
24
+ settledIcon,
25
+ setToolVisualState,
26
+ textFromResult,
27
+ toolIconColor,
28
+ toolViewportWidth,
29
+ } from "./tool/result.ts";
30
+ import { showMoreHintText } from "./show-more-hint.ts";
31
+ import { renderRichToolResult, type WriteExecutionMetadataStore } from "./tool/diff/index.ts";
32
+ import { getMessageDisplayTheme } from "./message-display.ts";
33
+
34
+ // 成功勾:亮绿 truecolor(与 message-display 一致)
35
+ const BRIGHT_GREEN = "\x1b[38;2;80;220;100m";
36
+ const ANSI_FG_RESET = "\x1b[39m";
37
+
38
+ const GLOBAL_TOOL_RENDER_PATCH = Symbol.for("pi.ccstyle.global-tool-render-patch");
39
+ const COMPONENT_TOOL_RENDER_MODE = Symbol.for("pi.ccstyle.component-tool-render-mode");
40
+ const COMPONENT_TOOL_SELF_SHELL_MODE = Symbol.for("pi.ccstyle.component-tool-self-shell-mode");
41
+ const TOOL_EXPANDED_BACKGROUND_PATCH = Symbol.for("pi.ccstyle.tool-expanded-background-patch");
42
+
43
+ const AGENT_FAMILY_TOOL_NAMES = new Set([
44
+ "Agent",
45
+ "Agents",
46
+ "get_subagent_result",
47
+ "steer_subagent",
48
+ ]);
49
+ // pi-subagents 等扩展为 Agent 提供专用渲染器,ccstyle 必须保留。
50
+ const DEDICATED_RENDERER_TOOLS = new Set(["Agent"]);
51
+
52
+ export type DefaultModeHooks = {
53
+ /** 本安装是否仍持有全局工具渲染补丁。 */
54
+ isOwner(): boolean;
55
+ shutdown(): void;
56
+ };
57
+
58
+ type ToolRenderMethods = {
59
+ hasRendererDefinition: (...args: any[]) => boolean;
60
+ getRenderShell: (...args: any[]) => "default" | "self";
61
+ getCallRenderer: (...args: any[]) => any;
62
+ getResultRenderer: (...args: any[]) => any;
63
+ };
64
+
65
+ type GlobalToolRenderPatch = {
66
+ version: 2;
67
+ prototype: any;
68
+ owner: object;
69
+ active: boolean;
70
+ enabled: () => boolean;
71
+ mode: () => CompactStyleMode;
72
+ wrap: (tool: any) => any;
73
+ byDefinition: WeakMap<object, any>;
74
+ byName: Map<string, any>;
75
+ downstream: ToolRenderMethods;
76
+ installed: ToolRenderMethods;
77
+ // 兼容旧扩展读取 Symbol 上的 legacy 字段。
78
+ originalHasRendererDefinition: ToolRenderMethods["hasRendererDefinition"];
79
+ originalGetRenderShell: ToolRenderMethods["getRenderShell"];
80
+ originalGetCallRenderer: ToolRenderMethods["getCallRenderer"];
81
+ originalGetResultRenderer: ToolRenderMethods["getResultRenderer"];
82
+ };
83
+
84
+ type ToolExpandedBackgroundPatch = {
85
+ active: boolean;
86
+ prototype: any;
87
+ installed: (...args: any[]) => void;
88
+ original: (...args: any[]) => void;
89
+ dispose: () => void;
90
+ };
91
+
92
+ export function shouldRenderRichDiff(
93
+ mode: CompactStyleMode,
94
+ toolName: string,
95
+ isError: boolean,
96
+ ): boolean {
97
+ return mode === "on" && !isError && (toolName === "edit" || toolName === "write");
98
+ }
99
+
100
+ export function isMcpToolDefinition(definition: any, toolName: string): boolean {
101
+ const label = typeof definition?.label === "string" ? definition.label.trim() : "";
102
+ if (/^MCP(?::|$)/i.test(label)) return true;
103
+ if (toolName === "mcp" || /^mcp[_:-]|[_:-]mcp[_:-]/i.test(toolName)) return true;
104
+ if (label) return false;
105
+ const description = typeof definition?.description === "string" ? definition.description : "";
106
+ return /\bModel Context Protocol\b/i.test(description);
107
+ }
108
+
109
+ export function humanizeMcpToolName(toolName: string): string {
110
+ const words = toolName
111
+ .replace(/^mcp(?:[_:-]+)+/i, "")
112
+ .split(/[_:-]+/)
113
+ .filter(Boolean);
114
+ return words.length
115
+ ? words.map((word) => word[0]!.toUpperCase() + word.slice(1)).join(" ")
116
+ : "MCP";
117
+ }
118
+
119
+ /** 排除名单内且自带 renderer 的工具保留原渲染。 */
120
+ export function preservesOriginalRenderer(
121
+ extensionDefinition: any,
122
+ toolName: string,
123
+ builtInToolDefinition?: any,
124
+ excludeRenderers: readonly string[] = config.excludeRenderers,
125
+ ): boolean {
126
+ if (!excludeRenderers.includes(toolName)) return false;
127
+ return [extensionDefinition, builtInToolDefinition].some(
128
+ (definition) =>
129
+ definition?.renderShell === "self" ||
130
+ typeof definition?.renderCall === "function" ||
131
+ typeof definition?.renderResult === "function",
132
+ );
133
+ }
134
+
135
+ function renderDefault(tool: any, slot: "renderCall" | "renderResult", args: any[], fallback = "") {
136
+ try {
137
+ if (typeof tool?.[slot] === "function") return tool[slot](...args);
138
+ } catch {
139
+ // Fall through to raw fallback.
140
+ }
141
+ return new Text(fallback, 0, 0);
142
+ }
143
+
144
+ function humanizeToolLabel(label: string): string {
145
+ return label
146
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
147
+ .replace(/[_-]+/g, " ")
148
+ .replace(/\b\w/g, (char) => char.toUpperCase());
149
+ }
150
+
151
+ function singleToolCallSummary(
152
+ toolName: string,
153
+ label: string,
154
+ args: any,
155
+ ): { main: string; detail: string } {
156
+ const title = label === toolName ? humanizeToolLabel(label) : label;
157
+ if (!args || typeof args !== "object") return { main: title, detail: "" };
158
+ const name = toolName.toLowerCase();
159
+ const value = (fallback: string, ...keys: string[]) => {
160
+ const found = keys.map((key) => args[key]).find((item) => typeof item === "string" && item);
161
+ // 与多 tool 摘要对齐:从头截断,上限 96 字符(tool-grouping oneLine 默认值)。
162
+ return `${title} ${oneLine(found || fallback, 96)}`;
163
+ };
164
+ if (AGENT_FAMILY_TOOL_NAMES.has(toolName) && args.agent_id) {
165
+ return { main: `${title} ${oneLine(args.agent_id, 96)}`, detail: "" };
166
+ }
167
+ // Agents 走 ccstyle wrapper;Agent 保留专用渲染器。
168
+ if (name === "agents") {
169
+ return {
170
+ main: value("launch agents", "description", "prompt"),
171
+ detail: "",
172
+ };
173
+ }
174
+ if (name === "skill") return { main: value("run skill", "name"), detail: "" };
175
+ if (name === "enterplanmode" || name === "enter_plan_mode") {
176
+ return { main: `${title} enable read-only planning`, detail: "" };
177
+ }
178
+ if (name === "exitplanmode" || name === "exit_plan_mode") {
179
+ return { main: `${title} present plan`, detail: "" };
180
+ }
181
+ if (name === "taskcreate") return { main: value("create task", "subject"), detail: "" };
182
+ if (name === "tasklist") return { main: `${title} task list`, detail: "" };
183
+ if (name === "taskget" || name === "taskupdate") {
184
+ return { main: value("task", "taskId", "task_id"), detail: "" };
185
+ }
186
+ if (name === "taskoutput" || name === "taskstop") {
187
+ return { main: value("background task", "task_id", "taskId"), detail: "" };
188
+ }
189
+ if (name === "taskexecute") {
190
+ const ids = Array.isArray(args.task_ids)
191
+ ? args.task_ids
192
+ : Array.isArray(args.taskIds)
193
+ ? args.taskIds
194
+ : [];
195
+ const summary = ids.length
196
+ ? `${ids[0]}${ids.length > 1 ? ` (+${ids.length - 1} tasks)` : ""}`
197
+ : "start tasks";
198
+ return { main: `${title} ${summary}`, detail: "" };
199
+ }
200
+ if (toolName === "read") {
201
+ const details = [
202
+ args.offset !== undefined ? `offset=${args.offset}` : "",
203
+ args.limit !== undefined ? `limit=${args.limit}` : "",
204
+ ].filter(Boolean);
205
+ return {
206
+ main: `${title}${args.path ? ` ${oneLine(args.path, 96)}` : ""}`,
207
+ detail: details.length ? ` (${details.join(", ")})` : "",
208
+ };
209
+ }
210
+ const preferred =
211
+ args.path ??
212
+ args.file_path ??
213
+ args.command ??
214
+ args.query ??
215
+ args.question ??
216
+ args.pattern ??
217
+ args.url ??
218
+ args.name ??
219
+ args.tool_use_id ??
220
+ args.toolCallId ??
221
+ args.id ??
222
+ args.message;
223
+ return {
224
+ main:
225
+ preferred !== undefined && preferred !== null && typeof preferred !== "object"
226
+ ? `${title} ${oneLine(preferred, 96)}`
227
+ : title,
228
+ detail: "",
229
+ };
230
+ }
231
+
232
+ type ParsedTask = { id: string; status: string; subject: string };
233
+
234
+ function parseTaskList(text: string): ParsedTask[] {
235
+ return text
236
+ .split("\n")
237
+ .map((line) => line.match(/^#(\d+) \[([^\]]+)] (.+)$/))
238
+ .filter((match): match is RegExpMatchArray => Boolean(match))
239
+ .map((match) => ({ id: match[1]!, status: match[2]!, subject: match[3]! }));
240
+ }
241
+
242
+ function taskListSummary(tasks: ParsedTask[]): string {
243
+ const counts = { pending: 0, in_progress: 0, completed: 0 };
244
+ for (const task of tasks) {
245
+ if (task.status in counts) counts[task.status as keyof typeof counts]++;
246
+ }
247
+ return [
248
+ `${tasks.length} tasks`,
249
+ counts.in_progress ? `${counts.in_progress} in progress` : "",
250
+ counts.pending ? `${counts.pending} pending` : "",
251
+ counts.completed ? `${counts.completed} completed` : "",
252
+ ]
253
+ .filter(Boolean)
254
+ .join(" • ");
255
+ }
256
+
257
+ function renderExpandedTaskResult(
258
+ toolName: string,
259
+ text: string,
260
+ theme: any,
261
+ isError: boolean,
262
+ ): any | undefined {
263
+ if (isError) return undefined;
264
+ if (toolName === "TaskList") {
265
+ const tasks = parseTaskList(text);
266
+ if (!tasks.length) return undefined;
267
+ const limit = Math.max(1, config.expandedPreviewMaxLines);
268
+ const rows = tasks.slice(0, limit).map((task) => {
269
+ const color =
270
+ task.status === "completed"
271
+ ? "success"
272
+ : task.status === "in_progress"
273
+ ? "warning"
274
+ : "muted";
275
+ return ` ${theme.fg("accent", `#${task.id}`)} ${theme.fg(color, task.status)} ${theme.fg("dim", task.subject)}`;
276
+ });
277
+ if (tasks.length > rows.length)
278
+ rows.push(theme.fg("muted", ` … ${tasks.length - rows.length} more tasks`));
279
+ return new Text(` ↳ ${theme.fg("muted", taskListSummary(tasks))}\n${rows.join("\n")}`, 0, 0);
280
+ }
281
+ const line = text.trim();
282
+ if (!line || line.includes("\n")) return undefined;
283
+ let formatted: string | undefined;
284
+ let match: RegExpMatchArray | null;
285
+ if (
286
+ toolName === "TaskCreate" &&
287
+ (match = line.match(/^Task #(\d+) created successfully: (.+)$/))
288
+ ) {
289
+ formatted = `${theme.fg("success", "Created task")} ${theme.fg("accent", `#${match[1]}`)} ${theme.fg("muted", match[2])}`;
290
+ } else if (toolName === "TaskUpdate" && (match = line.match(/^Updated task #(\d+) (.+)$/))) {
291
+ formatted = `${theme.fg("success", "Updated task")} ${theme.fg("accent", `#${match[1]}`)} ${theme.fg("muted", match[2])}`;
292
+ } else if (toolName === "TaskExecute") {
293
+ formatted = `${theme.fg("success", "Started")} ${theme.fg("muted", line)}`;
294
+ } else if (toolName === "TaskStop") {
295
+ formatted = `${theme.fg("success", "Stopped")} ${theme.fg("muted", line)}`;
296
+ }
297
+ return formatted ? new Text(` ↳ ${formatted}`, 0, 0) : undefined;
298
+ }
299
+
300
+ /** 用 ccstyle call/result 包装任意工具定义。 */
301
+ function createCcstyleTool(
302
+ originalTool: any,
303
+ writeExecutionMetadata: WriteExecutionMetadataStore,
304
+ ): any {
305
+ const toolName = originalTool.name;
306
+ const label = isMcpToolDefinition(originalTool, toolName)
307
+ ? humanizeMcpToolName(toolName)
308
+ : originalTool.label || toolName;
309
+
310
+ return {
311
+ ...originalTool,
312
+ renderShell: "self",
313
+ renderCall(args: any, theme: any, context: any) {
314
+ if (config.mode !== "on") {
315
+ return renderDefault(originalTool, "renderCall", [args, theme, context], String(toolName));
316
+ }
317
+
318
+ const visualState = resolveToolVisualState(context);
319
+ const isPending =
320
+ visualState === "pending" ||
321
+ (!visualState && (context?.isPartial || context?.executionStarted));
322
+ if (isPending) scheduleAnimation(context);
323
+ const rawIcon = isPending ? pendingIcon(toolName) : settledIcon(toolName, visualState);
324
+ const icon =
325
+ visualState === "success"
326
+ ? `${BRIGHT_GREEN}${rawIcon}${ANSI_FG_RESET}`
327
+ : theme.fg(toolIconColor(context), rawIcon);
328
+ const summary = singleToolCallSummary(toolName, label, args);
329
+ let cachedWidth: number | undefined;
330
+ let cachedLine: string | undefined;
331
+ return {
332
+ render(width: number) {
333
+ if (cachedLine !== undefined && cachedWidth === width) return [cachedLine];
334
+ const viewportWidth = toolViewportWidth(width);
335
+ const callWidth = Math.max(0, viewportWidth - visibleWidth(icon) - 2);
336
+ const mainWidth = Math.max(0, callWidth - visibleWidth(summary.detail));
337
+ cachedWidth = width;
338
+ // 纯文本先截断再着色(省略号不带 ANSI);从头截断,与多 tool 一致
339
+ const line = ` ${icon} ${theme.fg("toolTitle", headTruncateToWidth(summary.main, mainWidth))}${theme.fg("dim", summary.detail)}`;
340
+ cachedLine = truncateToWidth(line, viewportWidth, "");
341
+ return [cachedLine];
342
+ },
343
+ invalidate() {},
344
+ };
345
+ },
346
+ renderResult(result: any, options: any, theme: any, context: any) {
347
+ if (config.mode !== "on") {
348
+ return renderDefault(
349
+ originalTool,
350
+ "renderResult",
351
+ [result, options, theme, context],
352
+ textFromResult(result),
353
+ );
354
+ }
355
+
356
+ if (options?.isPartial) {
357
+ return new Text(theme.fg("muted", " ↳ Pending…"), 0, 0);
358
+ }
359
+
360
+ const isError = options?.isError || context?.isError;
361
+ setToolVisualState(context, isError ? "error" : "success");
362
+ const expanded = isToolExpanded(options, context);
363
+ const toolCallId = context?.toolCallId;
364
+ if (shouldRenderRichDiff(config.mode, toolName, Boolean(isError))) {
365
+ // getter 保证 Diff indicator / wrap / limits 下次绘制即更新
366
+ const richResult = renderRichToolResult(
367
+ toolName,
368
+ result,
369
+ {
370
+ ...options,
371
+ expanded,
372
+ // 全局共享状态避免 /reload 后旧 result renderer 闭包失联
373
+ isHovered: () => isToolCallHovered(toolCallId),
374
+ },
375
+ theme,
376
+ context,
377
+ writeExecutionMetadata,
378
+ getToolDisplayConfig,
379
+ );
380
+ if (richResult) return insetComponent(richResult);
381
+ }
382
+
383
+ const text = textFromResult(result, expanded);
384
+ const args = context?.args;
385
+ if (expanded) {
386
+ const taskResult = renderExpandedTaskResult(toolName, text, theme, Boolean(isError));
387
+ if (taskResult) return taskResult;
388
+ }
389
+ const tasks = !isError && toolName === "TaskList" ? parseTaskList(text) : [];
390
+ const outputLines = outputLineCount(result) || countLines(text);
391
+ const lineWord = outputLines === 1 ? "line" : "lines";
392
+ const action = toolName === "read" ? "loaded" : "returned";
393
+ const rendered = tasks.length
394
+ ? taskListSummary(tasks)
395
+ : isError
396
+ ? text
397
+ ? oneLine(text)
398
+ : "Failed"
399
+ : outputLines
400
+ ? `${outputLines} ${lineWord} ${action}`
401
+ : "Done";
402
+ const expandable = !expanded && (tasks.length > 0 || hasExpandableDetail(text, args));
403
+ const hintText = showMoreHintText();
404
+ const hintPrefix = expandable ? theme.fg("dim", " • ") : "";
405
+ const hint = expandable ? hintPrefix + theme.fg("dim", hintText) : "";
406
+ const hoveredHint = expandable ? hintPrefix + theme.fg("text", hintText) : "";
407
+ if (expanded) {
408
+ return renderExpandedToolResult(
409
+ text || "",
410
+ theme,
411
+ Boolean(isError),
412
+ context?.lastComponent,
413
+ args,
414
+ context,
415
+ );
416
+ }
417
+ if (context?.state) context.state.ccstyleIoView = undefined;
418
+ let cachedWidth: number | undefined;
419
+ let cachedLine: string | undefined;
420
+ let cachedHoveredLine: string | undefined;
421
+ return {
422
+ render(width: number) {
423
+ if (cachedLine === undefined || cachedWidth !== width) {
424
+ cachedWidth = width;
425
+ cachedLine = theme.fg(
426
+ isError ? "error" : "muted",
427
+ renderCollapsedToolResultToWidth(rendered, hint, width),
428
+ );
429
+ cachedHoveredLine = theme.fg(
430
+ isError ? "error" : "muted",
431
+ renderCollapsedToolResultToWidth(rendered, hoveredHint, width),
432
+ );
433
+ }
434
+ return [isToolCallHovered(toolCallId) ? cachedHoveredLine! : cachedLine];
435
+ },
436
+ invalidate() {},
437
+ };
438
+ },
439
+ };
440
+ }
441
+
442
+ function syncToolShell(component: any, shell: "default" | "self"): void {
443
+ const target = shell === "self" ? component.selfRenderContainer : component.contentBox;
444
+ if (!target || !Array.isArray(component.children)) return;
445
+ const candidates = new Set(
446
+ [component.contentText, component.contentBox, component.selfRenderContainer].filter(Boolean),
447
+ );
448
+ const indexes = component.children
449
+ .map((child: any, index: number) => (candidates.has(child) ? index : -1))
450
+ .filter((index: number) => index >= 0);
451
+ const targetIndex = indexes[0];
452
+ // 构造期 getRenderShell 先于 Pi 挂载 shell;此处勿挂载,否则构造器会二次添加。
453
+ if (targetIndex === undefined) return;
454
+ component.children[targetIndex] = target;
455
+ for (const index of indexes.sort((left: number, right: number) => right - left)) {
456
+ if (index !== targetIndex) component.children.splice(index, 1);
457
+ }
458
+ }
459
+
460
+ function shouldGloballyStyleTool(component: any, patch: GlobalToolRenderPatch): boolean {
461
+ const extensionDefinition = component.toolDefinition;
462
+ const builtInDefinition = component.builtInToolDefinition;
463
+ const definition = extensionDefinition ?? builtInDefinition;
464
+ const toolName = String(component.toolName || definition?.name || "");
465
+ const useCcstyle =
466
+ patch.mode() === "on" &&
467
+ !DEDICATED_RENDERER_TOOLS.has(toolName) &&
468
+ !preservesOriginalRenderer(extensionDefinition, toolName, builtInDefinition);
469
+ component[COMPONENT_TOOL_RENDER_MODE] = useCcstyle;
470
+ return useCcstyle;
471
+ }
472
+
473
+ function shouldUseSelfShell(component: any, _patch: GlobalToolRenderPatch): boolean {
474
+ component[COMPONENT_TOOL_SELF_SHELL_MODE] = false;
475
+ return false;
476
+ }
477
+
478
+ function getGloballyStyledTool(component: any, patch: GlobalToolRenderPatch): any {
479
+ const definition = component.toolDefinition ?? component.builtInToolDefinition;
480
+ if (definition && typeof definition === "object") {
481
+ let wrapped = patch.byDefinition.get(definition);
482
+ if (!wrapped) {
483
+ wrapped = patch.wrap(definition);
484
+ patch.byDefinition.set(definition, wrapped);
485
+ }
486
+ return wrapped;
487
+ }
488
+
489
+ const name = String(component.toolName || "tool");
490
+ let wrapped = patch.byName.get(name);
491
+ if (!wrapped) {
492
+ wrapped = patch.wrap({ name, label: name });
493
+ patch.byName.set(name, wrapped);
494
+ }
495
+ return wrapped;
496
+ }
497
+
498
+ function prototypeToolRenderMethods(prototype: any): ToolRenderMethods {
499
+ return {
500
+ hasRendererDefinition: prototype.hasRendererDefinition,
501
+ getRenderShell: prototype.getRenderShell,
502
+ getCallRenderer: prototype.getCallRenderer,
503
+ getResultRenderer: prototype.getResultRenderer,
504
+ };
505
+ }
506
+
507
+ function isOwnershipAwarePatch(value: any): value is GlobalToolRenderPatch {
508
+ if (!value || value.version !== 2 || !value.installed || !value.downstream) return false;
509
+ return ["hasRendererDefinition", "getRenderShell", "getCallRenderer", "getResultRenderer"].every(
510
+ (name) =>
511
+ typeof value.installed[name] === "function" && typeof value.downstream[name] === "function",
512
+ );
513
+ }
514
+
515
+ function isLegacyInstalledWrapper(method: unknown, downstreamField: string): boolean {
516
+ if (typeof method !== "function") return false;
517
+ try {
518
+ const source = Function.prototype.toString.call(method);
519
+ return (
520
+ source.includes(downstreamField) &&
521
+ (source.includes("shouldGloballyStyleTool") ||
522
+ source.includes("shouldUseSelfShell") ||
523
+ source.includes("getGloballyStyledTool"))
524
+ );
525
+ } catch {
526
+ return false;
527
+ }
528
+ }
529
+
530
+ function downstreamForGlobalToolInstall(prototype: any, previous: any): ToolRenderMethods {
531
+ const current = prototypeToolRenderMethods(prototype);
532
+ if (!previous || previous.prototype !== prototype) return current;
533
+ if (isOwnershipAwarePatch(previous)) {
534
+ return {
535
+ hasRendererDefinition:
536
+ current.hasRendererDefinition === previous.installed.hasRendererDefinition
537
+ ? previous.downstream.hasRendererDefinition
538
+ : current.hasRendererDefinition,
539
+ getRenderShell:
540
+ current.getRenderShell === previous.installed.getRenderShell
541
+ ? previous.downstream.getRenderShell
542
+ : current.getRenderShell,
543
+ getCallRenderer:
544
+ current.getCallRenderer === previous.installed.getCallRenderer
545
+ ? previous.downstream.getCallRenderer
546
+ : current.getCallRenderer,
547
+ getResultRenderer:
548
+ current.getResultRenderer === previous.installed.getResultRenderer
549
+ ? previous.downstream.getResultRenderer
550
+ : current.getResultRenderer,
551
+ };
552
+ }
553
+
554
+ // pre-v2 Symbol 无 wrapper 引用;能识别则回退,否则保留当前方法为 external。
555
+ const legacyDownstream = (method: Function, field: string): Function => {
556
+ const saved = previous[field];
557
+ return typeof saved === "function" && isLegacyInstalledWrapper(method, field) ? saved : method;
558
+ };
559
+ return {
560
+ hasRendererDefinition: legacyDownstream(
561
+ current.hasRendererDefinition,
562
+ "originalHasRendererDefinition",
563
+ ) as ToolRenderMethods["hasRendererDefinition"],
564
+ getRenderShell: legacyDownstream(
565
+ current.getRenderShell,
566
+ "originalGetRenderShell",
567
+ ) as ToolRenderMethods["getRenderShell"],
568
+ getCallRenderer: legacyDownstream(
569
+ current.getCallRenderer,
570
+ "originalGetCallRenderer",
571
+ ) as ToolRenderMethods["getCallRenderer"],
572
+ getResultRenderer: legacyDownstream(
573
+ current.getResultRenderer,
574
+ "originalGetResultRenderer",
575
+ ) as ToolRenderMethods["getResultRenderer"],
576
+ };
577
+ }
578
+
579
+ function disconnectGlobalToolRenderPatch(patch: any): void {
580
+ if (!patch || typeof patch !== "object") return;
581
+ patch.active = false;
582
+ patch.enabled = () => false;
583
+ patch.mode = () => "off";
584
+ patch.wrap = (tool: any) => tool;
585
+ patch.byDefinition = new WeakMap();
586
+ if (patch.byName && typeof patch.byName.clear === "function") patch.byName.clear();
587
+ else patch.byName = new Map();
588
+ }
589
+
590
+ function installGlobalToolRendering(
591
+ writeExecutionMetadata: WriteExecutionMetadataStore,
592
+ ): GlobalToolRenderPatch {
593
+ const prototype = (ToolExecutionComponent as any).prototype;
594
+ const host = globalThis as any;
595
+ const previous = host[GLOBAL_TOOL_RENDER_PATCH];
596
+ const downstream = downstreamForGlobalToolInstall(prototype, previous);
597
+ // 外部仍持有的旧 wrapper 先变为无回调 pass-through,再挂新安装。
598
+ disconnectGlobalToolRenderPatch(previous);
599
+
600
+ const patch: GlobalToolRenderPatch = {
601
+ version: 2,
602
+ prototype,
603
+ owner: {},
604
+ active: true,
605
+ enabled: () => config.mode === "on",
606
+ mode: () => config.mode,
607
+ wrap: (tool: any) => createCcstyleTool(tool, writeExecutionMetadata),
608
+ byDefinition: new WeakMap(),
609
+ byName: new Map(),
610
+ downstream,
611
+ installed: undefined as any,
612
+ originalHasRendererDefinition: downstream.hasRendererDefinition,
613
+ originalGetRenderShell: downstream.getRenderShell,
614
+ originalGetCallRenderer: downstream.getCallRenderer,
615
+ originalGetResultRenderer: downstream.getResultRenderer,
616
+ };
617
+
618
+ patch.installed = {
619
+ hasRendererDefinition: function (this: any, ...args: any[]) {
620
+ if (patch.active && shouldGloballyStyleTool(this, patch)) return true;
621
+ return patch.downstream.hasRendererDefinition.apply(this, args);
622
+ },
623
+ getRenderShell: function (this: any, ...args: any[]) {
624
+ if (!patch.active) return patch.downstream.getRenderShell.apply(this, args);
625
+ const useSelfShell = shouldUseSelfShell(this, patch);
626
+ const useCcstyle = shouldGloballyStyleTool(this, patch);
627
+ const shell =
628
+ useSelfShell || (useCcstyle && !this.expanded)
629
+ ? "self"
630
+ : useCcstyle
631
+ ? "default"
632
+ : patch.downstream.getRenderShell.apply(this, args);
633
+ syncToolShell(this, shell);
634
+ return shell;
635
+ },
636
+ getCallRenderer: function (this: any, ...args: any[]) {
637
+ if (patch.active && shouldGloballyStyleTool(this, patch)) {
638
+ return getGloballyStyledTool(this, patch).renderCall;
639
+ }
640
+ return patch.downstream.getCallRenderer.apply(this, args);
641
+ },
642
+ getResultRenderer: function (this: any, ...args: any[]) {
643
+ if (patch.active && shouldGloballyStyleTool(this, patch)) {
644
+ return getGloballyStyledTool(this, patch).renderResult;
645
+ }
646
+ return patch.downstream.getResultRenderer.apply(this, args);
647
+ },
648
+ };
649
+
650
+ prototype.hasRendererDefinition = patch.installed.hasRendererDefinition;
651
+ prototype.getRenderShell = patch.installed.getRenderShell;
652
+ prototype.getCallRenderer = patch.installed.getCallRenderer;
653
+ prototype.getResultRenderer = patch.installed.getResultRenderer;
654
+ host[GLOBAL_TOOL_RENDER_PATCH] = patch;
655
+ return patch;
656
+ }
657
+
658
+ function deactivateGlobalToolRendering(patch: GlobalToolRenderPatch): void {
659
+ if (!patch.active) return;
660
+ disconnectGlobalToolRenderPatch(patch);
661
+ const prototype = patch.prototype;
662
+ if (prototype.hasRendererDefinition === patch.installed.hasRendererDefinition) {
663
+ prototype.hasRendererDefinition = patch.downstream.hasRendererDefinition;
664
+ }
665
+ if (prototype.getRenderShell === patch.installed.getRenderShell) {
666
+ prototype.getRenderShell = patch.downstream.getRenderShell;
667
+ }
668
+ if (prototype.getCallRenderer === patch.installed.getCallRenderer) {
669
+ prototype.getCallRenderer = patch.downstream.getCallRenderer;
670
+ }
671
+ if (prototype.getResultRenderer === patch.installed.getResultRenderer) {
672
+ prototype.getResultRenderer = patch.downstream.getResultRenderer;
673
+ }
674
+ }
675
+
676
+ /** 展开面板背景统一为 user message 背景色;折叠行保持原生状态色。
677
+ * 必须在 compact-mode 之后安装,shutdown 时先于 compact-mode 释放。 */
678
+ export function installToolExpandedBackground(): () => void {
679
+ const host = globalThis as any;
680
+ const previous = host[TOOL_EXPANDED_BACKGROUND_PATCH] as ToolExpandedBackgroundPatch | undefined;
681
+ if (previous) previous.dispose();
682
+ const prototype = ToolExecutionComponent.prototype as unknown as { updateDisplay: () => void };
683
+ const original = prototype.updateDisplay;
684
+ const patch: ToolExpandedBackgroundPatch = {
685
+ active: true,
686
+ prototype,
687
+ installed: function (this: any) {
688
+ original.call(this);
689
+ if (!patch.active || config.mode !== "on" || !this.expanded) return;
690
+ const theme = getMessageDisplayTheme();
691
+ if (!theme?.bg) return;
692
+ const box = this.contentBox;
693
+ if (box?.setBgFn) box.setBgFn((text: string) => theme.bg("userMessageBg", text));
694
+ },
695
+ original,
696
+ dispose: () => {
697
+ patch.active = false;
698
+ if (prototype.updateDisplay === patch.installed) {
699
+ prototype.updateDisplay = original;
700
+ }
701
+ if (host[TOOL_EXPANDED_BACKGROUND_PATCH] === patch) {
702
+ delete host[TOOL_EXPANDED_BACKGROUND_PATCH];
703
+ }
704
+ },
705
+ };
706
+ prototype.updateDisplay = patch.installed;
707
+ host[TOOL_EXPANDED_BACKGROUND_PATCH] = patch;
708
+ return patch.dispose;
709
+ }
710
+
711
+ /** 安装 default mode 全局工具渲染补丁(不含展开背景,见 installToolExpandedBackground)。 */
712
+ export function installDefaultMode(
713
+ writeExecutionMetadata: WriteExecutionMetadataStore,
714
+ ): DefaultModeHooks {
715
+ const globalToolRendering = installGlobalToolRendering(writeExecutionMetadata);
716
+ return {
717
+ isOwner() {
718
+ return (
719
+ (globalThis as any)[GLOBAL_TOOL_RENDER_PATCH] === globalToolRendering &&
720
+ globalToolRendering.active
721
+ );
722
+ },
723
+ shutdown() {
724
+ deactivateGlobalToolRendering(globalToolRendering);
725
+ },
726
+ };
727
+ }