@herbertgao/pi-extensions 2026.8.1 → 2026.8.3
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 +13 -3
- package/node_modules/@czottmann/pi-automode/README.md +16 -2
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +35 -0
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +18 -9
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +6 -2
- package/node_modules/@czottmann/pi-automode/examples/automode.local.json +6 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +11 -7
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +100 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +32 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +78 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +16 -4
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +23 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +22 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +18 -2
- package/node_modules/@czottmann/pi-automode/package.json +4 -4
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +23 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +99 -0
- package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +30 -0
- package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +16 -0
- package/node_modules/@dietrichgebert/ponytail/AGENTS.md +32 -0
- package/node_modules/@dietrichgebert/ponytail/LICENSE +21 -0
- package/node_modules/@dietrichgebert/ponytail/README.es.md +298 -0
- package/node_modules/@dietrichgebert/ponytail/README.ko.md +315 -0
- package/node_modules/@dietrichgebert/ponytail/README.md +351 -0
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +21 -0
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +62 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +115 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +27 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +27 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +44 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +21 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +96 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +169 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +98 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +130 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +85 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.ps1 +24 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.sh +18 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +77 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +26 -0
- package/node_modules/@dietrichgebert/ponytail/package.json +47 -0
- package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +211 -0
- package/node_modules/@dietrichgebert/ponytail/pi-extension/package.json +8 -0
- package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +60 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +120 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +41 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +44 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +50 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +71 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +57 -0
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +6 -10
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +5 -9
- 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 +15 -9
- 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} +3 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +24 -83
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +1 -1
- 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 +452 -94
- 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 +66 -776
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/{feature → renderer}/markdown-enhance.ts +134 -11
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +130 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +90 -568
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +144 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +143 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/scroll.ts +195 -0
- 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 +4 -4
- 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} +27 -10
- 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/renderer/transcript-refresh.ts +91 -0
- 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-cc-extensions/themes/cc-dark.json +1 -0
- package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-light.json +2 -2
- package/node_modules/@herbertgao/pi-stash/README.md +9 -9
- package/node_modules/@herbertgao/pi-stash/package.json +1 -1
- package/node_modules/@herbertgao/pi-stash/src/index.ts +2 -1
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +20 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +6 -2
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- 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/custom-agents.ts +85 -11
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +61 -39
- 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/@herbertgao/pi-subagents/src/settings.ts +12 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +2 -0
- package/node_modules/@narumitw/pi-btw/LICENSE +21 -0
- package/node_modules/@narumitw/pi-btw/README.md +210 -0
- package/node_modules/@narumitw/pi-btw/package.json +53 -0
- package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +632 -0
- package/node_modules/@narumitw/pi-btw/src/btw.ts +996 -0
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +339 -0
- package/node_modules/@narumitw/pi-btw/src/index.ts +1 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +296 -0
- package/node_modules/@narumitw/pi-btw/src/settings.ts +237 -0
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +238 -0
- package/node_modules/@narumitw/pi-btw/src/text.ts +10 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +620 -0
- package/node_modules/@pi-plugins/fast-mode/LICENSE +21 -0
- package/node_modules/@pi-plugins/fast-mode/README.md +92 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts +6 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +2026 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -0
- package/node_modules/@pi-plugins/fast-mode/package.json +73 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +78 -0
- package/node_modules/pi-mcp-adapter/README.md +80 -16
- package/node_modules/pi-mcp-adapter/agent-dir.ts +40 -0
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +377 -0
- package/node_modules/pi-mcp-adapter/commands.ts +21 -9
- package/node_modules/pi-mcp-adapter/config.ts +110 -49
- package/node_modules/pi-mcp-adapter/direct-tools.ts +40 -27
- package/node_modules/pi-mcp-adapter/elicitation-handler.ts +37 -36
- package/node_modules/pi-mcp-adapter/errors.ts +21 -17
- package/node_modules/pi-mcp-adapter/host-html-template.ts +13 -7
- package/node_modules/pi-mcp-adapter/index.ts +52 -17
- package/node_modules/pi-mcp-adapter/init.ts +9 -7
- package/node_modules/pi-mcp-adapter/json-schema-validator.ts +2 -2
- package/node_modules/pi-mcp-adapter/lifecycle.ts +8 -8
- package/node_modules/pi-mcp-adapter/logger.ts +1 -1
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +122 -25
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +120 -2
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +138 -61
- package/node_modules/pi-mcp-adapter/mcp-code.ts +13 -11
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +62 -17
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +15 -11
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +34 -15
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +131 -34
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +2 -2
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +7 -4
- package/node_modules/pi-mcp-adapter/mcp-trace.ts +59 -64
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +34 -26
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +6 -4
- package/node_modules/pi-mcp-adapter/oauth-handler.ts +1 -1
- package/node_modules/pi-mcp-adapter/oauth.ts +48 -0
- package/node_modules/pi-mcp-adapter/onboarding-state.ts +19 -11
- package/node_modules/pi-mcp-adapter/package.json +20 -9
- package/node_modules/pi-mcp-adapter/panel-keys.ts +20 -4
- package/node_modules/pi-mcp-adapter/prompts.ts +2 -2
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +56 -21
- package/node_modules/pi-mcp-adapter/sampling-handler.ts +22 -15
- package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -1
- package/node_modules/pi-mcp-adapter/server-manager.ts +165 -113
- package/node_modules/pi-mcp-adapter/session-recovery.ts +11 -12
- package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +3 -3
- package/node_modules/pi-mcp-adapter/state.ts +3 -1
- package/node_modules/pi-mcp-adapter/tool-approval.ts +67 -4
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +6 -5
- package/node_modules/pi-mcp-adapter/tool-registrar.ts +187 -3
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +14 -2
- package/node_modules/pi-mcp-adapter/ts-shape.ts +9 -2
- package/node_modules/pi-mcp-adapter/types.ts +111 -22
- package/node_modules/pi-mcp-adapter/ui-app-bridge-helpers.ts +40 -0
- package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +28 -19
- package/node_modules/pi-mcp-adapter/ui-server.ts +90 -58
- package/node_modules/pi-mcp-adapter/ui-session.ts +16 -14
- package/node_modules/pi-mcp-adapter/unix-socket-transport.ts +4 -4
- package/node_modules/pi-mcp-adapter/utils.ts +23 -9
- 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 +37 -12
- 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,26 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { setToolTuiFullscreen } from "./show-more-hint.ts";
|
|
1
|
+
import { hasActiveTextPreview, showTextPreview } from "../../feature/context.ts";
|
|
2
|
+
import { ToolGroupComponent } from "../tool/grouping.ts";
|
|
3
|
+
import { isCompactAssistantComponent, setHoveredCompactAssistant } from "../compact-mode.ts";
|
|
4
|
+
import { config } from "../../config/config.ts";
|
|
5
|
+
import { isLazyProxyTui } from "../../utils/fullscreen-detect.ts";
|
|
6
|
+
import { setToolTuiFullscreen } from "../show-more-hint.ts";
|
|
8
7
|
import {
|
|
9
8
|
type ExpandedToolIoView,
|
|
10
9
|
getActiveIoViewFrame,
|
|
11
|
-
invalidateIoView,
|
|
12
10
|
isExpandedToolIoView,
|
|
13
11
|
type IoViewFrameState,
|
|
14
12
|
setActiveIoViewFrame,
|
|
15
13
|
type ToolIoSection,
|
|
16
|
-
} from "
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
} from "../tool/result.ts";
|
|
15
|
+
import {
|
|
16
|
+
collectToolComponents,
|
|
17
|
+
extractToolFramePlacements,
|
|
18
|
+
isSgrLeftPress,
|
|
19
|
+
isToolExecutionComponent,
|
|
20
|
+
parseSgrMousePackets,
|
|
21
|
+
stripTerminalSequences,
|
|
22
|
+
stripTerminalSequencesPreservingLayout,
|
|
23
|
+
toolFrameMarker,
|
|
24
|
+
type FrameToolPlacement,
|
|
25
|
+
type SgrMousePacket,
|
|
26
|
+
} from "./packets.ts";
|
|
27
|
+
import {
|
|
28
|
+
collectFullscreenToolCards,
|
|
29
|
+
componentAtLocalRow,
|
|
30
|
+
collapsedHintHitbox,
|
|
31
|
+
fullscreenContentWidth,
|
|
32
|
+
fullscreenLeafAt,
|
|
33
|
+
isScrollbarColumnAt,
|
|
34
|
+
} from "./layout.ts";
|
|
35
|
+
import {
|
|
36
|
+
fullscreenLazyTui,
|
|
37
|
+
hideScrollButton,
|
|
38
|
+
isScrollBottomInput,
|
|
39
|
+
renderScrollButton,
|
|
40
|
+
resetScrollButtonState,
|
|
41
|
+
scheduleScrollButtonSync,
|
|
42
|
+
setScrollButtonHovered,
|
|
43
|
+
setScrollButtonVisible,
|
|
44
|
+
setScrollButtonWidget,
|
|
45
|
+
setToolMouseTui,
|
|
46
|
+
getScrollButtonVisible,
|
|
47
|
+
getScrollButtonWidget,
|
|
48
|
+
getToolMouseTui,
|
|
49
|
+
toolMouseInteractionActive,
|
|
50
|
+
updateScrollButtonFromInput,
|
|
51
|
+
} from "./scroll.ts";
|
|
52
|
+
import {
|
|
53
|
+
applyFullscreenHover,
|
|
54
|
+
cachedFullscreenComponentAtRow,
|
|
55
|
+
sharedToolHoverState,
|
|
56
|
+
setHoveredToolCallId,
|
|
57
|
+
setHoveredToolGroup,
|
|
58
|
+
setHoveredToolIo,
|
|
59
|
+
type FullscreenHoverTarget,
|
|
60
|
+
} from "./hover.ts";
|
|
24
61
|
|
|
25
62
|
type FrameToolRender = {
|
|
26
63
|
component: any;
|
|
@@ -28,17 +65,6 @@ type FrameToolRender = {
|
|
|
28
65
|
contentBoxLines: number;
|
|
29
66
|
};
|
|
30
67
|
|
|
31
|
-
/** Final painted placement of one outermost tool/group row after parent layout. */
|
|
32
|
-
type FrameToolPlacement = {
|
|
33
|
-
component: any;
|
|
34
|
-
componentRow: number;
|
|
35
|
-
lineIndex: number;
|
|
36
|
-
/** Marker-stripped final line text as painted after parent layout. */
|
|
37
|
-
finalLine: string;
|
|
38
|
-
view?: ExpandedToolIoView;
|
|
39
|
-
section?: ToolIoSection;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
68
|
type InteractionRegion = {
|
|
43
69
|
kind: "collapsed-hint" | "expanded-card" | "show-more" | "scroll-bottom";
|
|
44
70
|
row: number;
|
|
@@ -51,23 +77,14 @@ type InteractionRegion = {
|
|
|
51
77
|
|
|
52
78
|
type InteractionFrame = { regions: InteractionRegion[] };
|
|
53
79
|
|
|
54
|
-
/** Zero-width APC row marker (like pi CURSOR_MARKER); stripped before terminal output. */
|
|
55
|
-
const TOOL_FRAME_MARKER_RE = /_cc:t(\d+):(\d+)/g;
|
|
56
|
-
const TOOL_VIEW_MARKER_RE = /_cc:v(\d+):([io])/g;
|
|
57
|
-
const toolFrameMarker = (id: number, row: number) => `_cc:t${id}:${row}`;
|
|
58
|
-
|
|
59
80
|
const TOOL_MOUSE_WIDGET_KEY = "ccstyle-tool-mouse";
|
|
60
81
|
const TOOL_MOUSE_MOTION_ENABLE = "\x1b[?1003h\x1b[?1006h";
|
|
61
82
|
const TOOL_MOUSE_MOTION_DISABLE = "\x1b[?1003l";
|
|
62
83
|
const FULLSCREEN_MOTION_ENABLED = Symbol("ccstyle.fullscreen-motion-enabled");
|
|
63
|
-
const TOOL_HOVER_STATE_KEY = Symbol.for("pi.ccstyle.tool-hover-state");
|
|
64
84
|
const TOOL_MOUSE_OWNER_KEY = Symbol.for("pi.ccstyle.tool-mouse-owner");
|
|
65
85
|
const DEFAULT_TOOL_MOUSE_OWNER = {};
|
|
66
86
|
export const TOOL_MOUSE_DISABLE = "\x1b[?1006l\x1b[?1003l\x1b[?1000l";
|
|
67
|
-
|
|
68
|
-
const ZENTUI_PAGE_DOWN_INPUT = /^\x1b\[6;9(?::[12])?~$|^\x1b\[57422;9(?::[12])?u$|^\x1b\[1;6B$/;
|
|
69
|
-
const SCROLL_BOTTOM_SHORTCUT = "ctrl+end";
|
|
70
|
-
export let toolMouseTui: any = null;
|
|
87
|
+
|
|
71
88
|
let toolMouseUi: any = null;
|
|
72
89
|
let toolMouseInputUnsubscribe: (() => void) | null = null;
|
|
73
90
|
let toolMouseRenderPatchTui: any = null;
|
|
@@ -78,268 +95,12 @@ let toolMouseRawWrite: ((data: string) => unknown) | null = null;
|
|
|
78
95
|
let toolMouseInstallationOwner: object | null = null;
|
|
79
96
|
let fullscreenMotionTerminal: any = null;
|
|
80
97
|
let ownsFullscreenMotion = false;
|
|
81
|
-
let scrollButtonVisible = false;
|
|
82
|
-
let scrollButtonHovered = false;
|
|
83
|
-
let scrollButtonWidget: any = null;
|
|
84
|
-
let scrollButtonSyncScheduled = false;
|
|
85
98
|
let sessionRenderTimer: ReturnType<typeof setTimeout> | null = null;
|
|
86
|
-
type SharedToolHoverState = { toolCallId: string | null };
|
|
87
|
-
function sharedToolHoverState(): SharedToolHoverState {
|
|
88
|
-
const host = globalThis as any;
|
|
89
|
-
return (host[TOOL_HOVER_STATE_KEY] ??= { toolCallId: null });
|
|
90
|
-
}
|
|
91
|
-
export let hoveredToolCallId: string | null = sharedToolHoverState().toolCallId;
|
|
92
|
-
function setHoveredToolCallId(toolCallId: string | null): void {
|
|
93
|
-
hoveredToolCallId = toolCallId;
|
|
94
|
-
sharedToolHoverState().toolCallId = toolCallId;
|
|
95
|
-
}
|
|
96
|
-
export function isToolCallHovered(toolCallId: string | null | undefined): boolean {
|
|
97
|
-
return Boolean(toolCallId && sharedToolHoverState().toolCallId === toolCallId);
|
|
98
|
-
}
|
|
99
|
-
let hoveredToolGroup: ToolGroupComponent | null = null;
|
|
100
99
|
let latestInteractionFrame: InteractionFrame = { regions: [] };
|
|
101
100
|
|
|
102
|
-
function parseSgrMousePackets(data: string): SgrMousePacket[] | null {
|
|
103
|
-
const pattern = /\x1b\[<(\d+);(\d+);(\d+)([Mm])/g;
|
|
104
|
-
const packets: SgrMousePacket[] = [];
|
|
105
|
-
let offset = 0;
|
|
106
|
-
|
|
107
|
-
for (const match of data.matchAll(pattern)) {
|
|
108
|
-
if (match.index !== offset) return null;
|
|
109
|
-
offset = match.index + match[0].length;
|
|
110
|
-
packets.push({
|
|
111
|
-
code: Number(match[1]),
|
|
112
|
-
col: Number(match[2]),
|
|
113
|
-
row: Number(match[3]),
|
|
114
|
-
final: match[4] as "M" | "m",
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return packets.length > 0 && offset === data.length ? packets : null;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function isSgrLeftPress(packet: SgrMousePacket): boolean {
|
|
122
|
-
const baseButton = packet.code & ~(4 | 8 | 16 | 32);
|
|
123
|
-
return packet.final === "M" && baseButton === 0 && (packet.code & 32) === 0;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function stripTerminalSequencesPreservingLayout(value: string): string {
|
|
127
|
-
return value
|
|
128
|
-
.replace(/\x1b\][^\x07]*(?:\x07|\x1b\\)/g, "")
|
|
129
|
-
.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "");
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function stripTerminalSequences(value: string): string {
|
|
133
|
-
return stripTerminalSequencesPreservingLayout(value).replace(/\s+/g, " ").trim();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function isToolExecutionComponent(value: any): boolean {
|
|
137
|
-
return Boolean(
|
|
138
|
-
value &&
|
|
139
|
-
typeof value === "object" &&
|
|
140
|
-
typeof value.toolCallId === "string" &&
|
|
141
|
-
typeof value.setExpanded === "function" &&
|
|
142
|
-
typeof value.render === "function",
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function collectToolComponents(component: any, tools: any[], seen = new Set<any>()): void {
|
|
147
|
-
if (!component || typeof component !== "object" || seen.has(component)) return;
|
|
148
|
-
seen.add(component);
|
|
149
|
-
if (isToolExecutionComponent(component)) {
|
|
150
|
-
tools.push(component);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
if (Array.isArray(component.children)) {
|
|
154
|
-
for (const child of component.children) collectToolComponents(child, tools, seen);
|
|
155
|
-
}
|
|
156
|
-
try {
|
|
157
|
-
const mounted = component.getMountedRoots?.();
|
|
158
|
-
if (Array.isArray(mounted)) {
|
|
159
|
-
for (const root of mounted) collectToolComponents(root, tools, seen);
|
|
160
|
-
}
|
|
161
|
-
} catch {
|
|
162
|
-
// renderer 切换中的惰性 Proxy 可能暂时没有 mounted roots。
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function stripToolFrameMarkers(line: string): string {
|
|
167
|
-
return line.replace(TOOL_FRAME_MARKER_RE, "").replace(TOOL_VIEW_MARKER_RE, "");
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function extractToolFramePlacements(
|
|
171
|
-
lines: string[],
|
|
172
|
-
idToComponent: Map<number, any>,
|
|
173
|
-
idToView: Map<number, ExpandedToolIoView>,
|
|
174
|
-
): { lines: string[]; placements: FrameToolPlacement[] } {
|
|
175
|
-
const placements: FrameToolPlacement[] = [];
|
|
176
|
-
const cleaned = lines.map((line, lineIndex) => {
|
|
177
|
-
const toolMatches = [...line.matchAll(TOOL_FRAME_MARKER_RE)];
|
|
178
|
-
const viewMatches = [...line.matchAll(TOOL_VIEW_MARKER_RE)];
|
|
179
|
-
const finalLine = stripToolFrameMarkers(line);
|
|
180
|
-
let view: ExpandedToolIoView | undefined;
|
|
181
|
-
let section: ToolIoSection | undefined;
|
|
182
|
-
for (const match of viewMatches) {
|
|
183
|
-
const candidate = idToView.get(Number(match[1]));
|
|
184
|
-
if (!candidate) continue;
|
|
185
|
-
view = candidate;
|
|
186
|
-
section = match[2] === "i" ? "input" : "output";
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
for (const match of toolMatches) {
|
|
190
|
-
const component = idToComponent.get(Number(match[1]));
|
|
191
|
-
if (!component) continue;
|
|
192
|
-
placements.push({
|
|
193
|
-
component,
|
|
194
|
-
componentRow: Number(match[2]),
|
|
195
|
-
lineIndex,
|
|
196
|
-
finalLine,
|
|
197
|
-
view,
|
|
198
|
-
section,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
return finalLine;
|
|
202
|
-
});
|
|
203
|
-
return { lines: cleaned, placements };
|
|
204
|
-
}
|
|
205
|
-
|
|
206
101
|
/** Summary markers used by Pi and ccstyle; unlike the trailing hint, these survive truncation. */
|
|
207
102
|
const COLLAPSED_TOOL_SUMMARY = /^\s*(?:↳|└|⎿|●|✓|✗|…)/;
|
|
208
103
|
|
|
209
|
-
function toolMouseInteractionActive(): boolean {
|
|
210
|
-
if (config.mode === "off") return false;
|
|
211
|
-
if (isLazyProxyTui(toolMouseTui)) return true;
|
|
212
|
-
return true;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function formatShortcut(shortcut: string): string {
|
|
216
|
-
return shortcut
|
|
217
|
-
.split("+")
|
|
218
|
-
.map((part) =>
|
|
219
|
-
part.length <= 1 ? part.toUpperCase() : `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`,
|
|
220
|
-
)
|
|
221
|
-
.join("+");
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function isScrollBottomInput(data: string): boolean {
|
|
225
|
-
return matchesKey(data, SCROLL_BOTTOM_SHORTCUT);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function wheelDirection(data: string): "up" | "down" | null {
|
|
229
|
-
const packets = parseSgrMousePackets(data);
|
|
230
|
-
for (const packet of packets ?? []) {
|
|
231
|
-
if (packet.final !== "M") continue;
|
|
232
|
-
const baseButton = packet.code & ~(4 | 8 | 16 | 32);
|
|
233
|
-
if (baseButton === 64) return "up";
|
|
234
|
-
if (baseButton === 65) return "down";
|
|
235
|
-
}
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function isScrollNavigationInput(data: string): boolean {
|
|
240
|
-
if (
|
|
241
|
-
matchesKey(data, "pageUp") ||
|
|
242
|
-
matchesKey(data, "pageDown") ||
|
|
243
|
-
ZENTUI_PAGE_UP_INPUT.test(data) ||
|
|
244
|
-
ZENTUI_PAGE_DOWN_INPUT.test(data) ||
|
|
245
|
-
// 官方 fullscreen viewport 的可滚动键(half-page/prompt/top/bottom)。
|
|
246
|
-
[
|
|
247
|
-
"tui.altScreen.pageUp",
|
|
248
|
-
"tui.altScreen.pageDown",
|
|
249
|
-
"tui.altScreen.halfPageUp",
|
|
250
|
-
"tui.altScreen.halfPageDown",
|
|
251
|
-
"tui.altScreen.previousPrompt",
|
|
252
|
-
"tui.altScreen.nextPrompt",
|
|
253
|
-
"tui.altScreen.top",
|
|
254
|
-
"tui.altScreen.bottom",
|
|
255
|
-
].some((key) => getKeybindings().matches(data, key))
|
|
256
|
-
) {
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
const packets = parseSgrMousePackets(data);
|
|
260
|
-
return Boolean(
|
|
261
|
-
packets?.some((packet) => {
|
|
262
|
-
const baseButton = packet.code & ~(4 | 8 | 16 | 32);
|
|
263
|
-
return packet.final === "M" && (baseButton === 64 || baseButton === 65);
|
|
264
|
-
}),
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
function isAtTranscriptBottom(tui: any): boolean {
|
|
269
|
-
// 惰性 Proxy fullscreen:官方 viewport 以 isFollowingOutput 判定是否在底部。
|
|
270
|
-
if (fullscreenLazyTui(tui)) return isFullscreenAtBottom(tui);
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function hideScrollButton(tui: any): void {
|
|
275
|
-
const changed = scrollButtonVisible || scrollButtonHovered;
|
|
276
|
-
scrollButtonVisible = false;
|
|
277
|
-
scrollButtonHovered = false;
|
|
278
|
-
if (changed) tui.requestRender?.();
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
function scheduleScrollButtonSync(tui: any, data: string): void {
|
|
282
|
-
if (
|
|
283
|
-
!fullscreenLazyTui(tui) ||
|
|
284
|
-
!toolMouseInteractionActive() ||
|
|
285
|
-
!isScrollNavigationInput(data) ||
|
|
286
|
-
scrollButtonSyncScheduled
|
|
287
|
-
)
|
|
288
|
-
return;
|
|
289
|
-
scrollButtonSyncScheduled = true;
|
|
290
|
-
const previousLines = tui.previousLines;
|
|
291
|
-
const check = (attempt: number) => {
|
|
292
|
-
scrollButtonSyncScheduled = false;
|
|
293
|
-
if (toolMouseTui !== tui) return;
|
|
294
|
-
// Pi renders on its own frame timer. Inspect the resulting viewport before
|
|
295
|
-
// showing the button so empty or non-scrollable transcripts never flash it.
|
|
296
|
-
const rendered = tui.previousLines !== previousLines;
|
|
297
|
-
// fullscreen 下 isFollowingOutput 是即时状态,无需等待官方帧渲染。
|
|
298
|
-
if (!rendered && attempt < 4 && !fullscreenLazyTui(tui)) {
|
|
299
|
-
scrollButtonSyncScheduled = true;
|
|
300
|
-
const timer = setTimeout(() => check(attempt + 1), 16);
|
|
301
|
-
if (typeof timer === "object" && timer !== null && "unref" in timer) {
|
|
302
|
-
(timer as { unref: () => void }).unref();
|
|
303
|
-
}
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
const nextVisible = !isAtTranscriptBottom(tui);
|
|
307
|
-
if (nextVisible !== scrollButtonVisible) {
|
|
308
|
-
scrollButtonVisible = nextVisible;
|
|
309
|
-
tui.requestRender?.();
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
process.nextTick(() => check(0));
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
function updateScrollButtonFromInput(tui: any, data: string): void {
|
|
316
|
-
if (!fullscreenLazyTui(tui) || !toolMouseInteractionActive()) return;
|
|
317
|
-
if (matchesKey(data, "enter") || matchesKey(data, "return")) hideScrollButton(tui);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
function renderComponentTree(component: any, width: number): string[] {
|
|
321
|
-
if (!component || typeof component !== "object") return [];
|
|
322
|
-
try {
|
|
323
|
-
const lines = component.render?.(width);
|
|
324
|
-
if (Array.isArray(lines) && lines.length > 0) return lines;
|
|
325
|
-
} catch {
|
|
326
|
-
// Fall through to children for hidden container renderers.
|
|
327
|
-
}
|
|
328
|
-
if (!Array.isArray(component.children)) return [];
|
|
329
|
-
return component.children.flatMap((child: any) => renderComponentTree(child, width));
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
let hoveredToolIoView: ExpandedToolIoView | null = null;
|
|
333
|
-
let hoveredToolIoSection: ToolIoSection | null = null;
|
|
334
|
-
|
|
335
|
-
function collapsedHintHitbox(line: string): { startCol: number; endCol: number } | null {
|
|
336
|
-
const plain = stripTerminalSequencesPreservingLayout(line);
|
|
337
|
-
const match = /(\([^()\n]* \/ click\)|click to show more|to show more)(?=\)?\s*$)/.exec(plain);
|
|
338
|
-
if (!match?.[1]) return null;
|
|
339
|
-
const startCol = visibleWidth(plain.slice(0, match.index)) + 1;
|
|
340
|
-
return { startCol, endCol: startCol + visibleWidth(match[1]) - 1 };
|
|
341
|
-
}
|
|
342
|
-
|
|
343
104
|
function interactionRegionAt(packet: SgrMousePacket): InteractionRegion | null {
|
|
344
105
|
const matches = latestInteractionFrame.regions.filter(
|
|
345
106
|
(region) =>
|
|
@@ -369,41 +130,11 @@ function tryOpenToolIoShowMore(region: InteractionRegion): boolean {
|
|
|
369
130
|
return true;
|
|
370
131
|
}
|
|
371
132
|
|
|
372
|
-
export function setHoveredToolIo(
|
|
373
|
-
view: ExpandedToolIoView | null,
|
|
374
|
-
section: ToolIoSection | null,
|
|
375
|
-
): boolean {
|
|
376
|
-
// resultRendererComponent 可能是 Text/第三方 renderer;reload 后也可能残留旧实例。
|
|
377
|
-
const nextView = isExpandedToolIoView(view) ? view : null;
|
|
378
|
-
const nextSection = nextView ? section : null;
|
|
379
|
-
if (nextView === hoveredToolIoView && nextSection === hoveredToolIoSection) return false;
|
|
380
|
-
if (isExpandedToolIoView(hoveredToolIoView)) {
|
|
381
|
-
hoveredToolIoView.setHoveredSection(null);
|
|
382
|
-
invalidateIoView(hoveredToolIoView);
|
|
383
|
-
}
|
|
384
|
-
hoveredToolIoView = nextView;
|
|
385
|
-
hoveredToolIoSection = nextSection;
|
|
386
|
-
if (nextView) {
|
|
387
|
-
nextView.setHoveredSection(nextSection);
|
|
388
|
-
invalidateIoView(nextView);
|
|
389
|
-
}
|
|
390
|
-
return true;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
export function setHoveredToolGroup(group: ToolGroupComponent | null): boolean {
|
|
394
|
-
if (group === hoveredToolGroup) return false;
|
|
395
|
-
hoveredToolGroup?.setHintHovered(false);
|
|
396
|
-
hoveredToolGroup = group;
|
|
397
|
-
group?.setHintHovered(true);
|
|
398
|
-
return true;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
133
|
function updateToolSummaryHover(tui: any, packet: SgrMousePacket): void {
|
|
402
134
|
if ((packet.code & 32) === 0 || packet.final !== "M") return;
|
|
403
135
|
const region = interactionRegionAt(packet);
|
|
404
136
|
const nextScrollButtonHovered = region?.kind === "scroll-bottom";
|
|
405
|
-
const scrollButtonChanged = nextScrollButtonHovered
|
|
406
|
-
scrollButtonHovered = nextScrollButtonHovered;
|
|
137
|
+
const scrollButtonChanged = setScrollButtonHovered(nextScrollButtonHovered);
|
|
407
138
|
const component = region?.component;
|
|
408
139
|
const nextToolCallId = region?.kind === "collapsed-hint" ? (component?.toolCallId ?? null) : null;
|
|
409
140
|
const nextGroup = component instanceof ToolGroupComponent ? component : null;
|
|
@@ -446,22 +177,6 @@ function toggleToolAtMouseClick(tui: any, packet: SgrMousePacket): boolean {
|
|
|
446
177
|
return true;
|
|
447
178
|
}
|
|
448
179
|
|
|
449
|
-
function renderScrollButton(width: number, theme: any): string[] {
|
|
450
|
-
if (!scrollButtonVisible || !fullscreenLazyTui(toolMouseTui)) return [];
|
|
451
|
-
const shortcut = formatShortcut(SCROLL_BOTTOM_SHORTCUT);
|
|
452
|
-
const label = theme.fg(
|
|
453
|
-
scrollButtonHovered ? "text" : "accent",
|
|
454
|
-
`[ ↓ Back to bottom · ${shortcut} ]`,
|
|
455
|
-
);
|
|
456
|
-
const leftPad = Math.max(0, Math.floor((width - visibleWidth(label)) / 2));
|
|
457
|
-
return [`${" ".repeat(leftPad)}${truncateToWidth(label, width, "…")}`];
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
/** 惰性 Proxy 官方 fullscreen(TuiAltScreen)判定。 */
|
|
461
|
-
function fullscreenLazyTui(tui: any): boolean {
|
|
462
|
-
return isLazyProxyTui(tui) && tui.mode === "fullscreen";
|
|
463
|
-
}
|
|
464
|
-
|
|
465
180
|
function officialFullscreenHasAllMotion(): boolean {
|
|
466
181
|
const term = process.env.TERM?.toLowerCase() ?? "";
|
|
467
182
|
return !(
|
|
@@ -522,141 +237,9 @@ function releaseFullscreenToolMouseMotion(tui?: any): void {
|
|
|
522
237
|
}
|
|
523
238
|
}
|
|
524
239
|
|
|
525
|
-
/** 官方 fullscreen:是否已跟随 transcript 底部(按钮隐藏条件)。 */
|
|
526
|
-
function isFullscreenAtBottom(tui: any): boolean {
|
|
527
|
-
const following = tui.isFollowingOutput ?? tui.getPrimaryScrollView?.()?.isFollowingEnd ?? true;
|
|
528
|
-
return Boolean(following);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
240
|
const FULLSCREEN_VIEWPORT_PATCH = Symbol("ccstyle.fullscreen-viewport-patch");
|
|
532
241
|
const FULLSCREEN_WHEEL_SCROLL_ORIGINAL = Symbol("ccstyle.fullscreen-wheel-scroll-original");
|
|
533
242
|
|
|
534
|
-
/** 布局树点查询:返回 (x,y) 处最深含行 leaf box(屏幕行 → 组件局部行)。 */
|
|
535
|
-
function fullscreenLeafAt(
|
|
536
|
-
layout: any,
|
|
537
|
-
x: number,
|
|
538
|
-
y: number,
|
|
539
|
-
): { box: any; localRow: number } | null {
|
|
540
|
-
const root = layout?.root;
|
|
541
|
-
if (!root) return null;
|
|
542
|
-
let best: { box: any; localRow: number } | null = null;
|
|
543
|
-
let bestDepth = -1;
|
|
544
|
-
const visit = (box: any, depth: number) => {
|
|
545
|
-
if (!box) return;
|
|
546
|
-
const clip = box.clip;
|
|
547
|
-
if (!clip || x < clip.x || x >= clip.x + clip.width || y < clip.y || y >= clip.y + clip.height)
|
|
548
|
-
return;
|
|
549
|
-
const isLeaf = !Array.isArray(box.children) || box.children.length === 0;
|
|
550
|
-
if (
|
|
551
|
-
isLeaf &&
|
|
552
|
-
y >= box.rect.y &&
|
|
553
|
-
y < box.rect.y + Math.max(1, box.rect.height) &&
|
|
554
|
-
depth > bestDepth
|
|
555
|
-
) {
|
|
556
|
-
best = { box, localRow: Math.max(0, y - box.rect.y) };
|
|
557
|
-
bestDepth = depth;
|
|
558
|
-
}
|
|
559
|
-
for (const child of box.children ?? []) visit(child, depth + 1);
|
|
560
|
-
};
|
|
561
|
-
visit(root, 0);
|
|
562
|
-
return best;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
/** leaf 自身不带 scrollView;内容宽度由最近的 scroll 祖先决定。 */
|
|
566
|
-
function fullscreenContentWidth(box: any, terminalWidth: number): number {
|
|
567
|
-
for (let current = box; current; current = current.parent) {
|
|
568
|
-
if (typeof current.scrollView?.getContentWidth === "function") {
|
|
569
|
-
return Math.max(1, current.scrollView.getContentWidth(terminalWidth));
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
return terminalWidth;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
/** 点击列是否为官方滚动条列(放行官方拖动)。 */
|
|
576
|
-
function isScrollbarColumnAt(layout: any, x: number): boolean {
|
|
577
|
-
let hit = false;
|
|
578
|
-
const visit = (box: any) => {
|
|
579
|
-
if (hit || !box) return;
|
|
580
|
-
if (box.scrollView?.isScrollbarVisible && x === box.rect.x + box.rect.width - 1) {
|
|
581
|
-
hit = true;
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
for (const child of box.children ?? []) visit(child);
|
|
585
|
-
};
|
|
586
|
-
visit(layout?.root);
|
|
587
|
-
return hit;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
type ComponentRowHit = {
|
|
591
|
-
component: any;
|
|
592
|
-
row: number;
|
|
593
|
-
/** 内部工具命中时所属的展开 group;普通卡点击仍折叠整个 group。 */
|
|
594
|
-
group?: ToolGroupComponent;
|
|
595
|
-
};
|
|
596
|
-
|
|
597
|
-
/**
|
|
598
|
-
* 布局 leaf box 的组件通常是容器(documentContainer/dock 容器等),工具卡与
|
|
599
|
-
* widget 在其 children 内。按局部行遍历组件树,定位实际命中的子组件。
|
|
600
|
-
*/
|
|
601
|
-
function componentAtLocalRow(
|
|
602
|
-
component: any,
|
|
603
|
-
localRow: number,
|
|
604
|
-
width: number,
|
|
605
|
-
): ComponentRowHit | null {
|
|
606
|
-
if (component instanceof ToolGroupComponent) {
|
|
607
|
-
// 展开的 group:头两行(空行 + 头行)归 group,其余行映射到内部工具。
|
|
608
|
-
const child = component.childAtRow(localRow, width);
|
|
609
|
-
return child ? { ...child, group: component } : { component, row: localRow };
|
|
610
|
-
}
|
|
611
|
-
if (isToolExecutionComponent(component)) {
|
|
612
|
-
return { component, row: localRow };
|
|
613
|
-
}
|
|
614
|
-
if (isCompactAssistantComponent(component)) {
|
|
615
|
-
// compact 摘要行整体作为可展开卡片(折叠摘要 / 展开内容)。
|
|
616
|
-
return { component, row: localRow };
|
|
617
|
-
}
|
|
618
|
-
if (component === scrollButtonWidget) {
|
|
619
|
-
return { component, row: localRow };
|
|
620
|
-
}
|
|
621
|
-
if (!Array.isArray(component.children)) return null;
|
|
622
|
-
let offset = 0;
|
|
623
|
-
for (const child of component.children) {
|
|
624
|
-
let lines: string[] = [];
|
|
625
|
-
try {
|
|
626
|
-
const rendered = child.render?.(width);
|
|
627
|
-
if (Array.isArray(rendered)) lines = rendered.map((line) => String(line));
|
|
628
|
-
} catch {
|
|
629
|
-
lines = [];
|
|
630
|
-
}
|
|
631
|
-
if (localRow < offset + lines.length) {
|
|
632
|
-
return (
|
|
633
|
-
componentAtLocalRow(child, localRow - offset, width) ?? {
|
|
634
|
-
component: child,
|
|
635
|
-
row: localRow - offset,
|
|
636
|
-
}
|
|
637
|
-
);
|
|
638
|
-
}
|
|
639
|
-
offset += lines.length;
|
|
640
|
-
}
|
|
641
|
-
return null;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
/** fullscreen single-expand:group 作为整体,不继续递归其内部工具。 */
|
|
645
|
-
function collectFullscreenToolCards(component: any, out: any[], seen = new Set<any>()): void {
|
|
646
|
-
if (!component || typeof component !== "object" || seen.has(component)) return;
|
|
647
|
-
seen.add(component);
|
|
648
|
-
if (
|
|
649
|
-
isToolExecutionComponent(component) ||
|
|
650
|
-
component instanceof ToolGroupComponent ||
|
|
651
|
-
isCompactAssistantComponent(component)
|
|
652
|
-
) {
|
|
653
|
-
out.push(component);
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
if (!Array.isArray(component.children)) return;
|
|
657
|
-
for (const child of component.children) collectFullscreenToolCards(child, out, seen);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
243
|
/**
|
|
661
244
|
* 官方 fullscreen 工具卡点击:collapsed hint 点击展开
|
|
662
245
|
* (有且仅保持一个展开:展开前收起其他工具卡),expanded 整卡二次点击收起,
|
|
@@ -681,7 +264,7 @@ function handleFullscreenToolClick(tui: any, packet: SgrMousePacket): boolean {
|
|
|
681
264
|
const component = target.component;
|
|
682
265
|
const card = target.group ?? component;
|
|
683
266
|
// 回到底部按钮:按组件引用命中,不依赖渲染行缓存。
|
|
684
|
-
if (
|
|
267
|
+
if (getScrollButtonVisible() && component === getScrollButtonWidget()) {
|
|
685
268
|
tui.scrollToBottom?.();
|
|
686
269
|
hideScrollButton(tui);
|
|
687
270
|
return true;
|
|
@@ -740,47 +323,8 @@ function handleFullscreenToolClick(tui: any, packet: SgrMousePacket): boolean {
|
|
|
740
323
|
return true;
|
|
741
324
|
}
|
|
742
325
|
|
|
743
|
-
/** hover 与点击共用组件定位;同一布局下按容器/宽度/行缓存,避免 motion 重复渲染。 */
|
|
744
|
-
let fullscreenHoverCacheLayout: unknown = null;
|
|
745
|
-
let fullscreenHoverComponentCache = new WeakMap<object, Map<string, ComponentRowHit | null>>();
|
|
746
|
-
|
|
747
|
-
function cachedFullscreenComponentAtRow(
|
|
748
|
-
layout: any,
|
|
749
|
-
container: any,
|
|
750
|
-
row: number,
|
|
751
|
-
width: number,
|
|
752
|
-
): ComponentRowHit | null {
|
|
753
|
-
if (!container || typeof container !== "object") return null;
|
|
754
|
-
if (fullscreenHoverCacheLayout !== layout) {
|
|
755
|
-
fullscreenHoverCacheLayout = layout;
|
|
756
|
-
fullscreenHoverComponentCache = new WeakMap();
|
|
757
|
-
}
|
|
758
|
-
let rows = fullscreenHoverComponentCache.get(container);
|
|
759
|
-
if (!rows) {
|
|
760
|
-
rows = new Map();
|
|
761
|
-
fullscreenHoverComponentCache.set(container, rows);
|
|
762
|
-
}
|
|
763
|
-
const key = `${width}:${row}`;
|
|
764
|
-
if (rows.has(key)) return rows.get(key) ?? null;
|
|
765
|
-
const hit = componentAtLocalRow(container, row, width);
|
|
766
|
-
rows.set(key, hit);
|
|
767
|
-
return hit;
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
/** fullscreen 鼠标悬停目标。 */
|
|
771
|
-
type FullscreenHoverTarget =
|
|
772
|
-
| { kind: "button" }
|
|
773
|
-
| { kind: "group"; component: ToolGroupComponent }
|
|
774
|
-
| { kind: "assistant"; component: any }
|
|
775
|
-
| {
|
|
776
|
-
kind: "tool";
|
|
777
|
-
component: any;
|
|
778
|
-
view: ExpandedToolIoView | null;
|
|
779
|
-
section: ToolIoSection | null;
|
|
780
|
-
};
|
|
781
|
-
|
|
782
326
|
/**
|
|
783
|
-
* fullscreen
|
|
327
|
+
* fullscreen 鼠标悬停:collapsed 卡 [click to show more] hint、
|
|
784
328
|
* expanded 卡截断头 show-more、回到底部按钮。motion 不 consume,官方链照常。
|
|
785
329
|
*/
|
|
786
330
|
function handleFullscreenToolHover(tui: any, packet: SgrMousePacket): void {
|
|
@@ -794,7 +338,7 @@ function handleFullscreenToolHover(tui: any, packet: SgrMousePacket): void {
|
|
|
794
338
|
if (hit) {
|
|
795
339
|
const line = hit.box.lines?.[hit.localRow];
|
|
796
340
|
// 回到底部按钮:渲染行文本 + 列区间识别(零组件树开销)。
|
|
797
|
-
if (typeof line === "string" &&
|
|
341
|
+
if (typeof line === "string" && getScrollButtonVisible() && line.includes("[ ↓")) {
|
|
798
342
|
const plain = stripTerminalSequencesPreservingLayout(line);
|
|
799
343
|
const idx = plain.indexOf("[ ↓");
|
|
800
344
|
if (idx >= 0 && x >= idx && x <= idx + plain.length - 1) {
|
|
@@ -846,32 +390,6 @@ function handleFullscreenToolHover(tui: any, packet: SgrMousePacket): void {
|
|
|
846
390
|
applyFullscreenHover(tui, target);
|
|
847
391
|
}
|
|
848
392
|
|
|
849
|
-
/** 悬停状态变化才触发渲染(motion 事件密集,状态不变跳过)。 */
|
|
850
|
-
function applyFullscreenHover(tui: any, target: FullscreenHoverTarget | null): void {
|
|
851
|
-
let changed = false;
|
|
852
|
-
const nextCallId =
|
|
853
|
-
target?.kind === "tool" && !target.component.expanded
|
|
854
|
-
? (target.component.toolCallId ?? null)
|
|
855
|
-
: null;
|
|
856
|
-
if (nextCallId !== sharedToolHoverState().toolCallId) {
|
|
857
|
-
setHoveredToolCallId(nextCallId);
|
|
858
|
-
changed = true;
|
|
859
|
-
}
|
|
860
|
-
const nextGroup = target?.kind === "group" ? target.component : null;
|
|
861
|
-
if (setHoveredToolGroup(nextGroup)) changed = true;
|
|
862
|
-
const nextAssistant = target?.kind === "assistant" ? target.component : null;
|
|
863
|
-
if (setHoveredCompactAssistant(nextAssistant)) changed = true;
|
|
864
|
-
const nextView = target?.kind === "tool" ? target.view : null;
|
|
865
|
-
const nextSection = target?.kind === "tool" ? target.section : null;
|
|
866
|
-
if (setHoveredToolIo(nextView, nextSection)) changed = true;
|
|
867
|
-
const nextButton = target?.kind === "button";
|
|
868
|
-
if (nextButton !== scrollButtonHovered) {
|
|
869
|
-
scrollButtonHovered = nextButton;
|
|
870
|
-
changed = true;
|
|
871
|
-
}
|
|
872
|
-
if (changed) tui.requestRender?.();
|
|
873
|
-
}
|
|
874
|
-
|
|
875
393
|
/**
|
|
876
394
|
* 实例级包装 TuiAltScreen.handleViewportInput(惰性 Proxy 安全):
|
|
877
395
|
* 原型方法取 original(绕开 proxy 函数包装),实例 own property 装 wrapper
|
|
@@ -1211,40 +729,40 @@ function patchToolMouseMotionAfterRender(tui: any): void {
|
|
|
1211
729
|
}
|
|
1212
730
|
|
|
1213
731
|
function handleToolMouseInput(data: string): { consume: true } | undefined {
|
|
1214
|
-
if (!
|
|
732
|
+
if (!getToolMouseTui()) return undefined;
|
|
1215
733
|
// 惰性 Proxy fullscreen:鼠标由 handleViewportInput 包装消费(官方链之前),
|
|
1216
734
|
// 此处只处理键盘(鼠标事件在官方 listener 已被 consume,到不了这里)。
|
|
1217
|
-
if (fullscreenLazyTui(
|
|
1218
|
-
scheduleScrollButtonSync(
|
|
735
|
+
if (fullscreenLazyTui(getToolMouseTui())) {
|
|
736
|
+
scheduleScrollButtonSync(getToolMouseTui(), data);
|
|
1219
737
|
if (isScrollBottomInput(data)) {
|
|
1220
|
-
|
|
1221
|
-
hideScrollButton(
|
|
738
|
+
getToolMouseTui().scrollToBottom?.();
|
|
739
|
+
hideScrollButton(getToolMouseTui());
|
|
1222
740
|
return { consume: true };
|
|
1223
741
|
}
|
|
1224
742
|
return undefined;
|
|
1225
743
|
}
|
|
1226
|
-
updateScrollButtonFromInput(
|
|
744
|
+
updateScrollButtonFromInput(getToolMouseTui(), data);
|
|
1227
745
|
// Off mode restores native input: wheel keeps scrolling through Pi's normal
|
|
1228
746
|
// dispatcher, while hover/click affordances are entirely inactive.
|
|
1229
747
|
if (!toolMouseInteractionActive()) return undefined;
|
|
1230
748
|
const packets = parseSgrMousePackets(data);
|
|
1231
749
|
if (!packets) {
|
|
1232
|
-
scheduleScrollButtonSync(
|
|
750
|
+
scheduleScrollButtonSync(getToolMouseTui(), data);
|
|
1233
751
|
return undefined;
|
|
1234
752
|
}
|
|
1235
753
|
|
|
1236
754
|
let consumed = false;
|
|
1237
755
|
for (const packet of packets) {
|
|
1238
|
-
updateToolSummaryHover(
|
|
756
|
+
updateToolSummaryHover(getToolMouseTui(), packet);
|
|
1239
757
|
if (!isSgrLeftPress(packet)) continue;
|
|
1240
|
-
if (toggleToolAtMouseClick(
|
|
758
|
+
if (toggleToolAtMouseClick(getToolMouseTui(), packet)) {
|
|
1241
759
|
consumed = true;
|
|
1242
760
|
}
|
|
1243
761
|
}
|
|
1244
762
|
|
|
1245
763
|
// Let scrolling, motion, release, and clicks outside tool results reach the
|
|
1246
764
|
// normal TUI input chain (including other extensions such as pi-zentui).
|
|
1247
|
-
scheduleScrollButtonSync(
|
|
765
|
+
scheduleScrollButtonSync(getToolMouseTui(), data);
|
|
1248
766
|
return consumed ? { consume: true } : undefined;
|
|
1249
767
|
}
|
|
1250
768
|
|
|
@@ -1264,8 +782,8 @@ export function teardownToolMouseInteraction(
|
|
|
1264
782
|
setHoveredToolIo(null, null);
|
|
1265
783
|
setHoveredCompactAssistant(null);
|
|
1266
784
|
try {
|
|
1267
|
-
if (isLazyProxyTui(
|
|
1268
|
-
else
|
|
785
|
+
if (isLazyProxyTui(getToolMouseTui())) releaseFullscreenToolMouseMotion(getToolMouseTui());
|
|
786
|
+
else getToolMouseTui()?.terminal?.write?.(TOOL_MOUSE_DISABLE);
|
|
1269
787
|
} catch {
|
|
1270
788
|
// The terminal may already be closed during shutdown.
|
|
1271
789
|
}
|
|
@@ -1275,12 +793,9 @@ export function teardownToolMouseInteraction(
|
|
|
1275
793
|
// The UI context may already have been reset during /reload.
|
|
1276
794
|
}
|
|
1277
795
|
restoreToolMouseRenderPatch();
|
|
1278
|
-
restoreFullscreenViewportInput(
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
scrollButtonWidget = null;
|
|
1282
|
-
scrollButtonSyncScheduled = false;
|
|
1283
|
-
toolMouseTui = null;
|
|
796
|
+
restoreFullscreenViewportInput(getToolMouseTui());
|
|
797
|
+
resetScrollButtonState();
|
|
798
|
+
setToolMouseTui(null);
|
|
1284
799
|
toolMouseUi = null;
|
|
1285
800
|
if (host[TOOL_MOUSE_OWNER_KEY] === owner) delete host[TOOL_MOUSE_OWNER_KEY];
|
|
1286
801
|
if (toolMouseInstallationOwner === owner) toolMouseInstallationOwner = null;
|
|
@@ -1290,9 +805,9 @@ export function teardownToolMouseInteraction(
|
|
|
1290
805
|
export function resetToolHoverState(): void {
|
|
1291
806
|
setHoveredToolCallId(null);
|
|
1292
807
|
setHoveredCompactAssistant(null);
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
releaseFullscreenToolMouseMotion(
|
|
808
|
+
setScrollButtonVisible(false);
|
|
809
|
+
setScrollButtonHovered(false);
|
|
810
|
+
releaseFullscreenToolMouseMotion(getToolMouseTui());
|
|
1296
811
|
}
|
|
1297
812
|
|
|
1298
813
|
export function installToolMouseInteraction(
|
|
@@ -1311,20 +826,20 @@ export function installToolMouseInteraction(
|
|
|
1311
826
|
// 0.84+ 的 tui 是惰性 Proxy:regular 保留原生 scrollback;fullscreen
|
|
1312
827
|
// 由官方 LayoutFrame 命中,并由扩展补齐 hover 所需的 all-motion 上报。
|
|
1313
828
|
ctx.ui.setWidget(TOOL_MOUSE_WIDGET_KEY, (tui: any, theme: any) => {
|
|
1314
|
-
|
|
829
|
+
setToolMouseTui(tui);
|
|
1315
830
|
setToolTuiFullscreen(fullscreenLazyTui(tui));
|
|
1316
831
|
if (isLazyProxyTui(tui)) {
|
|
1317
832
|
patchFullscreenViewportInput(tui);
|
|
1318
833
|
ensureFullscreenToolMouseMotion(tui);
|
|
1319
|
-
|
|
834
|
+
setScrollButtonWidget({
|
|
1320
835
|
render: (width: number) => {
|
|
1321
836
|
patchFullscreenViewportInput(tui);
|
|
1322
837
|
ensureFullscreenToolMouseMotion(tui);
|
|
1323
838
|
return renderScrollButton(width, theme);
|
|
1324
839
|
},
|
|
1325
840
|
invalidate() {},
|
|
1326
|
-
};
|
|
1327
|
-
return
|
|
841
|
+
});
|
|
842
|
+
return getScrollButtonWidget();
|
|
1328
843
|
}
|
|
1329
844
|
// Wrap doRender to capture the live frame for tool click/hover mapping.
|
|
1330
845
|
patchToolMouseMotionAfterRender(tui);
|
|
@@ -1333,7 +848,7 @@ export function installToolMouseInteraction(
|
|
|
1333
848
|
render: (width: number) => renderScrollButton(width, theme),
|
|
1334
849
|
invalidate() {},
|
|
1335
850
|
};
|
|
1336
|
-
|
|
851
|
+
setScrollButtonWidget(widget);
|
|
1337
852
|
return widget;
|
|
1338
853
|
});
|
|
1339
854
|
toolMouseInputUnsubscribe = ctx.ui.onTerminalInput(handleToolMouseInput);
|
|
@@ -1346,7 +861,7 @@ function refreshToolRendererComponents(tui: any): void {
|
|
|
1346
861
|
}
|
|
1347
862
|
|
|
1348
863
|
export function scheduleSessionRender(refresh?: () => void): void {
|
|
1349
|
-
const tui =
|
|
864
|
+
const tui = getToolMouseTui();
|
|
1350
865
|
if (!tui || typeof tui.requestRender !== "function") return;
|
|
1351
866
|
if (sessionRenderTimer) clearTimeout(sessionRenderTimer);
|
|
1352
867
|
// Restored transcripts are populated at different points for startup, reload,
|
|
@@ -1354,10 +869,17 @@ export function scheduleSessionRender(refresh?: () => void): void {
|
|
|
1354
869
|
// rebuild finish so messages are not left hidden until the next terminal input.
|
|
1355
870
|
sessionRenderTimer = setTimeout(() => {
|
|
1356
871
|
sessionRenderTimer = null;
|
|
1357
|
-
if (
|
|
872
|
+
if (getToolMouseTui() !== tui) return;
|
|
1358
873
|
patchToolMouseMotionAfterRender(tui);
|
|
1359
874
|
refreshToolRendererComponents(tui);
|
|
1360
875
|
refresh?.();
|
|
1361
876
|
tui.requestRender(true);
|
|
1362
877
|
}, 0);
|
|
1363
878
|
}
|
|
879
|
+
|
|
880
|
+
export {
|
|
881
|
+
hoveredToolCallId,
|
|
882
|
+
isToolCallHovered,
|
|
883
|
+
setHoveredToolGroup,
|
|
884
|
+
setHoveredToolIo,
|
|
885
|
+
} from "./hover.ts";
|