@astralyn/pi 0.83.0 → 0.84.1
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 +66 -0
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/register-bedrock.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.js.map +1 -1
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +22 -3
- 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 +104 -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 +5 -15
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +42 -82
- package/dist/cli/credential-print.js.map +1 -1
- 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 +127 -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/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- 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/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.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/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.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/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +0 -8
- 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 +30 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +177 -187
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.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 +235 -42
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.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 +43 -20
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +2 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +25 -29
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +26 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +17 -18
- 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/index.d.ts.map +1 -1
- package/dist/core/keybindings.d.ts +165 -125
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +37 -13
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +4 -2
- 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 -11
- 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 +30 -13
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +241 -91
- 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 +84 -16
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +63 -42
- 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 +25 -0
- package/dist/core/pi-manifest.js.map +1 -0
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- 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/radius.d.ts.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/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +2 -46
- 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 +12 -10
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +0 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +10 -12
- 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 +47 -33
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +4 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +18 -14
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.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 +15 -10
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.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 +18 -17
- 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/index.d.ts.map +1 -1
- package/dist/core/tools/index.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/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +12 -18
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.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/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.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 -3
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +0 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/extensions/biu/index.d.ts +19 -0
- package/dist/extensions/biu/index.d.ts.map +1 -0
- package/dist/extensions/biu/index.js +350 -0
- package/dist/extensions/biu/index.js.map +1 -0
- package/dist/extensions/biu/prompts.d.ts +26 -0
- package/dist/extensions/biu/prompts.d.ts.map +1 -0
- package/dist/extensions/biu/prompts.js +260 -0
- package/dist/extensions/biu/prompts.js.map +1 -0
- package/dist/extensions/biu/workspace.d.ts +122 -0
- package/dist/extensions/biu/workspace.d.ts.map +1 -0
- package/dist/extensions/biu/workspace.js +404 -0
- package/dist/extensions/biu/workspace.js.map +1 -0
- package/dist/extensions/deepwiki/client.d.ts.map +1 -1
- package/dist/extensions/deepwiki/client.js.map +1 -1
- package/dist/extensions/deepwiki/constants.d.ts.map +1 -1
- package/dist/extensions/deepwiki/constants.js.map +1 -1
- package/dist/extensions/deepwiki/contents.d.ts.map +1 -1
- package/dist/extensions/deepwiki/contents.js.map +1 -1
- package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
- package/dist/extensions/deepwiki/execute.js.map +1 -1
- package/dist/extensions/deepwiki/http.d.ts.map +1 -1
- package/dist/extensions/deepwiki/http.js.map +1 -1
- package/dist/extensions/deepwiki/index.d.ts.map +1 -1
- package/dist/extensions/deepwiki/index.js.map +1 -1
- package/dist/extensions/deepwiki/render.d.ts.map +1 -1
- package/dist/extensions/deepwiki/render.js.map +1 -1
- package/dist/extensions/deepwiki/schema.d.ts +1 -1
- package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
- package/dist/extensions/deepwiki/schema.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +0 -2
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/huggingface.d.ts.map +1 -1
- package/dist/extensions/llama/huggingface.js +0 -2
- package/dist/extensions/llama/huggingface.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 +21 -7
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/llama/ui.d.ts.map +1 -1
- package/dist/extensions/llama/ui.js +12 -28
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/extensions/question/constants.d.ts.map +1 -1
- package/dist/extensions/question/constants.js.map +1 -1
- package/dist/extensions/question/dialog-primitives.d.ts.map +1 -1
- package/dist/extensions/question/dialog-primitives.js.map +1 -1
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/index.d.ts.map +1 -1
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/question/limits.d.ts.map +1 -1
- package/dist/extensions/question/render-cache.d.ts.map +1 -1
- package/dist/extensions/question/render-cache.js +3 -4
- package/dist/extensions/question/render-cache.js.map +1 -1
- package/dist/extensions/question/render.d.ts.map +1 -1
- package/dist/extensions/question/render.js.map +1 -1
- package/dist/extensions/question/results.d.ts.map +1 -1
- package/dist/extensions/question/results.js.map +1 -1
- package/dist/extensions/question/schema.d.ts.map +1 -1
- package/dist/extensions/question/schema.js.map +1 -1
- package/dist/extensions/question/state.d.ts.map +1 -1
- package/dist/extensions/question/state.js.map +1 -1
- package/dist/extensions/question/types.d.ts.map +1 -1
- package/dist/extensions/rewind/anchor.d.ts.map +1 -1
- package/dist/extensions/rewind/anchor.js.map +1 -1
- package/dist/extensions/rewind/config.d.ts.map +1 -1
- package/dist/extensions/rewind/config.js.map +1 -1
- package/dist/extensions/rewind/engine.d.ts.map +1 -1
- package/dist/extensions/rewind/engine.js.map +1 -1
- package/dist/extensions/rewind/gc.d.ts.map +1 -1
- package/dist/extensions/rewind/gc.js.map +1 -1
- package/dist/extensions/rewind/index.d.ts.map +1 -1
- package/dist/extensions/rewind/index.js.map +1 -1
- package/dist/extensions/rewind/menu.d.ts.map +1 -1
- package/dist/extensions/rewind/menu.js.map +1 -1
- package/dist/extensions/rewind/paths.d.ts.map +1 -1
- package/dist/extensions/rewind/paths.js.map +1 -1
- package/dist/extensions/rewind/restore.d.ts.map +1 -1
- package/dist/extensions/rewind/restore.js.map +1 -1
- package/dist/extensions/rewind/snapshot.d.ts.map +1 -1
- package/dist/extensions/rewind/snapshot.js.map +1 -1
- package/dist/extensions/rewind/storage.d.ts.map +1 -1
- package/dist/extensions/rewind/storage.js.map +1 -1
- package/dist/extensions/rewind/text.d.ts.map +1 -1
- package/dist/extensions/rewind/text.js.map +1 -1
- package/dist/extensions/rewind/tool-path.d.ts.map +1 -1
- package/dist/extensions/rewind/tool-path.js.map +1 -1
- package/dist/extensions/router/constants.d.ts +3 -0
- package/dist/extensions/router/constants.d.ts.map +1 -1
- package/dist/extensions/router/constants.js +3 -0
- package/dist/extensions/router/constants.js.map +1 -1
- package/dist/extensions/router/dialog.d.ts +14 -7
- package/dist/extensions/router/dialog.d.ts.map +1 -1
- package/dist/extensions/router/dialog.js +70 -132
- package/dist/extensions/router/dialog.js.map +1 -1
- package/dist/extensions/router/index.d.ts.map +1 -1
- package/dist/extensions/router/index.js.map +1 -1
- package/dist/extensions/router/presets.d.ts +8 -3
- package/dist/extensions/router/presets.d.ts.map +1 -1
- package/dist/extensions/router/presets.js +33 -17
- package/dist/extensions/router/presets.js.map +1 -1
- package/dist/extensions/router/probe.d.ts.map +1 -1
- package/dist/extensions/router/probe.js.map +1 -1
- package/dist/extensions/router/register.d.ts +3 -3
- package/dist/extensions/router/register.d.ts.map +1 -1
- package/dist/extensions/router/register.js.map +1 -1
- package/dist/extensions/router/store.d.ts.map +1 -1
- package/dist/extensions/router/store.js.map +1 -1
- package/dist/extensions/router/stream.d.ts.map +1 -1
- package/dist/extensions/router/stream.js.map +1 -1
- package/dist/extensions/router/types.d.ts.map +1 -1
- package/dist/extensions/router/ui.d.ts +11 -2
- package/dist/extensions/router/ui.d.ts.map +1 -1
- package/dist/extensions/router/ui.js +316 -171
- package/dist/extensions/router/ui.js.map +1 -1
- package/dist/extensions/statusline/index.d.ts.map +1 -1
- package/dist/extensions/statusline/index.js +17 -9
- package/dist/extensions/statusline/index.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents.d.ts.map +1 -1
- package/dist/extensions/subagent/agents.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts.map +1 -1
- package/dist/extensions/subagent/index.d.ts +3 -0
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +83 -12
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/picker.d.ts.map +1 -1
- package/dist/extensions/subagent/picker.js +2 -9
- package/dist/extensions/subagent/picker.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +33 -9
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/resolve.d.ts.map +1 -1
- package/dist/extensions/subagent/resolve.js.map +1 -1
- package/dist/extensions/subagent/retry.d.ts.map +1 -1
- package/dist/extensions/subagent/retry.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts +2 -1
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +10 -12
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/schema.d.ts.map +1 -1
- package/dist/extensions/subagent/schema.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +41 -1
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/settings.d.ts.map +1 -1
- package/dist/extensions/subagent/settings.js +46 -36
- package/dist/extensions/subagent/settings.js.map +1 -1
- package/dist/extensions/subagent/types.d.ts +0 -1
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/todo/constants.d.ts.map +1 -1
- package/dist/extensions/todo/constants.js.map +1 -1
- package/dist/extensions/todo/index.d.ts.map +1 -1
- package/dist/extensions/todo/index.js.map +1 -1
- package/dist/extensions/todo/overlay.d.ts.map +1 -1
- package/dist/extensions/todo/overlay.js +6 -10
- package/dist/extensions/todo/overlay.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +2 -2
- package/dist/extensions/todo/schema.d.ts.map +1 -1
- package/dist/extensions/todo/state.d.ts.map +1 -1
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +70 -25
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +6 -10
- package/dist/modes/interactive/components/armin.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 -11
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +4 -10
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +0 -3
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +1 -3
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +5 -22
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +1 -7
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +8 -8
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +1 -4
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -7
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js +6 -8
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +0 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -7
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +2 -8
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +1 -9
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +2 -4
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -4
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +3 -9
- package/dist/modes/interactive/components/login-dialog.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 +28 -29
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +3 -11
- package/dist/modes/interactive/components/oauth-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 +34 -13
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +35 -60
- package/dist/modes/interactive/components/session-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 -14
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +0 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +0 -2
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +0 -2
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +0 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +18 -36
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +2 -3
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +19 -39
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +0 -6
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +3 -6
- package/dist/modes/interactive/components/user-message-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 +8 -5
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +46 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +538 -282
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.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 +11 -8
- 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 +4 -4
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +24 -12
- 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/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +5 -4
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +4 -3
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.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 +1 -0
- 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/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- 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/coalescing-terminal.d.ts +20 -4
- package/dist/utils/coalescing-terminal.d.ts.map +1 -1
- package/dist/utils/coalescing-terminal.js +48 -12
- package/dist/utils/coalescing-terminal.js.map +1 -1
- package/dist/utils/deprecation.d.ts.map +1 -1
- package/dist/utils/deprecation.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/html.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-process.d.ts.map +1 -1
- package/dist/utils/image-process.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.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/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.js.map +1 -1
- 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/photon.d.ts.map +1 -1
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.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 +4 -6
- 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 +20 -2
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/bundled/README.md +1 -0
- package/docs/bundled/extensions/biu.md +63 -0
- package/docs/bundled/extensions/router.md +20 -14
- package/docs/bundled/extensions/statusline.md +7 -5
- package/docs/custom-provider.md +123 -2
- package/docs/development.md +83 -0
- package/docs/docs.json +8 -4
- package/docs/extensions.md +30 -5
- package/docs/json.md +21 -2
- package/docs/keybindings.md +46 -14
- package/docs/models.md +21 -3
- package/docs/providers.md +9 -1
- package/docs/quickstart.md +2 -0
- package/docs/rpc.md +12 -11
- package/docs/sdk.md +46 -0
- package/docs/security.md +1 -1
- package/docs/settings.md +4 -1
- package/docs/themes.md +7 -5
- package/docs/usage.md +8 -0
- package/examples/extensions/custom-compaction.ts +1 -16
- package/examples/extensions/custom-provider-anthropic/index.ts +2 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +5 -5
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -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/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +2 -11
- package/examples/extensions/qna.ts +3 -7
- package/examples/extensions/sandbox/package-lock.json +3 -3
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/summarize.ts +8 -18
- package/examples/extensions/with-deps/package-lock.json +4 -4
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +11 -2
- package/examples/sdk/02-custom-model.ts +1 -2
- package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/examples/sdk/README.md +1 -0
- package/npm-shrinkwrap.json +193 -264
- package/package.json +15 -8
|
@@ -6,7 +6,8 @@ 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, 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
13
|
import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.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,7 @@ import { copyToClipboard, readClipboardText } from "../../utils/clipboard.js";
|
|
|
29
31
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
30
32
|
import { CoalescingTerminal } from "../../utils/coalescing-terminal.js";
|
|
31
33
|
import { parseGitUrl } from "../../utils/git.js";
|
|
34
|
+
import { openBrowser } from "../../utils/open-browser.js";
|
|
32
35
|
import { getCwdRelativePath } from "../../utils/paths.js";
|
|
33
36
|
import { killTrackedDetachedChildren } from "../../utils/shell.js";
|
|
34
37
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
@@ -51,6 +54,7 @@ import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
|
51
54
|
import { FooterComponent, formatTokens } from "./components/footer.js";
|
|
52
55
|
import { formatKeyText, keyDisplayText, keyHint, keyText, rawKeyHint } from "./components/keybinding-hints.js";
|
|
53
56
|
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
57
|
+
import { createMermaidMarkdownTransformer } from "./components/mermaid.js";
|
|
54
58
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
55
59
|
import { formatAuthSelectorProviderType, OAuthSelectorComponent, } from "./components/oauth-selector.js";
|
|
56
60
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
@@ -72,8 +76,6 @@ function isExpandable(obj) {
|
|
|
72
76
|
return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
|
|
73
77
|
}
|
|
74
78
|
class ExpandableText extends Text {
|
|
75
|
-
getCollapsedText;
|
|
76
|
-
getExpandedText;
|
|
77
79
|
constructor(getCollapsedText, getExpandedText, expanded = false, paddingX = 0, paddingY = 0) {
|
|
78
80
|
super(expanded ? getExpandedText() : getCollapsedText(), paddingX, paddingY);
|
|
79
81
|
this.getCollapsedText = getCollapsedText;
|
|
@@ -161,98 +163,49 @@ function formatLoginProviderCompletionDescription(provider) {
|
|
|
161
163
|
const authTypes = provider.authTypes.map(formatAuthSelectorProviderType).join("/");
|
|
162
164
|
return provider.name === provider.id ? authTypes : `${provider.name} · ${authTypes}`;
|
|
163
165
|
}
|
|
166
|
+
/** Composition root for selecting the interactive terminal renderer. */
|
|
167
|
+
export function createInteractiveTui(options) {
|
|
168
|
+
const terminal = options.terminal ?? new ProcessTerminal();
|
|
169
|
+
if (options.tuiMode === "fullscreen") {
|
|
170
|
+
return new TuiAltScreen(terminal, options.showHardwareCursor, options.logDirectory, {
|
|
171
|
+
openUrl: openBrowser,
|
|
172
|
+
onRightClickPaste: options.onRightClickPaste,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return new TuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);
|
|
176
|
+
}
|
|
177
|
+
/** Stable reference for components while InteractiveMode replaces the active renderer. */
|
|
178
|
+
export function createInteractiveTuiReference(getTui) {
|
|
179
|
+
return new Proxy({}, {
|
|
180
|
+
get: (_target, property) => {
|
|
181
|
+
const tui = getTui();
|
|
182
|
+
const value = Reflect.get(tui, property, tui);
|
|
183
|
+
if (typeof value !== "function")
|
|
184
|
+
return value;
|
|
185
|
+
let methodTui = tui;
|
|
186
|
+
let method = value;
|
|
187
|
+
return (...args) => {
|
|
188
|
+
const currentTui = getTui();
|
|
189
|
+
if (currentTui !== methodTui) {
|
|
190
|
+
const currentMethod = Reflect.get(currentTui, property, currentTui);
|
|
191
|
+
if (typeof currentMethod !== "function") {
|
|
192
|
+
throw new TypeError(`TUI property ${String(property)} is not callable`);
|
|
193
|
+
}
|
|
194
|
+
methodTui = currentTui;
|
|
195
|
+
method = currentMethod;
|
|
196
|
+
}
|
|
197
|
+
return Reflect.apply(method, methodTui, args);
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
set: (_target, property, value) => {
|
|
201
|
+
const tui = getTui();
|
|
202
|
+
return Reflect.set(tui, property, value, tui);
|
|
203
|
+
},
|
|
204
|
+
has: (_target, property) => Reflect.has(getTui(), property),
|
|
205
|
+
getPrototypeOf: () => Reflect.getPrototypeOf(getTui()),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
164
208
|
export class InteractiveMode {
|
|
165
|
-
runtimeHost;
|
|
166
|
-
ui;
|
|
167
|
-
coalescingTerminal;
|
|
168
|
-
agentRunActive = false;
|
|
169
|
-
loadedResourcesContainer;
|
|
170
|
-
chatContainer;
|
|
171
|
-
pendingMessagesContainer;
|
|
172
|
-
statusContainer;
|
|
173
|
-
defaultEditor;
|
|
174
|
-
editor;
|
|
175
|
-
editorComponentFactory;
|
|
176
|
-
autocompleteProvider;
|
|
177
|
-
autocompleteProviderWrappers = [];
|
|
178
|
-
fdPath;
|
|
179
|
-
editorContainer;
|
|
180
|
-
footer;
|
|
181
|
-
footerDataProvider;
|
|
182
|
-
// Stored so the same manager can be injected into custom editors, selectors, and extension UI.
|
|
183
|
-
keybindings;
|
|
184
|
-
version;
|
|
185
|
-
isInitialized = false;
|
|
186
|
-
onInputCallback;
|
|
187
|
-
pendingUserInputs = [];
|
|
188
|
-
activeStatusIndicator = undefined;
|
|
189
|
-
activeSelector = null;
|
|
190
|
-
activeSelectorCleanup = null;
|
|
191
|
-
idleStatus = new IdleStatus();
|
|
192
|
-
workingMessage = undefined;
|
|
193
|
-
workingVisible = true;
|
|
194
|
-
workingIndicatorOptions = undefined;
|
|
195
|
-
defaultWorkingMessage = "Working...";
|
|
196
|
-
defaultHiddenThinkingLabel = "Thinking...";
|
|
197
|
-
hiddenThinkingLabel = this.defaultHiddenThinkingLabel;
|
|
198
|
-
lastSigintTime = 0;
|
|
199
|
-
lastEscapeTime = 0;
|
|
200
|
-
changelogMarkdown = undefined;
|
|
201
|
-
startupNoticesShown = false;
|
|
202
|
-
anthropicSubscriptionWarningShown = false;
|
|
203
|
-
// Status line tracking (for mutating immediately-sequential status updates)
|
|
204
|
-
lastStatusSpacer = undefined;
|
|
205
|
-
lastStatusText = undefined;
|
|
206
|
-
// Streaming message tracking
|
|
207
|
-
streamingComponent = undefined;
|
|
208
|
-
streamingMessage = undefined;
|
|
209
|
-
// Tool execution tracking: toolCallId -> component
|
|
210
|
-
pendingTools = new Map();
|
|
211
|
-
// Tool output expansion state
|
|
212
|
-
toolOutputExpanded = false;
|
|
213
|
-
// Thinking block visibility state
|
|
214
|
-
hideThinkingBlock = false;
|
|
215
|
-
outputPad = 1;
|
|
216
|
-
// Skill commands: command name -> skill file path
|
|
217
|
-
skillCommands = new Map();
|
|
218
|
-
// Agent subscription unsubscribe function
|
|
219
|
-
unsubscribe;
|
|
220
|
-
signalCleanupHandlers = [];
|
|
221
|
-
// Track if editor is in bash mode (text starts with !)
|
|
222
|
-
isBashMode = false;
|
|
223
|
-
// Track current bash execution component
|
|
224
|
-
bashComponent = undefined;
|
|
225
|
-
// Track pending bash components (shown in pending area, moved to chat on submit)
|
|
226
|
-
pendingBashComponents = [];
|
|
227
|
-
// Auto-compaction state
|
|
228
|
-
autoCompactionEscapeHandler;
|
|
229
|
-
// Auto-retry state
|
|
230
|
-
retryEscapeHandler;
|
|
231
|
-
// Messages queued while compaction is running
|
|
232
|
-
compactionQueuedMessages = [];
|
|
233
|
-
// Shutdown state
|
|
234
|
-
shutdownRequested = false;
|
|
235
|
-
// Extension UI state
|
|
236
|
-
extensionSelector = undefined;
|
|
237
|
-
extensionInput = undefined;
|
|
238
|
-
extensionEditor = undefined;
|
|
239
|
-
extensionTerminalInputUnsubscribers = new Set();
|
|
240
|
-
// Extension widgets (components rendered above/below the editor)
|
|
241
|
-
extensionWidgetsAbove = new Map();
|
|
242
|
-
extensionWidgetsBelow = new Map();
|
|
243
|
-
widgetContainerAbove;
|
|
244
|
-
widgetContainerBelow;
|
|
245
|
-
// Custom footer from extension (undefined = use built-in footer)
|
|
246
|
-
customFooter = undefined;
|
|
247
|
-
// Header container that holds the built-in or custom header
|
|
248
|
-
headerContainer;
|
|
249
|
-
// Built-in header (logo + keybinding hints + changelog)
|
|
250
|
-
builtInHeader = undefined;
|
|
251
|
-
// Custom header from extension (undefined = use built-in header)
|
|
252
|
-
customHeader = undefined;
|
|
253
|
-
options;
|
|
254
|
-
autoTrustOnReloadCwd;
|
|
255
|
-
themeController;
|
|
256
209
|
// Convenience accessors
|
|
257
210
|
get session() {
|
|
258
211
|
return this.runtimeHost.session;
|
|
@@ -267,8 +220,78 @@ export class InteractiveMode {
|
|
|
267
220
|
return this.session.settingsManager;
|
|
268
221
|
}
|
|
269
222
|
constructor(runtimeHost, options = {}) {
|
|
223
|
+
this.autocompleteProviderWrappers = [];
|
|
224
|
+
this.isInitialized = false;
|
|
225
|
+
this.pendingUserInputs = [];
|
|
226
|
+
this.activeStatusIndicator = undefined;
|
|
227
|
+
this.idleStatus = new IdleStatus();
|
|
228
|
+
this.workingMessage = undefined;
|
|
229
|
+
this.workingVisible = true;
|
|
230
|
+
this.workingIndicatorOptions = undefined;
|
|
231
|
+
this.defaultWorkingMessage = "Working...";
|
|
232
|
+
this.defaultHiddenThinkingLabel = "Thinking...";
|
|
233
|
+
this.hiddenThinkingLabel = this.defaultHiddenThinkingLabel;
|
|
234
|
+
this.lastSigintTime = 0;
|
|
235
|
+
this.lastEscapeTime = 0;
|
|
236
|
+
this.changelogMarkdown = undefined;
|
|
237
|
+
this.startupNoticesShown = false;
|
|
238
|
+
this.anthropicSubscriptionWarningShown = false;
|
|
239
|
+
// Status line tracking (for mutating immediately-sequential status updates)
|
|
240
|
+
this.lastStatusSpacer = undefined;
|
|
241
|
+
this.lastStatusText = undefined;
|
|
242
|
+
// Streaming message tracking
|
|
243
|
+
this.streamingComponent = undefined;
|
|
244
|
+
this.streamingMessage = undefined;
|
|
245
|
+
// Tool execution tracking: toolCallId -> component
|
|
246
|
+
this.pendingTools = new Map();
|
|
247
|
+
// Tool output expansion state
|
|
248
|
+
this.toolOutputExpanded = false;
|
|
249
|
+
// Thinking block visibility state
|
|
250
|
+
this.hideThinkingBlock = false;
|
|
251
|
+
this.outputPad = 1;
|
|
252
|
+
this.mermaidMarkdownTransformer = createMermaidMarkdownTransformer({
|
|
253
|
+
getMode: () => this.settingsManager.getMermaidRenderingMode(),
|
|
254
|
+
theme,
|
|
255
|
+
});
|
|
256
|
+
// Skill commands: command name -> skill file path
|
|
257
|
+
this.skillCommands = new Map();
|
|
258
|
+
this.signalCleanupHandlers = [];
|
|
259
|
+
// Track if editor is in bash mode (text starts with !)
|
|
260
|
+
this.isBashMode = false;
|
|
261
|
+
// Track current bash execution component
|
|
262
|
+
this.bashComponent = undefined;
|
|
263
|
+
// Track pending bash components (shown in pending area, moved to chat on submit)
|
|
264
|
+
this.pendingBashComponents = [];
|
|
265
|
+
// Messages queued while compaction is running
|
|
266
|
+
this.compactionQueuedMessages = [];
|
|
267
|
+
// Shutdown state
|
|
268
|
+
this.shutdownRequested = false;
|
|
269
|
+
// Extension UI state
|
|
270
|
+
this.extensionSelector = undefined;
|
|
271
|
+
this.extensionInput = undefined;
|
|
272
|
+
this.extensionEditor = undefined;
|
|
273
|
+
this.extensionTerminalInputSubscriptions = new Set();
|
|
274
|
+
// Extension widgets (components rendered above/below the editor)
|
|
275
|
+
this.extensionWidgetsAbove = new Map();
|
|
276
|
+
this.extensionWidgetsBelow = new Map();
|
|
277
|
+
// Custom footer from extension (undefined = use built-in footer)
|
|
278
|
+
this.customFooter = undefined;
|
|
279
|
+
// Built-in header (logo + keybinding hints + changelog)
|
|
280
|
+
this.builtInHeader = undefined;
|
|
281
|
+
// Custom header from extension (undefined = use built-in header)
|
|
282
|
+
this.customHeader = undefined;
|
|
283
|
+
this.onRightClickPaste = () => {
|
|
284
|
+
void this.handleRightClickPaste();
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Gracefully shutdown the agent.
|
|
288
|
+
* Stops the TUI before emitting shutdown events so extension UI cleanup cannot
|
|
289
|
+
* repaint the final frame while the process is exiting.
|
|
290
|
+
*/
|
|
291
|
+
this.isShuttingDown = false;
|
|
270
292
|
this.runtimeHost = runtimeHost;
|
|
271
|
-
|
|
293
|
+
const tuiMode = options.tuiMode ?? this.settingsManager.getTuiMode();
|
|
294
|
+
this.options = { ...options, tuiMode };
|
|
272
295
|
this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
|
|
273
296
|
this.runtimeHost.setBeforeSessionInvalidate(() => {
|
|
274
297
|
this.resetExtensionUI();
|
|
@@ -279,27 +302,30 @@ export class InteractiveMode {
|
|
|
279
302
|
this.version = VERSION;
|
|
280
303
|
const terminal = new CoalescingTerminal();
|
|
281
304
|
this.coalescingTerminal = terminal;
|
|
282
|
-
this.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
// readViewportTop falls back to the bottom-anchored repaint.
|
|
289
|
-
terminal.setViewportTopProvider(() => this.ui.previousViewportTop);
|
|
290
|
-
// Scrollback preservation stays on from agent_start until the user's
|
|
291
|
-
// next input after the run settles: post-run reflow frames must not
|
|
292
|
-
// yank a reader who is still scrolled up, but once the user acts they
|
|
293
|
-
// are back at the bottom and upstream's clean wipe-and-replay wins.
|
|
294
|
-
this.ui.addInputListener(() => {
|
|
295
|
-
if (!this.agentRunActive)
|
|
296
|
-
this.coalescingTerminal.setScrollbackPreservation(false);
|
|
297
|
-
return undefined;
|
|
305
|
+
this.renderer = createInteractiveTui({
|
|
306
|
+
tuiMode,
|
|
307
|
+
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
308
|
+
logDirectory: getAgentDir(),
|
|
309
|
+
terminal,
|
|
310
|
+
onRightClickPaste: this.onRightClickPaste,
|
|
298
311
|
});
|
|
312
|
+
this.ui = createInteractiveTuiReference(() => this.renderer);
|
|
313
|
+
// Lets full-redraw rewrites scroll grown content into scrollback
|
|
314
|
+
// instead of dropping the lines pushed above the screen. The render
|
|
315
|
+
// state comes from pi-tui's public captureRenderState(); pi-tui
|
|
316
|
+
// writes each full-redraw frame before updating its bookkeeping, so
|
|
317
|
+
// the wrapper observes the pre-frame viewport top. Fullscreen
|
|
318
|
+
// renderers return undefined (their frames do not match the rewrite
|
|
319
|
+
// shape anyway), falling back to the bottom-anchored repaint.
|
|
320
|
+
terminal.setViewportTopProvider(() => this.renderer instanceof TuiMainScreen ? this.renderer.captureRenderState().previousViewportTop : undefined);
|
|
299
321
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
300
322
|
this.headerContainer = new Container();
|
|
301
323
|
this.loadedResourcesContainer = new Container();
|
|
302
324
|
this.chatContainer = new Container();
|
|
325
|
+
this.documentContainer = new Container();
|
|
326
|
+
this.documentContainer.addChild(this.headerContainer);
|
|
327
|
+
this.documentContainer.addChild(this.loadedResourcesContainer);
|
|
328
|
+
this.documentContainer.addChild(this.chatContainer);
|
|
303
329
|
this.pendingMessagesContainer = new Container();
|
|
304
330
|
this.statusContainer = new Container();
|
|
305
331
|
this.widgetContainerAbove = new Container();
|
|
@@ -318,6 +344,8 @@ export class InteractiveMode {
|
|
|
318
344
|
this.footerDataProvider = new FooterDataProvider(this.sessionManager.getCwd());
|
|
319
345
|
this.footer = new FooterComponent(this.session, this.footerDataProvider);
|
|
320
346
|
this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
347
|
+
this.footerContainer = new Container();
|
|
348
|
+
this.footerContainer.addChild(this.footer);
|
|
321
349
|
// Load hide thinking block setting
|
|
322
350
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
323
351
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
@@ -373,11 +401,10 @@ export class InteractiveMode {
|
|
|
373
401
|
}));
|
|
374
402
|
const modelCommand = slashCommands.find((command) => command.name === "model");
|
|
375
403
|
if (modelCommand) {
|
|
376
|
-
modelCommand.getArgumentCompletions =
|
|
377
|
-
// Get available models (scoped or from registry)
|
|
404
|
+
modelCommand.getArgumentCompletions = (prefix) => {
|
|
378
405
|
const models = this.session.scopedModels.length > 0
|
|
379
406
|
? this.session.scopedModels.map((s) => s.model)
|
|
380
|
-
:
|
|
407
|
+
: this.session.modelRuntime.getAvailableSnapshot();
|
|
381
408
|
if (models.length === 0)
|
|
382
409
|
return null;
|
|
383
410
|
// Create items with provider/id format
|
|
@@ -478,6 +505,73 @@ export class InteractiveMode {
|
|
|
478
505
|
}
|
|
479
506
|
this.chatContainer.addChild(new DynamicBorder());
|
|
480
507
|
}
|
|
508
|
+
mountInteractiveTui(tui, components) {
|
|
509
|
+
for (const component of components)
|
|
510
|
+
tui.addChild(component);
|
|
511
|
+
if (TuiLayouts.isViewportTUI(tui)) {
|
|
512
|
+
if (!this.fullscreenLayoutRoot)
|
|
513
|
+
throw new Error("Fullscreen layout is not initialized");
|
|
514
|
+
tui.setLayoutRoot(this.fullscreenLayoutRoot);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
stopInteractiveTui() {
|
|
518
|
+
if (this.renderer.mode === "fullscreen") {
|
|
519
|
+
while (this.renderer.hasOverlayEntries)
|
|
520
|
+
this.renderer.hideOverlay();
|
|
521
|
+
this.switchTuiMode("regular", false, false);
|
|
522
|
+
this.renderer.renderNow();
|
|
523
|
+
}
|
|
524
|
+
this.ui.stop();
|
|
525
|
+
}
|
|
526
|
+
switchTuiMode(mode, restoreProgress = true, startRenderer = true) {
|
|
527
|
+
const previousUi = this.renderer;
|
|
528
|
+
if (mode === previousUi.mode)
|
|
529
|
+
return true;
|
|
530
|
+
if (previousUi.hasOverlayEntries)
|
|
531
|
+
return false;
|
|
532
|
+
const components = [...previousUi.children];
|
|
533
|
+
const focus = previousUi.getFocusedComponent();
|
|
534
|
+
const terminal = previousUi.terminal;
|
|
535
|
+
const showHardwareCursor = previousUi.getShowHardwareCursor();
|
|
536
|
+
const clearOnShrink = previousUi.getClearOnShrink();
|
|
537
|
+
const onDebug = previousUi.onDebug;
|
|
538
|
+
if (previousUi instanceof TuiMainScreen) {
|
|
539
|
+
this.mainScreenRenderState = previousUi.captureRenderState();
|
|
540
|
+
}
|
|
541
|
+
previousUi.stop({ preserveScreen: true });
|
|
542
|
+
previousUi.setFocus(null);
|
|
543
|
+
previousUi.clear();
|
|
544
|
+
if (TuiLayouts.isViewportTUI(previousUi))
|
|
545
|
+
previousUi.setLayoutRoot(undefined);
|
|
546
|
+
const nextUi = createInteractiveTui({
|
|
547
|
+
tuiMode: mode,
|
|
548
|
+
showHardwareCursor,
|
|
549
|
+
logDirectory: getAgentDir(),
|
|
550
|
+
terminal,
|
|
551
|
+
onRightClickPaste: this.onRightClickPaste,
|
|
552
|
+
});
|
|
553
|
+
nextUi.setClearOnShrink(clearOnShrink);
|
|
554
|
+
nextUi.onDebug = onDebug;
|
|
555
|
+
if (nextUi instanceof TuiMainScreen && this.mainScreenRenderState) {
|
|
556
|
+
nextUi.restoreRenderState(this.mainScreenRenderState);
|
|
557
|
+
}
|
|
558
|
+
this.renderer = nextUi;
|
|
559
|
+
this.options.tuiMode = mode;
|
|
560
|
+
this.mountInteractiveTui(nextUi, components);
|
|
561
|
+
nextUi.invalidate();
|
|
562
|
+
nextUi.setFocus(focus);
|
|
563
|
+
if (!startRenderer)
|
|
564
|
+
return true;
|
|
565
|
+
nextUi.start();
|
|
566
|
+
this.themeController.rebindTui();
|
|
567
|
+
this.rebindExtensionTerminalInputListeners();
|
|
568
|
+
if (restoreProgress &&
|
|
569
|
+
this.settingsManager.getShowTerminalProgress() &&
|
|
570
|
+
(this.session.isStreaming || this.session.isCompacting)) {
|
|
571
|
+
terminal.setProgress(true);
|
|
572
|
+
}
|
|
573
|
+
return true;
|
|
574
|
+
}
|
|
481
575
|
async init() {
|
|
482
576
|
if (this.isInitialized)
|
|
483
577
|
return;
|
|
@@ -501,18 +595,36 @@ export class InteractiveMode {
|
|
|
501
595
|
: "";
|
|
502
596
|
console.log(theme.fg("dim", `Model scope: ${modelList}${cycleHint}`));
|
|
503
597
|
}
|
|
504
|
-
//
|
|
505
|
-
// Keep loaded resources before chat so restored session messages never precede them.
|
|
506
|
-
this.ui.addChild(this.headerContainer);
|
|
507
|
-
this.ui.addChild(this.loadedResourcesContainer);
|
|
508
|
-
this.ui.addChild(this.chatContainer);
|
|
509
|
-
this.ui.addChild(this.pendingMessagesContainer);
|
|
510
|
-
this.ui.addChild(this.statusContainer);
|
|
598
|
+
// Keep one component tree and remount it when changing renderers.
|
|
511
599
|
this.renderWidgets(); // Initialize with default spacer
|
|
512
|
-
this.
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
600
|
+
this.transcriptScrollView = new TuiLayouts.ScrollView(this.documentContainer, {
|
|
601
|
+
follow: "end",
|
|
602
|
+
primary: true,
|
|
603
|
+
overscroll: "chain",
|
|
604
|
+
scrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
605
|
+
scrollbarStyle: (text) => theme.bg("scrollbarThumb", text),
|
|
606
|
+
});
|
|
607
|
+
const dock = new TuiLayouts.VStack([
|
|
608
|
+
{ component: this.pendingMessagesContainer, shrink: 1, minSize: 0 },
|
|
609
|
+
{ component: this.statusContainer, shrink: 1, minSize: 0 },
|
|
610
|
+
{ component: this.widgetContainerAbove, shrink: 1, minSize: 0 },
|
|
611
|
+
{ component: this.editorContainer, shrink: 1, minSize: 3 },
|
|
612
|
+
{ component: this.widgetContainerBelow, shrink: 1, minSize: 0 },
|
|
613
|
+
{ component: this.footerContainer, shrink: 1, minSize: 1 },
|
|
614
|
+
]);
|
|
615
|
+
this.fullscreenLayoutRoot = new TuiLayouts.VStack([
|
|
616
|
+
{ component: this.transcriptScrollView, basis: 0, grow: 1, shrink: 1, minSize: 1 },
|
|
617
|
+
{ component: dock, basis: "auto", grow: 0, shrink: 1, minSize: 1 },
|
|
618
|
+
]);
|
|
619
|
+
this.mountInteractiveTui(this.renderer, [
|
|
620
|
+
this.documentContainer,
|
|
621
|
+
this.pendingMessagesContainer,
|
|
622
|
+
this.statusContainer,
|
|
623
|
+
this.widgetContainerAbove,
|
|
624
|
+
this.editorContainer,
|
|
625
|
+
this.widgetContainerBelow,
|
|
626
|
+
this.footerContainer,
|
|
627
|
+
]);
|
|
516
628
|
this.ui.setFocus(this.editor);
|
|
517
629
|
this.setupKeyHandlers();
|
|
518
630
|
this.setupEditorSubmitHandler();
|
|
@@ -604,10 +716,13 @@ export class InteractiveMode {
|
|
|
604
716
|
async run() {
|
|
605
717
|
await this.init();
|
|
606
718
|
if (!process.env.PI_OFFLINE) {
|
|
719
|
+
const controller = new AbortController();
|
|
720
|
+
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
607
721
|
void this.session.modelRuntime
|
|
608
|
-
.refresh()
|
|
722
|
+
.refresh({ signal: controller.signal })
|
|
609
723
|
.then(() => this.updateAvailableProviderCount())
|
|
610
|
-
.catch(() => { })
|
|
724
|
+
.catch(() => { })
|
|
725
|
+
.finally(() => clearTimeout(timeout));
|
|
611
726
|
}
|
|
612
727
|
// Start version check asynchronously
|
|
613
728
|
checkForNewPiVersion(this.version).then((newRelease) => {
|
|
@@ -1259,6 +1374,7 @@ export class InteractiveMode {
|
|
|
1259
1374
|
if (result.cancelled) {
|
|
1260
1375
|
return { cancelled: true };
|
|
1261
1376
|
}
|
|
1377
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
1262
1378
|
this.clearChat();
|
|
1263
1379
|
this.renderInitialMessages();
|
|
1264
1380
|
if (result.editorText && !this.editor.getText().trim()) {
|
|
@@ -1292,8 +1408,12 @@ export class InteractiveMode {
|
|
|
1292
1408
|
this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });
|
|
1293
1409
|
this.showStartupNoticesIfNeeded();
|
|
1294
1410
|
}
|
|
1411
|
+
applyFullscreenScrollbarSetting() {
|
|
1412
|
+
this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
|
|
1413
|
+
}
|
|
1295
1414
|
applyRuntimeSettings() {
|
|
1296
1415
|
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
1416
|
+
this.applyFullscreenScrollbarSetting();
|
|
1297
1417
|
this.footer.setSession(this.session);
|
|
1298
1418
|
this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
1299
1419
|
this.footerDataProvider.setCwd(this.sessionManager.getCwd());
|
|
@@ -1362,6 +1482,10 @@ export class InteractiveMode {
|
|
|
1362
1482
|
this.pendingTools.clear();
|
|
1363
1483
|
}
|
|
1364
1484
|
renderCurrentSessionState() {
|
|
1485
|
+
// Resuming, forking, or starting a new session rebuilds the transcript
|
|
1486
|
+
// at the user's request; the rebuild's full redraw keeps the clean
|
|
1487
|
+
// wipe-and-replay even if preservation is still windowed on.
|
|
1488
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
1365
1489
|
this.loadedResourcesContainer.clear();
|
|
1366
1490
|
this.clearChat();
|
|
1367
1491
|
this.pendingMessagesContainer.clear();
|
|
@@ -1405,6 +1529,9 @@ export class InteractiveMode {
|
|
|
1405
1529
|
}
|
|
1406
1530
|
this.chatContainer.addChild(component);
|
|
1407
1531
|
}
|
|
1532
|
+
getMarkdownTransformers() {
|
|
1533
|
+
return [this.mermaidMarkdownTransformer, ...this.session.extensionRunner.getMarkdownTransformers()];
|
|
1534
|
+
}
|
|
1408
1535
|
/**
|
|
1409
1536
|
* Set up keyboard shortcuts registered by extensions.
|
|
1410
1537
|
*/
|
|
@@ -1484,7 +1611,7 @@ export class InteractiveMode {
|
|
|
1484
1611
|
this.activeStatusIndicator?.dispose();
|
|
1485
1612
|
this.activeStatusIndicator = undefined;
|
|
1486
1613
|
this.statusContainer.clear();
|
|
1487
|
-
if (hadActiveStatusIndicator && this.ui.getClearOnShrink()) {
|
|
1614
|
+
if (hadActiveStatusIndicator && this.options.tuiMode === "regular" && this.ui.getClearOnShrink()) {
|
|
1488
1615
|
this.statusContainer.addChild(this.idleStatus);
|
|
1489
1616
|
}
|
|
1490
1617
|
}
|
|
@@ -1598,7 +1725,7 @@ export class InteractiveMode {
|
|
|
1598
1725
|
this.setHiddenThinkingLabel();
|
|
1599
1726
|
}
|
|
1600
1727
|
// Maximum total widget lines to prevent viewport overflow
|
|
1601
|
-
static MAX_WIDGET_LINES = 10;
|
|
1728
|
+
static { this.MAX_WIDGET_LINES = 10; }
|
|
1602
1729
|
/**
|
|
1603
1730
|
* Render all extension widgets to the widget container.
|
|
1604
1731
|
*/
|
|
@@ -1632,22 +1759,16 @@ export class InteractiveMode {
|
|
|
1632
1759
|
if (this.customFooter?.dispose) {
|
|
1633
1760
|
this.customFooter.dispose();
|
|
1634
1761
|
}
|
|
1635
|
-
|
|
1636
|
-
if (this.customFooter) {
|
|
1637
|
-
this.ui.removeChild(this.customFooter);
|
|
1638
|
-
}
|
|
1639
|
-
else {
|
|
1640
|
-
this.ui.removeChild(this.footer);
|
|
1641
|
-
}
|
|
1762
|
+
this.footerContainer.clear();
|
|
1642
1763
|
if (factory) {
|
|
1643
1764
|
// Create and add custom footer, passing the data provider
|
|
1644
1765
|
this.customFooter = factory(this.ui, theme, this.footerDataProvider);
|
|
1645
|
-
this.
|
|
1766
|
+
this.footerContainer.addChild(this.customFooter);
|
|
1646
1767
|
}
|
|
1647
1768
|
else {
|
|
1648
1769
|
// Restore built-in footer
|
|
1649
1770
|
this.customFooter = undefined;
|
|
1650
|
-
this.
|
|
1771
|
+
this.footerContainer.addChild(this.footer);
|
|
1651
1772
|
}
|
|
1652
1773
|
this.ui.requestRender();
|
|
1653
1774
|
}
|
|
@@ -1693,18 +1814,23 @@ export class InteractiveMode {
|
|
|
1693
1814
|
this.ui.requestRender();
|
|
1694
1815
|
}
|
|
1695
1816
|
addExtensionTerminalInputListener(handler) {
|
|
1696
|
-
const
|
|
1697
|
-
this.
|
|
1817
|
+
const subscription = { handler, unsubscribe: this.ui.addInputListener(handler) };
|
|
1818
|
+
this.extensionTerminalInputSubscriptions.add(subscription);
|
|
1698
1819
|
return () => {
|
|
1699
|
-
unsubscribe();
|
|
1700
|
-
this.
|
|
1820
|
+
subscription.unsubscribe();
|
|
1821
|
+
this.extensionTerminalInputSubscriptions.delete(subscription);
|
|
1701
1822
|
};
|
|
1702
1823
|
}
|
|
1703
|
-
|
|
1704
|
-
for (const
|
|
1705
|
-
unsubscribe();
|
|
1824
|
+
rebindExtensionTerminalInputListeners() {
|
|
1825
|
+
for (const subscription of this.extensionTerminalInputSubscriptions) {
|
|
1826
|
+
subscription.unsubscribe();
|
|
1827
|
+
subscription.unsubscribe = this.ui.addInputListener(subscription.handler);
|
|
1706
1828
|
}
|
|
1707
|
-
|
|
1829
|
+
}
|
|
1830
|
+
clearExtensionTerminalInputListeners() {
|
|
1831
|
+
for (const subscription of this.extensionTerminalInputSubscriptions)
|
|
1832
|
+
subscription.unsubscribe();
|
|
1833
|
+
this.extensionTerminalInputSubscriptions.clear();
|
|
1708
1834
|
}
|
|
1709
1835
|
/**
|
|
1710
1836
|
* Create the ExtensionUIContext for extensions.
|
|
@@ -1805,6 +1931,7 @@ export class InteractiveMode {
|
|
|
1805
1931
|
cancelHint: opts?.cancelHint,
|
|
1806
1932
|
onToggleToolsExpanded: () => this.toggleToolOutputExpansion(),
|
|
1807
1933
|
});
|
|
1934
|
+
this.disposeActiveSelector();
|
|
1808
1935
|
this.editorContainer.clear();
|
|
1809
1936
|
this.editorContainer.addChild(this.extensionSelector);
|
|
1810
1937
|
this.ui.setFocus(this.extensionSelector);
|
|
@@ -1826,7 +1953,9 @@ export class InteractiveMode {
|
|
|
1826
1953
|
* Show a confirmation dialog for extensions.
|
|
1827
1954
|
*/
|
|
1828
1955
|
async showExtensionConfirm(title, message, opts) {
|
|
1829
|
-
|
|
1956
|
+
// The message is context, not a heading: render it as the selector's muted
|
|
1957
|
+
// subtitle instead of folding it into the accent-bold title.
|
|
1958
|
+
const result = await this.showExtensionSelector(title, ["Yes", "No"], { ...opts, subtitle: message });
|
|
1830
1959
|
return result === "Yes";
|
|
1831
1960
|
}
|
|
1832
1961
|
async promptForMissingSessionCwd(error) {
|
|
@@ -1856,6 +1985,7 @@ export class InteractiveMode {
|
|
|
1856
1985
|
this.hideExtensionInput();
|
|
1857
1986
|
resolve(undefined);
|
|
1858
1987
|
}, { tui: this.ui, timeout: opts?.timeout });
|
|
1988
|
+
this.disposeActiveSelector();
|
|
1859
1989
|
this.editorContainer.clear();
|
|
1860
1990
|
this.editorContainer.addChild(this.extensionInput);
|
|
1861
1991
|
this.ui.setFocus(this.extensionInput);
|
|
@@ -1885,6 +2015,7 @@ export class InteractiveMode {
|
|
|
1885
2015
|
this.hideExtensionEditor();
|
|
1886
2016
|
resolve(undefined);
|
|
1887
2017
|
}, undefined, this.settingsManager.getExternalEditorCommand());
|
|
2018
|
+
this.disposeActiveSelector();
|
|
1888
2019
|
this.editorContainer.clear();
|
|
1889
2020
|
this.editorContainer.addChild(this.extensionEditor);
|
|
1890
2021
|
this.ui.setFocus(this.extensionEditor);
|
|
@@ -1909,6 +2040,7 @@ export class InteractiveMode {
|
|
|
1909
2040
|
this.editorComponentFactory = factory;
|
|
1910
2041
|
// Save text from current editor before switching
|
|
1911
2042
|
const currentText = this.editor.getText();
|
|
2043
|
+
this.disposeActiveSelector();
|
|
1912
2044
|
this.editorContainer.clear();
|
|
1913
2045
|
if (factory) {
|
|
1914
2046
|
// Create the custom editor with tui, theme, and keybindings
|
|
@@ -1925,6 +2057,9 @@ export class InteractiveMode {
|
|
|
1925
2057
|
if (newEditor.setPaddingX !== undefined) {
|
|
1926
2058
|
newEditor.setPaddingX(this.defaultEditor.getPaddingX());
|
|
1927
2059
|
}
|
|
2060
|
+
if (newEditor.setAutocompleteMaxVisible !== undefined) {
|
|
2061
|
+
newEditor.setAutocompleteMaxVisible(this.defaultEditor.getAutocompleteMaxVisible());
|
|
2062
|
+
}
|
|
1928
2063
|
// Set autocomplete if supported
|
|
1929
2064
|
if (newEditor.setAutocompleteProvider && this.autocompleteProvider) {
|
|
1930
2065
|
newEditor.setAutocompleteProvider(this.autocompleteProvider);
|
|
@@ -2029,6 +2164,7 @@ export class InteractiveMode {
|
|
|
2029
2164
|
options?.onHandle?.(handle);
|
|
2030
2165
|
}
|
|
2031
2166
|
else {
|
|
2167
|
+
this.disposeActiveSelector();
|
|
2032
2168
|
this.editorContainer.clear();
|
|
2033
2169
|
this.editorContainer.addChild(component);
|
|
2034
2170
|
this.ui.setFocus(component);
|
|
@@ -2115,7 +2251,7 @@ export class InteractiveMode {
|
|
|
2115
2251
|
this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
|
|
2116
2252
|
this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
|
|
2117
2253
|
this.defaultEditor.onAction("app.editor.external", () => void this.handleOpenExternalEditor());
|
|
2118
|
-
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand());
|
|
2254
|
+
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true }));
|
|
2119
2255
|
this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
|
|
2120
2256
|
this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
|
|
2121
2257
|
this.defaultEditor.onAction("app.session.new", () => this.handleClearCommand());
|
|
@@ -2135,6 +2271,22 @@ export class InteractiveMode {
|
|
|
2135
2271
|
void this.handleClipboardPaste();
|
|
2136
2272
|
};
|
|
2137
2273
|
}
|
|
2274
|
+
async handleRightClickPaste() {
|
|
2275
|
+
const target = this.renderer.getFocusedComponent();
|
|
2276
|
+
const handleInput = target?.handleInput;
|
|
2277
|
+
if (!target || !handleInput)
|
|
2278
|
+
return;
|
|
2279
|
+
try {
|
|
2280
|
+
const text = await readClipboardText();
|
|
2281
|
+
if (!text || this.renderer.getFocusedComponent() !== target)
|
|
2282
|
+
return;
|
|
2283
|
+
handleInput.call(target, `\x1b[200~${text}\x1b[201~`);
|
|
2284
|
+
this.ui.requestRender();
|
|
2285
|
+
}
|
|
2286
|
+
catch {
|
|
2287
|
+
// Silently ignore clipboard errors (may not have permission, etc.)
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2138
2290
|
async handleClipboardPaste() {
|
|
2139
2291
|
try {
|
|
2140
2292
|
const image = await readClipboardImage();
|
|
@@ -2355,8 +2507,9 @@ export class InteractiveMode {
|
|
|
2355
2507
|
this.footer.invalidate();
|
|
2356
2508
|
switch (event.type) {
|
|
2357
2509
|
case "agent_start":
|
|
2358
|
-
|
|
2359
|
-
|
|
2510
|
+
// Opens the scrollback-preservation window; the terminal
|
|
2511
|
+
// closes it on the user's next input after the run settles.
|
|
2512
|
+
this.coalescingTerminal.setAgentRunActive(true);
|
|
2360
2513
|
this.clearPendingTools();
|
|
2361
2514
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
2362
2515
|
this.ui.terminal.setProgress(true);
|
|
@@ -2416,17 +2569,17 @@ export class InteractiveMode {
|
|
|
2416
2569
|
this.ui.requestRender();
|
|
2417
2570
|
}
|
|
2418
2571
|
else if (event.message.role === "assistant") {
|
|
2419
|
-
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad);
|
|
2572
|
+
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
2420
2573
|
this.streamingMessage = event.message;
|
|
2421
2574
|
this.chatContainer.addChild(this.streamingComponent);
|
|
2422
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2575
|
+
this.streamingComponent.updateContent(this.streamingMessage, true);
|
|
2423
2576
|
this.ui.requestRender();
|
|
2424
2577
|
}
|
|
2425
2578
|
break;
|
|
2426
2579
|
case "message_update":
|
|
2427
2580
|
if (this.streamingComponent && event.message.role === "assistant") {
|
|
2428
2581
|
this.streamingMessage = event.message;
|
|
2429
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2582
|
+
this.streamingComponent.updateContent(this.streamingMessage, true);
|
|
2430
2583
|
for (const content of this.streamingMessage.content) {
|
|
2431
2584
|
if (content.type === "toolCall") {
|
|
2432
2585
|
if (!this.pendingTools.has(content.id)) {
|
|
@@ -2459,7 +2612,7 @@ export class InteractiveMode {
|
|
|
2459
2612
|
: "Operation aborted";
|
|
2460
2613
|
this.streamingMessage.errorMessage = errorMessage;
|
|
2461
2614
|
}
|
|
2462
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2615
|
+
this.streamingComponent.updateContent(this.streamingMessage, false);
|
|
2463
2616
|
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
|
2464
2617
|
if (!errorMessage) {
|
|
2465
2618
|
errorMessage = this.streamingMessage.errorMessage || "Error";
|
|
@@ -2533,7 +2686,7 @@ export class InteractiveMode {
|
|
|
2533
2686
|
// Preservation itself stays on until the next user input; the
|
|
2534
2687
|
// run's trailing reflow frames may land after this event while
|
|
2535
2688
|
// the reader is still scrolled up.
|
|
2536
|
-
this.
|
|
2689
|
+
this.coalescingTerminal.setAgentRunActive(false);
|
|
2537
2690
|
await this.checkShutdownRequested();
|
|
2538
2691
|
break;
|
|
2539
2692
|
case "compaction_start": {
|
|
@@ -2735,12 +2888,12 @@ export class InteractiveMode {
|
|
|
2735
2888
|
// Render user message separately if present
|
|
2736
2889
|
if (skillBlock.userMessage) {
|
|
2737
2890
|
this.chatContainer.addChild(new Spacer(1));
|
|
2738
|
-
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
2891
|
+
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad, this.getMarkdownTransformers());
|
|
2739
2892
|
this.chatContainer.addChild(userComponent);
|
|
2740
2893
|
}
|
|
2741
2894
|
}
|
|
2742
2895
|
else {
|
|
2743
|
-
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
2896
|
+
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad, this.getMarkdownTransformers());
|
|
2744
2897
|
this.chatContainer.addChild(userComponent);
|
|
2745
2898
|
}
|
|
2746
2899
|
if (options?.populateHistory) {
|
|
@@ -2750,7 +2903,7 @@ export class InteractiveMode {
|
|
|
2750
2903
|
break;
|
|
2751
2904
|
}
|
|
2752
2905
|
case "assistant": {
|
|
2753
|
-
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad);
|
|
2906
|
+
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
2754
2907
|
this.chatContainer.addChild(assistantComponent);
|
|
2755
2908
|
break;
|
|
2756
2909
|
}
|
|
@@ -2933,12 +3086,6 @@ export class InteractiveMode {
|
|
|
2933
3086
|
// Only called when editor is empty (enforced by CustomEditor)
|
|
2934
3087
|
void this.shutdown();
|
|
2935
3088
|
}
|
|
2936
|
-
/**
|
|
2937
|
-
* Gracefully shutdown the agent.
|
|
2938
|
-
* Stops the TUI before emitting shutdown events so extension UI cleanup cannot
|
|
2939
|
-
* repaint the final frame while the process is exiting.
|
|
2940
|
-
*/
|
|
2941
|
-
isShuttingDown = false;
|
|
2942
3089
|
async shutdown(options) {
|
|
2943
3090
|
if (this.isShuttingDown)
|
|
2944
3091
|
return;
|
|
@@ -3180,6 +3327,8 @@ export class InteractiveMode {
|
|
|
3180
3327
|
this.setToolsExpanded(!this.toolOutputExpanded);
|
|
3181
3328
|
}
|
|
3182
3329
|
setToolsExpanded(expanded) {
|
|
3330
|
+
if (expanded === this.toolOutputExpanded)
|
|
3331
|
+
return;
|
|
3183
3332
|
this.toolOutputExpanded = expanded;
|
|
3184
3333
|
// An explicit toggle prefers upstream's clean wipe-and-replay even
|
|
3185
3334
|
// mid-run: the user just pressed the key, so they are interacting at
|
|
@@ -3242,7 +3391,7 @@ export class InteractiveMode {
|
|
|
3242
3391
|
}
|
|
3243
3392
|
showError(errorMessage) {
|
|
3244
3393
|
this.chatContainer.addChild(new Spacer(1));
|
|
3245
|
-
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`),
|
|
3394
|
+
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`), this.outputPad, 0));
|
|
3246
3395
|
this.ui.requestRender();
|
|
3247
3396
|
}
|
|
3248
3397
|
showWarning(warningMessage) {
|
|
@@ -3448,52 +3597,50 @@ export class InteractiveMode {
|
|
|
3448
3597
|
// =========================================================================
|
|
3449
3598
|
// Selectors
|
|
3450
3599
|
// =========================================================================
|
|
3600
|
+
disposeActiveSelector() {
|
|
3601
|
+
const dispose = this.activeSelectorDispose;
|
|
3602
|
+
this.activeSelectorToken = undefined;
|
|
3603
|
+
this.activeSelectorDispose = undefined;
|
|
3604
|
+
dispose?.();
|
|
3605
|
+
}
|
|
3451
3606
|
/**
|
|
3452
3607
|
* Shows a selector component in place of the editor.
|
|
3453
3608
|
* @param create Factory that receives a `done` callback and returns the component and focus target
|
|
3454
3609
|
*/
|
|
3455
3610
|
showSelector(create) {
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
this.activeSelector = null;
|
|
3459
|
-
let selector;
|
|
3611
|
+
const token = {};
|
|
3612
|
+
let dispose;
|
|
3460
3613
|
let disposed = false;
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
if (disposed || !selector)
|
|
3614
|
+
const disposeOnce = () => {
|
|
3615
|
+
if (disposed)
|
|
3464
3616
|
return;
|
|
3465
3617
|
disposed = true;
|
|
3466
|
-
|
|
3618
|
+
dispose?.();
|
|
3467
3619
|
};
|
|
3468
3620
|
const done = () => {
|
|
3469
|
-
|
|
3621
|
+
disposeOnce();
|
|
3622
|
+
if (this.activeSelectorToken !== token)
|
|
3470
3623
|
return;
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
this.editorContainer.clear();
|
|
3477
|
-
this.editorContainer.addChild(this.editor);
|
|
3478
|
-
this.ui.setFocus(this.editor);
|
|
3479
|
-
}
|
|
3624
|
+
this.activeSelectorToken = undefined;
|
|
3625
|
+
this.activeSelectorDispose = undefined;
|
|
3626
|
+
this.editorContainer.clear();
|
|
3627
|
+
this.editorContainer.addChild(this.editor);
|
|
3628
|
+
this.ui.setFocus(this.editor);
|
|
3480
3629
|
};
|
|
3481
3630
|
const created = create(done);
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
}
|
|
3487
|
-
this.activeSelector = selector;
|
|
3488
|
-
this.activeSelectorCleanup = dispose;
|
|
3631
|
+
dispose = created.dispose;
|
|
3632
|
+
this.disposeActiveSelector();
|
|
3633
|
+
this.activeSelectorToken = token;
|
|
3634
|
+
this.activeSelectorDispose = disposeOnce;
|
|
3489
3635
|
this.editorContainer.clear();
|
|
3490
|
-
this.editorContainer.addChild(
|
|
3636
|
+
this.editorContainer.addChild(created.component);
|
|
3491
3637
|
this.ui.setFocus(created.focus);
|
|
3492
3638
|
this.ui.requestRender();
|
|
3493
3639
|
}
|
|
3494
3640
|
showSettingsSelector() {
|
|
3495
3641
|
this.showSelector((done) => {
|
|
3496
|
-
|
|
3642
|
+
let selector;
|
|
3643
|
+
selector = new SettingsSelectorComponent({
|
|
3497
3644
|
autoCompact: this.session.autoCompactionEnabled,
|
|
3498
3645
|
showImages: this.settingsManager.getShowImages(),
|
|
3499
3646
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
@@ -3510,6 +3657,7 @@ export class InteractiveMode {
|
|
|
3510
3657
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3511
3658
|
availableThemes: getAvailableThemes(),
|
|
3512
3659
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
3660
|
+
mermaidRenderingMode: this.settingsManager.getMermaidRenderingMode(),
|
|
3513
3661
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
3514
3662
|
enableInstallTelemetry: this.settingsManager.getEnableInstallTelemetry(),
|
|
3515
3663
|
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
@@ -3523,6 +3671,8 @@ export class InteractiveMode {
|
|
|
3523
3671
|
quietStartup: this.settingsManager.getQuietStartup(),
|
|
3524
3672
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
3525
3673
|
showTerminalProgress: this.settingsManager.getShowTerminalProgress(),
|
|
3674
|
+
tuiMode: this.ui.mode,
|
|
3675
|
+
fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
3526
3676
|
warnings: this.settingsManager.getWarnings(),
|
|
3527
3677
|
}, {
|
|
3528
3678
|
onAutoCompactChange: (enabled) => {
|
|
@@ -3591,6 +3741,11 @@ export class InteractiveMode {
|
|
|
3591
3741
|
this.clearChat();
|
|
3592
3742
|
this.rebuildChatFromMessages();
|
|
3593
3743
|
},
|
|
3744
|
+
onMermaidRenderingModeChange: (mode) => {
|
|
3745
|
+
this.settingsManager.setMermaidRenderingMode(mode);
|
|
3746
|
+
this.chatContainer.invalidate();
|
|
3747
|
+
this.ui.requestRender();
|
|
3748
|
+
},
|
|
3594
3749
|
onShowCacheMissNoticesChange: (shown) => {
|
|
3595
3750
|
this.settingsManager.setShowCacheMissNotices(shown);
|
|
3596
3751
|
this.rebuildChatFromMessages();
|
|
@@ -3660,6 +3815,21 @@ export class InteractiveMode {
|
|
|
3660
3815
|
onShowTerminalProgressChange: (enabled) => {
|
|
3661
3816
|
this.settingsManager.setShowTerminalProgress(enabled);
|
|
3662
3817
|
},
|
|
3818
|
+
onTuiModeChange: (mode) => {
|
|
3819
|
+
if (!this.switchTuiMode(mode)) {
|
|
3820
|
+
selector?.getSettingsList().updateValue("tui-mode", this.ui.mode);
|
|
3821
|
+
this.showStatus("Close active overlays before changing TUI mode");
|
|
3822
|
+
return;
|
|
3823
|
+
}
|
|
3824
|
+
this.settingsManager.setTuiMode(mode);
|
|
3825
|
+
if (!this.activeStatusIndicator)
|
|
3826
|
+
this.statusContainer.clear();
|
|
3827
|
+
this.showStatus(`TUI mode: ${mode}`);
|
|
3828
|
+
},
|
|
3829
|
+
onFullscreenScrollbarChange: (mode) => {
|
|
3830
|
+
this.settingsManager.setFullscreenScrollbar(mode);
|
|
3831
|
+
this.applyFullscreenScrollbarSetting();
|
|
3832
|
+
},
|
|
3663
3833
|
onWarningsChange: (warnings) => {
|
|
3664
3834
|
this.settingsManager.setWarnings(warnings);
|
|
3665
3835
|
},
|
|
@@ -3694,20 +3864,37 @@ export class InteractiveMode {
|
|
|
3694
3864
|
this.showModelSelector(searchTerm);
|
|
3695
3865
|
}
|
|
3696
3866
|
async findExactModelMatch(searchTerm) {
|
|
3697
|
-
const
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
if (this.session.scopedModels.length > 0)
|
|
3702
|
-
return
|
|
3703
|
-
|
|
3867
|
+
const cachedModels = this.session.scopedModels.length > 0
|
|
3868
|
+
? this.session.scopedModels.map((scoped) => scoped.model)
|
|
3869
|
+
: [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
3870
|
+
const cachedMatch = findExactModelReferenceMatch(searchTerm, cachedModels);
|
|
3871
|
+
if (cachedMatch || this.session.scopedModels.length > 0)
|
|
3872
|
+
return cachedMatch;
|
|
3873
|
+
this.showStatus("Refreshing model catalogs…");
|
|
3874
|
+
const controller = new AbortController();
|
|
3875
|
+
let timedOut = false;
|
|
3876
|
+
const timeout = setTimeout(() => {
|
|
3877
|
+
timedOut = true;
|
|
3878
|
+
controller.abort();
|
|
3879
|
+
}, 15_000);
|
|
3704
3880
|
try {
|
|
3705
|
-
await this.session.modelRuntime.refresh();
|
|
3706
|
-
|
|
3881
|
+
const result = await this.session.modelRuntime.refresh({ signal: controller.signal });
|
|
3882
|
+
if (result.aborted && timedOut) {
|
|
3883
|
+
this.showWarning("Model refresh timed out; searching cached models.");
|
|
3884
|
+
}
|
|
3885
|
+
else if (result.errors.size > 0) {
|
|
3886
|
+
this.showWarning(`Could not refresh ${[...result.errors.keys()].join(", ")}; searching cached models.`);
|
|
3887
|
+
}
|
|
3707
3888
|
}
|
|
3708
|
-
catch {
|
|
3709
|
-
|
|
3889
|
+
catch (error) {
|
|
3890
|
+
this.showWarning(timedOut
|
|
3891
|
+
? "Model refresh timed out; searching cached models."
|
|
3892
|
+
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`);
|
|
3893
|
+
}
|
|
3894
|
+
finally {
|
|
3895
|
+
clearTimeout(timeout);
|
|
3710
3896
|
}
|
|
3897
|
+
return findExactModelReferenceMatch(searchTerm, [...this.session.modelRuntime.getAvailableSnapshot()]);
|
|
3711
3898
|
}
|
|
3712
3899
|
/** Update the footer's available provider count from the current snapshot without refreshing catalogs. */
|
|
3713
3900
|
updateAvailableProviderCount() {
|
|
@@ -3809,73 +3996,67 @@ export class InteractiveMode {
|
|
|
3809
3996
|
done();
|
|
3810
3997
|
this.ui.requestRender();
|
|
3811
3998
|
}, initialSearchInput);
|
|
3812
|
-
return { component: selector, focus: selector };
|
|
3999
|
+
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
3813
4000
|
});
|
|
3814
4001
|
}
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
const allModels = [...(await this.session.modelRuntime.getAvailable())];
|
|
3819
|
-
const allModelIds = new Set(allModels.map((model) => `${model.provider}/${model.id}`));
|
|
4002
|
+
showModelsSelector() {
|
|
4003
|
+
let availableModels = [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
4004
|
+
let availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));
|
|
3820
4005
|
const configuredPatterns = this.settingsManager.getEnabledModels();
|
|
3821
4006
|
const sessionScopedModels = this.session.scopedModels;
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
currentEnabledIds = configuredScope.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);
|
|
3839
|
-
}
|
|
3840
|
-
for (const diagnostic of configuredScope?.diagnostics ?? []) {
|
|
3841
|
-
if (diagnostic.code !== "no-match")
|
|
3842
|
-
continue;
|
|
3843
|
-
currentEnabledIds ??= [];
|
|
3844
|
-
if (!currentEnabledIds.includes(diagnostic.pattern))
|
|
3845
|
-
currentEnabledIds.push(diagnostic.pattern);
|
|
3846
|
-
}
|
|
3847
|
-
// Helper to update session's scoped models (session-only, no persist)
|
|
3848
|
-
const updateSessionModels = async (enabledIds) => {
|
|
4007
|
+
const configuredEnabledIds = (models) => {
|
|
4008
|
+
if (!configuredPatterns?.length)
|
|
4009
|
+
return null;
|
|
4010
|
+
const resolved = resolveModelScopeFromModels(configuredPatterns, models);
|
|
4011
|
+
const ids = resolved.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);
|
|
4012
|
+
for (const diagnostic of resolved.diagnostics) {
|
|
4013
|
+
if (diagnostic.code === "no-match" && !ids.includes(diagnostic.pattern))
|
|
4014
|
+
ids.push(diagnostic.pattern);
|
|
4015
|
+
}
|
|
4016
|
+
return ids;
|
|
4017
|
+
};
|
|
4018
|
+
let currentEnabledIds = sessionScopedModels.length > 0
|
|
4019
|
+
? sessionScopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`)
|
|
4020
|
+
: configuredEnabledIds(availableModels);
|
|
4021
|
+
let selectionChanged = false;
|
|
4022
|
+
const updateSessionModels = (enabledIds) => {
|
|
3849
4023
|
currentEnabledIds = enabledIds === null ? null : [...enabledIds];
|
|
3850
|
-
const hasEnabledAvailableModel = enabledIds?.some((id) =>
|
|
3851
|
-
const allAvailableModelsEnabled = enabledIds !== null && [...
|
|
4024
|
+
const hasEnabledAvailableModel = enabledIds?.some((id) => availableModelIds.has(id)) ?? false;
|
|
4025
|
+
const allAvailableModelsEnabled = enabledIds !== null && [...availableModelIds].every((id) => enabledIds.includes(id));
|
|
3852
4026
|
if (enabledIds && hasEnabledAvailableModel && !allAvailableModelsEnabled) {
|
|
3853
|
-
const newScopedModels =
|
|
3854
|
-
this.session.setScopedModels(newScopedModels.map((
|
|
3855
|
-
model:
|
|
3856
|
-
thinkingLevel:
|
|
4027
|
+
const newScopedModels = resolveModelScopeFromModels(enabledIds, availableModels).scopedModels;
|
|
4028
|
+
this.session.setScopedModels(newScopedModels.map((scoped) => ({
|
|
4029
|
+
model: scoped.model,
|
|
4030
|
+
thinkingLevel: scoped.thinkingLevel,
|
|
3857
4031
|
})));
|
|
3858
4032
|
}
|
|
3859
4033
|
else {
|
|
3860
|
-
// All enabled or none enabled = no filter
|
|
3861
4034
|
this.session.setScopedModels([]);
|
|
3862
4035
|
}
|
|
3863
|
-
|
|
4036
|
+
this.updateAvailableProviderCount();
|
|
3864
4037
|
this.ui.requestRender();
|
|
3865
4038
|
};
|
|
3866
4039
|
this.showSelector((done) => {
|
|
4040
|
+
let disposed = false;
|
|
4041
|
+
let timedOut = false;
|
|
4042
|
+
const controller = new AbortController();
|
|
4043
|
+
const timeout = setTimeout(() => {
|
|
4044
|
+
timedOut = true;
|
|
4045
|
+
controller.abort();
|
|
4046
|
+
}, 15_000);
|
|
3867
4047
|
const selector = new ScopedModelsSelectorComponent({
|
|
3868
|
-
allModels,
|
|
4048
|
+
allModels: availableModels,
|
|
3869
4049
|
enabledModelIds: currentEnabledIds,
|
|
4050
|
+
refreshStatus: "Refreshing model catalogs…",
|
|
3870
4051
|
}, {
|
|
3871
|
-
onChange:
|
|
3872
|
-
|
|
4052
|
+
onChange: (enabledIds) => {
|
|
4053
|
+
selectionChanged = true;
|
|
4054
|
+
updateSessionModels(enabledIds);
|
|
3873
4055
|
},
|
|
3874
4056
|
onPersist: (enabledIds) => {
|
|
3875
|
-
// Persist to settings
|
|
3876
4057
|
const allEnabled = enabledIds !== null &&
|
|
3877
|
-
enabledIds.length ===
|
|
3878
|
-
enabledIds.every((id) =>
|
|
4058
|
+
enabledIds.length === availableModels.length &&
|
|
4059
|
+
enabledIds.every((id) => availableModelIds.has(id));
|
|
3879
4060
|
const newPatterns = enabledIds === null || allEnabled ? undefined : enabledIds;
|
|
3880
4061
|
this.settingsManager.setEnabledModels(newPatterns ? [...newPatterns] : undefined);
|
|
3881
4062
|
this.showStatus("Model selection saved to settings");
|
|
@@ -3885,7 +4066,51 @@ export class InteractiveMode {
|
|
|
3885
4066
|
this.ui.requestRender();
|
|
3886
4067
|
},
|
|
3887
4068
|
});
|
|
3888
|
-
|
|
4069
|
+
void this.session.modelRuntime
|
|
4070
|
+
.refresh({ signal: controller.signal })
|
|
4071
|
+
.then((result) => {
|
|
4072
|
+
if (disposed)
|
|
4073
|
+
return;
|
|
4074
|
+
availableModels = [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
4075
|
+
availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));
|
|
4076
|
+
if (!selectionChanged && sessionScopedModels.length === 0) {
|
|
4077
|
+
currentEnabledIds = configuredEnabledIds(availableModels);
|
|
4078
|
+
selector.updateModels(availableModels, currentEnabledIds);
|
|
4079
|
+
}
|
|
4080
|
+
else {
|
|
4081
|
+
selector.updateModels(availableModels);
|
|
4082
|
+
}
|
|
4083
|
+
if (currentEnabledIds !== null)
|
|
4084
|
+
updateSessionModels(currentEnabledIds);
|
|
4085
|
+
if (result.aborted && timedOut) {
|
|
4086
|
+
selector.setRefreshStatus("Model refresh timed out; showing cached models.", "warning");
|
|
4087
|
+
}
|
|
4088
|
+
else if (result.errors.size > 0) {
|
|
4089
|
+
selector.setRefreshStatus(`Could not refresh ${[...result.errors.keys()].join(", ")}; showing cached models.`, "warning");
|
|
4090
|
+
}
|
|
4091
|
+
else {
|
|
4092
|
+
selector.setRefreshStatus("Model catalogs refreshed.", "success");
|
|
4093
|
+
}
|
|
4094
|
+
this.ui.requestRender();
|
|
4095
|
+
})
|
|
4096
|
+
.catch((error) => {
|
|
4097
|
+
if (disposed)
|
|
4098
|
+
return;
|
|
4099
|
+
selector.setRefreshStatus(timedOut
|
|
4100
|
+
? "Model refresh timed out; showing cached models."
|
|
4101
|
+
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
4102
|
+
this.ui.requestRender();
|
|
4103
|
+
})
|
|
4104
|
+
.finally(() => clearTimeout(timeout));
|
|
4105
|
+
return {
|
|
4106
|
+
component: selector,
|
|
4107
|
+
focus: selector,
|
|
4108
|
+
dispose: () => {
|
|
4109
|
+
disposed = true;
|
|
4110
|
+
clearTimeout(timeout);
|
|
4111
|
+
controller.abort();
|
|
4112
|
+
},
|
|
4113
|
+
};
|
|
3889
4114
|
});
|
|
3890
4115
|
}
|
|
3891
4116
|
showUserMessageSelector() {
|
|
@@ -4014,6 +4239,9 @@ export class InteractiveMode {
|
|
|
4014
4239
|
this.showStatus("Navigation cancelled");
|
|
4015
4240
|
return;
|
|
4016
4241
|
}
|
|
4242
|
+
// User-committed tree navigation rebuilds the transcript; its
|
|
4243
|
+
// full redraw bypasses scrollback preservation.
|
|
4244
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
4017
4245
|
// Update UI
|
|
4018
4246
|
this.clearChat();
|
|
4019
4247
|
this.renderInitialMessages();
|
|
@@ -4147,7 +4375,7 @@ export class InteractiveMode {
|
|
|
4147
4375
|
return options.sort((a, b) => a.name.localeCompare(b.name));
|
|
4148
4376
|
}
|
|
4149
4377
|
async getLogoutProviderOptions() {
|
|
4150
|
-
return (await this.session.modelRuntime.listCredentials())
|
|
4378
|
+
return (await this.session.modelRuntime.listCredentials({ signal: AbortSignal.timeout(15_000) }))
|
|
4151
4379
|
.map(({ providerId, type }) => ({
|
|
4152
4380
|
id: providerId,
|
|
4153
4381
|
name: this.session.modelRuntime.getProvider(providerId)?.name ?? providerId,
|
|
@@ -4165,7 +4393,6 @@ export class InteractiveMode {
|
|
|
4165
4393
|
provider.name.toLowerCase() === normalizedProviderRef);
|
|
4166
4394
|
}
|
|
4167
4395
|
async handleLoginCommand(providerRef) {
|
|
4168
|
-
await this.session.modelRuntime.getAvailable();
|
|
4169
4396
|
if (!providerRef) {
|
|
4170
4397
|
this.showLoginAuthTypeSelector();
|
|
4171
4398
|
return;
|
|
@@ -4279,7 +4506,14 @@ export class InteractiveMode {
|
|
|
4279
4506
|
this.showLoginAuthTypeSelector();
|
|
4280
4507
|
return;
|
|
4281
4508
|
}
|
|
4282
|
-
|
|
4509
|
+
let providerOptions;
|
|
4510
|
+
try {
|
|
4511
|
+
providerOptions = await this.getLogoutProviderOptions();
|
|
4512
|
+
}
|
|
4513
|
+
catch (error) {
|
|
4514
|
+
this.showError(`Could not read stored credentials: ${error instanceof Error ? error.message : String(error)}`);
|
|
4515
|
+
return;
|
|
4516
|
+
}
|
|
4283
4517
|
if (providerOptions.length === 0) {
|
|
4284
4518
|
this.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");
|
|
4285
4519
|
return;
|
|
@@ -4292,7 +4526,9 @@ export class InteractiveMode {
|
|
|
4292
4526
|
return;
|
|
4293
4527
|
}
|
|
4294
4528
|
try {
|
|
4295
|
-
await this.session.modelRuntime.logout(providerOption.id
|
|
4529
|
+
await this.session.modelRuntime.logout(providerOption.id, {
|
|
4530
|
+
signal: AbortSignal.timeout(15_000),
|
|
4531
|
+
});
|
|
4296
4532
|
await this.updateAvailableProviderCount();
|
|
4297
4533
|
const message = providerOption.authType === "oauth"
|
|
4298
4534
|
? `Logged out of ${providerOption.name}`
|
|
@@ -4300,7 +4536,10 @@ export class InteractiveMode {
|
|
|
4300
4536
|
this.showStatus(message);
|
|
4301
4537
|
}
|
|
4302
4538
|
catch (error) {
|
|
4303
|
-
|
|
4539
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4540
|
+
this.showError(error instanceof CredentialSynchronizationError
|
|
4541
|
+
? `Credentials removed for ${providerOption.name}, but local model state could not be synchronized: ${message}`
|
|
4542
|
+
: `Logout failed: ${message}`);
|
|
4304
4543
|
}
|
|
4305
4544
|
}, () => {
|
|
4306
4545
|
done();
|
|
@@ -4310,12 +4549,11 @@ export class InteractiveMode {
|
|
|
4310
4549
|
});
|
|
4311
4550
|
}
|
|
4312
4551
|
async completeProviderAuthentication(providerId, providerName, authType, previousModel) {
|
|
4313
|
-
await this.session.modelRuntime.getAvailable();
|
|
4314
4552
|
const actionLabel = authType === "oauth" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;
|
|
4315
4553
|
let selectedModel;
|
|
4316
4554
|
let selectionError;
|
|
4317
4555
|
if (isUnknownModel(previousModel)) {
|
|
4318
|
-
const availableModels =
|
|
4556
|
+
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4319
4557
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4320
4558
|
if (!hasDefaultModelProvider(providerId)) {
|
|
4321
4559
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
@@ -4358,6 +4596,25 @@ export class InteractiveMode {
|
|
|
4358
4596
|
void this.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
4359
4597
|
}
|
|
4360
4598
|
}
|
|
4599
|
+
const controller = new AbortController();
|
|
4600
|
+
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
4601
|
+
void this.session.modelRuntime
|
|
4602
|
+
.refresh({ providers: [providerId], signal: controller.signal })
|
|
4603
|
+
.then((result) => {
|
|
4604
|
+
if (result.aborted) {
|
|
4605
|
+
this.showWarning(`${actionLabel}, but its model catalog refresh timed out; using cached models.`);
|
|
4606
|
+
}
|
|
4607
|
+
else if (result.errors.size > 0) {
|
|
4608
|
+
this.showWarning(`${actionLabel}, but its model catalog could not be refreshed; using cached models.`);
|
|
4609
|
+
}
|
|
4610
|
+
this.updateAvailableProviderCount();
|
|
4611
|
+
this.footer.invalidate();
|
|
4612
|
+
this.ui.requestRender();
|
|
4613
|
+
})
|
|
4614
|
+
.catch((error) => {
|
|
4615
|
+
this.showWarning(`${actionLabel}, but its model catalog could not be refreshed: ${error instanceof Error ? error.message : String(error)}`);
|
|
4616
|
+
})
|
|
4617
|
+
.finally(() => clearTimeout(timeout));
|
|
4361
4618
|
}
|
|
4362
4619
|
showAmbientAuthDialog(providerOption) {
|
|
4363
4620
|
const restoreEditor = () => {
|
|
@@ -4403,7 +4660,10 @@ export class InteractiveMode {
|
|
|
4403
4660
|
catch (error) {
|
|
4404
4661
|
restoreEditor();
|
|
4405
4662
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4406
|
-
if (
|
|
4663
|
+
if (error instanceof CredentialSynchronizationError) {
|
|
4664
|
+
this.showError(`Saved API key for ${providerName}, but local model state could not be synchronized: ${errorMsg}`);
|
|
4665
|
+
}
|
|
4666
|
+
else if (errorMsg !== "Login cancelled") {
|
|
4407
4667
|
this.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);
|
|
4408
4668
|
}
|
|
4409
4669
|
}
|
|
@@ -4506,7 +4766,10 @@ export class InteractiveMode {
|
|
|
4506
4766
|
catch (error) {
|
|
4507
4767
|
restoreEditor();
|
|
4508
4768
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4509
|
-
if (
|
|
4769
|
+
if (error instanceof CredentialSynchronizationError) {
|
|
4770
|
+
this.showError(`Logged in to ${providerName}, but local model state could not be synchronized: ${errorMsg}`);
|
|
4771
|
+
}
|
|
4772
|
+
else if (errorMsg !== "Login cancelled") {
|
|
4510
4773
|
this.showError(`Failed to login to ${providerName}: ${errorMsg}`);
|
|
4511
4774
|
}
|
|
4512
4775
|
}
|
|
@@ -4551,13 +4814,16 @@ export class InteractiveMode {
|
|
|
4551
4814
|
}
|
|
4552
4815
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
4553
4816
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
4817
|
+
// The user asked for this rebuild; its full redraw keeps the
|
|
4818
|
+
// upstream wipe-and-replay even if preservation is still windowed
|
|
4819
|
+
// on from the previous run.
|
|
4820
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
4554
4821
|
this.rebuildChatFromMessages();
|
|
4555
4822
|
chatRestoredBeforeSessionStart = true;
|
|
4556
4823
|
};
|
|
4557
4824
|
try {
|
|
4558
4825
|
await this.session.reload({ beforeSessionStart: restoreChatBeforeSessionStart });
|
|
4559
4826
|
restoreChatBeforeSessionStart();
|
|
4560
|
-
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
4561
4827
|
this.keybindings.reload();
|
|
4562
4828
|
const activeHeader = this.customHeader ?? this.builtInHeader;
|
|
4563
4829
|
if (isExpandable(activeHeader)) {
|
|
@@ -4565,20 +4831,7 @@ export class InteractiveMode {
|
|
|
4565
4831
|
}
|
|
4566
4832
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
4567
4833
|
await this.themeController.applyFromSettings();
|
|
4568
|
-
|
|
4569
|
-
const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
|
|
4570
|
-
this.defaultEditor.setPaddingX(editorPaddingX);
|
|
4571
|
-
this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible);
|
|
4572
|
-
if (this.editor !== this.defaultEditor) {
|
|
4573
|
-
this.editor.setPaddingX?.(editorPaddingX);
|
|
4574
|
-
this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible);
|
|
4575
|
-
}
|
|
4576
|
-
this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());
|
|
4577
|
-
const clearOnShrink = this.settingsManager.getClearOnShrink();
|
|
4578
|
-
this.ui.setClearOnShrink(clearOnShrink);
|
|
4579
|
-
if (!clearOnShrink && !this.activeStatusIndicator) {
|
|
4580
|
-
this.statusContainer.clear();
|
|
4581
|
-
}
|
|
4834
|
+
this.applyRuntimeSettings();
|
|
4582
4835
|
this.setupAutocompleteProvider();
|
|
4583
4836
|
const runner = this.session.extensionRunner;
|
|
4584
4837
|
this.setupExtensionShortcuts(runner);
|
|
@@ -4774,7 +5027,7 @@ export class InteractiveMode {
|
|
|
4774
5027
|
}
|
|
4775
5028
|
}
|
|
4776
5029
|
}
|
|
4777
|
-
async handleCopyCommand() {
|
|
5030
|
+
async handleCopyCommand(options = {}) {
|
|
4778
5031
|
const text = this.session.getLastAssistantText();
|
|
4779
5032
|
if (!text) {
|
|
4780
5033
|
this.showError("No agent messages to copy yet.");
|
|
@@ -4782,7 +5035,12 @@ export class InteractiveMode {
|
|
|
4782
5035
|
}
|
|
4783
5036
|
try {
|
|
4784
5037
|
await copyToClipboard(text);
|
|
4785
|
-
|
|
5038
|
+
if (options.flashConfirmation && this.ui instanceof TuiAltScreen) {
|
|
5039
|
+
this.ui.flash("Copied!");
|
|
5040
|
+
}
|
|
5041
|
+
else {
|
|
5042
|
+
this.showStatus("Copied last agent message to clipboard");
|
|
5043
|
+
}
|
|
4786
5044
|
}
|
|
4787
5045
|
catch (error) {
|
|
4788
5046
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
@@ -5145,9 +5403,7 @@ export class InteractiveMode {
|
|
|
5145
5403
|
}
|
|
5146
5404
|
}
|
|
5147
5405
|
stop() {
|
|
5148
|
-
this.
|
|
5149
|
-
this.activeSelectorCleanup = null;
|
|
5150
|
-
this.activeSelector = null;
|
|
5406
|
+
this.disposeActiveSelector();
|
|
5151
5407
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
5152
5408
|
this.ui.terminal.setProgress(false);
|
|
5153
5409
|
}
|
|
@@ -5162,7 +5418,7 @@ export class InteractiveMode {
|
|
|
5162
5418
|
this.unsubscribe();
|
|
5163
5419
|
}
|
|
5164
5420
|
if (this.isInitialized) {
|
|
5165
|
-
this.
|
|
5421
|
+
this.stopInteractiveTui();
|
|
5166
5422
|
this.isInitialized = false;
|
|
5167
5423
|
}
|
|
5168
5424
|
this.unregisterSignalHandlers();
|