@humain/terminal 0.0.1 → 0.0.3-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +271 -9
- package/README.md +143 -119
- package/dist/cli/args.d.ts +4 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +42 -37
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts +19 -0
- package/dist/cli/auth-check.d.ts.map +1 -0
- package/dist/cli/auth-check.js +50 -0
- package/dist/cli/auth-check.js.map +1 -0
- package/dist/cli/auth-command.d.ts +24 -0
- package/dist/cli/auth-command.d.ts.map +1 -0
- package/dist/cli/auth-command.js +103 -0
- package/dist/cli/auth-command.js.map +1 -0
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -2
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts +13 -0
- package/dist/cli/credential-print.d.ts.map +1 -0
- package/dist/cli/credential-print.js +76 -0
- package/dist/cli/credential-print.js.map +1 -0
- package/dist/cli/experimental/auth.d.ts +16 -0
- package/dist/cli/experimental/auth.d.ts.map +1 -0
- package/dist/cli/experimental/auth.js +13 -0
- package/dist/cli/experimental/auth.js.map +1 -0
- package/dist/cli/experimental/cli.d.ts +6 -0
- package/dist/cli/experimental/cli.d.ts.map +1 -0
- package/dist/cli/experimental/cli.js +5 -0
- package/dist/cli/experimental/cli.js.map +1 -0
- package/dist/cli/experimental/command-options.d.ts +17 -0
- package/dist/cli/experimental/command-options.d.ts.map +1 -0
- package/dist/cli/experimental/command-options.js +35 -0
- package/dist/cli/experimental/command-options.js.map +1 -0
- package/dist/cli/experimental/command.d.ts +63 -0
- package/dist/cli/experimental/command.d.ts.map +1 -0
- package/dist/cli/experimental/command.js +130 -0
- package/dist/cli/experimental/command.js.map +1 -0
- package/dist/cli/experimental/commands/client.d.ts +13 -0
- package/dist/cli/experimental/commands/client.d.ts.map +1 -0
- package/dist/cli/experimental/commands/client.js +25 -0
- package/dist/cli/experimental/commands/client.js.map +1 -0
- package/dist/cli/experimental/commands/pi.d.ts +15 -0
- package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
- package/dist/cli/experimental/commands/pi.js +28 -0
- package/dist/cli/experimental/commands/pi.js.map +1 -0
- package/dist/cli/experimental/commands/server.d.ts +13 -0
- package/dist/cli/experimental/commands/server.d.ts.map +1 -0
- package/dist/cli/experimental/commands/server.js +25 -0
- package/dist/cli/experimental/commands/server.js.map +1 -0
- package/dist/cli/experimental/transport-address.d.ts +10 -0
- package/dist/cli/experimental/transport-address.d.ts.map +1 -0
- package/dist/cli/experimental/transport-address.js +38 -0
- package/dist/cli/experimental/transport-address.js.map +1 -0
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +2 -2
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -2
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/remote-session.d.ts +53 -0
- package/dist/client/remote-session.d.ts.map +1 -0
- package/dist/client/remote-session.js +340 -0
- package/dist/client/remote-session.js.map +1 -0
- package/dist/client/transcript.d.ts +12 -0
- package/dist/client/transcript.d.ts.map +1 -0
- package/dist/client/transcript.js +98 -0
- package/dist/client/transcript.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -11
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +85 -76
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +25 -9
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +237 -39
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +60 -41
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +10 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +34 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +10 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +5 -0
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/keybindings.d.ts +45 -5
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +29 -5
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +4 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -10
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +4 -3
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +42 -10
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +32 -13
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +233 -73
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts +12 -7
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +83 -14
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts +6 -3
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +93 -67
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts +8 -0
- package/dist/core/pi-manifest.d.ts.map +1 -0
- package/dist/core/pi-manifest.js +28 -0
- package/dist/core/pi-manifest.js.map +1 -0
- package/dist/core/provider-composer.d.ts +4 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +36 -15
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +73 -67
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +15 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +64 -10
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +5 -5
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +11 -8
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +3 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +12 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +40 -16
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +8 -0
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +5 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +16 -15
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +4 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +11 -7
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +7 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +16 -19
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +4 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +5 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts +4 -0
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +5 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +4 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +7 -3
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +4 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +6 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +11 -2
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +22 -8
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/humain/agent-execution-protocol.d.ts +218 -0
- package/dist/humain/agent-execution-protocol.d.ts.map +1 -0
- package/dist/humain/agent-execution-protocol.js +204 -0
- package/dist/humain/agent-execution-protocol.js.map +1 -0
- package/dist/humain/agent-execution-runtime.d.ts +35 -0
- package/dist/humain/agent-execution-runtime.d.ts.map +1 -0
- package/dist/humain/agent-execution-runtime.js +170 -0
- package/dist/humain/agent-execution-runtime.js.map +1 -0
- package/dist/humain/index.d.ts.map +1 -1
- package/dist/humain/index.js +8 -7
- package/dist/humain/index.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +660 -0
- package/dist/humain/mcp-adapter/vendor/LICENSE +21 -0
- package/dist/humain/mcp-adapter/vendor/README.md +733 -0
- package/dist/humain/mcp-adapter/vendor/abort.ts +34 -0
- package/dist/humain/mcp-adapter/vendor/agent-dir.ts +60 -0
- package/dist/humain/mcp-adapter/vendor/agent-plugin-loader.ts +377 -0
- package/dist/humain/mcp-adapter/vendor/app-bridge.bundle.js +67 -0
- package/dist/humain/mcp-adapter/vendor/banner.png +0 -0
- package/dist/humain/mcp-adapter/vendor/cli.js +209 -0
- package/dist/humain/mcp-adapter/vendor/commands.ts +627 -0
- package/dist/humain/mcp-adapter/vendor/config.ts +1226 -0
- package/dist/humain/mcp-adapter/vendor/consent-manager.ts +64 -0
- package/dist/humain/mcp-adapter/vendor/direct-tools.ts +604 -0
- package/dist/humain/mcp-adapter/vendor/elicitation-handler.ts +348 -0
- package/dist/humain/mcp-adapter/vendor/error-signal.ts +21 -0
- package/dist/humain/mcp-adapter/vendor/errors.ts +223 -0
- package/dist/humain/mcp-adapter/vendor/glimpse-ui.ts +80 -0
- package/dist/humain/mcp-adapter/vendor/host-html-template.ts +461 -0
- package/dist/humain/mcp-adapter/vendor/index.bundle.d.mts +4 -0
- package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +15923 -0
- package/dist/humain/mcp-adapter/vendor/index.ts +898 -0
- package/dist/humain/mcp-adapter/vendor/init.ts +649 -0
- package/dist/humain/mcp-adapter/vendor/json-schema-validator.ts +69 -0
- package/dist/humain/mcp-adapter/vendor/lifecycle.ts +147 -0
- package/dist/humain/mcp-adapter/vendor/logger.ts +169 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +993 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth.ts +1000 -0
- package/dist/humain/mcp-adapter/vendor/mcp-callback-server.ts +510 -0
- package/dist/humain/mcp-adapter/vendor/mcp-code.ts +354 -0
- package/dist/humain/mcp-adapter/vendor/mcp-keyring-helper.cjs +89 -0
- package/dist/humain/mcp-adapter/vendor/mcp-oauth-provider.ts +616 -0
- package/dist/humain/mcp-adapter/vendor/mcp-output-guard.ts +408 -0
- package/dist/humain/mcp-adapter/vendor/mcp-panel.ts +1015 -0
- package/dist/humain/mcp-adapter/vendor/mcp-probe.ts +187 -0
- package/dist/humain/mcp-adapter/vendor/mcp-script-worker.mjs +130 -0
- package/dist/humain/mcp-adapter/vendor/mcp-setup-panel.ts +666 -0
- package/dist/humain/mcp-adapter/vendor/mcp-status.ts +109 -0
- package/dist/humain/mcp-adapter/vendor/mcp-trace.ts +306 -0
- package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +353 -0
- package/dist/humain/mcp-adapter/vendor/npx-resolver.ts +543 -0
- package/dist/humain/mcp-adapter/vendor/oauth-handler.ts +30 -0
- package/dist/humain/mcp-adapter/vendor/oauth.ts +48 -0
- package/dist/humain/mcp-adapter/vendor/onboarding-state.ts +76 -0
- package/dist/humain/mcp-adapter/vendor/package.json +178 -0
- package/dist/humain/mcp-adapter/vendor/panel-keys.ts +53 -0
- package/dist/humain/mcp-adapter/vendor/prompts.ts +353 -0
- package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +1331 -0
- package/dist/humain/mcp-adapter/vendor/resource-tools.ts +17 -0
- package/dist/humain/mcp-adapter/vendor/runtime-owner.ts +91 -0
- package/dist/humain/mcp-adapter/vendor/sampling-handler.ts +284 -0
- package/dist/humain/mcp-adapter/vendor/search-ranking.ts +206 -0
- package/dist/humain/mcp-adapter/vendor/server-manager.ts +1124 -0
- package/dist/humain/mcp-adapter/vendor/session-recovery.ts +151 -0
- package/dist/humain/mcp-adapter/vendor/skills/mcp-scripting/SKILL.md +38 -0
- package/dist/humain/mcp-adapter/vendor/state.ts +62 -0
- package/dist/humain/mcp-adapter/vendor/tool-approval.ts +182 -0
- package/dist/humain/mcp-adapter/vendor/tool-metadata.ts +276 -0
- package/dist/humain/mcp-adapter/vendor/tool-registrar.ts +253 -0
- package/dist/humain/mcp-adapter/vendor/tool-result-renderer.ts +423 -0
- package/dist/humain/mcp-adapter/vendor/ts-shape.ts +149 -0
- package/dist/humain/mcp-adapter/vendor/types.ts +859 -0
- package/dist/humain/mcp-adapter/vendor/ui-app-bridge-helpers.ts +40 -0
- package/dist/humain/mcp-adapter/vendor/ui-resource-handler.ts +250 -0
- package/dist/humain/mcp-adapter/vendor/ui-server.ts +866 -0
- package/dist/humain/mcp-adapter/vendor/ui-session.ts +570 -0
- package/dist/humain/mcp-adapter/vendor/ui-stream-types.ts +89 -0
- package/dist/humain/mcp-adapter/vendor/ui-tool-visibility.ts +25 -0
- package/dist/humain/mcp-adapter/vendor/unix-socket-transport.ts +85 -0
- package/dist/humain/mcp-adapter/vendor/utils.ts +310 -0
- package/dist/humain/mcp-adapter.d.ts +3 -0
- package/dist/humain/mcp-adapter.d.ts.map +1 -0
- package/dist/humain/mcp-adapter.js +5 -0
- package/dist/humain/mcp-adapter.js.map +1 -0
- package/dist/humain/pi-agent-execution-host.d.ts +34 -0
- package/dist/humain/pi-agent-execution-host.d.ts.map +1 -0
- package/dist/humain/pi-agent-execution-host.js +77 -0
- package/dist/humain/pi-agent-execution-host.js.map +1 -0
- package/dist/humain/web-access/host.d.ts +4 -0
- package/dist/humain/web-access/host.d.ts.map +1 -0
- package/dist/humain/web-access/host.js +3 -0
- package/dist/humain/web-access/host.js.map +1 -0
- package/dist/humain/web-access/index.d.ts +3 -0
- package/dist/humain/web-access/index.d.ts.map +1 -0
- package/dist/humain/web-access/index.js +5 -0
- package/dist/humain/web-access/index.js.map +1 -0
- package/dist/humain/web-access/vendor/activity.d.ts +34 -0
- package/dist/humain/web-access/vendor/activity.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/activity.js +68 -0
- package/dist/humain/web-access/vendor/activity.js.map +1 -0
- package/dist/humain/web-access/vendor/anysearch.d.ts +8 -0
- package/dist/humain/web-access/vendor/anysearch.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/anysearch.js +167 -0
- package/dist/humain/web-access/vendor/anysearch.js.map +1 -0
- package/dist/humain/web-access/vendor/bocha.d.ts +4 -0
- package/dist/humain/web-access/vendor/bocha.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/bocha.js +219 -0
- package/dist/humain/web-access/vendor/bocha.js.map +1 -0
- package/dist/humain/web-access/vendor/brave.d.ts +4 -0
- package/dist/humain/web-access/vendor/brave.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/brave.js +194 -0
- package/dist/humain/web-access/vendor/brave.js.map +1 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts +12 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.js +230 -0
- package/dist/humain/web-access/vendor/brightdata-unlocker.js.map +1 -0
- package/dist/humain/web-access/vendor/brightdata.d.ts +8 -0
- package/dist/humain/web-access/vendor/brightdata.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/brightdata.js +519 -0
- package/dist/humain/web-access/vendor/brightdata.js.map +1 -0
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts +10 -0
- package/dist/humain/web-access/vendor/chrome-cookies.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/chrome-cookies.js +438 -0
- package/dist/humain/web-access/vendor/chrome-cookies.js.map +1 -0
- package/dist/humain/web-access/vendor/content-find.d.ts +11 -0
- package/dist/humain/web-access/vendor/content-find.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/content-find.js +117 -0
- package/dist/humain/web-access/vendor/content-find.js.map +1 -0
- package/dist/humain/web-access/vendor/credential-source.d.ts +28 -0
- package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/credential-source.js +151 -0
- package/dist/humain/web-access/vendor/credential-source.js.map +1 -0
- package/dist/humain/web-access/vendor/curator-page.d.ts +29 -0
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-page.js +3554 -0
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts +93 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.js +688 -0
- package/dist/humain/web-access/vendor/curator-server.js.map +1 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts +60 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.js +416 -0
- package/dist/humain/web-access/vendor/datalab-pdf-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/declared-web-links.d.ts +16 -0
- package/dist/humain/web-access/vendor/declared-web-links.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/declared-web-links.js +168 -0
- package/dist/humain/web-access/vendor/declared-web-links.js.map +1 -0
- package/dist/humain/web-access/vendor/duckduckgo.d.ts +4 -0
- package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/duckduckgo.js +123 -0
- package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -0
- package/dist/humain/web-access/vendor/exa.d.ts +10 -0
- package/dist/humain/web-access/vendor/exa.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/exa.js +426 -0
- package/dist/humain/web-access/vendor/exa.js.map +1 -0
- package/dist/humain/web-access/vendor/extract.d.ts +46 -0
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/extract.js +1064 -0
- package/dist/humain/web-access/vendor/extract.js.map +1 -0
- package/dist/humain/web-access/vendor/feature-config.d.ts +3 -0
- package/dist/humain/web-access/vendor/feature-config.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/feature-config.js +27 -0
- package/dist/humain/web-access/vendor/feature-config.js.map +1 -0
- package/dist/humain/web-access/vendor/fetch-params.d.ts +25 -0
- package/dist/humain/web-access/vendor/fetch-params.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/fetch-params.js +57 -0
- package/dist/humain/web-access/vendor/fetch-params.js.map +1 -0
- package/dist/humain/web-access/vendor/firecrawl.d.ts +12 -0
- package/dist/humain/web-access/vendor/firecrawl.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/firecrawl.js +239 -0
- package/dist/humain/web-access/vendor/firecrawl.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-api.d.ts +27 -0
- package/dist/humain/web-access/vendor/gemini-api.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-api.js +230 -0
- package/dist/humain/web-access/vendor/gemini-api.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts +9 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.js +85 -0
- package/dist/humain/web-access/vendor/gemini-pdf-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-search.d.ts +40 -0
- package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-search.js +814 -0
- package/dist/humain/web-access/vendor/gemini-search.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-url-context.d.ts +4 -0
- package/dist/humain/web-access/vendor/gemini-url-context.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-url-context.js +101 -0
- package/dist/humain/web-access/vendor/gemini-url-context.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web-config.d.ts +4 -0
- package/dist/humain/web-access/vendor/gemini-web-config.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web-config.js +42 -0
- package/dist/humain/web-access/vendor/gemini-web-config.js.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web.d.ts +18 -0
- package/dist/humain/web-access/vendor/gemini-web.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/gemini-web.js +385 -0
- package/dist/humain/web-access/vendor/gemini-web.js.map +1 -0
- package/dist/humain/web-access/vendor/github-api.d.ts +7 -0
- package/dist/humain/web-access/vendor/github-api.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/github-api.js +160 -0
- package/dist/humain/web-access/vendor/github-api.js.map +1 -0
- package/dist/humain/web-access/vendor/github-extract.d.ts +13 -0
- package/dist/humain/web-access/vendor/github-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/github-extract.js +635 -0
- package/dist/humain/web-access/vendor/github-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/index.d.ts +4 -0
- package/dist/humain/web-access/vendor/index.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/index.js +3002 -0
- package/dist/humain/web-access/vendor/index.js.map +1 -0
- package/dist/humain/web-access/vendor/jina-search.d.ts +8 -0
- package/dist/humain/web-access/vendor/jina-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/jina-search.js +255 -0
- package/dist/humain/web-access/vendor/jina-search.js.map +1 -0
- package/dist/humain/web-access/vendor/kagi.d.ts +15 -0
- package/dist/humain/web-access/vendor/kagi.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/kagi.js +262 -0
- package/dist/humain/web-access/vendor/kagi.js.map +1 -0
- package/dist/humain/web-access/vendor/ollama.d.ts +15 -0
- package/dist/humain/web-access/vendor/ollama.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/ollama.js +216 -0
- package/dist/humain/web-access/vendor/ollama.js.map +1 -0
- package/dist/humain/web-access/vendor/openai-search.d.ts +15 -0
- package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/openai-search.js +459 -0
- package/dist/humain/web-access/vendor/openai-search.js.map +1 -0
- package/dist/humain/web-access/vendor/page-query.d.ts +16 -0
- package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/page-query.js +79 -0
- package/dist/humain/web-access/vendor/page-query.js.map +1 -0
- package/dist/humain/web-access/vendor/parallel.d.ts +12 -0
- package/dist/humain/web-access/vendor/parallel.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/parallel.js +343 -0
- package/dist/humain/web-access/vendor/parallel.js.map +1 -0
- package/dist/humain/web-access/vendor/pdf-extract.d.ts +44 -0
- package/dist/humain/web-access/vendor/pdf-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/pdf-extract.js +298 -0
- package/dist/humain/web-access/vendor/pdf-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/perplexity.d.ts +20 -0
- package/dist/humain/web-access/vendor/perplexity.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/perplexity.js +159 -0
- package/dist/humain/web-access/vendor/perplexity.js.map +1 -0
- package/dist/humain/web-access/vendor/querit.d.ts +10 -0
- package/dist/humain/web-access/vendor/querit.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/querit.js +335 -0
- package/dist/humain/web-access/vendor/querit.js.map +1 -0
- package/dist/humain/web-access/vendor/render-search-error.d.ts +57 -0
- package/dist/humain/web-access/vendor/render-search-error.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/render-search-error.js +130 -0
- package/dist/humain/web-access/vendor/render-search-error.js.map +1 -0
- package/dist/humain/web-access/vendor/rsc-extract.d.ts +12 -0
- package/dist/humain/web-access/vendor/rsc-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/rsc-extract.js +329 -0
- package/dist/humain/web-access/vendor/rsc-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/search1api.d.ts +10 -0
- package/dist/humain/web-access/vendor/search1api.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/search1api.js +251 -0
- package/dist/humain/web-access/vendor/search1api.js.map +1 -0
- package/dist/humain/web-access/vendor/searchinfinity.d.ts +8 -0
- package/dist/humain/web-access/vendor/searchinfinity.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/searchinfinity.js +229 -0
- package/dist/humain/web-access/vendor/searchinfinity.js.map +1 -0
- package/dist/humain/web-access/vendor/searxng.d.ts +4 -0
- package/dist/humain/web-access/vendor/searxng.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/searxng.js +238 -0
- package/dist/humain/web-access/vendor/searxng.js.map +1 -0
- package/dist/humain/web-access/vendor/serpbase.d.ts +4 -0
- package/dist/humain/web-access/vendor/serpbase.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serpbase.js +211 -0
- package/dist/humain/web-access/vendor/serpbase.js.map +1 -0
- package/dist/humain/web-access/vendor/serpdive.d.ts +8 -0
- package/dist/humain/web-access/vendor/serpdive.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serpdive.js +267 -0
- package/dist/humain/web-access/vendor/serpdive.js.map +1 -0
- package/dist/humain/web-access/vendor/source-check.d.ts +99 -0
- package/dist/humain/web-access/vendor/source-check.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/source-check.js +205 -0
- package/dist/humain/web-access/vendor/source-check.js.map +1 -0
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts +50 -0
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/ssrf-protection.js +466 -0
- package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -0
- package/dist/humain/web-access/vendor/storage.d.ts +55 -0
- package/dist/humain/web-access/vendor/storage.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/storage.js +485 -0
- package/dist/humain/web-access/vendor/storage.js.map +1 -0
- package/dist/humain/web-access/vendor/summary-model-scope.d.ts +25 -0
- package/dist/humain/web-access/vendor/summary-model-scope.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/summary-model-scope.js +98 -0
- package/dist/humain/web-access/vendor/summary-model-scope.js.map +1 -0
- package/dist/humain/web-access/vendor/summary-review.d.ts +24 -0
- package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/summary-review.js +341 -0
- package/dist/humain/web-access/vendor/summary-review.js.map +1 -0
- package/dist/humain/web-access/vendor/tavily.d.ts +8 -0
- package/dist/humain/web-access/vendor/tavily.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/tavily.js +194 -0
- package/dist/humain/web-access/vendor/tavily.js.map +1 -0
- package/dist/humain/web-access/vendor/tinyfish.d.ts +11 -0
- package/dist/humain/web-access/vendor/tinyfish.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/tinyfish.js +331 -0
- package/dist/humain/web-access/vendor/tinyfish.js.map +1 -0
- package/dist/humain/web-access/vendor/utils.d.ts +20 -0
- package/dist/humain/web-access/vendor/utils.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/utils.js +91 -0
- package/dist/humain/web-access/vendor/utils.js.map +1 -0
- package/dist/humain/web-access/vendor/video-extract.d.ts +16 -0
- package/dist/humain/web-access/vendor/video-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/video-extract.js +335 -0
- package/dist/humain/web-access/vendor/video-extract.js.map +1 -0
- package/dist/humain/web-access/vendor/xai-search.d.ts +13 -0
- package/dist/humain/web-access/vendor/xai-search.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/xai-search.js +331 -0
- package/dist/humain/web-access/vendor/xai-search.js.map +1 -0
- package/dist/humain/web-access/vendor/youtube-extract.d.ts +27 -0
- package/dist/humain/web-access/vendor/youtube-extract.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/youtube-extract.js +282 -0
- package/dist/humain/web-access/vendor/youtube-extract.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +2 -2
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +194 -84
- package/dist/main.js.map +1 -1
- package/dist/modes/agent-exec-mode.d.ts +14 -0
- package/dist/modes/agent-exec-mode.d.ts.map +1 -0
- package/dist/modes/agent-exec-mode.js +92 -0
- package/dist/modes/agent-exec-mode.js.map +1 -0
- package/dist/modes/index.d.ts +4 -2
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +2 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +13 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +7 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
- package/dist/modes/interactive/components/earendil-announcement.js +40 -0
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.js +19 -0
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
- package/dist/modes/interactive/components/mermaid.d.ts +11 -0
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
- package/dist/modes/interactive/components/mermaid.js +75 -0
- package/dist/modes/interactive/components/mermaid.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +20 -5
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +30 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +9 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +45 -9
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +601 -217
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -0
- package/dist/modes/interactive/theme/light.json +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +10 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +5 -1
- package/dist/modes/interactive/theme/theme.d.ts +2 -2
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +24 -6
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +28 -0
- package/dist/modes/json-event.d.ts.map +1 -0
- package/dist/modes/json-event.js +12 -0
- package/dist/modes/json-event.js.map +1 -0
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +12 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +12 -5
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +55 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +26 -3
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +15 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +11 -9
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js +3 -2
- package/dist/rpc-entry.js.map +1 -1
- package/dist/server/create-harness.d.ts +26 -0
- package/dist/server/create-harness.d.ts.map +1 -0
- package/dist/server/create-harness.js +104 -0
- package/dist/server/create-harness.js.map +1 -0
- package/dist/utils/abort.d.ts +5 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +48 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +22 -2
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/management-http.d.ts +23 -0
- package/dist/utils/management-http.d.ts.map +1 -0
- package/dist/utils/management-http.js +50 -0
- package/dist/utils/management-http.js.map +1 -0
- package/dist/utils/paths.d.ts +3 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +23 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts +19 -0
- package/dist/utils/tool-result-images.d.ts.map +1 -0
- package/dist/utils/tool-result-images.js +45 -0
- package/dist/utils/tool-result-images.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +13 -25
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +4 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +23 -5
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +2 -2
- package/docs/custom-provider.md +16 -8
- package/docs/extensions.md +33 -6
- package/docs/humain-terminal.md +21 -1
- package/docs/json.md +24 -19
- package/docs/keybindings.md +46 -14
- package/docs/models.md +32 -11
- package/docs/providers.md +10 -1
- package/docs/quickstart.md +39 -37
- package/docs/rpc.md +31 -11
- package/docs/sdk.md +21 -2
- package/docs/security.md +21 -21
- package/docs/session-format.md +15 -13
- package/docs/settings.md +4 -1
- package/docs/themes.md +5 -3
- package/docs/usage.md +7 -0
- package/examples/extensions/custom-compaction.ts +3 -18
- package/examples/extensions/custom-provider-anthropic/index.ts +13 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +5 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +4 -13
- package/examples/extensions/qna.ts +5 -9
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/summarize.ts +9 -20
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +11 -2
- package/examples/sdk/02-custom-model.ts +2 -3
- package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
- package/examples/sdk/12-full-control.ts +3 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +2779 -543
- package/package.json +42 -13
- package/src/humain/mcp-adapter/UPSTREAM.md +15 -0
- package/src/humain/mcp-adapter/upstream.json +7 -0
- package/src/humain/mcp-adapter/vendor/CHANGELOG.md +660 -0
- package/src/humain/mcp-adapter/vendor/LICENSE +21 -0
- package/src/humain/web-access/UPSTREAM.md +17 -0
- package/src/humain/web-access/upstream.json +23 -0
- package/src/humain/web-access/vendor/LICENSE +21 -0
|
@@ -6,10 +6,11 @@ import * as crypto from "node:crypto";
|
|
|
6
6
|
import * as fs from "node:fs";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
-
import
|
|
9
|
+
import * as TuiLayouts from "@earendil-works/pi-tui";
|
|
10
|
+
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
|
|
10
11
|
import chalk from "chalk";
|
|
11
12
|
import { spawn, spawnSync } from "child_process";
|
|
12
|
-
import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME,
|
|
13
|
+
import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
13
14
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
14
15
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
15
16
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
@@ -17,7 +18,8 @@ import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
|
17
18
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
18
19
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
19
20
|
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
20
|
-
import { defaultModelPerProvider, findExactModelReferenceMatch,
|
|
21
|
+
import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScopeFromModels, } from "../../core/model-resolver.js";
|
|
22
|
+
import { CredentialSynchronizationError } from "../../core/model-runtime.js";
|
|
21
23
|
import { DefaultPackageManager } from "../../core/package-manager.js";
|
|
22
24
|
import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
|
|
23
25
|
import { SessionManager, sessionEntryToContextMessages } from "../../core/session-manager.js";
|
|
@@ -29,6 +31,8 @@ import { getChangelogPath, getNewEntries, normalizeChangelogLinks, parseChangelo
|
|
|
29
31
|
import { copyToClipboard, readClipboardText } from "../../utils/clipboard.js";
|
|
30
32
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
31
33
|
import { parseGitUrl } from "../../utils/git.js";
|
|
34
|
+
import { openBrowser } from "../../utils/open-browser.js";
|
|
35
|
+
import { getCwdRelativePath } from "../../utils/paths.js";
|
|
32
36
|
import { getPiUserAgent } from "../../utils/pi-user-agent.js";
|
|
33
37
|
import { killTrackedDetachedChildren } from "../../utils/shell.js";
|
|
34
38
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
@@ -44,12 +48,14 @@ import { CustomEntryComponent } from "./components/custom-entry.js";
|
|
|
44
48
|
import { CustomMessageComponent } from "./components/custom-message.js";
|
|
45
49
|
import { DaxnutsComponent } from "./components/daxnuts.js";
|
|
46
50
|
import { DynamicBorder } from "./components/dynamic-border.js";
|
|
51
|
+
import { EarendilAnnouncementComponent } from "./components/earendil-announcement.js";
|
|
47
52
|
import { ExtensionEditorComponent } from "./components/extension-editor.js";
|
|
48
53
|
import { ExtensionInputComponent } from "./components/extension-input.js";
|
|
49
54
|
import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
50
55
|
import { FooterComponent, formatTokens } from "./components/footer.js";
|
|
51
56
|
import { formatKeyText, keyDisplayText, keyHint, keyText, rawKeyHint } from "./components/keybinding-hints.js";
|
|
52
57
|
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
58
|
+
import { createMermaidMarkdownTransformer } from "./components/mermaid.js";
|
|
53
59
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
54
60
|
import { formatAuthSelectorProviderType, OAuthSelectorComponent, } from "./components/oauth-selector.js";
|
|
55
61
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
@@ -159,11 +165,58 @@ function formatLoginProviderCompletionDescription(provider) {
|
|
|
159
165
|
const authTypes = provider.authTypes.map(formatAuthSelectorProviderType).join("/");
|
|
160
166
|
return provider.name === provider.id ? authTypes : `${provider.name} · ${authTypes}`;
|
|
161
167
|
}
|
|
168
|
+
/** Composition root for selecting the interactive terminal renderer. */
|
|
169
|
+
export function createInteractiveTui(options) {
|
|
170
|
+
const terminal = options.terminal ?? new ProcessTerminal();
|
|
171
|
+
if (options.tuiMode === "fullscreen") {
|
|
172
|
+
return new TuiAltScreen(terminal, options.showHardwareCursor, options.logDirectory, {
|
|
173
|
+
openUrl: openBrowser,
|
|
174
|
+
onRightClickPaste: options.onRightClickPaste,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return new TuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);
|
|
178
|
+
}
|
|
179
|
+
/** Stable reference for components while InteractiveMode replaces the active renderer. */
|
|
180
|
+
export function createInteractiveTuiReference(getTui) {
|
|
181
|
+
return new Proxy({}, {
|
|
182
|
+
get: (_target, property) => {
|
|
183
|
+
const tui = getTui();
|
|
184
|
+
const value = Reflect.get(tui, property, tui);
|
|
185
|
+
if (typeof value !== "function")
|
|
186
|
+
return value;
|
|
187
|
+
let methodTui = tui;
|
|
188
|
+
let method = value;
|
|
189
|
+
return (...args) => {
|
|
190
|
+
const currentTui = getTui();
|
|
191
|
+
if (currentTui !== methodTui) {
|
|
192
|
+
const currentMethod = Reflect.get(currentTui, property, currentTui);
|
|
193
|
+
if (typeof currentMethod !== "function") {
|
|
194
|
+
throw new TypeError(`TUI property ${String(property)} is not callable`);
|
|
195
|
+
}
|
|
196
|
+
methodTui = currentTui;
|
|
197
|
+
method = currentMethod;
|
|
198
|
+
}
|
|
199
|
+
return Reflect.apply(method, methodTui, args);
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
set: (_target, property, value) => {
|
|
203
|
+
const tui = getTui();
|
|
204
|
+
return Reflect.set(tui, property, value, tui);
|
|
205
|
+
},
|
|
206
|
+
has: (_target, property) => Reflect.has(getTui(), property),
|
|
207
|
+
getPrototypeOf: () => Reflect.getPrototypeOf(getTui()),
|
|
208
|
+
});
|
|
209
|
+
}
|
|
162
210
|
export class InteractiveMode {
|
|
163
211
|
runtimeHost;
|
|
212
|
+
renderer;
|
|
164
213
|
ui;
|
|
214
|
+
mainScreenRenderState;
|
|
165
215
|
loadedResourcesContainer;
|
|
166
216
|
chatContainer;
|
|
217
|
+
documentContainer;
|
|
218
|
+
transcriptScrollView;
|
|
219
|
+
fullscreenLayoutRoot;
|
|
167
220
|
pendingMessagesContainer;
|
|
168
221
|
statusContainer;
|
|
169
222
|
defaultEditor;
|
|
@@ -173,7 +226,10 @@ export class InteractiveMode {
|
|
|
173
226
|
autocompleteProviderWrappers = [];
|
|
174
227
|
fdPath;
|
|
175
228
|
editorContainer;
|
|
229
|
+
activeSelectorToken;
|
|
230
|
+
activeSelectorDispose;
|
|
176
231
|
footer;
|
|
232
|
+
footerContainer;
|
|
177
233
|
footerDataProvider;
|
|
178
234
|
// Stored so the same manager can be injected into custom editors, selectors, and extension UI.
|
|
179
235
|
keybindings;
|
|
@@ -207,6 +263,10 @@ export class InteractiveMode {
|
|
|
207
263
|
// Thinking block visibility state
|
|
208
264
|
hideThinkingBlock = false;
|
|
209
265
|
outputPad = 1;
|
|
266
|
+
mermaidMarkdownTransformer = createMermaidMarkdownTransformer({
|
|
267
|
+
getMode: () => this.settingsManager.getMermaidRenderingMode(),
|
|
268
|
+
theme,
|
|
269
|
+
});
|
|
210
270
|
// Skill commands: command name -> skill file path
|
|
211
271
|
skillCommands = new Map();
|
|
212
272
|
// Agent subscription unsubscribe function
|
|
@@ -230,7 +290,7 @@ export class InteractiveMode {
|
|
|
230
290
|
extensionSelector = undefined;
|
|
231
291
|
extensionInput = undefined;
|
|
232
292
|
extensionEditor = undefined;
|
|
233
|
-
|
|
293
|
+
extensionTerminalInputSubscriptions = new Set();
|
|
234
294
|
// Extension widgets (components rendered above/below the editor)
|
|
235
295
|
extensionWidgetsAbove = new Map();
|
|
236
296
|
extensionWidgetsBelow = new Map();
|
|
@@ -245,6 +305,9 @@ export class InteractiveMode {
|
|
|
245
305
|
// Custom header from extension (undefined = use built-in header)
|
|
246
306
|
customHeader = undefined;
|
|
247
307
|
options;
|
|
308
|
+
onRightClickPaste = () => {
|
|
309
|
+
void this.handleRightClickPaste();
|
|
310
|
+
};
|
|
248
311
|
autoTrustOnReloadCwd;
|
|
249
312
|
themeController;
|
|
250
313
|
// Convenience accessors
|
|
@@ -262,7 +325,8 @@ export class InteractiveMode {
|
|
|
262
325
|
}
|
|
263
326
|
constructor(runtimeHost, options = {}) {
|
|
264
327
|
this.runtimeHost = runtimeHost;
|
|
265
|
-
|
|
328
|
+
const tuiMode = options.tuiMode ?? this.settingsManager.getTuiMode();
|
|
329
|
+
this.options = { ...options, tuiMode };
|
|
266
330
|
this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
|
|
267
331
|
this.runtimeHost.setBeforeSessionInvalidate(() => {
|
|
268
332
|
this.resetExtensionUI();
|
|
@@ -271,11 +335,21 @@ export class InteractiveMode {
|
|
|
271
335
|
await this.rebindCurrentSession({ renderBeforeBind: true });
|
|
272
336
|
});
|
|
273
337
|
this.version = VERSION;
|
|
274
|
-
this.
|
|
338
|
+
this.renderer = createInteractiveTui({
|
|
339
|
+
tuiMode,
|
|
340
|
+
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
341
|
+
logDirectory: getAgentDir(),
|
|
342
|
+
onRightClickPaste: this.onRightClickPaste,
|
|
343
|
+
});
|
|
344
|
+
this.ui = createInteractiveTuiReference(() => this.renderer);
|
|
275
345
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
276
346
|
this.headerContainer = new Container();
|
|
277
347
|
this.loadedResourcesContainer = new Container();
|
|
278
348
|
this.chatContainer = new Container();
|
|
349
|
+
this.documentContainer = new Container();
|
|
350
|
+
this.documentContainer.addChild(this.headerContainer);
|
|
351
|
+
this.documentContainer.addChild(this.loadedResourcesContainer);
|
|
352
|
+
this.documentContainer.addChild(this.chatContainer);
|
|
279
353
|
this.pendingMessagesContainer = new Container();
|
|
280
354
|
this.statusContainer = new Container();
|
|
281
355
|
this.widgetContainerAbove = new Container();
|
|
@@ -294,6 +368,8 @@ export class InteractiveMode {
|
|
|
294
368
|
this.footerDataProvider = new FooterDataProvider(this.sessionManager.getCwd());
|
|
295
369
|
this.footer = new FooterComponent(this.session, this.footerDataProvider);
|
|
296
370
|
this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
371
|
+
this.footerContainer = new Container();
|
|
372
|
+
this.footerContainer.addChild(this.footer);
|
|
297
373
|
// Load hide thinking block setting
|
|
298
374
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
299
375
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
@@ -349,11 +425,10 @@ export class InteractiveMode {
|
|
|
349
425
|
}));
|
|
350
426
|
const modelCommand = slashCommands.find((command) => command.name === "model");
|
|
351
427
|
if (modelCommand) {
|
|
352
|
-
modelCommand.getArgumentCompletions =
|
|
353
|
-
// Get available models (scoped or from registry)
|
|
428
|
+
modelCommand.getArgumentCompletions = (prefix) => {
|
|
354
429
|
const models = this.session.scopedModels.length > 0
|
|
355
430
|
? this.session.scopedModels.map((s) => s.model)
|
|
356
|
-
:
|
|
431
|
+
: this.session.modelRuntime.getAvailableSnapshot();
|
|
357
432
|
if (models.length === 0)
|
|
358
433
|
return null;
|
|
359
434
|
// Create items with provider/id format
|
|
@@ -454,6 +529,73 @@ export class InteractiveMode {
|
|
|
454
529
|
}
|
|
455
530
|
this.chatContainer.addChild(new DynamicBorder());
|
|
456
531
|
}
|
|
532
|
+
mountInteractiveTui(tui, components) {
|
|
533
|
+
for (const component of components)
|
|
534
|
+
tui.addChild(component);
|
|
535
|
+
if (TuiLayouts.isViewportTUI(tui)) {
|
|
536
|
+
if (!this.fullscreenLayoutRoot)
|
|
537
|
+
throw new Error("Fullscreen layout is not initialized");
|
|
538
|
+
tui.setLayoutRoot(this.fullscreenLayoutRoot);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
stopInteractiveTui() {
|
|
542
|
+
if (this.renderer.mode === "fullscreen") {
|
|
543
|
+
while (this.renderer.hasOverlayEntries)
|
|
544
|
+
this.renderer.hideOverlay();
|
|
545
|
+
this.switchTuiMode("regular", false, false);
|
|
546
|
+
this.renderer.renderNow();
|
|
547
|
+
}
|
|
548
|
+
this.ui.stop();
|
|
549
|
+
}
|
|
550
|
+
switchTuiMode(mode, restoreProgress = true, startRenderer = true) {
|
|
551
|
+
const previousUi = this.renderer;
|
|
552
|
+
if (mode === previousUi.mode)
|
|
553
|
+
return true;
|
|
554
|
+
if (previousUi.hasOverlayEntries)
|
|
555
|
+
return false;
|
|
556
|
+
const components = [...previousUi.children];
|
|
557
|
+
const focus = previousUi.getFocusedComponent();
|
|
558
|
+
const terminal = previousUi.terminal;
|
|
559
|
+
const showHardwareCursor = previousUi.getShowHardwareCursor();
|
|
560
|
+
const clearOnShrink = previousUi.getClearOnShrink();
|
|
561
|
+
const onDebug = previousUi.onDebug;
|
|
562
|
+
if (previousUi instanceof TuiMainScreen) {
|
|
563
|
+
this.mainScreenRenderState = previousUi.captureRenderState();
|
|
564
|
+
}
|
|
565
|
+
previousUi.stop({ preserveScreen: true });
|
|
566
|
+
previousUi.setFocus(null);
|
|
567
|
+
previousUi.clear();
|
|
568
|
+
if (TuiLayouts.isViewportTUI(previousUi))
|
|
569
|
+
previousUi.setLayoutRoot(undefined);
|
|
570
|
+
const nextUi = createInteractiveTui({
|
|
571
|
+
tuiMode: mode,
|
|
572
|
+
showHardwareCursor,
|
|
573
|
+
logDirectory: getAgentDir(),
|
|
574
|
+
terminal,
|
|
575
|
+
onRightClickPaste: this.onRightClickPaste,
|
|
576
|
+
});
|
|
577
|
+
nextUi.setClearOnShrink(clearOnShrink);
|
|
578
|
+
nextUi.onDebug = onDebug;
|
|
579
|
+
if (nextUi instanceof TuiMainScreen && this.mainScreenRenderState) {
|
|
580
|
+
nextUi.restoreRenderState(this.mainScreenRenderState);
|
|
581
|
+
}
|
|
582
|
+
this.renderer = nextUi;
|
|
583
|
+
this.options.tuiMode = mode;
|
|
584
|
+
this.mountInteractiveTui(nextUi, components);
|
|
585
|
+
nextUi.invalidate();
|
|
586
|
+
nextUi.setFocus(focus);
|
|
587
|
+
if (!startRenderer)
|
|
588
|
+
return true;
|
|
589
|
+
nextUi.start();
|
|
590
|
+
this.themeController.rebindTui();
|
|
591
|
+
this.rebindExtensionTerminalInputListeners();
|
|
592
|
+
if (restoreProgress &&
|
|
593
|
+
this.settingsManager.getShowTerminalProgress() &&
|
|
594
|
+
(this.session.isStreaming || this.session.isCompacting)) {
|
|
595
|
+
terminal.setProgress(true);
|
|
596
|
+
}
|
|
597
|
+
return true;
|
|
598
|
+
}
|
|
457
599
|
async init() {
|
|
458
600
|
if (this.isInitialized)
|
|
459
601
|
return;
|
|
@@ -477,18 +619,36 @@ export class InteractiveMode {
|
|
|
477
619
|
: "";
|
|
478
620
|
console.log(theme.fg("dim", `Model scope: ${modelList}${cycleHint}`));
|
|
479
621
|
}
|
|
480
|
-
//
|
|
481
|
-
// Keep loaded resources before chat so restored session messages never precede them.
|
|
482
|
-
this.ui.addChild(this.headerContainer);
|
|
483
|
-
this.ui.addChild(this.loadedResourcesContainer);
|
|
484
|
-
this.ui.addChild(this.chatContainer);
|
|
485
|
-
this.ui.addChild(this.pendingMessagesContainer);
|
|
486
|
-
this.ui.addChild(this.statusContainer);
|
|
622
|
+
// Keep one component tree and remount it when changing renderers.
|
|
487
623
|
this.renderWidgets(); // Initialize with default spacer
|
|
488
|
-
this.
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
624
|
+
this.transcriptScrollView = new TuiLayouts.ScrollView(this.documentContainer, {
|
|
625
|
+
follow: "end",
|
|
626
|
+
primary: true,
|
|
627
|
+
overscroll: "chain",
|
|
628
|
+
scrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
629
|
+
scrollbarStyle: (text) => theme.bg("scrollbarThumb", text),
|
|
630
|
+
});
|
|
631
|
+
const dock = new TuiLayouts.VStack([
|
|
632
|
+
{ component: this.pendingMessagesContainer, shrink: 1, minSize: 0 },
|
|
633
|
+
{ component: this.statusContainer, shrink: 1, minSize: 0 },
|
|
634
|
+
{ component: this.widgetContainerAbove, shrink: 1, minSize: 0 },
|
|
635
|
+
{ component: this.editorContainer, shrink: 1, minSize: 3 },
|
|
636
|
+
{ component: this.widgetContainerBelow, shrink: 1, minSize: 0 },
|
|
637
|
+
{ component: this.footerContainer, shrink: 1, minSize: 1 },
|
|
638
|
+
]);
|
|
639
|
+
this.fullscreenLayoutRoot = new TuiLayouts.VStack([
|
|
640
|
+
{ component: this.transcriptScrollView, basis: 0, grow: 1, shrink: 1, minSize: 1 },
|
|
641
|
+
{ component: dock, basis: "auto", grow: 0, shrink: 1, minSize: 1 },
|
|
642
|
+
]);
|
|
643
|
+
this.mountInteractiveTui(this.renderer, [
|
|
644
|
+
this.documentContainer,
|
|
645
|
+
this.pendingMessagesContainer,
|
|
646
|
+
this.statusContainer,
|
|
647
|
+
this.widgetContainerAbove,
|
|
648
|
+
this.editorContainer,
|
|
649
|
+
this.widgetContainerBelow,
|
|
650
|
+
this.footerContainer,
|
|
651
|
+
]);
|
|
492
652
|
this.ui.setFocus(this.editor);
|
|
493
653
|
this.setupKeyHandlers();
|
|
494
654
|
this.setupEditorSubmitHandler();
|
|
@@ -498,7 +658,7 @@ export class InteractiveMode {
|
|
|
498
658
|
await this.themeController.applyFromSettings();
|
|
499
659
|
// Add header with keybindings from config (unless silenced)
|
|
500
660
|
if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
|
|
501
|
-
const logo = theme.fg("accent",
|
|
661
|
+
const logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
|
|
502
662
|
// Build startup instructions using keybinding hint helpers
|
|
503
663
|
const hint = (keybinding, description) => keyHint(keybinding, description);
|
|
504
664
|
const expandedInstructions = [
|
|
@@ -530,7 +690,7 @@ export class InteractiveMode {
|
|
|
530
690
|
hint("app.tools.expand", "more"),
|
|
531
691
|
].join(theme.fg("muted", " · "));
|
|
532
692
|
const compactOnboarding = theme.fg("dim", `Press ${keyText("app.tools.expand")} to show full startup help and loaded resources.`);
|
|
533
|
-
const onboarding = theme.fg("dim",
|
|
693
|
+
const onboarding = theme.fg("dim", `Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.`);
|
|
534
694
|
this.builtInHeader = new ExpandableText(() => `${logo}\n${compactInstructions}\n${compactOnboarding}\n\n${onboarding}`, () => `${logo}\n${expandedInstructions}\n\n${onboarding}`, this.getStartupExpansionState(), 1, 0);
|
|
535
695
|
// Setup UI layout
|
|
536
696
|
this.headerContainer.addChild(new Spacer(1));
|
|
@@ -580,10 +740,13 @@ export class InteractiveMode {
|
|
|
580
740
|
async run() {
|
|
581
741
|
await this.init();
|
|
582
742
|
if (!process.env.PI_OFFLINE) {
|
|
743
|
+
const controller = new AbortController();
|
|
744
|
+
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
583
745
|
void this.session.modelRuntime
|
|
584
|
-
.refresh()
|
|
746
|
+
.refresh({ signal: controller.signal })
|
|
585
747
|
.then(() => this.updateAvailableProviderCount())
|
|
586
|
-
.catch(() => { })
|
|
748
|
+
.catch(() => { })
|
|
749
|
+
.finally(() => clearTimeout(timeout));
|
|
587
750
|
}
|
|
588
751
|
// Start version check asynchronously
|
|
589
752
|
checkForNewPiVersion(this.version).then((newRelease) => {
|
|
@@ -620,7 +783,7 @@ export class InteractiveMode {
|
|
|
620
783
|
if (modelsJsonError) {
|
|
621
784
|
this.showError(`models.json error: ${modelsJsonError}`);
|
|
622
785
|
}
|
|
623
|
-
if (modelFallbackMessage
|
|
786
|
+
if (modelFallbackMessage) {
|
|
624
787
|
this.showWarning(modelFallbackMessage);
|
|
625
788
|
}
|
|
626
789
|
void this.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
@@ -658,7 +821,7 @@ export class InteractiveMode {
|
|
|
658
821
|
}
|
|
659
822
|
}
|
|
660
823
|
async checkForPackageUpdates() {
|
|
661
|
-
if (process.env
|
|
824
|
+
if (process.env.PI_OFFLINE) {
|
|
662
825
|
return [];
|
|
663
826
|
}
|
|
664
827
|
try {
|
|
@@ -711,7 +874,7 @@ export class InteractiveMode {
|
|
|
711
874
|
return "tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.";
|
|
712
875
|
}
|
|
713
876
|
if (extendedKeysFormat === "xterm") {
|
|
714
|
-
return
|
|
877
|
+
return "tmux extended-keys-format is xterm. Pi works best with csi-u. Add `set -g extended-keys-format csi-u` to ~/.tmux.conf and restart tmux.";
|
|
715
878
|
}
|
|
716
879
|
return undefined;
|
|
717
880
|
}
|
|
@@ -742,13 +905,13 @@ export class InteractiveMode {
|
|
|
742
905
|
return undefined;
|
|
743
906
|
}
|
|
744
907
|
reportInstallTelemetry(version) {
|
|
745
|
-
if (process.env
|
|
908
|
+
if (process.env.PI_OFFLINE) {
|
|
746
909
|
return;
|
|
747
910
|
}
|
|
748
911
|
if (!isInstallTelemetryEnabled(this.settingsManager)) {
|
|
749
912
|
return;
|
|
750
913
|
}
|
|
751
|
-
void fetch(
|
|
914
|
+
void fetch(`https://pi.dev/api/report-install?version=${encodeURIComponent(version)}`, {
|
|
752
915
|
headers: {
|
|
753
916
|
"User-Agent": getPiUserAgent(version),
|
|
754
917
|
},
|
|
@@ -763,20 +926,6 @@ export class InteractiveMode {
|
|
|
763
926
|
codeBlockIndent: this.settingsManager.getCodeBlockIndent(),
|
|
764
927
|
};
|
|
765
928
|
}
|
|
766
|
-
isNoModelsAvailableMessage(message) {
|
|
767
|
-
return message?.startsWith("No models available.") ?? false;
|
|
768
|
-
}
|
|
769
|
-
getNoModelsStartupNotice() {
|
|
770
|
-
if (!this.isNoModelsAvailableMessage(this.options.modelFallbackMessage)) {
|
|
771
|
-
return undefined;
|
|
772
|
-
}
|
|
773
|
-
return [
|
|
774
|
-
theme.bold(theme.fg("warning", "Model setup required")),
|
|
775
|
-
`${theme.fg("muted", "No models are available yet. Run ")}${theme.bold("/login")}${theme.fg("muted", " to add a provider.")}`,
|
|
776
|
-
`${theme.fg("dim", "Then use ")}${theme.bold("/model")}${theme.fg("dim", " if you want to switch models.")}`,
|
|
777
|
-
`${theme.fg("dim", "Docs: ")}${theme.fg("accent", "docs/providers.md")}${theme.fg("dim", ", ")}${theme.fg("accent", "docs/models.md")}`,
|
|
778
|
-
].join("\n");
|
|
779
|
-
}
|
|
780
929
|
// =========================================================================
|
|
781
930
|
// Extension System
|
|
782
931
|
// =========================================================================
|
|
@@ -794,6 +943,15 @@ export class InteractiveMode {
|
|
|
794
943
|
result = result.replace(/\/index\.ts$/, "").replace(/\/index\.js$/, "");
|
|
795
944
|
return result;
|
|
796
945
|
}
|
|
946
|
+
formatContextPath(p) {
|
|
947
|
+
const cwd = path.resolve(this.sessionManager.getCwd());
|
|
948
|
+
const absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(cwd, p);
|
|
949
|
+
const relativePath = getCwdRelativePath(absolutePath, cwd);
|
|
950
|
+
if (relativePath !== undefined) {
|
|
951
|
+
return relativePath;
|
|
952
|
+
}
|
|
953
|
+
return this.formatDisplayPath(absolutePath);
|
|
954
|
+
}
|
|
797
955
|
getStartupExpansionState() {
|
|
798
956
|
return this.options.verbose || this.toolOutputExpanded;
|
|
799
957
|
}
|
|
@@ -830,43 +988,92 @@ export class InteractiveMode {
|
|
|
830
988
|
}
|
|
831
989
|
return this.formatDisplayPath(fullPath);
|
|
832
990
|
}
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
991
|
+
getCompactPathLabel(resourcePath, sourceInfo) {
|
|
992
|
+
const shortPath = this.getShortPath(resourcePath, sourceInfo);
|
|
993
|
+
const normalizedPath = shortPath.replace(/\\/g, "/");
|
|
994
|
+
const segments = normalizedPath.split("/").filter((segment) => segment.length > 0 && segment !== "~");
|
|
995
|
+
if (segments.length > 0) {
|
|
996
|
+
return segments[segments.length - 1];
|
|
837
997
|
}
|
|
838
|
-
|
|
839
|
-
return versionStart === -1 ? packageSpec : packageSpec.slice(0, versionStart);
|
|
998
|
+
return shortPath;
|
|
840
999
|
}
|
|
841
|
-
|
|
842
|
-
const
|
|
843
|
-
if (scopedMatch) {
|
|
844
|
-
return `${scopedMatch[1]}/${this.stripLegacyPackagePrefix(scopedMatch[2])}`;
|
|
845
|
-
}
|
|
846
|
-
const sanitized = packageName.replace(/^pi[-_]/, "");
|
|
847
|
-
return sanitized || packageName;
|
|
848
|
-
}
|
|
849
|
-
getPackageSourceName(source) {
|
|
1000
|
+
getCompactPackageSourceLabel(sourceInfo) {
|
|
1001
|
+
const source = sourceInfo?.source ?? "";
|
|
850
1002
|
if (source.startsWith("npm:")) {
|
|
851
|
-
return
|
|
1003
|
+
return source.slice("npm:".length) || source;
|
|
852
1004
|
}
|
|
853
1005
|
const gitSource = parseGitUrl(source);
|
|
854
|
-
if (gitSource
|
|
855
|
-
return gitSource.path
|
|
856
|
-
.split("/")
|
|
857
|
-
.map((segment, index, segments) => index === segments.length - 1 ? this.stripLegacyPackagePrefix(segment) : segment)
|
|
858
|
-
.join("/");
|
|
1006
|
+
if (gitSource) {
|
|
1007
|
+
return gitSource.path || source;
|
|
859
1008
|
}
|
|
860
1009
|
return source;
|
|
861
1010
|
}
|
|
862
|
-
|
|
863
|
-
if (
|
|
864
|
-
return
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
|
|
1011
|
+
getCompactExtensionLabel(resourcePath, sourceInfo) {
|
|
1012
|
+
if (!this.isPackageSource(sourceInfo)) {
|
|
1013
|
+
return this.getCompactPathLabel(resourcePath, sourceInfo);
|
|
1014
|
+
}
|
|
1015
|
+
const sourceLabel = this.getCompactPackageSourceLabel(sourceInfo);
|
|
1016
|
+
if (!sourceLabel) {
|
|
1017
|
+
return this.getCompactPathLabel(resourcePath, sourceInfo);
|
|
1018
|
+
}
|
|
1019
|
+
const shortPath = this.getShortPath(resourcePath, sourceInfo).replace(/\\/g, "/");
|
|
1020
|
+
const packagePath = shortPath.startsWith("extensions/") ? shortPath.slice("extensions/".length) : shortPath;
|
|
1021
|
+
const parsedPath = path.posix.parse(packagePath);
|
|
1022
|
+
if (parsedPath.name === "index") {
|
|
1023
|
+
return !parsedPath.dir || parsedPath.dir === "." ? sourceLabel : `${sourceLabel}:${parsedPath.dir}`;
|
|
1024
|
+
}
|
|
1025
|
+
return `${sourceLabel}:${packagePath}`;
|
|
1026
|
+
}
|
|
1027
|
+
getCompactDisplayPathSegments(resourcePath) {
|
|
1028
|
+
return this.formatDisplayPath(resourcePath)
|
|
1029
|
+
.replace(/\\/g, "/")
|
|
1030
|
+
.split("/")
|
|
1031
|
+
.filter((segment) => segment.length > 0 && segment !== "~");
|
|
1032
|
+
}
|
|
1033
|
+
getCompactNonPackageExtensionLabel(resourcePath, index, allPaths) {
|
|
1034
|
+
const segments = allPaths[index]?.segments;
|
|
1035
|
+
if (!segments || segments.length === 0) {
|
|
1036
|
+
return this.getCompactPathLabel(resourcePath);
|
|
1037
|
+
}
|
|
1038
|
+
for (let segmentCount = 1; segmentCount <= segments.length; segmentCount += 1) {
|
|
1039
|
+
const candidate = segments.slice(-segmentCount).join("/");
|
|
1040
|
+
const isUnique = allPaths.every((item, itemIndex) => {
|
|
1041
|
+
if (itemIndex === index) {
|
|
1042
|
+
return true;
|
|
1043
|
+
}
|
|
1044
|
+
return item.segments.slice(-segmentCount).join("/") !== candidate;
|
|
1045
|
+
});
|
|
1046
|
+
if (isUnique) {
|
|
1047
|
+
return candidate;
|
|
1048
|
+
}
|
|
868
1049
|
}
|
|
869
|
-
return
|
|
1050
|
+
return segments.join("/");
|
|
1051
|
+
}
|
|
1052
|
+
getCompactExtensionLabels(extensions) {
|
|
1053
|
+
const nonPackageExtensions = extensions
|
|
1054
|
+
.map((extension) => {
|
|
1055
|
+
const segments = this.getCompactDisplayPathSegments(extension.path);
|
|
1056
|
+
const lastSegment = segments[segments.length - 1];
|
|
1057
|
+
if (segments.length > 1 && (lastSegment === "index.ts" || lastSegment === "index.js")) {
|
|
1058
|
+
segments.pop();
|
|
1059
|
+
}
|
|
1060
|
+
return {
|
|
1061
|
+
path: extension.path,
|
|
1062
|
+
sourceInfo: extension.sourceInfo,
|
|
1063
|
+
segments,
|
|
1064
|
+
};
|
|
1065
|
+
})
|
|
1066
|
+
.filter((extension) => !this.isPackageSource(extension.sourceInfo));
|
|
1067
|
+
return extensions.map((extension) => {
|
|
1068
|
+
if (this.isPackageSource(extension.sourceInfo)) {
|
|
1069
|
+
return this.getCompactExtensionLabel(extension.path, extension.sourceInfo);
|
|
1070
|
+
}
|
|
1071
|
+
const nonPackageIndex = nonPackageExtensions.findIndex((item) => item.path === extension.path);
|
|
1072
|
+
if (nonPackageIndex === -1) {
|
|
1073
|
+
return this.getCompactPathLabel(extension.path, extension.sourceInfo);
|
|
1074
|
+
}
|
|
1075
|
+
return this.getCompactNonPackageExtensionLabel(extension.path, nonPackageIndex, nonPackageExtensions);
|
|
1076
|
+
});
|
|
870
1077
|
}
|
|
871
1078
|
getDisplaySourceInfo(sourceInfo) {
|
|
872
1079
|
const source = sourceInfo?.source ?? "local";
|
|
@@ -887,7 +1094,7 @@ export class InteractiveMode {
|
|
|
887
1094
|
return { label: "path", scopeLabel: scope === "temporary" ? "temp" : undefined, color: "muted" };
|
|
888
1095
|
}
|
|
889
1096
|
const scopeLabel = scope === "user" ? "user" : scope === "project" ? "project" : scope === "temporary" ? "temp" : undefined;
|
|
890
|
-
return { label:
|
|
1097
|
+
return { label: source, scopeLabel, color: "accent" };
|
|
891
1098
|
}
|
|
892
1099
|
getScopeGroup(sourceInfo) {
|
|
893
1100
|
const source = sourceInfo?.source ?? "local";
|
|
@@ -935,7 +1142,7 @@ export class InteractiveMode {
|
|
|
935
1142
|
}
|
|
936
1143
|
const sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
937
1144
|
for (const [source, items] of sortedPackages) {
|
|
938
|
-
lines.push(` ${theme.fg("mdLink",
|
|
1145
|
+
lines.push(` ${theme.fg("mdLink", source)}`);
|
|
939
1146
|
const sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));
|
|
940
1147
|
for (const item of sortedPackagePaths) {
|
|
941
1148
|
lines.push(theme.fg("dim", ` ${options.formatPackagePath(item, source)}`));
|
|
@@ -1011,24 +1218,22 @@ export class InteractiveMode {
|
|
|
1011
1218
|
this.loadedResourcesContainer.clear();
|
|
1012
1219
|
const showListing = options?.force || this.options.verbose || !this.settingsManager.getQuietStartup();
|
|
1013
1220
|
const showDiagnostics = showListing || options?.showDiagnosticsWhenQuiet === true;
|
|
1014
|
-
|
|
1015
|
-
if (!showListing && !showDiagnostics && !noModelsStartupNotice) {
|
|
1221
|
+
if (!showListing && !showDiagnostics) {
|
|
1016
1222
|
return;
|
|
1017
1223
|
}
|
|
1018
1224
|
const sectionHeader = (name, color = "mdHeading") => theme.fg(color, `[${name}]`);
|
|
1019
|
-
const
|
|
1225
|
+
const formatCompactList = (items, options) => {
|
|
1226
|
+
const labels = items.map((item) => item.trim()).filter((item) => item.length > 0);
|
|
1227
|
+
if (options?.sort !== false) {
|
|
1228
|
+
labels.sort((a, b) => a.localeCompare(b));
|
|
1229
|
+
}
|
|
1230
|
+
return theme.fg("dim", ` ${labels.join(", ")}`);
|
|
1231
|
+
};
|
|
1020
1232
|
const addLoadedSection = (name, collapsedBody, expandedBody = collapsedBody, color = "mdHeading") => {
|
|
1021
1233
|
const section = new ExpandableText(() => `${sectionHeader(name, color)}\n${collapsedBody}`, () => `${sectionHeader(name, color)}\n${expandedBody}`, this.getStartupExpansionState(), 0, 0);
|
|
1022
1234
|
this.loadedResourcesContainer.addChild(section);
|
|
1023
1235
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1024
1236
|
};
|
|
1025
|
-
if (noModelsStartupNotice) {
|
|
1026
|
-
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1027
|
-
this.loadedResourcesContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
1028
|
-
this.loadedResourcesContainer.addChild(new Text(noModelsStartupNotice, 1, 0));
|
|
1029
|
-
this.loadedResourcesContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
1030
|
-
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1031
|
-
}
|
|
1032
1237
|
const skillsResult = this.session.resourceLoader.getSkills();
|
|
1033
1238
|
const promptsResult = this.session.resourceLoader.getPrompts();
|
|
1034
1239
|
const themesResult = this.session.resourceLoader.getThemes();
|
|
@@ -1062,13 +1267,18 @@ export class InteractiveMode {
|
|
|
1062
1267
|
}
|
|
1063
1268
|
}
|
|
1064
1269
|
if (showListing) {
|
|
1065
|
-
const
|
|
1270
|
+
const systemPromptSource = this.session.resourceLoader.getSystemPromptSource();
|
|
1271
|
+
const contextFiles = [
|
|
1272
|
+
...(systemPromptSource ? [systemPromptSource] : []),
|
|
1273
|
+
...this.session.resourceLoader.getAppendSystemPromptSources(),
|
|
1274
|
+
...this.session.resourceLoader.getAgentsFiles().agentsFiles,
|
|
1275
|
+
];
|
|
1066
1276
|
if (contextFiles.length > 0) {
|
|
1067
1277
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1068
1278
|
const contextList = contextFiles
|
|
1069
1279
|
.map((f) => theme.fg("dim", ` ${this.formatDisplayPath(f.path)}`))
|
|
1070
1280
|
.join("\n");
|
|
1071
|
-
const contextCompactList =
|
|
1281
|
+
const contextCompactList = formatCompactList(contextFiles.map((contextFile) => this.formatContextPath(contextFile.path)), { sort: false });
|
|
1072
1282
|
addLoadedSection("Context", contextCompactList, contextList);
|
|
1073
1283
|
}
|
|
1074
1284
|
const skills = skillsResult.skills;
|
|
@@ -1078,7 +1288,7 @@ export class InteractiveMode {
|
|
|
1078
1288
|
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
1079
1289
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1080
1290
|
});
|
|
1081
|
-
const skillCompactList =
|
|
1291
|
+
const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
|
|
1082
1292
|
addLoadedSection("Skills", skillCompactList, skillList);
|
|
1083
1293
|
}
|
|
1084
1294
|
const templates = this.session.promptTemplates;
|
|
@@ -1095,7 +1305,7 @@ export class InteractiveMode {
|
|
|
1095
1305
|
return template ? `/${template.name}` : this.formatDisplayPath(item.path);
|
|
1096
1306
|
},
|
|
1097
1307
|
});
|
|
1098
|
-
const promptCompactList =
|
|
1308
|
+
const promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));
|
|
1099
1309
|
addLoadedSection("Prompts", promptCompactList, templateList);
|
|
1100
1310
|
}
|
|
1101
1311
|
if (extensions.length > 0) {
|
|
@@ -1104,7 +1314,7 @@ export class InteractiveMode {
|
|
|
1104
1314
|
formatPath: (item) => this.formatExtensionDisplayPath(item.path),
|
|
1105
1315
|
formatPackagePath: (item) => this.formatExtensionDisplayPath(this.getShortPath(item.path, item.sourceInfo)),
|
|
1106
1316
|
});
|
|
1107
|
-
const extensionCompactList =
|
|
1317
|
+
const extensionCompactList = formatCompactList(this.getCompactExtensionLabels(extensions));
|
|
1108
1318
|
addLoadedSection("Extensions", extensionCompactList, extList, "mdHeading");
|
|
1109
1319
|
}
|
|
1110
1320
|
// Show loaded themes (excluding built-in)
|
|
@@ -1119,7 +1329,7 @@ export class InteractiveMode {
|
|
|
1119
1329
|
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
1120
1330
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1121
1331
|
});
|
|
1122
|
-
const themeCompactList =
|
|
1332
|
+
const themeCompactList = formatCompactList(customThemes.map((loadedTheme) => loadedTheme.name ?? this.getCompactPathLabel(loadedTheme.sourcePath, loadedTheme.sourceInfo)));
|
|
1123
1333
|
addLoadedSection("Themes", themeCompactList, themeList);
|
|
1124
1334
|
}
|
|
1125
1335
|
}
|
|
@@ -1239,8 +1449,12 @@ export class InteractiveMode {
|
|
|
1239
1449
|
this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });
|
|
1240
1450
|
this.showStartupNoticesIfNeeded();
|
|
1241
1451
|
}
|
|
1452
|
+
applyFullscreenScrollbarSetting() {
|
|
1453
|
+
this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
|
|
1454
|
+
}
|
|
1242
1455
|
applyRuntimeSettings() {
|
|
1243
1456
|
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
1457
|
+
this.applyFullscreenScrollbarSetting();
|
|
1244
1458
|
this.footer.setSession(this.session);
|
|
1245
1459
|
this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
1246
1460
|
this.footerDataProvider.setCwd(this.sessionManager.getCwd());
|
|
@@ -1262,16 +1476,19 @@ export class InteractiveMode {
|
|
|
1262
1476
|
}
|
|
1263
1477
|
}
|
|
1264
1478
|
async rebindCurrentSession(options = {}) {
|
|
1479
|
+
const session = this.session;
|
|
1265
1480
|
this.unsubscribe?.();
|
|
1266
1481
|
this.unsubscribe = undefined;
|
|
1267
1482
|
this.applyRuntimeSettings();
|
|
1268
1483
|
if (options.renderBeforeBind) {
|
|
1269
1484
|
this.renderCurrentSessionState();
|
|
1270
1485
|
this.subscribeToAgent();
|
|
1271
|
-
await this.bindCurrentSessionExtensions();
|
|
1272
1486
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1487
|
+
await this.bindCurrentSessionExtensions();
|
|
1488
|
+
if (this.session !== session) {
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
if (!options.renderBeforeBind) {
|
|
1275
1492
|
this.subscribeToAgent();
|
|
1276
1493
|
}
|
|
1277
1494
|
await this.updateAvailableProviderCount();
|
|
@@ -1301,6 +1518,9 @@ export class InteractiveMode {
|
|
|
1301
1518
|
getRegisteredToolDefinition(toolName) {
|
|
1302
1519
|
return this.session.getToolDefinition(toolName);
|
|
1303
1520
|
}
|
|
1521
|
+
getMarkdownTransformers() {
|
|
1522
|
+
return [this.mermaidMarkdownTransformer, ...this.session.extensionRunner.getMarkdownTransformers()];
|
|
1523
|
+
}
|
|
1304
1524
|
/**
|
|
1305
1525
|
* Set up keyboard shortcuts registered by extensions.
|
|
1306
1526
|
*/
|
|
@@ -1317,6 +1537,7 @@ export class InteractiveMode {
|
|
|
1317
1537
|
sessionManager: this.sessionManager,
|
|
1318
1538
|
modelRegistry: extensionRunner.getModelRegistry(),
|
|
1319
1539
|
model: this.session.model,
|
|
1540
|
+
scopedModels: this.session.scopedModels,
|
|
1320
1541
|
thinkingLevel: this.session.thinkingLevel,
|
|
1321
1542
|
isIdle: () => this.session.isIdle,
|
|
1322
1543
|
isProjectTrusted: () => this.settingsManager.isProjectTrusted(),
|
|
@@ -1379,7 +1600,7 @@ export class InteractiveMode {
|
|
|
1379
1600
|
this.activeStatusIndicator?.dispose();
|
|
1380
1601
|
this.activeStatusIndicator = undefined;
|
|
1381
1602
|
this.statusContainer.clear();
|
|
1382
|
-
if (hadActiveStatusIndicator && this.ui.getClearOnShrink()) {
|
|
1603
|
+
if (hadActiveStatusIndicator && this.options.tuiMode === "regular" && this.ui.getClearOnShrink()) {
|
|
1383
1604
|
this.statusContainer.addChild(this.idleStatus);
|
|
1384
1605
|
}
|
|
1385
1606
|
}
|
|
@@ -1527,22 +1748,16 @@ export class InteractiveMode {
|
|
|
1527
1748
|
if (this.customFooter?.dispose) {
|
|
1528
1749
|
this.customFooter.dispose();
|
|
1529
1750
|
}
|
|
1530
|
-
|
|
1531
|
-
if (this.customFooter) {
|
|
1532
|
-
this.ui.removeChild(this.customFooter);
|
|
1533
|
-
}
|
|
1534
|
-
else {
|
|
1535
|
-
this.ui.removeChild(this.footer);
|
|
1536
|
-
}
|
|
1751
|
+
this.footerContainer.clear();
|
|
1537
1752
|
if (factory) {
|
|
1538
1753
|
// Create and add custom footer, passing the data provider
|
|
1539
1754
|
this.customFooter = factory(this.ui, theme, this.footerDataProvider);
|
|
1540
|
-
this.
|
|
1755
|
+
this.footerContainer.addChild(this.customFooter);
|
|
1541
1756
|
}
|
|
1542
1757
|
else {
|
|
1543
1758
|
// Restore built-in footer
|
|
1544
1759
|
this.customFooter = undefined;
|
|
1545
|
-
this.
|
|
1760
|
+
this.footerContainer.addChild(this.footer);
|
|
1546
1761
|
}
|
|
1547
1762
|
this.ui.requestRender();
|
|
1548
1763
|
}
|
|
@@ -1588,18 +1803,23 @@ export class InteractiveMode {
|
|
|
1588
1803
|
this.ui.requestRender();
|
|
1589
1804
|
}
|
|
1590
1805
|
addExtensionTerminalInputListener(handler) {
|
|
1591
|
-
const
|
|
1592
|
-
this.
|
|
1806
|
+
const subscription = { handler, unsubscribe: this.ui.addInputListener(handler) };
|
|
1807
|
+
this.extensionTerminalInputSubscriptions.add(subscription);
|
|
1593
1808
|
return () => {
|
|
1594
|
-
unsubscribe();
|
|
1595
|
-
this.
|
|
1809
|
+
subscription.unsubscribe();
|
|
1810
|
+
this.extensionTerminalInputSubscriptions.delete(subscription);
|
|
1596
1811
|
};
|
|
1597
1812
|
}
|
|
1598
|
-
|
|
1599
|
-
for (const
|
|
1600
|
-
unsubscribe();
|
|
1813
|
+
rebindExtensionTerminalInputListeners() {
|
|
1814
|
+
for (const subscription of this.extensionTerminalInputSubscriptions) {
|
|
1815
|
+
subscription.unsubscribe();
|
|
1816
|
+
subscription.unsubscribe = this.ui.addInputListener(subscription.handler);
|
|
1601
1817
|
}
|
|
1602
|
-
|
|
1818
|
+
}
|
|
1819
|
+
clearExtensionTerminalInputListeners() {
|
|
1820
|
+
for (const subscription of this.extensionTerminalInputSubscriptions)
|
|
1821
|
+
subscription.unsubscribe();
|
|
1822
|
+
this.extensionTerminalInputSubscriptions.clear();
|
|
1603
1823
|
}
|
|
1604
1824
|
/**
|
|
1605
1825
|
* Create the ExtensionUIContext for extensions.
|
|
@@ -1694,6 +1914,7 @@ export class InteractiveMode {
|
|
|
1694
1914
|
this.hideExtensionSelector();
|
|
1695
1915
|
resolve(undefined);
|
|
1696
1916
|
}, { tui: this.ui, timeout: opts?.timeout, onToggleToolsExpanded: () => this.toggleToolOutputExpansion() });
|
|
1917
|
+
this.disposeActiveSelector();
|
|
1697
1918
|
this.editorContainer.clear();
|
|
1698
1919
|
this.editorContainer.addChild(this.extensionSelector);
|
|
1699
1920
|
this.ui.setFocus(this.extensionSelector);
|
|
@@ -1745,6 +1966,7 @@ export class InteractiveMode {
|
|
|
1745
1966
|
this.hideExtensionInput();
|
|
1746
1967
|
resolve(undefined);
|
|
1747
1968
|
}, { tui: this.ui, timeout: opts?.timeout });
|
|
1969
|
+
this.disposeActiveSelector();
|
|
1748
1970
|
this.editorContainer.clear();
|
|
1749
1971
|
this.editorContainer.addChild(this.extensionInput);
|
|
1750
1972
|
this.ui.setFocus(this.extensionInput);
|
|
@@ -1774,6 +1996,7 @@ export class InteractiveMode {
|
|
|
1774
1996
|
this.hideExtensionEditor();
|
|
1775
1997
|
resolve(undefined);
|
|
1776
1998
|
}, undefined, this.settingsManager.getExternalEditorCommand());
|
|
1999
|
+
this.disposeActiveSelector();
|
|
1777
2000
|
this.editorContainer.clear();
|
|
1778
2001
|
this.editorContainer.addChild(this.extensionEditor);
|
|
1779
2002
|
this.ui.setFocus(this.extensionEditor);
|
|
@@ -1798,6 +2021,7 @@ export class InteractiveMode {
|
|
|
1798
2021
|
this.editorComponentFactory = factory;
|
|
1799
2022
|
// Save text from current editor before switching
|
|
1800
2023
|
const currentText = this.editor.getText();
|
|
2024
|
+
this.disposeActiveSelector();
|
|
1801
2025
|
this.editorContainer.clear();
|
|
1802
2026
|
if (factory) {
|
|
1803
2027
|
// Create the custom editor with tui, theme, and keybindings
|
|
@@ -1814,6 +2038,9 @@ export class InteractiveMode {
|
|
|
1814
2038
|
if (newEditor.setPaddingX !== undefined) {
|
|
1815
2039
|
newEditor.setPaddingX(this.defaultEditor.getPaddingX());
|
|
1816
2040
|
}
|
|
2041
|
+
if (newEditor.setAutocompleteMaxVisible !== undefined) {
|
|
2042
|
+
newEditor.setAutocompleteMaxVisible(this.defaultEditor.getAutocompleteMaxVisible());
|
|
2043
|
+
}
|
|
1817
2044
|
// Set autocomplete if supported
|
|
1818
2045
|
if (newEditor.setAutocompleteProvider && this.autocompleteProvider) {
|
|
1819
2046
|
newEditor.setAutocompleteProvider(this.autocompleteProvider);
|
|
@@ -1918,6 +2145,7 @@ export class InteractiveMode {
|
|
|
1918
2145
|
options?.onHandle?.(handle);
|
|
1919
2146
|
}
|
|
1920
2147
|
else {
|
|
2148
|
+
this.disposeActiveSelector();
|
|
1921
2149
|
this.editorContainer.clear();
|
|
1922
2150
|
this.editorContainer.addChild(component);
|
|
1923
2151
|
this.ui.setFocus(component);
|
|
@@ -2004,7 +2232,7 @@ export class InteractiveMode {
|
|
|
2004
2232
|
this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
|
|
2005
2233
|
this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
|
|
2006
2234
|
this.defaultEditor.onAction("app.editor.external", () => void this.handleOpenExternalEditor());
|
|
2007
|
-
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand());
|
|
2235
|
+
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true }));
|
|
2008
2236
|
this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
|
|
2009
2237
|
this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
|
|
2010
2238
|
this.defaultEditor.onAction("app.session.new", () => this.handleClearCommand());
|
|
@@ -2024,13 +2252,29 @@ export class InteractiveMode {
|
|
|
2024
2252
|
void this.handleClipboardPaste();
|
|
2025
2253
|
};
|
|
2026
2254
|
}
|
|
2255
|
+
async handleRightClickPaste() {
|
|
2256
|
+
const target = this.renderer.getFocusedComponent();
|
|
2257
|
+
const handleInput = target?.handleInput;
|
|
2258
|
+
if (!target || !handleInput)
|
|
2259
|
+
return;
|
|
2260
|
+
try {
|
|
2261
|
+
const text = await readClipboardText();
|
|
2262
|
+
if (!text || this.renderer.getFocusedComponent() !== target)
|
|
2263
|
+
return;
|
|
2264
|
+
handleInput.call(target, `\x1b[200~${text}\x1b[201~`);
|
|
2265
|
+
this.ui.requestRender();
|
|
2266
|
+
}
|
|
2267
|
+
catch {
|
|
2268
|
+
// Silently ignore clipboard errors (may not have permission, etc.)
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2027
2271
|
async handleClipboardPaste() {
|
|
2028
2272
|
try {
|
|
2029
2273
|
const image = await readClipboardImage();
|
|
2030
2274
|
if (image) {
|
|
2031
2275
|
const tmpDir = os.tmpdir();
|
|
2032
2276
|
const ext = extensionForImageMimeType(image.mimeType) ?? "png";
|
|
2033
|
-
const fileName = `
|
|
2277
|
+
const fileName = `pi-clipboard-${crypto.randomUUID()}.${ext}`;
|
|
2034
2278
|
const filePath = path.join(tmpDir, fileName);
|
|
2035
2279
|
fs.writeFileSync(filePath, Buffer.from(image.bytes));
|
|
2036
2280
|
this.editor.insertTextAtCursor?.(filePath);
|
|
@@ -2166,6 +2410,11 @@ export class InteractiveMode {
|
|
|
2166
2410
|
this.editor.setText("");
|
|
2167
2411
|
return;
|
|
2168
2412
|
}
|
|
2413
|
+
if (text === "/dementedelves") {
|
|
2414
|
+
this.handleDementedDelves();
|
|
2415
|
+
this.editor.setText("");
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2169
2418
|
if (text === "/resume") {
|
|
2170
2419
|
this.showSessionSelector();
|
|
2171
2420
|
this.editor.setText("");
|
|
@@ -2287,17 +2536,17 @@ export class InteractiveMode {
|
|
|
2287
2536
|
this.ui.requestRender();
|
|
2288
2537
|
}
|
|
2289
2538
|
else if (event.message.role === "assistant") {
|
|
2290
|
-
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad);
|
|
2539
|
+
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
2291
2540
|
this.streamingMessage = event.message;
|
|
2292
2541
|
this.chatContainer.addChild(this.streamingComponent);
|
|
2293
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2542
|
+
this.streamingComponent.updateContent(this.streamingMessage, true);
|
|
2294
2543
|
this.ui.requestRender();
|
|
2295
2544
|
}
|
|
2296
2545
|
break;
|
|
2297
2546
|
case "message_update":
|
|
2298
2547
|
if (this.streamingComponent && event.message.role === "assistant") {
|
|
2299
2548
|
this.streamingMessage = event.message;
|
|
2300
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2549
|
+
this.streamingComponent.updateContent(this.streamingMessage, true);
|
|
2301
2550
|
for (const content of this.streamingMessage.content) {
|
|
2302
2551
|
if (content.type === "toolCall") {
|
|
2303
2552
|
if (!this.pendingTools.has(content.id)) {
|
|
@@ -2334,7 +2583,7 @@ export class InteractiveMode {
|
|
|
2334
2583
|
: "Operation aborted";
|
|
2335
2584
|
this.streamingMessage.errorMessage = errorMessage;
|
|
2336
2585
|
}
|
|
2337
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2586
|
+
this.streamingComponent.updateContent(this.streamingMessage, false);
|
|
2338
2587
|
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
|
2339
2588
|
if (!errorMessage) {
|
|
2340
2589
|
errorMessage = this.streamingMessage.errorMessage || "Error";
|
|
@@ -2608,12 +2857,12 @@ export class InteractiveMode {
|
|
|
2608
2857
|
// Render user message separately if present
|
|
2609
2858
|
if (skillBlock.userMessage) {
|
|
2610
2859
|
this.chatContainer.addChild(new Spacer(1));
|
|
2611
|
-
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
2860
|
+
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad, this.getMarkdownTransformers());
|
|
2612
2861
|
this.chatContainer.addChild(userComponent);
|
|
2613
2862
|
}
|
|
2614
2863
|
}
|
|
2615
2864
|
else {
|
|
2616
|
-
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
2865
|
+
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad, this.getMarkdownTransformers());
|
|
2617
2866
|
this.chatContainer.addChild(userComponent);
|
|
2618
2867
|
}
|
|
2619
2868
|
if (options?.populateHistory) {
|
|
@@ -2623,7 +2872,7 @@ export class InteractiveMode {
|
|
|
2623
2872
|
break;
|
|
2624
2873
|
}
|
|
2625
2874
|
case "assistant": {
|
|
2626
|
-
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad);
|
|
2875
|
+
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
2627
2876
|
this.chatContainer.addChild(assistantComponent);
|
|
2628
2877
|
break;
|
|
2629
2878
|
}
|
|
@@ -2775,7 +3024,7 @@ export class InteractiveMode {
|
|
|
2775
3024
|
if (this.chatContainer.children.length > 0) {
|
|
2776
3025
|
this.chatContainer.addChild(new Spacer(1));
|
|
2777
3026
|
}
|
|
2778
|
-
this.chatContainer.addChild(new Text(theme.fg("warning", `This project is not trusted. Project ${CONFIG_DIR_NAME} resources and packages are ignored. Use /trust to save a trust decision, then restart
|
|
3027
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `This project is not trusted. Project ${CONFIG_DIR_NAME} resources and packages are ignored. Use /trust to save a trust decision, then restart pi.`), 1, 0));
|
|
2779
3028
|
}
|
|
2780
3029
|
async getUserInput() {
|
|
2781
3030
|
const queuedInput = this.pendingUserInputs.shift();
|
|
@@ -2888,7 +3137,7 @@ export class InteractiveMode {
|
|
|
2888
3137
|
this.ui.stop();
|
|
2889
3138
|
}
|
|
2890
3139
|
catch { }
|
|
2891
|
-
console.error(
|
|
3140
|
+
console.error("pi exiting due to uncaughtException:");
|
|
2892
3141
|
console.error(error);
|
|
2893
3142
|
process.exit(1);
|
|
2894
3143
|
}
|
|
@@ -2930,7 +3179,7 @@ export class InteractiveMode {
|
|
|
2930
3179
|
this.signalCleanupHandlers.push(() => process.stderr.off("error", terminalErrorHandler));
|
|
2931
3180
|
// Restore the terminal before the process dies on any uncaught throw.
|
|
2932
3181
|
// Without this, an unhandled exception from extension code (or anywhere
|
|
2933
|
-
// in
|
|
3182
|
+
// in pi) leaves the terminal in raw mode with no cursor.
|
|
2934
3183
|
const uncaughtExceptionHandler = (error) => this.uncaughtCrash(error);
|
|
2935
3184
|
process.prependListener("uncaughtException", uncaughtExceptionHandler);
|
|
2936
3185
|
this.signalCleanupHandlers.push(() => process.off("uncaughtException", uncaughtExceptionHandler));
|
|
@@ -3057,6 +3306,8 @@ export class InteractiveMode {
|
|
|
3057
3306
|
this.setToolsExpanded(!this.toolOutputExpanded);
|
|
3058
3307
|
}
|
|
3059
3308
|
setToolsExpanded(expanded) {
|
|
3309
|
+
if (expanded === this.toolOutputExpanded)
|
|
3310
|
+
return;
|
|
3060
3311
|
this.toolOutputExpanded = expanded;
|
|
3061
3312
|
const activeHeader = this.customHeader ?? this.builtInHeader;
|
|
3062
3313
|
if (isExpandable(activeHeader)) {
|
|
@@ -3069,7 +3320,7 @@ export class InteractiveMode {
|
|
|
3069
3320
|
}
|
|
3070
3321
|
}
|
|
3071
3322
|
}
|
|
3072
|
-
this.
|
|
3323
|
+
this.showStatus(`Tool output: ${expanded ? "expanded" : "collapsed"}`);
|
|
3073
3324
|
}
|
|
3074
3325
|
toggleThinkingBlockVisibility() {
|
|
3075
3326
|
this.hideThinkingBlock = !this.hideThinkingBlock;
|
|
@@ -3112,7 +3363,7 @@ export class InteractiveMode {
|
|
|
3112
3363
|
}
|
|
3113
3364
|
showError(errorMessage) {
|
|
3114
3365
|
this.chatContainer.addChild(new Spacer(1));
|
|
3115
|
-
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`),
|
|
3366
|
+
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`), this.outputPad, 0));
|
|
3116
3367
|
this.ui.requestRender();
|
|
3117
3368
|
}
|
|
3118
3369
|
showWarning(warningMessage) {
|
|
@@ -3123,7 +3374,7 @@ export class InteractiveMode {
|
|
|
3123
3374
|
showNewVersionNotification(release) {
|
|
3124
3375
|
const action = theme.fg("accent", `${APP_NAME} update`);
|
|
3125
3376
|
const updateInstruction = theme.fg("muted", `New version ${release.version} is available. Run `) + action;
|
|
3126
|
-
const changelogUrl =
|
|
3377
|
+
const changelogUrl = "https://pi.dev/changelog";
|
|
3127
3378
|
const changelogLink = getCapabilities().hyperlinks
|
|
3128
3379
|
? hyperlink(theme.fg("accent", changelogUrl), changelogUrl)
|
|
3129
3380
|
: theme.fg("accent", changelogUrl);
|
|
@@ -3322,25 +3573,43 @@ export class InteractiveMode {
|
|
|
3322
3573
|
// =========================================================================
|
|
3323
3574
|
// Selectors
|
|
3324
3575
|
// =========================================================================
|
|
3576
|
+
disposeActiveSelector() {
|
|
3577
|
+
const dispose = this.activeSelectorDispose;
|
|
3578
|
+
this.activeSelectorToken = undefined;
|
|
3579
|
+
this.activeSelectorDispose = undefined;
|
|
3580
|
+
dispose?.();
|
|
3581
|
+
}
|
|
3325
3582
|
/**
|
|
3326
3583
|
* Shows a selector component in place of the editor.
|
|
3327
3584
|
* @param create Factory that receives a `done` callback and returns the component and focus target
|
|
3328
3585
|
*/
|
|
3329
3586
|
showSelector(create) {
|
|
3587
|
+
const token = {};
|
|
3588
|
+
let dispose;
|
|
3330
3589
|
const done = () => {
|
|
3590
|
+
dispose?.();
|
|
3591
|
+
if (this.activeSelectorToken !== token)
|
|
3592
|
+
return;
|
|
3593
|
+
this.activeSelectorToken = undefined;
|
|
3594
|
+
this.activeSelectorDispose = undefined;
|
|
3331
3595
|
this.editorContainer.clear();
|
|
3332
3596
|
this.editorContainer.addChild(this.editor);
|
|
3333
3597
|
this.ui.setFocus(this.editor);
|
|
3334
3598
|
};
|
|
3335
|
-
const
|
|
3599
|
+
const created = create(done);
|
|
3600
|
+
dispose = created.dispose;
|
|
3601
|
+
this.disposeActiveSelector();
|
|
3602
|
+
this.activeSelectorToken = token;
|
|
3603
|
+
this.activeSelectorDispose = dispose;
|
|
3336
3604
|
this.editorContainer.clear();
|
|
3337
|
-
this.editorContainer.addChild(component);
|
|
3338
|
-
this.ui.setFocus(focus);
|
|
3605
|
+
this.editorContainer.addChild(created.component);
|
|
3606
|
+
this.ui.setFocus(created.focus);
|
|
3339
3607
|
this.ui.requestRender();
|
|
3340
3608
|
}
|
|
3341
3609
|
showSettingsSelector() {
|
|
3342
3610
|
this.showSelector((done) => {
|
|
3343
|
-
|
|
3611
|
+
let selector;
|
|
3612
|
+
selector = new SettingsSelectorComponent({
|
|
3344
3613
|
autoCompact: this.session.autoCompactionEnabled,
|
|
3345
3614
|
showImages: this.settingsManager.getShowImages(),
|
|
3346
3615
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
@@ -3357,6 +3626,7 @@ export class InteractiveMode {
|
|
|
3357
3626
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3358
3627
|
availableThemes: getAvailableThemes(),
|
|
3359
3628
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
3629
|
+
mermaidRenderingMode: this.settingsManager.getMermaidRenderingMode(),
|
|
3360
3630
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
3361
3631
|
enableInstallTelemetry: this.settingsManager.getEnableInstallTelemetry(),
|
|
3362
3632
|
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
@@ -3370,6 +3640,8 @@ export class InteractiveMode {
|
|
|
3370
3640
|
quietStartup: this.settingsManager.getQuietStartup(),
|
|
3371
3641
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
3372
3642
|
showTerminalProgress: this.settingsManager.getShowTerminalProgress(),
|
|
3643
|
+
tuiMode: this.ui.mode,
|
|
3644
|
+
fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
3373
3645
|
warnings: this.settingsManager.getWarnings(),
|
|
3374
3646
|
}, {
|
|
3375
3647
|
onAutoCompactChange: (enabled) => {
|
|
@@ -3438,6 +3710,11 @@ export class InteractiveMode {
|
|
|
3438
3710
|
this.chatContainer.clear();
|
|
3439
3711
|
this.rebuildChatFromMessages();
|
|
3440
3712
|
},
|
|
3713
|
+
onMermaidRenderingModeChange: (mode) => {
|
|
3714
|
+
this.settingsManager.setMermaidRenderingMode(mode);
|
|
3715
|
+
this.chatContainer.invalidate();
|
|
3716
|
+
this.ui.requestRender();
|
|
3717
|
+
},
|
|
3441
3718
|
onShowCacheMissNoticesChange: (shown) => {
|
|
3442
3719
|
this.settingsManager.setShowCacheMissNotices(shown);
|
|
3443
3720
|
this.rebuildChatFromMessages();
|
|
@@ -3507,6 +3784,21 @@ export class InteractiveMode {
|
|
|
3507
3784
|
onShowTerminalProgressChange: (enabled) => {
|
|
3508
3785
|
this.settingsManager.setShowTerminalProgress(enabled);
|
|
3509
3786
|
},
|
|
3787
|
+
onTuiModeChange: (mode) => {
|
|
3788
|
+
if (!this.switchTuiMode(mode)) {
|
|
3789
|
+
selector?.getSettingsList().updateValue("tui-mode", this.ui.mode);
|
|
3790
|
+
this.showStatus("Close active overlays before changing TUI mode");
|
|
3791
|
+
return;
|
|
3792
|
+
}
|
|
3793
|
+
this.settingsManager.setTuiMode(mode);
|
|
3794
|
+
if (!this.activeStatusIndicator)
|
|
3795
|
+
this.statusContainer.clear();
|
|
3796
|
+
this.showStatus(`TUI mode: ${mode}`);
|
|
3797
|
+
},
|
|
3798
|
+
onFullscreenScrollbarChange: (mode) => {
|
|
3799
|
+
this.settingsManager.setFullscreenScrollbar(mode);
|
|
3800
|
+
this.applyFullscreenScrollbarSetting();
|
|
3801
|
+
},
|
|
3510
3802
|
onWarningsChange: (warnings) => {
|
|
3511
3803
|
this.settingsManager.setWarnings(warnings);
|
|
3512
3804
|
},
|
|
@@ -3541,20 +3833,37 @@ export class InteractiveMode {
|
|
|
3541
3833
|
this.showModelSelector(searchTerm);
|
|
3542
3834
|
}
|
|
3543
3835
|
async findExactModelMatch(searchTerm) {
|
|
3544
|
-
const
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
if (this.session.scopedModels.length > 0)
|
|
3549
|
-
return
|
|
3550
|
-
|
|
3836
|
+
const cachedModels = this.session.scopedModels.length > 0
|
|
3837
|
+
? this.session.scopedModels.map((scoped) => scoped.model)
|
|
3838
|
+
: [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
3839
|
+
const cachedMatch = findExactModelReferenceMatch(searchTerm, cachedModels);
|
|
3840
|
+
if (cachedMatch || this.session.scopedModels.length > 0)
|
|
3841
|
+
return cachedMatch;
|
|
3842
|
+
this.showStatus("Refreshing model catalogs…");
|
|
3843
|
+
const controller = new AbortController();
|
|
3844
|
+
let timedOut = false;
|
|
3845
|
+
const timeout = setTimeout(() => {
|
|
3846
|
+
timedOut = true;
|
|
3847
|
+
controller.abort();
|
|
3848
|
+
}, 15_000);
|
|
3551
3849
|
try {
|
|
3552
|
-
await this.session.modelRuntime.refresh();
|
|
3553
|
-
|
|
3850
|
+
const result = await this.session.modelRuntime.refresh({ signal: controller.signal });
|
|
3851
|
+
if (result.aborted && timedOut) {
|
|
3852
|
+
this.showWarning("Model refresh timed out; searching cached models.");
|
|
3853
|
+
}
|
|
3854
|
+
else if (result.errors.size > 0) {
|
|
3855
|
+
this.showWarning(`Could not refresh ${[...result.errors.keys()].join(", ")}; searching cached models.`);
|
|
3856
|
+
}
|
|
3554
3857
|
}
|
|
3555
|
-
catch {
|
|
3556
|
-
|
|
3858
|
+
catch (error) {
|
|
3859
|
+
this.showWarning(timedOut
|
|
3860
|
+
? "Model refresh timed out; searching cached models."
|
|
3861
|
+
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`);
|
|
3862
|
+
}
|
|
3863
|
+
finally {
|
|
3864
|
+
clearTimeout(timeout);
|
|
3557
3865
|
}
|
|
3866
|
+
return findExactModelReferenceMatch(searchTerm, [...this.session.modelRuntime.getAvailableSnapshot()]);
|
|
3558
3867
|
}
|
|
3559
3868
|
/** Update the footer's available provider count from the current snapshot without refreshing catalogs. */
|
|
3560
3869
|
updateAvailableProviderCount() {
|
|
@@ -3626,7 +3935,7 @@ export class InteractiveMode {
|
|
|
3626
3935
|
onSelect: (selection) => {
|
|
3627
3936
|
trustStore.setMany(selection.updates);
|
|
3628
3937
|
done();
|
|
3629
|
-
this.showStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart
|
|
3938
|
+
this.showStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart pi for this to take effect.`);
|
|
3630
3939
|
},
|
|
3631
3940
|
onCancel: () => {
|
|
3632
3941
|
done();
|
|
@@ -3656,73 +3965,67 @@ export class InteractiveMode {
|
|
|
3656
3965
|
done();
|
|
3657
3966
|
this.ui.requestRender();
|
|
3658
3967
|
}, initialSearchInput);
|
|
3659
|
-
return { component: selector, focus: selector };
|
|
3968
|
+
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
3660
3969
|
});
|
|
3661
3970
|
}
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
const allModels = [...(await this.session.modelRuntime.getAvailable())];
|
|
3666
|
-
const allModelIds = new Set(allModels.map((model) => `${model.provider}/${model.id}`));
|
|
3971
|
+
showModelsSelector() {
|
|
3972
|
+
let availableModels = [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
3973
|
+
let availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));
|
|
3667
3974
|
const configuredPatterns = this.settingsManager.getEnabledModels();
|
|
3668
3975
|
const sessionScopedModels = this.session.scopedModels;
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
currentEnabledIds = configuredScope.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);
|
|
3686
|
-
}
|
|
3687
|
-
for (const diagnostic of configuredScope?.diagnostics ?? []) {
|
|
3688
|
-
if (diagnostic.code !== "no-match")
|
|
3689
|
-
continue;
|
|
3690
|
-
currentEnabledIds ??= [];
|
|
3691
|
-
if (!currentEnabledIds.includes(diagnostic.pattern))
|
|
3692
|
-
currentEnabledIds.push(diagnostic.pattern);
|
|
3693
|
-
}
|
|
3694
|
-
// Helper to update session's scoped models (session-only, no persist)
|
|
3695
|
-
const updateSessionModels = async (enabledIds) => {
|
|
3976
|
+
const configuredEnabledIds = (models) => {
|
|
3977
|
+
if (!configuredPatterns?.length)
|
|
3978
|
+
return null;
|
|
3979
|
+
const resolved = resolveModelScopeFromModels(configuredPatterns, models);
|
|
3980
|
+
const ids = resolved.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);
|
|
3981
|
+
for (const diagnostic of resolved.diagnostics) {
|
|
3982
|
+
if (diagnostic.code === "no-match" && !ids.includes(diagnostic.pattern))
|
|
3983
|
+
ids.push(diagnostic.pattern);
|
|
3984
|
+
}
|
|
3985
|
+
return ids;
|
|
3986
|
+
};
|
|
3987
|
+
let currentEnabledIds = sessionScopedModels.length > 0
|
|
3988
|
+
? sessionScopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`)
|
|
3989
|
+
: configuredEnabledIds(availableModels);
|
|
3990
|
+
let selectionChanged = false;
|
|
3991
|
+
const updateSessionModels = (enabledIds) => {
|
|
3696
3992
|
currentEnabledIds = enabledIds === null ? null : [...enabledIds];
|
|
3697
|
-
const hasEnabledAvailableModel = enabledIds?.some((id) =>
|
|
3698
|
-
const allAvailableModelsEnabled = enabledIds !== null && [...
|
|
3993
|
+
const hasEnabledAvailableModel = enabledIds?.some((id) => availableModelIds.has(id)) ?? false;
|
|
3994
|
+
const allAvailableModelsEnabled = enabledIds !== null && [...availableModelIds].every((id) => enabledIds.includes(id));
|
|
3699
3995
|
if (enabledIds && hasEnabledAvailableModel && !allAvailableModelsEnabled) {
|
|
3700
|
-
const newScopedModels =
|
|
3701
|
-
this.session.setScopedModels(newScopedModels.map((
|
|
3702
|
-
model:
|
|
3703
|
-
thinkingLevel:
|
|
3996
|
+
const newScopedModels = resolveModelScopeFromModels(enabledIds, availableModels).scopedModels;
|
|
3997
|
+
this.session.setScopedModels(newScopedModels.map((scoped) => ({
|
|
3998
|
+
model: scoped.model,
|
|
3999
|
+
thinkingLevel: scoped.thinkingLevel,
|
|
3704
4000
|
})));
|
|
3705
4001
|
}
|
|
3706
4002
|
else {
|
|
3707
|
-
// All enabled or none enabled = no filter
|
|
3708
4003
|
this.session.setScopedModels([]);
|
|
3709
4004
|
}
|
|
3710
|
-
|
|
4005
|
+
this.updateAvailableProviderCount();
|
|
3711
4006
|
this.ui.requestRender();
|
|
3712
4007
|
};
|
|
3713
4008
|
this.showSelector((done) => {
|
|
4009
|
+
let disposed = false;
|
|
4010
|
+
let timedOut = false;
|
|
4011
|
+
const controller = new AbortController();
|
|
4012
|
+
const timeout = setTimeout(() => {
|
|
4013
|
+
timedOut = true;
|
|
4014
|
+
controller.abort();
|
|
4015
|
+
}, 15_000);
|
|
3714
4016
|
const selector = new ScopedModelsSelectorComponent({
|
|
3715
|
-
allModels,
|
|
4017
|
+
allModels: availableModels,
|
|
3716
4018
|
enabledModelIds: currentEnabledIds,
|
|
4019
|
+
refreshStatus: "Refreshing model catalogs…",
|
|
3717
4020
|
}, {
|
|
3718
|
-
onChange:
|
|
3719
|
-
|
|
4021
|
+
onChange: (enabledIds) => {
|
|
4022
|
+
selectionChanged = true;
|
|
4023
|
+
updateSessionModels(enabledIds);
|
|
3720
4024
|
},
|
|
3721
4025
|
onPersist: (enabledIds) => {
|
|
3722
|
-
// Persist to settings
|
|
3723
4026
|
const allEnabled = enabledIds !== null &&
|
|
3724
|
-
enabledIds.length ===
|
|
3725
|
-
enabledIds.every((id) =>
|
|
4027
|
+
enabledIds.length === availableModels.length &&
|
|
4028
|
+
enabledIds.every((id) => availableModelIds.has(id));
|
|
3726
4029
|
const newPatterns = enabledIds === null || allEnabled ? undefined : enabledIds;
|
|
3727
4030
|
this.settingsManager.setEnabledModels(newPatterns ? [...newPatterns] : undefined);
|
|
3728
4031
|
this.showStatus("Model selection saved to settings");
|
|
@@ -3732,7 +4035,51 @@ export class InteractiveMode {
|
|
|
3732
4035
|
this.ui.requestRender();
|
|
3733
4036
|
},
|
|
3734
4037
|
});
|
|
3735
|
-
|
|
4038
|
+
void this.session.modelRuntime
|
|
4039
|
+
.refresh({ signal: controller.signal })
|
|
4040
|
+
.then((result) => {
|
|
4041
|
+
if (disposed)
|
|
4042
|
+
return;
|
|
4043
|
+
availableModels = [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
4044
|
+
availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));
|
|
4045
|
+
if (!selectionChanged && sessionScopedModels.length === 0) {
|
|
4046
|
+
currentEnabledIds = configuredEnabledIds(availableModels);
|
|
4047
|
+
selector.updateModels(availableModels, currentEnabledIds);
|
|
4048
|
+
}
|
|
4049
|
+
else {
|
|
4050
|
+
selector.updateModels(availableModels);
|
|
4051
|
+
}
|
|
4052
|
+
if (currentEnabledIds !== null)
|
|
4053
|
+
updateSessionModels(currentEnabledIds);
|
|
4054
|
+
if (result.aborted && timedOut) {
|
|
4055
|
+
selector.setRefreshStatus("Model refresh timed out; showing cached models.", "warning");
|
|
4056
|
+
}
|
|
4057
|
+
else if (result.errors.size > 0) {
|
|
4058
|
+
selector.setRefreshStatus(`Could not refresh ${[...result.errors.keys()].join(", ")}; showing cached models.`, "warning");
|
|
4059
|
+
}
|
|
4060
|
+
else {
|
|
4061
|
+
selector.setRefreshStatus("Model catalogs refreshed.", "success");
|
|
4062
|
+
}
|
|
4063
|
+
this.ui.requestRender();
|
|
4064
|
+
})
|
|
4065
|
+
.catch((error) => {
|
|
4066
|
+
if (disposed)
|
|
4067
|
+
return;
|
|
4068
|
+
selector.setRefreshStatus(timedOut
|
|
4069
|
+
? "Model refresh timed out; showing cached models."
|
|
4070
|
+
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
4071
|
+
this.ui.requestRender();
|
|
4072
|
+
})
|
|
4073
|
+
.finally(() => clearTimeout(timeout));
|
|
4074
|
+
return {
|
|
4075
|
+
component: selector,
|
|
4076
|
+
focus: selector,
|
|
4077
|
+
dispose: () => {
|
|
4078
|
+
disposed = true;
|
|
4079
|
+
clearTimeout(timeout);
|
|
4080
|
+
controller.abort();
|
|
4081
|
+
},
|
|
4082
|
+
};
|
|
3736
4083
|
});
|
|
3737
4084
|
}
|
|
3738
4085
|
showUserMessageSelector() {
|
|
@@ -3794,7 +4141,7 @@ export class InteractiveMode {
|
|
|
3794
4141
|
this.showSelector((done) => {
|
|
3795
4142
|
const selector = new TreeSelectorComponent(tree, realLeafId, this.ui.terminal.rows, async (entryId) => {
|
|
3796
4143
|
// Selecting the current leaf is a no-op (already there)
|
|
3797
|
-
if (entryId ===
|
|
4144
|
+
if (entryId === this.sessionManager.getLeafId()) {
|
|
3798
4145
|
done();
|
|
3799
4146
|
this.showStatus("Already at this point");
|
|
3800
4147
|
return;
|
|
@@ -3829,6 +4176,11 @@ export class InteractiveMode {
|
|
|
3829
4176
|
break;
|
|
3830
4177
|
}
|
|
3831
4178
|
}
|
|
4179
|
+
// The user committed to navigating: stop the active response first.
|
|
4180
|
+
if (this.session.isStreaming) {
|
|
4181
|
+
this.restoreQueuedMessagesToEditor();
|
|
4182
|
+
await this.session.abort();
|
|
4183
|
+
}
|
|
3832
4184
|
// Set up escape handler and status indicator if summarizing
|
|
3833
4185
|
let showingSummaryIndicator = false;
|
|
3834
4186
|
const originalOnEscape = this.defaultEditor.onEscape;
|
|
@@ -3989,7 +4341,7 @@ export class InteractiveMode {
|
|
|
3989
4341
|
return options.sort((a, b) => a.name.localeCompare(b.name));
|
|
3990
4342
|
}
|
|
3991
4343
|
async getLogoutProviderOptions() {
|
|
3992
|
-
return (await this.session.modelRuntime.listCredentials())
|
|
4344
|
+
return (await this.session.modelRuntime.listCredentials({ signal: AbortSignal.timeout(15_000) }))
|
|
3993
4345
|
.map(({ providerId, type }) => ({
|
|
3994
4346
|
id: providerId,
|
|
3995
4347
|
name: this.session.modelRuntime.getProvider(providerId)?.name ?? providerId,
|
|
@@ -4007,7 +4359,6 @@ export class InteractiveMode {
|
|
|
4007
4359
|
provider.name.toLowerCase() === normalizedProviderRef);
|
|
4008
4360
|
}
|
|
4009
4361
|
async handleLoginCommand(providerRef) {
|
|
4010
|
-
await this.session.modelRuntime.getAvailable();
|
|
4011
4362
|
if (!providerRef) {
|
|
4012
4363
|
this.showLoginAuthTypeSelector();
|
|
4013
4364
|
return;
|
|
@@ -4121,7 +4472,14 @@ export class InteractiveMode {
|
|
|
4121
4472
|
this.showLoginAuthTypeSelector();
|
|
4122
4473
|
return;
|
|
4123
4474
|
}
|
|
4124
|
-
|
|
4475
|
+
let providerOptions;
|
|
4476
|
+
try {
|
|
4477
|
+
providerOptions = await this.getLogoutProviderOptions();
|
|
4478
|
+
}
|
|
4479
|
+
catch (error) {
|
|
4480
|
+
this.showError(`Could not read stored credentials: ${error instanceof Error ? error.message : String(error)}`);
|
|
4481
|
+
return;
|
|
4482
|
+
}
|
|
4125
4483
|
if (providerOptions.length === 0) {
|
|
4126
4484
|
this.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");
|
|
4127
4485
|
return;
|
|
@@ -4134,7 +4492,9 @@ export class InteractiveMode {
|
|
|
4134
4492
|
return;
|
|
4135
4493
|
}
|
|
4136
4494
|
try {
|
|
4137
|
-
await this.session.modelRuntime.logout(providerOption.id
|
|
4495
|
+
await this.session.modelRuntime.logout(providerOption.id, {
|
|
4496
|
+
signal: AbortSignal.timeout(15_000),
|
|
4497
|
+
});
|
|
4138
4498
|
await this.updateAvailableProviderCount();
|
|
4139
4499
|
const message = providerOption.authType === "oauth"
|
|
4140
4500
|
? `Logged out of ${providerOption.name}`
|
|
@@ -4142,7 +4502,10 @@ export class InteractiveMode {
|
|
|
4142
4502
|
this.showStatus(message);
|
|
4143
4503
|
}
|
|
4144
4504
|
catch (error) {
|
|
4145
|
-
|
|
4505
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4506
|
+
this.showError(error instanceof CredentialSynchronizationError
|
|
4507
|
+
? `Credentials removed for ${providerOption.name}, but local model state could not be synchronized: ${message}`
|
|
4508
|
+
: `Logout failed: ${message}`);
|
|
4146
4509
|
}
|
|
4147
4510
|
}, () => {
|
|
4148
4511
|
done();
|
|
@@ -4152,12 +4515,11 @@ export class InteractiveMode {
|
|
|
4152
4515
|
});
|
|
4153
4516
|
}
|
|
4154
4517
|
async completeProviderAuthentication(providerId, providerName, authType, previousModel) {
|
|
4155
|
-
await this.session.modelRuntime.getAvailable();
|
|
4156
4518
|
const actionLabel = authType === "oauth" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;
|
|
4157
4519
|
let selectedModel;
|
|
4158
4520
|
let selectionError;
|
|
4159
4521
|
if (isUnknownModel(previousModel)) {
|
|
4160
|
-
const availableModels =
|
|
4522
|
+
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4161
4523
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4162
4524
|
if (!hasDefaultModelProvider(providerId)) {
|
|
4163
4525
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
@@ -4200,6 +4562,25 @@ export class InteractiveMode {
|
|
|
4200
4562
|
void this.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
4201
4563
|
}
|
|
4202
4564
|
}
|
|
4565
|
+
const controller = new AbortController();
|
|
4566
|
+
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
4567
|
+
void this.session.modelRuntime
|
|
4568
|
+
.refresh({ providers: [providerId], signal: controller.signal })
|
|
4569
|
+
.then((result) => {
|
|
4570
|
+
if (result.aborted) {
|
|
4571
|
+
this.showWarning(`${actionLabel}, but its model catalog refresh timed out; using cached models.`);
|
|
4572
|
+
}
|
|
4573
|
+
else if (result.errors.size > 0) {
|
|
4574
|
+
this.showWarning(`${actionLabel}, but its model catalog could not be refreshed; using cached models.`);
|
|
4575
|
+
}
|
|
4576
|
+
this.updateAvailableProviderCount();
|
|
4577
|
+
this.footer.invalidate();
|
|
4578
|
+
this.ui.requestRender();
|
|
4579
|
+
})
|
|
4580
|
+
.catch((error) => {
|
|
4581
|
+
this.showWarning(`${actionLabel}, but its model catalog could not be refreshed: ${error instanceof Error ? error.message : String(error)}`);
|
|
4582
|
+
})
|
|
4583
|
+
.finally(() => clearTimeout(timeout));
|
|
4203
4584
|
}
|
|
4204
4585
|
showAmbientAuthDialog(providerOption) {
|
|
4205
4586
|
const restoreEditor = () => {
|
|
@@ -4245,7 +4626,10 @@ export class InteractiveMode {
|
|
|
4245
4626
|
catch (error) {
|
|
4246
4627
|
restoreEditor();
|
|
4247
4628
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4248
|
-
if (
|
|
4629
|
+
if (error instanceof CredentialSynchronizationError) {
|
|
4630
|
+
this.showError(`Saved API key for ${providerName}, but local model state could not be synchronized: ${errorMsg}`);
|
|
4631
|
+
}
|
|
4632
|
+
else if (errorMsg !== "Login cancelled") {
|
|
4249
4633
|
this.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);
|
|
4250
4634
|
}
|
|
4251
4635
|
}
|
|
@@ -4348,7 +4732,10 @@ export class InteractiveMode {
|
|
|
4348
4732
|
catch (error) {
|
|
4349
4733
|
restoreEditor();
|
|
4350
4734
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4351
|
-
if (
|
|
4735
|
+
if (error instanceof CredentialSynchronizationError) {
|
|
4736
|
+
this.showError(`Logged in to ${providerName}, but local model state could not be synchronized: ${errorMsg}`);
|
|
4737
|
+
}
|
|
4738
|
+
else if (errorMsg !== "Login cancelled") {
|
|
4352
4739
|
this.showError(`Failed to login to ${providerName}: ${errorMsg}`);
|
|
4353
4740
|
}
|
|
4354
4741
|
}
|
|
@@ -4399,7 +4786,6 @@ export class InteractiveMode {
|
|
|
4399
4786
|
try {
|
|
4400
4787
|
await this.session.reload({ beforeSessionStart: restoreChatBeforeSessionStart });
|
|
4401
4788
|
restoreChatBeforeSessionStart();
|
|
4402
|
-
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
4403
4789
|
this.keybindings.reload();
|
|
4404
4790
|
const activeHeader = this.customHeader ?? this.builtInHeader;
|
|
4405
4791
|
if (isExpandable(activeHeader)) {
|
|
@@ -4407,20 +4793,7 @@ export class InteractiveMode {
|
|
|
4407
4793
|
}
|
|
4408
4794
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
4409
4795
|
await this.themeController.applyFromSettings();
|
|
4410
|
-
|
|
4411
|
-
const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
|
|
4412
|
-
this.defaultEditor.setPaddingX(editorPaddingX);
|
|
4413
|
-
this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible);
|
|
4414
|
-
if (this.editor !== this.defaultEditor) {
|
|
4415
|
-
this.editor.setPaddingX?.(editorPaddingX);
|
|
4416
|
-
this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible);
|
|
4417
|
-
}
|
|
4418
|
-
this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());
|
|
4419
|
-
const clearOnShrink = this.settingsManager.getClearOnShrink();
|
|
4420
|
-
this.ui.setClearOnShrink(clearOnShrink);
|
|
4421
|
-
if (!clearOnShrink && !this.activeStatusIndicator) {
|
|
4422
|
-
this.statusContainer.clear();
|
|
4423
|
-
}
|
|
4796
|
+
this.applyRuntimeSettings();
|
|
4424
4797
|
this.setupAutocompleteProvider();
|
|
4425
4798
|
const runner = this.session.extensionRunner;
|
|
4426
4799
|
this.setupExtensionShortcuts(runner);
|
|
@@ -4616,7 +4989,7 @@ export class InteractiveMode {
|
|
|
4616
4989
|
}
|
|
4617
4990
|
}
|
|
4618
4991
|
}
|
|
4619
|
-
async handleCopyCommand() {
|
|
4992
|
+
async handleCopyCommand(options = {}) {
|
|
4620
4993
|
const text = this.session.getLastAssistantText();
|
|
4621
4994
|
if (!text) {
|
|
4622
4995
|
this.showError("No agent messages to copy yet.");
|
|
@@ -4624,7 +4997,12 @@ export class InteractiveMode {
|
|
|
4624
4997
|
}
|
|
4625
4998
|
try {
|
|
4626
4999
|
await copyToClipboard(text);
|
|
4627
|
-
|
|
5000
|
+
if (options.flashConfirmation && this.ui instanceof TuiAltScreen) {
|
|
5001
|
+
this.ui.flash("Copied!");
|
|
5002
|
+
}
|
|
5003
|
+
else {
|
|
5004
|
+
this.showStatus("Copied last agent message to clipboard");
|
|
5005
|
+
}
|
|
4628
5006
|
}
|
|
4629
5007
|
catch (error) {
|
|
4630
5008
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
@@ -4897,6 +5275,11 @@ export class InteractiveMode {
|
|
|
4897
5275
|
this.chatContainer.addChild(new ArminComponent(this.ui));
|
|
4898
5276
|
this.ui.requestRender();
|
|
4899
5277
|
}
|
|
5278
|
+
handleDementedDelves() {
|
|
5279
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
5280
|
+
this.chatContainer.addChild(new EarendilAnnouncementComponent());
|
|
5281
|
+
this.ui.requestRender();
|
|
5282
|
+
}
|
|
4900
5283
|
handleDaxnuts() {
|
|
4901
5284
|
this.chatContainer.addChild(new Spacer(1));
|
|
4902
5285
|
this.chatContainer.addChild(new DaxnutsComponent(this.ui));
|
|
@@ -4982,6 +5365,7 @@ export class InteractiveMode {
|
|
|
4982
5365
|
}
|
|
4983
5366
|
}
|
|
4984
5367
|
stop() {
|
|
5368
|
+
this.disposeActiveSelector();
|
|
4985
5369
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
4986
5370
|
this.ui.terminal.setProgress(false);
|
|
4987
5371
|
}
|
|
@@ -4994,7 +5378,7 @@ export class InteractiveMode {
|
|
|
4994
5378
|
this.unsubscribe();
|
|
4995
5379
|
}
|
|
4996
5380
|
if (this.isInitialized) {
|
|
4997
|
-
this.
|
|
5381
|
+
this.stopInteractiveTui();
|
|
4998
5382
|
this.isInitialized = false;
|
|
4999
5383
|
}
|
|
5000
5384
|
this.unregisterSignalHandlers();
|