@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.
- package/README.md +50 -2
- package/examples/pi-footer.json +275 -0
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +6 -8
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +5 -7
- package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +101 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +1 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +5 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/{utils/agent-summary.ts → feature/agent-summary/core.ts} +37 -35
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-summary.ts → agent-summary/index.ts} +2 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference.ts → reference/index.ts} +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-autocomplete.ts → reference/subagent.ts} +19 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-startup-header.ts → shell/startup-header.ts} +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{working-message.ts → shell/working-message.ts} +5 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +32 -28
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +379 -85
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +727 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +65 -775
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/{feature → renderer}/markdown-enhance.ts +35 -31
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-hover.ts → mouse/hover.ts} +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +34 -35
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-layout.ts → mouse/layout.ts} +5 -21
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-packets.ts → mouse/packets.ts} +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-scroll.ts → mouse/scroll.ts} +48 -37
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ansi-utils.ts +56 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-renderer.ts +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/line-width-safety.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +12 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/write-execution.ts +1 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-grouping.ts → tool/grouping.ts} +18 -8
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-result.ts → tool/result.ts} +4 -13
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +0 -27
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +2 -2
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +1 -0
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +3 -1
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +33 -35
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +26 -35
- package/node_modules/@herbertgao/pi-subagents/src/prompts.ts +15 -1
- package/node_modules/pi-footer/CHANGELOG.md +145 -0
- package/node_modules/pi-footer/LICENSE +21 -0
- package/node_modules/pi-footer/README.md +354 -0
- package/node_modules/pi-footer/package.json +68 -0
- package/node_modules/pi-footer/src/cache.ts +106 -0
- package/node_modules/pi-footer/src/colors.ts +237 -0
- package/node_modules/pi-footer/src/config.ts +202 -0
- package/node_modules/pi-footer/src/event-widgets.ts +41 -0
- package/node_modules/pi-footer/src/extension-statuses.ts +102 -0
- package/node_modules/pi-footer/src/git.ts +135 -0
- package/node_modules/pi-footer/src/index.ts +268 -0
- package/node_modules/pi-footer/src/metrics.ts +141 -0
- package/node_modules/pi-footer/src/presets.ts +383 -0
- package/node_modules/pi-footer/src/render.ts +114 -0
- package/node_modules/pi-footer/src/separators.ts +52 -0
- package/node_modules/pi-footer/src/types.ts +122 -0
- package/node_modules/pi-footer/src/ui/color-level-confirm.ts +22 -0
- package/node_modules/pi-footer/src/ui/color-options.ts +195 -0
- package/node_modules/pi-footer/src/ui/config-lifecycle.ts +61 -0
- package/node_modules/pi-footer/src/ui/edit-colors.ts +13 -0
- package/node_modules/pi-footer/src/ui/events.ts +35 -0
- package/node_modules/pi-footer/src/ui/extension-status-picker.ts +60 -0
- package/node_modules/pi-footer/src/ui/extension-statuses.ts +73 -0
- package/node_modules/pi-footer/src/ui/fields.ts +252 -0
- package/node_modules/pi-footer/src/ui/global-menu.ts +126 -0
- package/node_modules/pi-footer/src/ui/helpers.ts +44 -0
- package/node_modules/pi-footer/src/ui/layout.ts +17 -0
- package/node_modules/pi-footer/src/ui/line-list.ts +19 -0
- package/node_modules/pi-footer/src/ui/model.ts +64 -0
- package/node_modules/pi-footer/src/ui/navigation.ts +29 -0
- package/node_modules/pi-footer/src/ui/option-edit.ts +93 -0
- package/node_modules/pi-footer/src/ui/overlay-render.ts +103 -0
- package/node_modules/pi-footer/src/ui/screen-context.ts +18 -0
- package/node_modules/pi-footer/src/ui/screen-controller.ts +27 -0
- package/node_modules/pi-footer/src/ui/screen-render.ts +32 -0
- package/node_modules/pi-footer/src/ui/screen-state.ts +20 -0
- package/node_modules/pi-footer/src/ui/screen.ts +243 -0
- package/node_modules/pi-footer/src/ui/screens/add-widget.ts +92 -0
- package/node_modules/pi-footer/src/ui/screens/confirm-exit.ts +52 -0
- package/node_modules/pi-footer/src/ui/screens/controller.ts +12 -0
- package/node_modules/pi-footer/src/ui/screens/edit-colors.ts +68 -0
- package/node_modules/pi-footer/src/ui/screens/edit-widget.ts +115 -0
- package/node_modules/pi-footer/src/ui/screens/extension-status-row.ts +61 -0
- package/node_modules/pi-footer/src/ui/screens/global.ts +75 -0
- package/node_modules/pi-footer/src/ui/screens/line-list.ts +108 -0
- package/node_modules/pi-footer/src/ui/screens/main.ts +99 -0
- package/node_modules/pi-footer/src/ui/screens/terminal.ts +121 -0
- package/node_modules/pi-footer/src/ui/screens/widget-list.ts +154 -0
- package/node_modules/pi-footer/src/ui/terminal-menu.ts +32 -0
- package/node_modules/pi-footer/src/ui/theme.ts +48 -0
- package/node_modules/pi-footer/src/ui/title-bar.ts +100 -0
- package/node_modules/pi-footer/src/ui/widget-actions.ts +76 -0
- package/node_modules/pi-footer/src/ui.ts +66 -0
- package/node_modules/pi-footer/src/widgets/context.ts +28 -0
- package/node_modules/pi-footer/src/widgets/core/active-tools.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/context-window.ts +24 -0
- package/node_modules/pi-footer/src/widgets/core/cwd-basename.ts +19 -0
- package/node_modules/pi-footer/src/widgets/core/cwd.ts +108 -0
- package/node_modules/pi-footer/src/widgets/core/event.ts +34 -0
- package/node_modules/pi-footer/src/widgets/core/external-status.ts +102 -0
- package/node_modules/pi-footer/src/widgets/core/model-provider.ts +20 -0
- package/node_modules/pi-footer/src/widgets/core/model.ts +35 -0
- package/node_modules/pi-footer/src/widgets/core/provider.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/session-name.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/text-verbosity.ts +17 -0
- package/node_modules/pi-footer/src/widgets/core/thinking-level.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/ahead-behind.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/branch.ts +81 -0
- package/node_modules/pi-footer/src/widgets/git/clean.ts +19 -0
- package/node_modules/pi-footer/src/widgets/git/deletions.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/diff.ts +38 -0
- package/node_modules/pi-footer/src/widgets/git/insertions.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/remote.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/root.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/sha.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/staged.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/status.ts +19 -0
- package/node_modules/pi-footer/src/widgets/git/unstaged.ts +17 -0
- package/node_modules/pi-footer/src/widgets/git/untracked.ts +17 -0
- package/node_modules/pi-footer/src/widgets/instance.ts +118 -0
- package/node_modules/pi-footer/src/widgets/layout/custom-text.ts +18 -0
- package/node_modules/pi-footer/src/widgets/layout/flex-separator.ts +32 -0
- package/node_modules/pi-footer/src/widgets/layout/separator.ts +57 -0
- package/node_modules/pi-footer/src/widgets/layout/spacer.ts +31 -0
- package/node_modules/pi-footer/src/widgets/options.ts +122 -0
- package/node_modules/pi-footer/src/widgets/project/runtime.ts +361 -0
- package/node_modules/pi-footer/src/widgets/registry.ts +223 -0
- package/node_modules/pi-footer/src/widgets/session/assistant-messages.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/compactions.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/elapsed.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/last-activity.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/messages.ts +19 -0
- package/node_modules/pi-footer/src/widgets/session/session-id.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/session-start.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/tool-results.ts +17 -0
- package/node_modules/pi-footer/src/widgets/session/total-messages.ts +19 -0
- package/node_modules/pi-footer/src/widgets/session/total-time.ts +18 -0
- package/node_modules/pi-footer/src/widgets/session/user-messages.ts +17 -0
- package/node_modules/pi-footer/src/widgets/store.ts +26 -0
- package/node_modules/pi-footer/src/widgets/tokens/cache-hit-rate.ts +55 -0
- package/node_modules/pi-footer/src/widgets/tokens/cache-read.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/cache-write.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/context-bar.ts +108 -0
- package/node_modules/pi-footer/src/widgets/tokens/context-length.ts +26 -0
- package/node_modules/pi-footer/src/widgets/tokens/context-remaining.ts +29 -0
- package/node_modules/pi-footer/src/widgets/tokens/context.ts +29 -0
- package/node_modules/pi-footer/src/widgets/tokens/cost.ts +51 -0
- package/node_modules/pi-footer/src/widgets/tokens/input-speed.ts +25 -0
- package/node_modules/pi-footer/src/widgets/tokens/input-tokens.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/output-speed.ts +25 -0
- package/node_modules/pi-footer/src/widgets/tokens/output-tokens.ts +18 -0
- package/node_modules/pi-footer/src/widgets/tokens/tokens.ts +20 -0
- package/node_modules/pi-footer/src/widgets/tokens/total-speed.ts +25 -0
- package/node_modules/pi-footer/src/widgets/tokens/total-tokens.ts +18 -0
- package/node_modules/pi-footer/src/widgets/types.ts +181 -0
- package/node_modules/pi-footer/src/widgets/utils/colors.ts +11 -0
- package/node_modules/pi-footer/src/widgets/utils/context.ts +112 -0
- package/node_modules/pi-footer/src/widgets/utils/session.ts +19 -0
- package/node_modules/pi-footer/src/widgets/utils/token-format.ts +78 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +19 -0
- package/node_modules/pi-mcp-adapter/README.md +19 -4
- package/node_modules/pi-mcp-adapter/agent-dir.ts +40 -0
- package/node_modules/pi-mcp-adapter/commands.ts +12 -2
- package/node_modules/pi-mcp-adapter/direct-tools.ts +6 -8
- package/node_modules/pi-mcp-adapter/index.ts +15 -3
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +87 -4
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +138 -61
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +43 -4
- package/node_modules/pi-mcp-adapter/oauth.ts +48 -0
- package/node_modules/pi-mcp-adapter/package.json +8 -2
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +8 -10
- package/node_modules/pi-mcp-adapter/tool-registrar.ts +187 -3
- package/node_modules/pi-mcp-adapter/types.ts +2 -0
- package/node_modules/pi-web-access/CHANGELOG.md +45 -0
- package/node_modules/pi-web-access/README.md +104 -29
- package/node_modules/pi-web-access/bocha.ts +221 -0
- package/node_modules/pi-web-access/curator-page.ts +113 -12
- package/node_modules/pi-web-access/curator-server.ts +56 -20
- package/node_modules/pi-web-access/datalab-pdf-extract.ts +568 -0
- package/node_modules/pi-web-access/duckduckgo.ts +123 -0
- package/node_modules/pi-web-access/extract.ts +288 -143
- package/node_modules/pi-web-access/feature-config.ts +29 -0
- package/node_modules/pi-web-access/gemini-api.ts +4 -0
- package/node_modules/pi-web-access/gemini-search.ts +45 -12
- package/node_modules/pi-web-access/gemini-web.ts +68 -3
- package/node_modules/pi-web-access/index.ts +160 -71
- package/node_modules/pi-web-access/jina-search.ts +284 -0
- package/node_modules/pi-web-access/kagi.ts +12 -12
- package/node_modules/pi-web-access/openai-search.ts +12 -2
- package/node_modules/pi-web-access/package.json +4 -3
- package/node_modules/pi-web-access/pdf-extract.ts +327 -228
- package/node_modules/pi-web-access/storage.ts +440 -2
- package/node_modules/pi-web-access/summary-model-scope.ts +1 -1
- package/node_modules/pi-web-access/summary-review.ts +4 -2
- package/node_modules/pi-web-access/video-extract.ts +10 -8
- package/node_modules/pi-web-access/xai-search.ts +12 -2
- package/node_modules/pi-web-access/youtube-extract.ts +2 -1
- package/node_modules/remote-pi/LICENSE +21 -0
- package/node_modules/remote-pi/README.md +675 -0
- package/node_modules/remote-pi/dist/actions/handlers.d.ts +122 -0
- package/node_modules/remote-pi/dist/actions/handlers.js +160 -0
- package/node_modules/remote-pi/dist/actions/handlers.js.map +1 -0
- package/node_modules/remote-pi/dist/actions/registry.d.ts +39 -0
- package/node_modules/remote-pi/dist/actions/registry.js +58 -0
- package/node_modules/remote-pi/dist/actions/registry.js.map +1 -0
- package/node_modules/remote-pi/dist/bin/supervisord.d.ts +2 -0
- package/node_modules/remote-pi/dist/bin/supervisord.js +86 -0
- package/node_modules/remote-pi/dist/bin/supervisord.js.map +1 -0
- package/node_modules/remote-pi/dist/commands/builtin_mirror.d.ts +58 -0
- package/node_modules/remote-pi/dist/commands/builtin_mirror.js +71 -0
- package/node_modules/remote-pi/dist/commands/builtin_mirror.js.map +1 -0
- package/node_modules/remote-pi/dist/commands/list_commands.d.ts +60 -0
- package/node_modules/remote-pi/dist/commands/list_commands.js +73 -0
- package/node_modules/remote-pi/dist/commands/list_commands.js.map +1 -0
- package/node_modules/remote-pi/dist/config.d.ts +62 -0
- package/node_modules/remote-pi/dist/config.js +115 -0
- package/node_modules/remote-pi/dist/config.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/client.d.ts +20 -0
- package/node_modules/remote-pi/dist/daemon/client.js +131 -0
- package/node_modules/remote-pi/dist/daemon/client.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/control_protocol.d.ts +176 -0
- package/node_modules/remote-pi/dist/daemon/control_protocol.js +63 -0
- package/node_modules/remote-pi/dist/daemon/control_protocol.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/cron_log.d.ts +45 -0
- package/node_modules/remote-pi/dist/daemon/cron_log.js +72 -0
- package/node_modules/remote-pi/dist/daemon/cron_log.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/cron_registry.d.ts +80 -0
- package/node_modules/remote-pi/dist/daemon/cron_registry.js +194 -0
- package/node_modules/remote-pi/dist/daemon/cron_registry.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/id.d.ts +24 -0
- package/node_modules/remote-pi/dist/daemon/id.js +36 -0
- package/node_modules/remote-pi/dist/daemon/id.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/install.d.ts +170 -0
- package/node_modules/remote-pi/dist/daemon/install.js +547 -0
- package/node_modules/remote-pi/dist/daemon/install.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/registry.d.ts +63 -0
- package/node_modules/remote-pi/dist/daemon/registry.js +153 -0
- package/node_modules/remote-pi/dist/daemon/registry.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/rpc_child.d.ts +194 -0
- package/node_modules/remote-pi/dist/daemon/rpc_child.js +389 -0
- package/node_modules/remote-pi/dist/daemon/rpc_child.js.map +1 -0
- package/node_modules/remote-pi/dist/daemon/supervisor.d.ts +93 -0
- package/node_modules/remote-pi/dist/daemon/supervisor.js +596 -0
- package/node_modules/remote-pi/dist/daemon/supervisor.js.map +1 -0
- package/node_modules/remote-pi/dist/extension_ui_bridge.d.ts +26 -0
- package/node_modules/remote-pi/dist/extension_ui_bridge.js +341 -0
- package/node_modules/remote-pi/dist/extension_ui_bridge.js.map +1 -0
- package/node_modules/remote-pi/dist/index.d.ts +213 -0
- package/node_modules/remote-pi/dist/index.js +4996 -0
- package/node_modules/remote-pi/dist/index.js.map +1 -0
- package/node_modules/remote-pi/dist/mcp/mesh_result.d.ts +10 -0
- package/node_modules/remote-pi/dist/mcp/mesh_result.js +42 -0
- package/node_modules/remote-pi/dist/mcp/mesh_result.js.map +1 -0
- package/node_modules/remote-pi/dist/mcp/mesh_server.d.ts +16 -0
- package/node_modules/remote-pi/dist/mcp/mesh_server.js +327 -0
- package/node_modules/remote-pi/dist/mcp/mesh_server.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/canonical.d.ts +30 -0
- package/node_modules/remote-pi/dist/mesh/canonical.js +61 -0
- package/node_modules/remote-pi/dist/mesh/canonical.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/client.d.ts +18 -0
- package/node_modules/remote-pi/dist/mesh/client.js +125 -0
- package/node_modules/remote-pi/dist/mesh/client.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/encoding.d.ts +38 -0
- package/node_modules/remote-pi/dist/mesh/encoding.js +216 -0
- package/node_modules/remote-pi/dist/mesh/encoding.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/self_revoke.d.ts +73 -0
- package/node_modules/remote-pi/dist/mesh/self_revoke.js +401 -0
- package/node_modules/remote-pi/dist/mesh/self_revoke.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/siblings.d.ts +49 -0
- package/node_modules/remote-pi/dist/mesh/siblings.js +159 -0
- package/node_modules/remote-pi/dist/mesh/siblings.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/types.d.ts +34 -0
- package/node_modules/remote-pi/dist/mesh/types.js +11 -0
- package/node_modules/remote-pi/dist/mesh/types.js.map +1 -0
- package/node_modules/remote-pi/dist/mesh/verify.d.ts +17 -0
- package/node_modules/remote-pi/dist/mesh/verify.js +86 -0
- package/node_modules/remote-pi/dist/mesh/verify.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/crypto.d.ts +8 -0
- package/node_modules/remote-pi/dist/pairing/crypto.js +22 -0
- package/node_modules/remote-pi/dist/pairing/crypto.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/handshake.d.ts +28 -0
- package/node_modules/remote-pi/dist/pairing/handshake.js +113 -0
- package/node_modules/remote-pi/dist/pairing/handshake.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/noise-sha256.d.ts +16 -0
- package/node_modules/remote-pi/dist/pairing/noise-sha256.js +103 -0
- package/node_modules/remote-pi/dist/pairing/noise-sha256.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/qr.d.ts +59 -0
- package/node_modules/remote-pi/dist/pairing/qr.js +125 -0
- package/node_modules/remote-pi/dist/pairing/qr.js.map +1 -0
- package/node_modules/remote-pi/dist/pairing/storage.d.ts +120 -0
- package/node_modules/remote-pi/dist/pairing/storage.js +604 -0
- package/node_modules/remote-pi/dist/pairing/storage.js.map +1 -0
- package/node_modules/remote-pi/dist/protocol/codec.d.ts +7 -0
- package/node_modules/remote-pi/dist/protocol/codec.js +49 -0
- package/node_modules/remote-pi/dist/protocol/codec.js.map +1 -0
- package/node_modules/remote-pi/dist/protocol/types.d.ts +393 -0
- package/node_modules/remote-pi/dist/protocol/types.js +2 -0
- package/node_modules/remote-pi/dist/protocol/types.js.map +1 -0
- package/node_modules/remote-pi/dist/rooms.d.ts +29 -0
- package/node_modules/remote-pi/dist/rooms.js +57 -0
- package/node_modules/remote-pi/dist/rooms.js.map +1 -0
- package/node_modules/remote-pi/dist/session/address.d.ts +49 -0
- package/node_modules/remote-pi/dist/session/address.js +58 -0
- package/node_modules/remote-pi/dist/session/address.js.map +1 -0
- package/node_modules/remote-pi/dist/session/agent_bridge.d.ts +55 -0
- package/node_modules/remote-pi/dist/session/agent_bridge.js +146 -0
- package/node_modules/remote-pi/dist/session/agent_bridge.js.map +1 -0
- package/node_modules/remote-pi/dist/session/bridge.d.ts +37 -0
- package/node_modules/remote-pi/dist/session/bridge.js +130 -0
- package/node_modules/remote-pi/dist/session/bridge.js.map +1 -0
- package/node_modules/remote-pi/dist/session/broker.d.ts +189 -0
- package/node_modules/remote-pi/dist/session/broker.js +507 -0
- package/node_modules/remote-pi/dist/session/broker.js.map +1 -0
- package/node_modules/remote-pi/dist/session/broker_remote.d.ts +74 -0
- package/node_modules/remote-pi/dist/session/broker_remote.js +583 -0
- package/node_modules/remote-pi/dist/session/broker_remote.js.map +1 -0
- package/node_modules/remote-pi/dist/session/cwd_lock.d.ts +33 -0
- package/node_modules/remote-pi/dist/session/cwd_lock.js +126 -0
- package/node_modules/remote-pi/dist/session/cwd_lock.js.map +1 -0
- package/node_modules/remote-pi/dist/session/envelope.d.ts +33 -0
- package/node_modules/remote-pi/dist/session/envelope.js +117 -0
- package/node_modules/remote-pi/dist/session/envelope.js.map +1 -0
- package/node_modules/remote-pi/dist/session/global_config.d.ts +33 -0
- package/node_modules/remote-pi/dist/session/global_config.js +73 -0
- package/node_modules/remote-pi/dist/session/global_config.js.map +1 -0
- package/node_modules/remote-pi/dist/session/ipc.d.ts +27 -0
- package/node_modules/remote-pi/dist/session/ipc.js +22 -0
- package/node_modules/remote-pi/dist/session/ipc.js.map +1 -0
- package/node_modules/remote-pi/dist/session/leader_election.d.ts +32 -0
- package/node_modules/remote-pi/dist/session/leader_election.js +106 -0
- package/node_modules/remote-pi/dist/session/leader_election.js.map +1 -0
- package/node_modules/remote-pi/dist/session/local_config.d.ts +55 -0
- package/node_modules/remote-pi/dist/session/local_config.js +157 -0
- package/node_modules/remote-pi/dist/session/local_config.js.map +1 -0
- package/node_modules/remote-pi/dist/session/mesh_message.d.ts +20 -0
- package/node_modules/remote-pi/dist/session/mesh_message.js +28 -0
- package/node_modules/remote-pi/dist/session/mesh_message.js.map +1 -0
- package/node_modules/remote-pi/dist/session/mesh_node.d.ts +116 -0
- package/node_modules/remote-pi/dist/session/mesh_node.js +573 -0
- package/node_modules/remote-pi/dist/session/mesh_node.js.map +1 -0
- package/node_modules/remote-pi/dist/session/peer.d.ts +139 -0
- package/node_modules/remote-pi/dist/session/peer.js +451 -0
- package/node_modules/remote-pi/dist/session/peer.js.map +1 -0
- package/node_modules/remote-pi/dist/session/peer_inventory.d.ts +13 -0
- package/node_modules/remote-pi/dist/session/peer_inventory.js +48 -0
- package/node_modules/remote-pi/dist/session/peer_inventory.js.map +1 -0
- package/node_modules/remote-pi/dist/session/peer_limits.d.ts +9 -0
- package/node_modules/remote-pi/dist/session/peer_limits.js +21 -0
- package/node_modules/remote-pi/dist/session/peer_limits.js.map +1 -0
- package/node_modules/remote-pi/dist/session/setup_wizard.d.ts +39 -0
- package/node_modules/remote-pi/dist/session/setup_wizard.js +63 -0
- package/node_modules/remote-pi/dist/session/setup_wizard.js.map +1 -0
- package/node_modules/remote-pi/dist/session/tool_gate.d.ts +5 -0
- package/node_modules/remote-pi/dist/session/tool_gate.js +11 -0
- package/node_modules/remote-pi/dist/session/tool_gate.js.map +1 -0
- package/node_modules/remote-pi/dist/session/tools.d.ts +24 -0
- package/node_modules/remote-pi/dist/session/tools.js +252 -0
- package/node_modules/remote-pi/dist/session/tools.js.map +1 -0
- package/node_modules/remote-pi/dist/session/wizard.d.ts +13 -0
- package/node_modules/remote-pi/dist/session/wizard.js +20 -0
- package/node_modules/remote-pi/dist/session/wizard.js.map +1 -0
- package/node_modules/remote-pi/dist/settings.d.ts +15 -0
- package/node_modules/remote-pi/dist/settings.js +52 -0
- package/node_modules/remote-pi/dist/settings.js.map +1 -0
- package/node_modules/remote-pi/dist/transport/peer_channel.d.ts +37 -0
- package/node_modules/remote-pi/dist/transport/peer_channel.js +98 -0
- package/node_modules/remote-pi/dist/transport/peer_channel.js.map +1 -0
- package/node_modules/remote-pi/dist/transport/pi_forward_client.d.ts +29 -0
- package/node_modules/remote-pi/dist/transport/pi_forward_client.js +62 -0
- package/node_modules/remote-pi/dist/transport/pi_forward_client.js.map +1 -0
- package/node_modules/remote-pi/dist/transport/relay_client.d.ts +91 -0
- package/node_modules/remote-pi/dist/transport/relay_client.js +206 -0
- package/node_modules/remote-pi/dist/transport/relay_client.js.map +1 -0
- package/node_modules/remote-pi/dist/ui/footer.d.ts +32 -0
- package/node_modules/remote-pi/dist/ui/footer.js +34 -0
- package/node_modules/remote-pi/dist/ui/footer.js.map +1 -0
- package/node_modules/remote-pi/docs/daemon.md +289 -0
- package/node_modules/remote-pi/package.json +88 -0
- package/node_modules/remote-pi/service-templates/launchd.plist.template +35 -0
- package/node_modules/remote-pi/service-templates/systemd.service.template +19 -0
- package/node_modules/remote-pi/service-templates/task-launcher.vbs.template +10 -0
- package/node_modules/remote-pi/service-templates/task-scheduler.xml.template +38 -0
- package/node_modules/remote-pi/skills/agent-network/SKILL.md +310 -0
- package/package.json +25 -10
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-diff/write-display-utils.ts +0 -29
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference-core.ts → reference/session.ts} +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-aliases.ts → shell/aliases.ts} +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ATTRIBUTION.md +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-presentation.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/index.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/render-utils.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/shiki-highlight.ts +0 -0
- /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/types.ts +0 -0
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { ToolExecutionComponent } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
4
2
|
import type { CompactThinkingController } from "../feature/compact-thinking.ts";
|
|
5
|
-
import { installToolGrouping, type ToolGroupingHooks } from "./tool
|
|
3
|
+
import { installToolGrouping, type ToolGroupingHooks } from "./tool/grouping.ts";
|
|
6
4
|
import {
|
|
7
5
|
installCompactMode,
|
|
8
6
|
refreshCompactModeComponents,
|
|
9
7
|
type CompactModeHooks,
|
|
8
|
+
type CompactThinkingQuery,
|
|
10
9
|
} from "./compact-mode.ts";
|
|
10
|
+
import {
|
|
11
|
+
installDefaultMode,
|
|
12
|
+
installToolExpandedBackground,
|
|
13
|
+
type DefaultModeHooks,
|
|
14
|
+
} from "./default-mode.ts";
|
|
11
15
|
import { isLazyProxyTui } from "../utils/fullscreen-detect.ts";
|
|
12
16
|
import { showCcstylePanel } from "../config/panel.ts";
|
|
13
17
|
import {
|
|
14
18
|
config,
|
|
15
|
-
DEFAULT_CONFIG,
|
|
16
19
|
formatConfigStatus,
|
|
17
|
-
getCompactThinkingConfig,
|
|
18
|
-
getToolDisplayConfig,
|
|
19
20
|
normalizeConfig,
|
|
20
21
|
saveConfig,
|
|
21
22
|
setConfig,
|
|
@@ -24,73 +25,46 @@ import {
|
|
|
24
25
|
} from "../config/config.ts";
|
|
25
26
|
import {
|
|
26
27
|
installToolMouseInteraction,
|
|
27
|
-
isToolCallHovered,
|
|
28
28
|
resetToolHoverState,
|
|
29
29
|
scheduleSessionRender,
|
|
30
30
|
setHoveredToolGroup,
|
|
31
31
|
setHoveredToolIo,
|
|
32
32
|
teardownToolMouseInteraction,
|
|
33
|
-
toolMouseTui,
|
|
34
33
|
TOOL_MOUSE_DISABLE,
|
|
35
|
-
} from "./mouse
|
|
36
|
-
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
hasExpandableDetail,
|
|
40
|
-
headTruncateToWidth,
|
|
41
|
-
insetComponent,
|
|
42
|
-
isToolExpanded,
|
|
43
|
-
middleTruncateToWidth,
|
|
44
|
-
oneLine,
|
|
45
|
-
outputLineCount,
|
|
46
|
-
pendingIcon,
|
|
47
|
-
renderCollapsedToolResultToWidth,
|
|
48
|
-
renderExpandedToolResult,
|
|
49
|
-
resolveToolVisualState,
|
|
50
|
-
scheduleAnimation,
|
|
51
|
-
settledIcon,
|
|
52
|
-
setToolVisualState,
|
|
53
|
-
textFromResult,
|
|
54
|
-
toolIconColor,
|
|
55
|
-
toolViewportWidth,
|
|
56
|
-
} from "./tool-result.ts";
|
|
57
|
-
import { showMoreHintText } from "./show-more-hint.ts";
|
|
58
|
-
import type { CompactThinkingQuery } from "./compact-mode.ts";
|
|
59
|
-
import {
|
|
60
|
-
installWriteOverride,
|
|
61
|
-
renderRichToolResult,
|
|
62
|
-
WriteExecutionMetadataStore,
|
|
63
|
-
} from "./tool-diff/index.ts";
|
|
34
|
+
} from "./mouse/interaction.ts";
|
|
35
|
+
import { getToolMouseTui } from "./mouse/scroll.ts";
|
|
36
|
+
import { clearAllAnimations } from "./tool/result.ts";
|
|
37
|
+
import { installWriteOverride, WriteExecutionMetadataStore } from "./tool/diff/index.ts";
|
|
64
38
|
import {
|
|
65
|
-
getMessageDisplayTheme,
|
|
66
39
|
installMessageDisplayRendering,
|
|
67
40
|
refreshMessageDisplays,
|
|
68
41
|
setMessageDisplayTheme,
|
|
69
42
|
} from "./message-display.ts";
|
|
70
43
|
|
|
71
44
|
/**
|
|
72
|
-
* Claude Code Style for pi —
|
|
45
|
+
* Claude Code Style for pi — 装配入口。
|
|
73
46
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
47
|
+
* mode=on → default-mode(工具卡样式 + 展开背景)
|
|
48
|
+
* mode=compact → compact-mode(消息折叠摘要)
|
|
49
|
+
* 共用 → tool-grouping / message-display / mouse / write override
|
|
76
50
|
*/
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
51
|
+
|
|
52
|
+
const GLOBAL_COMPACTION_RENDER_PATCH = Symbol.for("pi.ccstyle.compaction-render-patch");
|
|
53
|
+
|
|
54
|
+
let compactModeHooks: CompactModeHooks | undefined;
|
|
80
55
|
|
|
81
56
|
function refreshCurrentTranscript(ctx?: any, toolGrouping?: ToolGroupingHooks): void {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
57
|
+
const tui = getToolMouseTui();
|
|
58
|
+
toolGrouping?.refresh(tui);
|
|
59
|
+
refreshMessageDisplays(tui);
|
|
60
|
+
refreshCompactModeComponents(tui);
|
|
85
61
|
compactModeHooks?.refresh();
|
|
86
|
-
|
|
62
|
+
tui?.requestRender?.(true);
|
|
87
63
|
ctx?.ui?.requestRender?.(true);
|
|
88
64
|
}
|
|
89
65
|
|
|
90
|
-
let compactModeHooks: CompactModeHooks | undefined;
|
|
91
|
-
|
|
92
66
|
function syncCompactMode(ctx: any): void {
|
|
93
|
-
refreshCompactModeComponents(
|
|
67
|
+
refreshCompactModeComponents(getToolMouseTui());
|
|
94
68
|
compactModeHooks?.sync(ctx);
|
|
95
69
|
}
|
|
96
70
|
|
|
@@ -98,708 +72,30 @@ function applyStyleMode(mode: CompactStyleMode, ctx: any, toolGrouping?: ToolGro
|
|
|
98
72
|
config.mode = mode;
|
|
99
73
|
saveConfig();
|
|
100
74
|
if (mode === "off") {
|
|
101
|
-
// Native rendering
|
|
102
|
-
// reporting so the terminal restores its default scrollback wheel scrolling.
|
|
75
|
+
// Native rendering:清 hover/click,关闭鼠标上报以恢复终端默认滚轮。
|
|
103
76
|
resetToolHoverState();
|
|
104
77
|
setHoveredToolGroup(null);
|
|
105
78
|
setHoveredToolIo(null, null);
|
|
106
79
|
// 惰性 Proxy(regular/fullscreen)不持有 reporting:regular 保终端回滚,
|
|
107
80
|
// fullscreen 归官方所有,均不能在此关闭。
|
|
108
|
-
|
|
109
|
-
|
|
81
|
+
const tui = getToolMouseTui();
|
|
82
|
+
if (tui && !isLazyProxyTui(tui)) {
|
|
83
|
+
tui.terminal?.write?.(TOOL_MOUSE_DISABLE);
|
|
110
84
|
}
|
|
111
85
|
} else if (mode === "compact") {
|
|
112
86
|
// 切入 compact:先收集当前 transcript,再同步全局展开状态和补丁所有权。
|
|
113
87
|
syncCompactMode(ctx);
|
|
114
88
|
}
|
|
89
|
+
// 立即重塑一次;再延迟一帧(与 session_start 同款),等面板/custom
|
|
90
|
+
// 卸下、主 transcript 重新挂载后再扫树,避免必须 /reload。
|
|
115
91
|
refreshCurrentTranscript(ctx, toolGrouping);
|
|
92
|
+
scheduleSessionRender(() => {
|
|
93
|
+
if (mode === "compact") syncCompactMode(ctx);
|
|
94
|
+
refreshCurrentTranscript(ctx, toolGrouping);
|
|
95
|
+
});
|
|
116
96
|
ctx.ui.notify(`Claude Code style: ${mode}`, "info");
|
|
117
97
|
}
|
|
118
98
|
|
|
119
|
-
function renderDefault(tool: any, slot: "renderCall" | "renderResult", args: any[], fallback = "") {
|
|
120
|
-
try {
|
|
121
|
-
if (typeof tool?.[slot] === "function") return tool[slot](...args);
|
|
122
|
-
} catch {
|
|
123
|
-
// Fall through to raw fallback.
|
|
124
|
-
}
|
|
125
|
-
return new Text(fallback, 0, 0);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function singleLine(text: string) {
|
|
129
|
-
return {
|
|
130
|
-
render: (width: number) => [truncateToWidth(text, width, "…")],
|
|
131
|
-
invalidate() {},
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function humanizeToolLabel(label: string): string {
|
|
136
|
-
return label
|
|
137
|
-
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
138
|
-
.replace(/[_-]+/g, " ")
|
|
139
|
-
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function singleToolCallSummary(
|
|
143
|
-
toolName: string,
|
|
144
|
-
label: string,
|
|
145
|
-
args: any,
|
|
146
|
-
): { main: string; detail: string } {
|
|
147
|
-
const title = label === toolName ? humanizeToolLabel(label) : label;
|
|
148
|
-
if (!args || typeof args !== "object") return { main: title, detail: "" };
|
|
149
|
-
const name = toolName.toLowerCase();
|
|
150
|
-
const value = (fallback: string, ...keys: string[]) => {
|
|
151
|
-
const found = keys.map((key) => args[key]).find((item) => typeof item === "string" && item);
|
|
152
|
-
// 与多 tool 摘要对齐:从头截断,上限 96 字符(tool-grouping oneLine 默认值)。
|
|
153
|
-
return `${title} ${oneLine(found || fallback, 96)}`;
|
|
154
|
-
};
|
|
155
|
-
if (AGENT_FAMILY_TOOL_NAMES.has(toolName) && args.agent_id) {
|
|
156
|
-
return { main: `${title} ${oneLine(args.agent_id, 96)}`, detail: "" };
|
|
157
|
-
}
|
|
158
|
-
// Agents still uses the ccstyle wrapper; Agent keeps its dedicated renderer.
|
|
159
|
-
if (name === "agents") {
|
|
160
|
-
return {
|
|
161
|
-
main: value("launch agents", "description", "prompt"),
|
|
162
|
-
detail: "",
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
if (name === "skill") return { main: value("run skill", "name"), detail: "" };
|
|
166
|
-
if (name === "enterplanmode" || name === "enter_plan_mode") {
|
|
167
|
-
return { main: `${title} enable read-only planning`, detail: "" };
|
|
168
|
-
}
|
|
169
|
-
if (name === "exitplanmode" || name === "exit_plan_mode") {
|
|
170
|
-
return { main: `${title} present plan`, detail: "" };
|
|
171
|
-
}
|
|
172
|
-
if (name === "taskcreate") return { main: value("create task", "subject"), detail: "" };
|
|
173
|
-
if (name === "tasklist") return { main: `${title} task list`, detail: "" };
|
|
174
|
-
if (name === "taskget" || name === "taskupdate") {
|
|
175
|
-
return { main: value("task", "taskId", "task_id"), detail: "" };
|
|
176
|
-
}
|
|
177
|
-
if (name === "taskoutput" || name === "taskstop") {
|
|
178
|
-
return { main: value("background task", "task_id", "taskId"), detail: "" };
|
|
179
|
-
}
|
|
180
|
-
if (name === "taskexecute") {
|
|
181
|
-
const ids = Array.isArray(args.task_ids)
|
|
182
|
-
? args.task_ids
|
|
183
|
-
: Array.isArray(args.taskIds)
|
|
184
|
-
? args.taskIds
|
|
185
|
-
: [];
|
|
186
|
-
const summary = ids.length
|
|
187
|
-
? `${ids[0]}${ids.length > 1 ? ` (+${ids.length - 1} tasks)` : ""}`
|
|
188
|
-
: "start tasks";
|
|
189
|
-
return { main: `${title} ${summary}`, detail: "" };
|
|
190
|
-
}
|
|
191
|
-
if (toolName === "read") {
|
|
192
|
-
const details = [
|
|
193
|
-
args.offset !== undefined ? `offset=${args.offset}` : "",
|
|
194
|
-
args.limit !== undefined ? `limit=${args.limit}` : "",
|
|
195
|
-
].filter(Boolean);
|
|
196
|
-
return {
|
|
197
|
-
main: `${title}${args.path ? ` ${oneLine(args.path, 96)}` : ""}`,
|
|
198
|
-
detail: details.length ? ` (${details.join(", ")})` : "",
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
const preferred =
|
|
202
|
-
args.path ??
|
|
203
|
-
args.file_path ??
|
|
204
|
-
args.command ??
|
|
205
|
-
args.query ??
|
|
206
|
-
args.question ??
|
|
207
|
-
args.pattern ??
|
|
208
|
-
args.url ??
|
|
209
|
-
args.name ??
|
|
210
|
-
args.tool_use_id ??
|
|
211
|
-
args.toolCallId ??
|
|
212
|
-
args.id ??
|
|
213
|
-
args.message;
|
|
214
|
-
return {
|
|
215
|
-
main:
|
|
216
|
-
preferred !== undefined && preferred !== null && typeof preferred !== "object"
|
|
217
|
-
? `${title} ${oneLine(preferred, 96)}`
|
|
218
|
-
: title,
|
|
219
|
-
detail: "",
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export function shouldRenderRichDiff(
|
|
224
|
-
mode: CompactStyleMode,
|
|
225
|
-
toolName: string,
|
|
226
|
-
isError: boolean,
|
|
227
|
-
): boolean {
|
|
228
|
-
return mode === "on" && !isError && (toolName === "edit" || toolName === "write");
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
type ParsedTask = { id: string; status: string; subject: string };
|
|
232
|
-
|
|
233
|
-
function parseTaskList(text: string): ParsedTask[] {
|
|
234
|
-
return text
|
|
235
|
-
.split("\n")
|
|
236
|
-
.map((line) => line.match(/^#(\d+) \[([^\]]+)] (.+)$/))
|
|
237
|
-
.filter((match): match is RegExpMatchArray => Boolean(match))
|
|
238
|
-
.map((match) => ({ id: match[1]!, status: match[2]!, subject: match[3]! }));
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function taskListSummary(tasks: ParsedTask[]): string {
|
|
242
|
-
const counts = { pending: 0, in_progress: 0, completed: 0 };
|
|
243
|
-
for (const task of tasks) {
|
|
244
|
-
if (task.status in counts) counts[task.status as keyof typeof counts]++;
|
|
245
|
-
}
|
|
246
|
-
return [
|
|
247
|
-
`${tasks.length} tasks`,
|
|
248
|
-
counts.in_progress ? `${counts.in_progress} in progress` : "",
|
|
249
|
-
counts.pending ? `${counts.pending} pending` : "",
|
|
250
|
-
counts.completed ? `${counts.completed} completed` : "",
|
|
251
|
-
]
|
|
252
|
-
.filter(Boolean)
|
|
253
|
-
.join(" • ");
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
function renderExpandedTaskResult(
|
|
257
|
-
toolName: string,
|
|
258
|
-
text: string,
|
|
259
|
-
theme: any,
|
|
260
|
-
isError: boolean,
|
|
261
|
-
): any | undefined {
|
|
262
|
-
if (isError) return undefined;
|
|
263
|
-
if (toolName === "TaskList") {
|
|
264
|
-
const tasks = parseTaskList(text);
|
|
265
|
-
if (!tasks.length) return undefined;
|
|
266
|
-
const limit = Math.max(1, config.expandedPreviewMaxLines);
|
|
267
|
-
const rows = tasks.slice(0, limit).map((task) => {
|
|
268
|
-
const color =
|
|
269
|
-
task.status === "completed"
|
|
270
|
-
? "success"
|
|
271
|
-
: task.status === "in_progress"
|
|
272
|
-
? "warning"
|
|
273
|
-
: "muted";
|
|
274
|
-
return ` ${theme.fg("accent", `#${task.id}`)} ${theme.fg(color, task.status)} ${theme.fg("dim", task.subject)}`;
|
|
275
|
-
});
|
|
276
|
-
if (tasks.length > rows.length)
|
|
277
|
-
rows.push(theme.fg("muted", ` … ${tasks.length - rows.length} more tasks`));
|
|
278
|
-
return new Text(` ↳ ${theme.fg("muted", taskListSummary(tasks))}\n${rows.join("\n")}`, 0, 0);
|
|
279
|
-
}
|
|
280
|
-
const line = text.trim();
|
|
281
|
-
if (!line || line.includes("\n")) return undefined;
|
|
282
|
-
let formatted: string | undefined;
|
|
283
|
-
let match: RegExpMatchArray | null;
|
|
284
|
-
if (
|
|
285
|
-
toolName === "TaskCreate" &&
|
|
286
|
-
(match = line.match(/^Task #(\d+) created successfully: (.+)$/))
|
|
287
|
-
) {
|
|
288
|
-
formatted = `${theme.fg("success", "Created task")} ${theme.fg("accent", `#${match[1]}`)} ${theme.fg("muted", match[2])}`;
|
|
289
|
-
} else if (toolName === "TaskUpdate" && (match = line.match(/^Updated task #(\d+) (.+)$/))) {
|
|
290
|
-
formatted = `${theme.fg("success", "Updated task")} ${theme.fg("accent", `#${match[1]}`)} ${theme.fg("muted", match[2])}`;
|
|
291
|
-
} else if (toolName === "TaskExecute") {
|
|
292
|
-
formatted = `${theme.fg("success", "Started")} ${theme.fg("muted", line)}`;
|
|
293
|
-
} else if (toolName === "TaskStop") {
|
|
294
|
-
formatted = `${theme.fg("success", "Stopped")} ${theme.fg("muted", line)}`;
|
|
295
|
-
}
|
|
296
|
-
return formatted ? new Text(` ↳ ${formatted}`, 0, 0) : undefined;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/** Wrap an arbitrary tool definition with ccstyle call/result rendering. */
|
|
300
|
-
function createCcstyleTool(
|
|
301
|
-
originalTool: any,
|
|
302
|
-
writeExecutionMetadata: WriteExecutionMetadataStore,
|
|
303
|
-
): any {
|
|
304
|
-
const toolName = originalTool.name;
|
|
305
|
-
const label = isMcpToolDefinition(originalTool, toolName)
|
|
306
|
-
? humanizeMcpToolName(toolName)
|
|
307
|
-
: originalTool.label || toolName;
|
|
308
|
-
|
|
309
|
-
return {
|
|
310
|
-
...originalTool,
|
|
311
|
-
renderShell: "self",
|
|
312
|
-
renderCall(args: any, theme: any, context: any) {
|
|
313
|
-
if (config.mode !== "on") {
|
|
314
|
-
return renderDefault(originalTool, "renderCall", [args, theme, context], String(toolName));
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const visualState = resolveToolVisualState(context);
|
|
318
|
-
const isPending =
|
|
319
|
-
visualState === "pending" ||
|
|
320
|
-
(!visualState && (context?.isPartial || context?.executionStarted));
|
|
321
|
-
if (isPending) scheduleAnimation(context);
|
|
322
|
-
const rawIcon = isPending ? pendingIcon(toolName) : settledIcon(toolName, visualState);
|
|
323
|
-
const icon =
|
|
324
|
-
visualState === "success"
|
|
325
|
-
? `${BRIGHT_GREEN}${rawIcon}${ANSI_FG_RESET}`
|
|
326
|
-
: theme.fg(toolIconColor(context), rawIcon);
|
|
327
|
-
const summary = singleToolCallSummary(toolName, label, args);
|
|
328
|
-
let cachedWidth: number | undefined;
|
|
329
|
-
let cachedLine: string | undefined;
|
|
330
|
-
return {
|
|
331
|
-
render(width: number) {
|
|
332
|
-
if (cachedLine !== undefined && cachedWidth === width) return [cachedLine];
|
|
333
|
-
const viewportWidth = toolViewportWidth(width);
|
|
334
|
-
const callWidth = Math.max(0, viewportWidth - visibleWidth(icon) - 2);
|
|
335
|
-
const mainWidth = Math.max(0, callWidth - visibleWidth(summary.detail));
|
|
336
|
-
cachedWidth = width;
|
|
337
|
-
// 纯文本先截断再着色(省略号不带 ANSI,避免 reset 破坏卡片背景);从头截断,与多 tool 一致
|
|
338
|
-
cachedLine = ` ${icon} ${theme.fg("toolTitle", headTruncateToWidth(summary.main, mainWidth))}${theme.fg("dim", summary.detail)}`;
|
|
339
|
-
return [truncateToWidth(cachedLine, viewportWidth, "")];
|
|
340
|
-
},
|
|
341
|
-
invalidate() {},
|
|
342
|
-
};
|
|
343
|
-
},
|
|
344
|
-
renderResult(result: any, options: any, theme: any, context: any) {
|
|
345
|
-
if (config.mode !== "on") {
|
|
346
|
-
return renderDefault(
|
|
347
|
-
originalTool,
|
|
348
|
-
"renderResult",
|
|
349
|
-
[result, options, theme, context],
|
|
350
|
-
textFromResult(result),
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if (options?.isPartial) {
|
|
355
|
-
return new Text(theme.fg("muted", " ↳ Pending…"), 0, 0);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const isError = options?.isError || context?.isError;
|
|
359
|
-
setToolVisualState(context, isError ? "error" : "success");
|
|
360
|
-
const expanded = isToolExpanded(options, context);
|
|
361
|
-
const toolCallId = context?.toolCallId;
|
|
362
|
-
if (shouldRenderRichDiff(config.mode, toolName, Boolean(isError))) {
|
|
363
|
-
// Pass getter so Diff indicator / wrap / limits update on the next paint
|
|
364
|
-
// without recreating the tool result component.
|
|
365
|
-
const richResult = renderRichToolResult(
|
|
366
|
-
toolName,
|
|
367
|
-
result,
|
|
368
|
-
{
|
|
369
|
-
...options,
|
|
370
|
-
expanded,
|
|
371
|
-
// 全局共享状态避免 /reload 后旧 result renderer 闭包失联。
|
|
372
|
-
isHovered: () => isToolCallHovered(toolCallId),
|
|
373
|
-
},
|
|
374
|
-
theme,
|
|
375
|
-
context,
|
|
376
|
-
writeExecutionMetadata,
|
|
377
|
-
getToolDisplayConfig,
|
|
378
|
-
);
|
|
379
|
-
if (richResult) return insetComponent(richResult);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const text = textFromResult(result, expanded);
|
|
383
|
-
const args = context?.args;
|
|
384
|
-
if (expanded) {
|
|
385
|
-
const taskResult = renderExpandedTaskResult(toolName, text, theme, Boolean(isError));
|
|
386
|
-
if (taskResult) return taskResult;
|
|
387
|
-
}
|
|
388
|
-
const tasks = !isError && toolName === "TaskList" ? parseTaskList(text) : [];
|
|
389
|
-
const outputLines = outputLineCount(result) || countLines(text);
|
|
390
|
-
const lineWord = outputLines === 1 ? "line" : "lines";
|
|
391
|
-
const action = toolName === "read" ? "loaded" : "returned";
|
|
392
|
-
const rendered = tasks.length
|
|
393
|
-
? taskListSummary(tasks)
|
|
394
|
-
: isError
|
|
395
|
-
? text
|
|
396
|
-
? oneLine(text)
|
|
397
|
-
: "Failed"
|
|
398
|
-
: outputLines
|
|
399
|
-
? `${outputLines} ${lineWord} ${action}`
|
|
400
|
-
: "Done";
|
|
401
|
-
const expandable = !expanded && (tasks.length > 0 || hasExpandableDetail(text, args));
|
|
402
|
-
const hintText = showMoreHintText();
|
|
403
|
-
const hintPrefix = expandable ? theme.fg("dim", " • ") : "";
|
|
404
|
-
const hint = expandable ? hintPrefix + theme.fg("dim", hintText) : "";
|
|
405
|
-
const hoveredHint = expandable ? hintPrefix + theme.fg("text", hintText) : "";
|
|
406
|
-
if (expanded) {
|
|
407
|
-
return renderExpandedToolResult(
|
|
408
|
-
text || "",
|
|
409
|
-
theme,
|
|
410
|
-
Boolean(isError),
|
|
411
|
-
context?.lastComponent,
|
|
412
|
-
args,
|
|
413
|
-
context,
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
if (context?.state) context.state.ccstyleIoView = undefined;
|
|
417
|
-
let cachedWidth: number | undefined;
|
|
418
|
-
let cachedLine: string | undefined;
|
|
419
|
-
let cachedHoveredLine: string | undefined;
|
|
420
|
-
return {
|
|
421
|
-
render(width: number) {
|
|
422
|
-
if (cachedLine === undefined || cachedWidth !== width) {
|
|
423
|
-
cachedWidth = width;
|
|
424
|
-
cachedLine = theme.fg(
|
|
425
|
-
isError ? "error" : "muted",
|
|
426
|
-
renderCollapsedToolResultToWidth(rendered, hint, width),
|
|
427
|
-
);
|
|
428
|
-
cachedHoveredLine = theme.fg(
|
|
429
|
-
isError ? "error" : "muted",
|
|
430
|
-
renderCollapsedToolResultToWidth(rendered, hoveredHint, width),
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
return [isToolCallHovered(toolCallId) ? cachedHoveredLine! : cachedLine];
|
|
434
|
-
},
|
|
435
|
-
invalidate() {},
|
|
436
|
-
};
|
|
437
|
-
},
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Apart from the write override used to capture pre-write content, renderers are
|
|
443
|
-
* applied through ToolExecutionComponent. Patch its lookup once so tools use the
|
|
444
|
-
* same ccstyle fallback shell by default. Tools named in excludeRenderers keep
|
|
445
|
-
* their original renderer.
|
|
446
|
-
*/
|
|
447
|
-
const GLOBAL_TOOL_RENDER_PATCH = Symbol.for("pi.ccstyle.global-tool-render-patch");
|
|
448
|
-
const COMPONENT_TOOL_RENDER_MODE = Symbol.for("pi.ccstyle.component-tool-render-mode");
|
|
449
|
-
const COMPONENT_TOOL_SELF_SHELL_MODE = Symbol.for("pi.ccstyle.component-tool-self-shell-mode");
|
|
450
|
-
const AGENT_FAMILY_TOOL_NAMES = new Set([
|
|
451
|
-
"Agent",
|
|
452
|
-
"Agents",
|
|
453
|
-
"get_subagent_result",
|
|
454
|
-
"steer_subagent",
|
|
455
|
-
]);
|
|
456
|
-
// pi-subagents 等扩展为 Agent 提供专用渲染器(displayName/运行统计),ccstyle 必须保留,不能 wrap。
|
|
457
|
-
const DEDICATED_RENDERER_TOOLS = new Set(["Agent"]);
|
|
458
|
-
|
|
459
|
-
type ToolRenderMethods = {
|
|
460
|
-
hasRendererDefinition: (...args: any[]) => boolean;
|
|
461
|
-
getRenderShell: (...args: any[]) => "default" | "self";
|
|
462
|
-
getCallRenderer: (...args: any[]) => any;
|
|
463
|
-
getResultRenderer: (...args: any[]) => any;
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
type GlobalToolRenderPatch = {
|
|
467
|
-
version: 2;
|
|
468
|
-
prototype: any;
|
|
469
|
-
owner: object;
|
|
470
|
-
active: boolean;
|
|
471
|
-
enabled: () => boolean;
|
|
472
|
-
mode: () => CompactStyleMode;
|
|
473
|
-
wrap: (tool: any) => any;
|
|
474
|
-
byDefinition: WeakMap<object, any>;
|
|
475
|
-
byName: Map<string, any>;
|
|
476
|
-
downstream: ToolRenderMethods;
|
|
477
|
-
installed: ToolRenderMethods;
|
|
478
|
-
// Keep the legacy aliases so an older extension build can read this Symbol.
|
|
479
|
-
originalHasRendererDefinition: ToolRenderMethods["hasRendererDefinition"];
|
|
480
|
-
originalGetRenderShell: ToolRenderMethods["getRenderShell"];
|
|
481
|
-
originalGetCallRenderer: ToolRenderMethods["getCallRenderer"];
|
|
482
|
-
originalGetResultRenderer: ToolRenderMethods["getResultRenderer"];
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
export function isMcpToolDefinition(definition: any, toolName: string): boolean {
|
|
486
|
-
const label = typeof definition?.label === "string" ? definition.label.trim() : "";
|
|
487
|
-
if (/^MCP(?::|$)/i.test(label)) return true;
|
|
488
|
-
if (toolName === "mcp" || /^mcp[_:-]|[_:-]mcp[_:-]/i.test(toolName)) return true;
|
|
489
|
-
if (label) return false;
|
|
490
|
-
const description = typeof definition?.description === "string" ? definition.description : "";
|
|
491
|
-
return /\bModel Context Protocol\b/i.test(description);
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
export function humanizeMcpToolName(toolName: string): string {
|
|
495
|
-
const words = toolName
|
|
496
|
-
.replace(/^mcp(?:[_:-]+)+/i, "")
|
|
497
|
-
.split(/[_:-]+/)
|
|
498
|
-
.filter(Boolean);
|
|
499
|
-
return words.length
|
|
500
|
-
? words.map((word) => word[0]!.toUpperCase() + word.slice(1)).join(" ")
|
|
501
|
-
: "MCP";
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/** Return true when this tool must keep its original renderer. */
|
|
505
|
-
export function preservesOriginalRenderer(
|
|
506
|
-
extensionDefinition: any,
|
|
507
|
-
toolName: string,
|
|
508
|
-
builtInToolDefinition?: any,
|
|
509
|
-
excludeRenderers: readonly string[] = config.excludeRenderers,
|
|
510
|
-
): boolean {
|
|
511
|
-
if (!excludeRenderers.includes(toolName)) return false;
|
|
512
|
-
return [extensionDefinition, builtInToolDefinition].some(
|
|
513
|
-
(definition) =>
|
|
514
|
-
definition?.renderShell === "self" ||
|
|
515
|
-
typeof definition?.renderCall === "function" ||
|
|
516
|
-
typeof definition?.renderResult === "function",
|
|
517
|
-
);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function syncToolShell(component: any, shell: "default" | "self"): void {
|
|
521
|
-
const target = shell === "self" ? component.selfRenderContainer : component.contentBox;
|
|
522
|
-
if (!target || !Array.isArray(component.children)) return;
|
|
523
|
-
const candidates = new Set(
|
|
524
|
-
[component.contentText, component.contentBox, component.selfRenderContainer].filter(Boolean),
|
|
525
|
-
);
|
|
526
|
-
const indexes = component.children
|
|
527
|
-
.map((child: any, index: number) => (candidates.has(child) ? index : -1))
|
|
528
|
-
.filter((index: number) => index >= 0);
|
|
529
|
-
const targetIndex = indexes[0];
|
|
530
|
-
// During construction getRenderShell() runs immediately before Pi mounts the
|
|
531
|
-
// selected shell. Do not mount it here or the constructor will add it twice.
|
|
532
|
-
if (targetIndex === undefined) return;
|
|
533
|
-
component.children[targetIndex] = target;
|
|
534
|
-
for (const index of indexes.sort((left: number, right: number) => right - left)) {
|
|
535
|
-
if (index !== targetIndex) component.children.splice(index, 1);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
function shouldGloballyStyleTool(component: any, patch: GlobalToolRenderPatch): boolean {
|
|
540
|
-
const extensionDefinition = component.toolDefinition;
|
|
541
|
-
const builtInDefinition = component.builtInToolDefinition;
|
|
542
|
-
const definition = extensionDefinition ?? builtInDefinition;
|
|
543
|
-
const toolName = String(component.toolName || definition?.name || "");
|
|
544
|
-
const useCcstyle =
|
|
545
|
-
patch.mode() === "on" &&
|
|
546
|
-
!DEDICATED_RENDERER_TOOLS.has(toolName) &&
|
|
547
|
-
!preservesOriginalRenderer(extensionDefinition, toolName, builtInDefinition);
|
|
548
|
-
component[COMPONENT_TOOL_RENDER_MODE] = useCcstyle;
|
|
549
|
-
return useCcstyle;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
function shouldUseSelfShell(component: any, _patch: GlobalToolRenderPatch): boolean {
|
|
553
|
-
component[COMPONENT_TOOL_SELF_SHELL_MODE] = false;
|
|
554
|
-
return false;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
function getGloballyStyledTool(component: any, patch: GlobalToolRenderPatch): any {
|
|
558
|
-
const definition = component.toolDefinition ?? component.builtInToolDefinition;
|
|
559
|
-
if (definition && typeof definition === "object") {
|
|
560
|
-
let wrapped = patch.byDefinition.get(definition);
|
|
561
|
-
if (!wrapped) {
|
|
562
|
-
wrapped = patch.wrap(definition);
|
|
563
|
-
patch.byDefinition.set(definition, wrapped);
|
|
564
|
-
}
|
|
565
|
-
return wrapped;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
const name = String(component.toolName || "tool");
|
|
569
|
-
let wrapped = patch.byName.get(name);
|
|
570
|
-
if (!wrapped) {
|
|
571
|
-
wrapped = patch.wrap({ name, label: name });
|
|
572
|
-
patch.byName.set(name, wrapped);
|
|
573
|
-
}
|
|
574
|
-
return wrapped;
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
function prototypeToolRenderMethods(prototype: any): ToolRenderMethods {
|
|
578
|
-
return {
|
|
579
|
-
hasRendererDefinition: prototype.hasRendererDefinition,
|
|
580
|
-
getRenderShell: prototype.getRenderShell,
|
|
581
|
-
getCallRenderer: prototype.getCallRenderer,
|
|
582
|
-
getResultRenderer: prototype.getResultRenderer,
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
function isOwnershipAwarePatch(value: any): value is GlobalToolRenderPatch {
|
|
587
|
-
if (!value || value.version !== 2 || !value.installed || !value.downstream) return false;
|
|
588
|
-
return ["hasRendererDefinition", "getRenderShell", "getCallRenderer", "getResultRenderer"].every(
|
|
589
|
-
(name) =>
|
|
590
|
-
typeof value.installed[name] === "function" && typeof value.downstream[name] === "function",
|
|
591
|
-
);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
function isLegacyInstalledWrapper(method: unknown, downstreamField: string): boolean {
|
|
595
|
-
if (typeof method !== "function") return false;
|
|
596
|
-
try {
|
|
597
|
-
const source = Function.prototype.toString.call(method);
|
|
598
|
-
return (
|
|
599
|
-
source.includes(downstreamField) &&
|
|
600
|
-
(source.includes("shouldGloballyStyleTool") ||
|
|
601
|
-
source.includes("shouldUseSelfShell") ||
|
|
602
|
-
source.includes("getGloballyStyledTool"))
|
|
603
|
-
);
|
|
604
|
-
} catch {
|
|
605
|
-
return false;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
function downstreamForGlobalToolInstall(prototype: any, previous: any): ToolRenderMethods {
|
|
610
|
-
const current = prototypeToolRenderMethods(prototype);
|
|
611
|
-
if (!previous || previous.prototype !== prototype) return current;
|
|
612
|
-
if (isOwnershipAwarePatch(previous)) {
|
|
613
|
-
return {
|
|
614
|
-
hasRendererDefinition:
|
|
615
|
-
current.hasRendererDefinition === previous.installed.hasRendererDefinition
|
|
616
|
-
? previous.downstream.hasRendererDefinition
|
|
617
|
-
: current.hasRendererDefinition,
|
|
618
|
-
getRenderShell:
|
|
619
|
-
current.getRenderShell === previous.installed.getRenderShell
|
|
620
|
-
? previous.downstream.getRenderShell
|
|
621
|
-
: current.getRenderShell,
|
|
622
|
-
getCallRenderer:
|
|
623
|
-
current.getCallRenderer === previous.installed.getCallRenderer
|
|
624
|
-
? previous.downstream.getCallRenderer
|
|
625
|
-
: current.getCallRenderer,
|
|
626
|
-
getResultRenderer:
|
|
627
|
-
current.getResultRenderer === previous.installed.getResultRenderer
|
|
628
|
-
? previous.downstream.getResultRenderer
|
|
629
|
-
: current.getResultRenderer,
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// Pre-v2 Symbol state did not retain wrapper references. Recognize its known
|
|
634
|
-
// wrappers when possible; otherwise preserve the current method as external.
|
|
635
|
-
const legacyDownstream = (method: Function, field: string): Function => {
|
|
636
|
-
const saved = previous[field];
|
|
637
|
-
return typeof saved === "function" && isLegacyInstalledWrapper(method, field) ? saved : method;
|
|
638
|
-
};
|
|
639
|
-
return {
|
|
640
|
-
hasRendererDefinition: legacyDownstream(
|
|
641
|
-
current.hasRendererDefinition,
|
|
642
|
-
"originalHasRendererDefinition",
|
|
643
|
-
) as ToolRenderMethods["hasRendererDefinition"],
|
|
644
|
-
getRenderShell: legacyDownstream(
|
|
645
|
-
current.getRenderShell,
|
|
646
|
-
"originalGetRenderShell",
|
|
647
|
-
) as ToolRenderMethods["getRenderShell"],
|
|
648
|
-
getCallRenderer: legacyDownstream(
|
|
649
|
-
current.getCallRenderer,
|
|
650
|
-
"originalGetCallRenderer",
|
|
651
|
-
) as ToolRenderMethods["getCallRenderer"],
|
|
652
|
-
getResultRenderer: legacyDownstream(
|
|
653
|
-
current.getResultRenderer,
|
|
654
|
-
"originalGetResultRenderer",
|
|
655
|
-
) as ToolRenderMethods["getResultRenderer"],
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
function disconnectGlobalToolRenderPatch(patch: any): void {
|
|
660
|
-
if (!patch || typeof patch !== "object") return;
|
|
661
|
-
patch.active = false;
|
|
662
|
-
patch.enabled = () => false;
|
|
663
|
-
patch.mode = () => "off";
|
|
664
|
-
patch.wrap = (tool: any) => tool;
|
|
665
|
-
patch.byDefinition = new WeakMap();
|
|
666
|
-
if (patch.byName && typeof patch.byName.clear === "function") patch.byName.clear();
|
|
667
|
-
else patch.byName = new Map();
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
function installGlobalToolRendering(
|
|
671
|
-
writeExecutionMetadata: WriteExecutionMetadataStore,
|
|
672
|
-
): GlobalToolRenderPatch {
|
|
673
|
-
const prototype = (ToolExecutionComponent as any).prototype;
|
|
674
|
-
const host = globalThis as any;
|
|
675
|
-
const previous = host[GLOBAL_TOOL_RENDER_PATCH];
|
|
676
|
-
const downstream = downstreamForGlobalToolInstall(prototype, previous);
|
|
677
|
-
// Any wrapper retained by an external owner must become a callback-free
|
|
678
|
-
// pass-through before the new installation is linked above it.
|
|
679
|
-
disconnectGlobalToolRenderPatch(previous);
|
|
680
|
-
|
|
681
|
-
const patch: GlobalToolRenderPatch = {
|
|
682
|
-
version: 2,
|
|
683
|
-
prototype,
|
|
684
|
-
owner: {},
|
|
685
|
-
active: true,
|
|
686
|
-
enabled: () => config.mode === "on",
|
|
687
|
-
mode: () => config.mode,
|
|
688
|
-
wrap: (tool: any) => createCcstyleTool(tool, writeExecutionMetadata),
|
|
689
|
-
byDefinition: new WeakMap(),
|
|
690
|
-
byName: new Map(),
|
|
691
|
-
downstream,
|
|
692
|
-
installed: undefined as any,
|
|
693
|
-
originalHasRendererDefinition: downstream.hasRendererDefinition,
|
|
694
|
-
originalGetRenderShell: downstream.getRenderShell,
|
|
695
|
-
originalGetCallRenderer: downstream.getCallRenderer,
|
|
696
|
-
originalGetResultRenderer: downstream.getResultRenderer,
|
|
697
|
-
};
|
|
698
|
-
|
|
699
|
-
patch.installed = {
|
|
700
|
-
hasRendererDefinition: function (this: any, ...args: any[]) {
|
|
701
|
-
if (patch.active && shouldGloballyStyleTool(this, patch)) return true;
|
|
702
|
-
return patch.downstream.hasRendererDefinition.apply(this, args);
|
|
703
|
-
},
|
|
704
|
-
getRenderShell: function (this: any, ...args: any[]) {
|
|
705
|
-
if (!patch.active) return patch.downstream.getRenderShell.apply(this, args);
|
|
706
|
-
const useSelfShell = shouldUseSelfShell(this, patch);
|
|
707
|
-
const useCcstyle = shouldGloballyStyleTool(this, patch);
|
|
708
|
-
const shell =
|
|
709
|
-
useSelfShell || (useCcstyle && !this.expanded)
|
|
710
|
-
? "self"
|
|
711
|
-
: useCcstyle
|
|
712
|
-
? "default"
|
|
713
|
-
: patch.downstream.getRenderShell.apply(this, args);
|
|
714
|
-
syncToolShell(this, shell);
|
|
715
|
-
return shell;
|
|
716
|
-
},
|
|
717
|
-
getCallRenderer: function (this: any, ...args: any[]) {
|
|
718
|
-
if (patch.active && shouldGloballyStyleTool(this, patch)) {
|
|
719
|
-
return getGloballyStyledTool(this, patch).renderCall;
|
|
720
|
-
}
|
|
721
|
-
return patch.downstream.getCallRenderer.apply(this, args);
|
|
722
|
-
},
|
|
723
|
-
getResultRenderer: function (this: any, ...args: any[]) {
|
|
724
|
-
if (patch.active && shouldGloballyStyleTool(this, patch)) {
|
|
725
|
-
return getGloballyStyledTool(this, patch).renderResult;
|
|
726
|
-
}
|
|
727
|
-
return patch.downstream.getResultRenderer.apply(this, args);
|
|
728
|
-
},
|
|
729
|
-
};
|
|
730
|
-
|
|
731
|
-
prototype.hasRendererDefinition = patch.installed.hasRendererDefinition;
|
|
732
|
-
prototype.getRenderShell = patch.installed.getRenderShell;
|
|
733
|
-
prototype.getCallRenderer = patch.installed.getCallRenderer;
|
|
734
|
-
prototype.getResultRenderer = patch.installed.getResultRenderer;
|
|
735
|
-
host[GLOBAL_TOOL_RENDER_PATCH] = patch;
|
|
736
|
-
return patch;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
function deactivateGlobalToolRendering(patch: GlobalToolRenderPatch): void {
|
|
740
|
-
if (!patch.active) return;
|
|
741
|
-
disconnectGlobalToolRenderPatch(patch);
|
|
742
|
-
const prototype = patch.prototype;
|
|
743
|
-
if (prototype.hasRendererDefinition === patch.installed.hasRendererDefinition) {
|
|
744
|
-
prototype.hasRendererDefinition = patch.downstream.hasRendererDefinition;
|
|
745
|
-
}
|
|
746
|
-
if (prototype.getRenderShell === patch.installed.getRenderShell) {
|
|
747
|
-
prototype.getRenderShell = patch.downstream.getRenderShell;
|
|
748
|
-
}
|
|
749
|
-
if (prototype.getCallRenderer === patch.installed.getCallRenderer) {
|
|
750
|
-
prototype.getCallRenderer = patch.downstream.getCallRenderer;
|
|
751
|
-
}
|
|
752
|
-
if (prototype.getResultRenderer === patch.installed.getResultRenderer) {
|
|
753
|
-
prototype.getResultRenderer = patch.downstream.getResultRenderer;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
const GLOBAL_COMPACTION_RENDER_PATCH = Symbol.for("pi.ccstyle.compaction-render-patch");
|
|
758
|
-
|
|
759
|
-
const TOOL_EXPANDED_BACKGROUND_PATCH = Symbol.for("pi.ccstyle.tool-expanded-background-patch");
|
|
760
|
-
|
|
761
|
-
type ToolExpandedBackgroundPatch = {
|
|
762
|
-
active: boolean;
|
|
763
|
-
prototype: any;
|
|
764
|
-
installed: (...args: any[]) => void;
|
|
765
|
-
original: (...args: any[]) => void;
|
|
766
|
-
dispose: () => void;
|
|
767
|
-
};
|
|
768
|
-
|
|
769
|
-
/** 展开面板背景统一为 user message 背景色;折叠行保持原生状态色(由 original 重设)。 */
|
|
770
|
-
function installToolExpandedBackground(): () => void {
|
|
771
|
-
const host = globalThis as any;
|
|
772
|
-
const previous = host[TOOL_EXPANDED_BACKGROUND_PATCH] as ToolExpandedBackgroundPatch | undefined;
|
|
773
|
-
if (previous) previous.dispose();
|
|
774
|
-
const prototype = ToolExecutionComponent.prototype as unknown as { updateDisplay: () => void };
|
|
775
|
-
const original = prototype.updateDisplay;
|
|
776
|
-
const patch: ToolExpandedBackgroundPatch = {
|
|
777
|
-
active: true,
|
|
778
|
-
prototype,
|
|
779
|
-
installed: function (this: any) {
|
|
780
|
-
original.call(this);
|
|
781
|
-
if (!patch.active || config.mode !== "on" || !this.expanded) return;
|
|
782
|
-
const theme = getMessageDisplayTheme();
|
|
783
|
-
if (!theme?.bg) return;
|
|
784
|
-
const box = this.contentBox;
|
|
785
|
-
if (box?.setBgFn) box.setBgFn((text: string) => theme.bg("userMessageBg", text));
|
|
786
|
-
},
|
|
787
|
-
original,
|
|
788
|
-
dispose: () => {
|
|
789
|
-
patch.active = false;
|
|
790
|
-
if (prototype.updateDisplay === patch.installed) {
|
|
791
|
-
prototype.updateDisplay = original;
|
|
792
|
-
}
|
|
793
|
-
if (host[TOOL_EXPANDED_BACKGROUND_PATCH] === patch) {
|
|
794
|
-
delete host[TOOL_EXPANDED_BACKGROUND_PATCH];
|
|
795
|
-
}
|
|
796
|
-
},
|
|
797
|
-
};
|
|
798
|
-
prototype.updateDisplay = patch.installed;
|
|
799
|
-
host[TOOL_EXPANDED_BACKGROUND_PATCH] = patch;
|
|
800
|
-
return patch.dispose;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
99
|
type LegacyCompactionRenderPatch = {
|
|
804
100
|
enabled?: () => boolean;
|
|
805
101
|
};
|
|
@@ -817,25 +113,26 @@ export default function (
|
|
|
817
113
|
configOverride?: Partial<Config>,
|
|
818
114
|
compactThinking?: CompactThinkingController,
|
|
819
115
|
) {
|
|
820
|
-
//
|
|
116
|
+
// 可选 override:集成测试不依赖用户全局配置。
|
|
821
117
|
if (configOverride) setConfig(normalizeConfig({ ...config, ...configOverride }));
|
|
822
118
|
const writeExecutionMetadata = new WriteExecutionMetadataStore();
|
|
823
119
|
const mouseOwner = {};
|
|
824
120
|
let installation:
|
|
825
121
|
| {
|
|
826
|
-
|
|
122
|
+
defaultMode: DefaultModeHooks;
|
|
827
123
|
toolGrouping: ToolGroupingHooks;
|
|
828
124
|
compactMode: CompactModeHooks;
|
|
829
125
|
disposeMessageDisplay: () => void;
|
|
830
126
|
disposeToolExpandedBackground: () => void;
|
|
831
127
|
}
|
|
832
128
|
| undefined;
|
|
129
|
+
|
|
833
130
|
const ensureTuiInstallation = (ctx: any) => {
|
|
834
131
|
if (ctx?.mode !== "tui" || !ctx?.hasUI) return undefined;
|
|
835
132
|
// 渲染层(工具样式/分组)是原型与组件级 patch,fullscreen 官方布局
|
|
836
133
|
// 同样渲染这些组件,因此两种模式都安装。
|
|
837
134
|
if (installation) return installation;
|
|
838
|
-
const
|
|
135
|
+
const defaultMode = installDefaultMode(writeExecutionMetadata);
|
|
839
136
|
const toolGrouping = installToolGrouping(() => config.mode === "on");
|
|
840
137
|
const compactMode = installCompactMode({
|
|
841
138
|
query: compactThinking as CompactThinkingQuery | undefined,
|
|
@@ -843,10 +140,11 @@ export default function (
|
|
|
843
140
|
});
|
|
844
141
|
compactModeHooks = compactMode;
|
|
845
142
|
const disposeMessageDisplay = installMessageDisplayRendering();
|
|
143
|
+
// 展开背景必须在 compact-mode 之后装,shutdown 时先于 compact 释放。
|
|
846
144
|
const disposeToolExpandedBackground = installToolExpandedBackground();
|
|
847
145
|
deactivateLegacyCompactionRendering();
|
|
848
146
|
installation = {
|
|
849
|
-
|
|
147
|
+
defaultMode,
|
|
850
148
|
toolGrouping,
|
|
851
149
|
compactMode,
|
|
852
150
|
disposeMessageDisplay,
|
|
@@ -910,15 +208,14 @@ export default function (
|
|
|
910
208
|
|
|
911
209
|
pi.on("tool_execution_end", async (event) => {
|
|
912
210
|
if (config.mode !== "compact") return;
|
|
913
|
-
// Agent
|
|
914
|
-
// 让 compact-thinking 先写入最终时长,再重绘摘要行。
|
|
211
|
+
// Agent 等工具收尾后延迟刷新,让 compact-thinking 先落最终态。
|
|
915
212
|
const toolCallId: string | undefined = event?.toolCallId;
|
|
916
213
|
setTimeout(() => {
|
|
917
214
|
compactModeHooks?.refreshToolCallMessage(toolCallId);
|
|
918
215
|
}, 0);
|
|
919
216
|
});
|
|
920
217
|
|
|
921
|
-
pi.on("session_start", async (
|
|
218
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
922
219
|
// 延迟到 session_start 注册 write override:加载阶段 getAllTools 不可用且其他扩展
|
|
923
220
|
// 尚未注册工具,无法检测外部 write 所有者(如 pi-spark),直接注册会与对方撞名。
|
|
924
221
|
// session_start 时所有扩展已加载完毕,installWriteOverride 内部会检测并让位。
|
|
@@ -936,10 +233,10 @@ export default function (
|
|
|
936
233
|
// compact-thinking 的 session_start 处理在本 handler 之后执行(在其之上再装
|
|
937
234
|
// 一层 updateContent);延迟再同步一次,保证 compact 补丁最终位于外层。
|
|
938
235
|
setTimeout(() => syncCompactMode(ctx), 0);
|
|
939
|
-
scheduleSessionRender(() => hooks.toolGrouping.refresh(
|
|
236
|
+
scheduleSessionRender(() => hooks.toolGrouping.refresh(getToolMouseTui()));
|
|
940
237
|
});
|
|
941
238
|
|
|
942
|
-
pi.on("session_compact", async (
|
|
239
|
+
pi.on("session_compact", async (_event, ctx) => {
|
|
943
240
|
const hooks = ensureTuiInstallation(ctx);
|
|
944
241
|
// Compaction rebuilds the transcript without session_start. Rebind after
|
|
945
242
|
// other TUI extensions may have replaced the root input dispatcher.
|
|
@@ -950,34 +247,35 @@ export default function (
|
|
|
950
247
|
syncCompactMode(ctx);
|
|
951
248
|
scheduleSessionRender(() => {
|
|
952
249
|
syncCompactMode(ctx);
|
|
953
|
-
hooks.toolGrouping.refresh(
|
|
250
|
+
hooks.toolGrouping.refresh(getToolMouseTui());
|
|
954
251
|
});
|
|
955
252
|
});
|
|
956
253
|
|
|
957
|
-
pi.on("session_tree", async (
|
|
254
|
+
pi.on("session_tree", async (_event, ctx) => {
|
|
958
255
|
// 会话树重建后在当前帧和下一帧各同步一次,替换旧组件引用。
|
|
959
256
|
if (ctx?.mode !== "tui" || !ctx?.hasUI) return;
|
|
960
257
|
syncCompactMode(ctx);
|
|
961
258
|
scheduleSessionRender(() => syncCompactMode(ctx));
|
|
962
259
|
});
|
|
963
260
|
|
|
964
|
-
pi.on("tool_execution_start", async (
|
|
261
|
+
pi.on("tool_execution_start", async (_event, ctx) => {
|
|
965
262
|
installation?.toolGrouping.setTheme(ctx.ui.theme);
|
|
966
263
|
});
|
|
967
264
|
|
|
968
|
-
pi.on("session_shutdown", async (
|
|
265
|
+
pi.on("session_shutdown", async () => {
|
|
969
266
|
writeExecutionMetadata.clear();
|
|
970
267
|
// 鼠标交互独立于渲染层:fullscreen 下 installation 为 undefined,
|
|
971
268
|
// 但 onTerminalInput 监听与 handleViewportInput 包装仍需释放。
|
|
972
269
|
teardownToolMouseInteraction(mouseOwner);
|
|
973
270
|
const current = installation;
|
|
974
|
-
if (
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
271
|
+
if (!current) return;
|
|
272
|
+
if (!current.defaultMode.isOwner()) {
|
|
273
|
+
// Replacement installers already disposed these owner-aware patches.
|
|
274
|
+
// Drop only this stale runtime's closure; global teardown belongs to the owner.
|
|
275
|
+
installation = undefined;
|
|
979
276
|
return;
|
|
980
|
-
|
|
277
|
+
}
|
|
278
|
+
current.defaultMode.shutdown();
|
|
981
279
|
current.toolGrouping.shutdown();
|
|
982
280
|
current.disposeToolExpandedBackground();
|
|
983
281
|
current.compactMode.shutdown();
|
|
@@ -989,26 +287,18 @@ export default function (
|
|
|
989
287
|
});
|
|
990
288
|
}
|
|
991
289
|
|
|
992
|
-
// ----
|
|
290
|
+
// ---- 对外导出:入口/测试实际消费的符号 ----
|
|
291
|
+
export { getCompactThinkingConfig } from "../config/config.ts";
|
|
993
292
|
export {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
} from "../config/config.ts";
|
|
1000
|
-
export type { CompactStyleMode, Config } from "../config/config.ts";
|
|
293
|
+
humanizeMcpToolName,
|
|
294
|
+
isMcpToolDefinition,
|
|
295
|
+
preservesOriginalRenderer,
|
|
296
|
+
shouldRenderRichDiff,
|
|
297
|
+
} from "./default-mode.ts";
|
|
1001
298
|
export {
|
|
1002
299
|
ExpandedToolIoView,
|
|
1003
300
|
ExpandedToolResultText,
|
|
1004
|
-
formatExpandHint,
|
|
1005
301
|
formatToolInputArgs,
|
|
1006
|
-
headTruncateToWidth,
|
|
1007
|
-
middleTruncateToWidth,
|
|
1008
|
-
outputLineCount,
|
|
1009
|
-
renderCollapsedToolResult,
|
|
1010
|
-
renderCollapsedToolResultToWidth,
|
|
1011
302
|
SHOW_MORE_LABEL,
|
|
1012
|
-
} from "./tool
|
|
1013
|
-
export
|
|
1014
|
-
export { installToolMouseInteraction } from "./mouse-interaction.ts";
|
|
303
|
+
} from "./tool/result.ts";
|
|
304
|
+
export { installToolMouseInteraction } from "./mouse/interaction.ts";
|