@astralyn/pi 0.83.0 → 0.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -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 +19 -0
- package/dist/cli/args.js.map +1 -1
- 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 +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +6 -5
- 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 +15 -9
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +159 -41
- 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 +21 -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 +157 -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 +41 -10
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +28 -13
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +239 -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.map +1 -1
- package/dist/core/tools/bash.js +12 -10
- 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.map +1 -1
- package/dist/core/tools/edit.js +4 -3
- 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 +3 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +13 -16
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -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.map +1 -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.map +1 -1
- package/dist/core/tools/read.js +1 -1
- 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.map +1 -1
- package/dist/core/tools/write.js +0 -1
- 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 +16 -7
- 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 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +518 -269
- 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 +13 -9
- 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/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 +1 -0
- package/dist/utils/coalescing-terminal.d.ts.map +1 -1
- package/dist/utils/coalescing-terminal.js +16 -8
- 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 +27 -3
- package/docs/json.md +21 -2
- package/docs/keybindings.md +38 -10
- package/docs/models.md +21 -3
- package/docs/providers.md +1 -0
- 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-gitlab-duo/index.ts +2 -1
- package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/handoff.ts +2 -11
- package/examples/extensions/qna.ts +3 -7
- package/examples/extensions/summarize.ts +8 -18
- 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,39 @@ 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, { openUrl: openBrowser });
|
|
171
|
+
}
|
|
172
|
+
return new TuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);
|
|
173
|
+
}
|
|
174
|
+
/** Stable reference for components while InteractiveMode replaces the active renderer. */
|
|
175
|
+
export function createInteractiveTuiReference(getTui) {
|
|
176
|
+
return new Proxy({}, {
|
|
177
|
+
get: (_target, property) => {
|
|
178
|
+
const tui = getTui();
|
|
179
|
+
const value = Reflect.get(tui, property, tui);
|
|
180
|
+
if (typeof value !== "function")
|
|
181
|
+
return value;
|
|
182
|
+
return (...args) => {
|
|
183
|
+
const tui = getTui();
|
|
184
|
+
const method = Reflect.get(tui, property, tui);
|
|
185
|
+
if (typeof method !== "function")
|
|
186
|
+
throw new TypeError(`TUI property ${String(property)} is not callable`);
|
|
187
|
+
return Reflect.apply(method, tui, args);
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
set: (_target, property, value) => {
|
|
191
|
+
const tui = getTui();
|
|
192
|
+
return Reflect.set(tui, property, value, tui);
|
|
193
|
+
},
|
|
194
|
+
has: (_target, property) => Reflect.has(getTui(), property),
|
|
195
|
+
getPrototypeOf: () => Reflect.getPrototypeOf(getTui()),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
164
198
|
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
199
|
// Convenience accessors
|
|
257
200
|
get session() {
|
|
258
201
|
return this.runtimeHost.session;
|
|
@@ -267,8 +210,85 @@ export class InteractiveMode {
|
|
|
267
210
|
return this.session.settingsManager;
|
|
268
211
|
}
|
|
269
212
|
constructor(runtimeHost, options = {}) {
|
|
213
|
+
// Input listeners live on the TUI renderer instance, which switchTuiMode
|
|
214
|
+
// replaces; this pair tracks the scrollback-preservation listener so it
|
|
215
|
+
// can be unsubscribed from the outgoing renderer and re-registered on the
|
|
216
|
+
// incoming one without duplicates.
|
|
217
|
+
this.scrollbackPreservationInputHandler = () => {
|
|
218
|
+
if (!this.agentRunActive)
|
|
219
|
+
this.coalescingTerminal.setScrollbackPreservation(false);
|
|
220
|
+
return undefined;
|
|
221
|
+
};
|
|
222
|
+
this.agentRunActive = false;
|
|
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
|
+
/**
|
|
284
|
+
* Gracefully shutdown the agent.
|
|
285
|
+
* Stops the TUI before emitting shutdown events so extension UI cleanup cannot
|
|
286
|
+
* repaint the final frame while the process is exiting.
|
|
287
|
+
*/
|
|
288
|
+
this.isShuttingDown = false;
|
|
270
289
|
this.runtimeHost = runtimeHost;
|
|
271
|
-
|
|
290
|
+
const tuiMode = options.tuiMode ?? this.settingsManager.getTuiMode();
|
|
291
|
+
this.options = { ...options, tuiMode };
|
|
272
292
|
this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
|
|
273
293
|
this.runtimeHost.setBeforeSessionInvalidate(() => {
|
|
274
294
|
this.resetExtensionUI();
|
|
@@ -279,7 +299,13 @@ export class InteractiveMode {
|
|
|
279
299
|
this.version = VERSION;
|
|
280
300
|
const terminal = new CoalescingTerminal();
|
|
281
301
|
this.coalescingTerminal = terminal;
|
|
282
|
-
this.
|
|
302
|
+
this.renderer = createInteractiveTui({
|
|
303
|
+
tuiMode,
|
|
304
|
+
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
305
|
+
logDirectory: getAgentDir(),
|
|
306
|
+
terminal,
|
|
307
|
+
});
|
|
308
|
+
this.ui = createInteractiveTuiReference(() => this.renderer);
|
|
283
309
|
// Lets full-redraw rewrites scroll grown content into scrollback
|
|
284
310
|
// instead of dropping the lines pushed above the screen.
|
|
285
311
|
// previousViewportTop is TS-private but a plain runtime field, and
|
|
@@ -291,15 +317,17 @@ export class InteractiveMode {
|
|
|
291
317
|
// next input after the run settles: post-run reflow frames must not
|
|
292
318
|
// yank a reader who is still scrolled up, but once the user acts they
|
|
293
319
|
// are back at the bottom and upstream's clean wipe-and-replay wins.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return undefined;
|
|
298
|
-
});
|
|
320
|
+
// The listener is registered on the initial renderer and rebound by
|
|
321
|
+
// switchTuiMode whenever the renderer is replaced.
|
|
322
|
+
this.scrollbackPreservationInputUnsubscribe = this.ui.addInputListener(this.scrollbackPreservationInputHandler);
|
|
299
323
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
300
324
|
this.headerContainer = new Container();
|
|
301
325
|
this.loadedResourcesContainer = new Container();
|
|
302
326
|
this.chatContainer = new Container();
|
|
327
|
+
this.documentContainer = new Container();
|
|
328
|
+
this.documentContainer.addChild(this.headerContainer);
|
|
329
|
+
this.documentContainer.addChild(this.loadedResourcesContainer);
|
|
330
|
+
this.documentContainer.addChild(this.chatContainer);
|
|
303
331
|
this.pendingMessagesContainer = new Container();
|
|
304
332
|
this.statusContainer = new Container();
|
|
305
333
|
this.widgetContainerAbove = new Container();
|
|
@@ -318,6 +346,8 @@ export class InteractiveMode {
|
|
|
318
346
|
this.footerDataProvider = new FooterDataProvider(this.sessionManager.getCwd());
|
|
319
347
|
this.footer = new FooterComponent(this.session, this.footerDataProvider);
|
|
320
348
|
this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
349
|
+
this.footerContainer = new Container();
|
|
350
|
+
this.footerContainer.addChild(this.footer);
|
|
321
351
|
// Load hide thinking block setting
|
|
322
352
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
323
353
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
@@ -373,11 +403,10 @@ export class InteractiveMode {
|
|
|
373
403
|
}));
|
|
374
404
|
const modelCommand = slashCommands.find((command) => command.name === "model");
|
|
375
405
|
if (modelCommand) {
|
|
376
|
-
modelCommand.getArgumentCompletions =
|
|
377
|
-
// Get available models (scoped or from registry)
|
|
406
|
+
modelCommand.getArgumentCompletions = (prefix) => {
|
|
378
407
|
const models = this.session.scopedModels.length > 0
|
|
379
408
|
? this.session.scopedModels.map((s) => s.model)
|
|
380
|
-
:
|
|
409
|
+
: this.session.modelRuntime.getAvailableSnapshot();
|
|
381
410
|
if (models.length === 0)
|
|
382
411
|
return null;
|
|
383
412
|
// Create items with provider/id format
|
|
@@ -478,6 +507,75 @@ export class InteractiveMode {
|
|
|
478
507
|
}
|
|
479
508
|
this.chatContainer.addChild(new DynamicBorder());
|
|
480
509
|
}
|
|
510
|
+
mountInteractiveTui(tui, components) {
|
|
511
|
+
for (const component of components)
|
|
512
|
+
tui.addChild(component);
|
|
513
|
+
if (TuiLayouts.isViewportTUI(tui)) {
|
|
514
|
+
if (!this.fullscreenLayoutRoot)
|
|
515
|
+
throw new Error("Fullscreen layout is not initialized");
|
|
516
|
+
tui.setLayoutRoot(this.fullscreenLayoutRoot);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
stopInteractiveTui() {
|
|
520
|
+
if (this.renderer.mode === "fullscreen") {
|
|
521
|
+
while (this.renderer.hasOverlayEntries)
|
|
522
|
+
this.renderer.hideOverlay();
|
|
523
|
+
this.switchTuiMode("regular", false, false);
|
|
524
|
+
this.renderer.renderNow();
|
|
525
|
+
}
|
|
526
|
+
this.ui.stop();
|
|
527
|
+
}
|
|
528
|
+
switchTuiMode(mode, restoreProgress = true, startRenderer = true) {
|
|
529
|
+
const previousUi = this.renderer;
|
|
530
|
+
if (mode === previousUi.mode)
|
|
531
|
+
return true;
|
|
532
|
+
if (previousUi.hasOverlayEntries)
|
|
533
|
+
return false;
|
|
534
|
+
const components = [...previousUi.children];
|
|
535
|
+
const focus = previousUi.getFocusedComponent();
|
|
536
|
+
const terminal = previousUi.terminal;
|
|
537
|
+
const showHardwareCursor = previousUi.getShowHardwareCursor();
|
|
538
|
+
const clearOnShrink = previousUi.getClearOnShrink();
|
|
539
|
+
const onDebug = previousUi.onDebug;
|
|
540
|
+
if (previousUi instanceof TuiMainScreen) {
|
|
541
|
+
this.mainScreenRenderState = previousUi.captureRenderState();
|
|
542
|
+
}
|
|
543
|
+
previousUi.stop({ preserveScreen: true });
|
|
544
|
+
previousUi.setFocus(null);
|
|
545
|
+
previousUi.clear();
|
|
546
|
+
if (TuiLayouts.isViewportTUI(previousUi))
|
|
547
|
+
previousUi.setLayoutRoot(undefined);
|
|
548
|
+
const nextUi = createInteractiveTui({
|
|
549
|
+
tuiMode: mode,
|
|
550
|
+
showHardwareCursor,
|
|
551
|
+
logDirectory: getAgentDir(),
|
|
552
|
+
terminal,
|
|
553
|
+
});
|
|
554
|
+
nextUi.setClearOnShrink(clearOnShrink);
|
|
555
|
+
nextUi.onDebug = onDebug;
|
|
556
|
+
if (nextUi instanceof TuiMainScreen && this.mainScreenRenderState) {
|
|
557
|
+
nextUi.restoreRenderState(this.mainScreenRenderState);
|
|
558
|
+
}
|
|
559
|
+
this.renderer = nextUi;
|
|
560
|
+
// Renderers own their input-listener sets; move the preservation
|
|
561
|
+
// listener onto the incoming renderer before anything else touches it.
|
|
562
|
+
this.rebindScrollbackPreservationInputListener();
|
|
563
|
+
this.options.tuiMode = mode;
|
|
564
|
+
this.mountInteractiveTui(nextUi, components);
|
|
565
|
+
nextUi.invalidate();
|
|
566
|
+
nextUi.setFocus(focus);
|
|
567
|
+
if (!startRenderer)
|
|
568
|
+
return true;
|
|
569
|
+
nextUi.start();
|
|
570
|
+
this.themeController.rebindTui();
|
|
571
|
+
this.rebindExtensionTerminalInputListeners();
|
|
572
|
+
if (restoreProgress &&
|
|
573
|
+
this.settingsManager.getShowTerminalProgress() &&
|
|
574
|
+
(this.session.isStreaming || this.session.isCompacting)) {
|
|
575
|
+
terminal.setProgress(true);
|
|
576
|
+
}
|
|
577
|
+
return true;
|
|
578
|
+
}
|
|
481
579
|
async init() {
|
|
482
580
|
if (this.isInitialized)
|
|
483
581
|
return;
|
|
@@ -501,18 +599,36 @@ export class InteractiveMode {
|
|
|
501
599
|
: "";
|
|
502
600
|
console.log(theme.fg("dim", `Model scope: ${modelList}${cycleHint}`));
|
|
503
601
|
}
|
|
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);
|
|
602
|
+
// Keep one component tree and remount it when changing renderers.
|
|
511
603
|
this.renderWidgets(); // Initialize with default spacer
|
|
512
|
-
this.
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
604
|
+
this.transcriptScrollView = new TuiLayouts.ScrollView(this.documentContainer, {
|
|
605
|
+
follow: "end",
|
|
606
|
+
primary: true,
|
|
607
|
+
overscroll: "chain",
|
|
608
|
+
scrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
609
|
+
scrollbarStyle: (text) => theme.bg("scrollbarThumb", text),
|
|
610
|
+
});
|
|
611
|
+
const dock = new TuiLayouts.VStack([
|
|
612
|
+
{ component: this.pendingMessagesContainer, shrink: 1, minSize: 0 },
|
|
613
|
+
{ component: this.statusContainer, shrink: 1, minSize: 0 },
|
|
614
|
+
{ component: this.widgetContainerAbove, shrink: 1, minSize: 0 },
|
|
615
|
+
{ component: this.editorContainer, shrink: 1, minSize: 3 },
|
|
616
|
+
{ component: this.widgetContainerBelow, shrink: 1, minSize: 0 },
|
|
617
|
+
{ component: this.footerContainer, shrink: 1, minSize: 1 },
|
|
618
|
+
]);
|
|
619
|
+
this.fullscreenLayoutRoot = new TuiLayouts.VStack([
|
|
620
|
+
{ component: this.transcriptScrollView, basis: 0, grow: 1, shrink: 1, minSize: 1 },
|
|
621
|
+
{ component: dock, basis: "auto", grow: 0, shrink: 1, minSize: 1 },
|
|
622
|
+
]);
|
|
623
|
+
this.mountInteractiveTui(this.renderer, [
|
|
624
|
+
this.documentContainer,
|
|
625
|
+
this.pendingMessagesContainer,
|
|
626
|
+
this.statusContainer,
|
|
627
|
+
this.widgetContainerAbove,
|
|
628
|
+
this.editorContainer,
|
|
629
|
+
this.widgetContainerBelow,
|
|
630
|
+
this.footerContainer,
|
|
631
|
+
]);
|
|
516
632
|
this.ui.setFocus(this.editor);
|
|
517
633
|
this.setupKeyHandlers();
|
|
518
634
|
this.setupEditorSubmitHandler();
|
|
@@ -604,10 +720,13 @@ export class InteractiveMode {
|
|
|
604
720
|
async run() {
|
|
605
721
|
await this.init();
|
|
606
722
|
if (!process.env.PI_OFFLINE) {
|
|
723
|
+
const controller = new AbortController();
|
|
724
|
+
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
607
725
|
void this.session.modelRuntime
|
|
608
|
-
.refresh()
|
|
726
|
+
.refresh({ signal: controller.signal })
|
|
609
727
|
.then(() => this.updateAvailableProviderCount())
|
|
610
|
-
.catch(() => { })
|
|
728
|
+
.catch(() => { })
|
|
729
|
+
.finally(() => clearTimeout(timeout));
|
|
611
730
|
}
|
|
612
731
|
// Start version check asynchronously
|
|
613
732
|
checkForNewPiVersion(this.version).then((newRelease) => {
|
|
@@ -1259,6 +1378,7 @@ export class InteractiveMode {
|
|
|
1259
1378
|
if (result.cancelled) {
|
|
1260
1379
|
return { cancelled: true };
|
|
1261
1380
|
}
|
|
1381
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
1262
1382
|
this.clearChat();
|
|
1263
1383
|
this.renderInitialMessages();
|
|
1264
1384
|
if (result.editorText && !this.editor.getText().trim()) {
|
|
@@ -1292,8 +1412,12 @@ export class InteractiveMode {
|
|
|
1292
1412
|
this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });
|
|
1293
1413
|
this.showStartupNoticesIfNeeded();
|
|
1294
1414
|
}
|
|
1415
|
+
applyFullscreenScrollbarSetting() {
|
|
1416
|
+
this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
|
|
1417
|
+
}
|
|
1295
1418
|
applyRuntimeSettings() {
|
|
1296
1419
|
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
1420
|
+
this.applyFullscreenScrollbarSetting();
|
|
1297
1421
|
this.footer.setSession(this.session);
|
|
1298
1422
|
this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
1299
1423
|
this.footerDataProvider.setCwd(this.sessionManager.getCwd());
|
|
@@ -1362,6 +1486,10 @@ export class InteractiveMode {
|
|
|
1362
1486
|
this.pendingTools.clear();
|
|
1363
1487
|
}
|
|
1364
1488
|
renderCurrentSessionState() {
|
|
1489
|
+
// Resuming, forking, or starting a new session rebuilds the transcript
|
|
1490
|
+
// at the user's request; the rebuild's full redraw keeps the clean
|
|
1491
|
+
// wipe-and-replay even if preservation is still windowed on.
|
|
1492
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
1365
1493
|
this.loadedResourcesContainer.clear();
|
|
1366
1494
|
this.clearChat();
|
|
1367
1495
|
this.pendingMessagesContainer.clear();
|
|
@@ -1405,6 +1533,9 @@ export class InteractiveMode {
|
|
|
1405
1533
|
}
|
|
1406
1534
|
this.chatContainer.addChild(component);
|
|
1407
1535
|
}
|
|
1536
|
+
getMarkdownTransformers() {
|
|
1537
|
+
return [this.mermaidMarkdownTransformer, ...this.session.extensionRunner.getMarkdownTransformers()];
|
|
1538
|
+
}
|
|
1408
1539
|
/**
|
|
1409
1540
|
* Set up keyboard shortcuts registered by extensions.
|
|
1410
1541
|
*/
|
|
@@ -1484,7 +1615,7 @@ export class InteractiveMode {
|
|
|
1484
1615
|
this.activeStatusIndicator?.dispose();
|
|
1485
1616
|
this.activeStatusIndicator = undefined;
|
|
1486
1617
|
this.statusContainer.clear();
|
|
1487
|
-
if (hadActiveStatusIndicator && this.ui.getClearOnShrink()) {
|
|
1618
|
+
if (hadActiveStatusIndicator && this.options.tuiMode === "regular" && this.ui.getClearOnShrink()) {
|
|
1488
1619
|
this.statusContainer.addChild(this.idleStatus);
|
|
1489
1620
|
}
|
|
1490
1621
|
}
|
|
@@ -1598,7 +1729,7 @@ export class InteractiveMode {
|
|
|
1598
1729
|
this.setHiddenThinkingLabel();
|
|
1599
1730
|
}
|
|
1600
1731
|
// Maximum total widget lines to prevent viewport overflow
|
|
1601
|
-
static MAX_WIDGET_LINES = 10;
|
|
1732
|
+
static { this.MAX_WIDGET_LINES = 10; }
|
|
1602
1733
|
/**
|
|
1603
1734
|
* Render all extension widgets to the widget container.
|
|
1604
1735
|
*/
|
|
@@ -1632,22 +1763,16 @@ export class InteractiveMode {
|
|
|
1632
1763
|
if (this.customFooter?.dispose) {
|
|
1633
1764
|
this.customFooter.dispose();
|
|
1634
1765
|
}
|
|
1635
|
-
|
|
1636
|
-
if (this.customFooter) {
|
|
1637
|
-
this.ui.removeChild(this.customFooter);
|
|
1638
|
-
}
|
|
1639
|
-
else {
|
|
1640
|
-
this.ui.removeChild(this.footer);
|
|
1641
|
-
}
|
|
1766
|
+
this.footerContainer.clear();
|
|
1642
1767
|
if (factory) {
|
|
1643
1768
|
// Create and add custom footer, passing the data provider
|
|
1644
1769
|
this.customFooter = factory(this.ui, theme, this.footerDataProvider);
|
|
1645
|
-
this.
|
|
1770
|
+
this.footerContainer.addChild(this.customFooter);
|
|
1646
1771
|
}
|
|
1647
1772
|
else {
|
|
1648
1773
|
// Restore built-in footer
|
|
1649
1774
|
this.customFooter = undefined;
|
|
1650
|
-
this.
|
|
1775
|
+
this.footerContainer.addChild(this.footer);
|
|
1651
1776
|
}
|
|
1652
1777
|
this.ui.requestRender();
|
|
1653
1778
|
}
|
|
@@ -1693,18 +1818,27 @@ export class InteractiveMode {
|
|
|
1693
1818
|
this.ui.requestRender();
|
|
1694
1819
|
}
|
|
1695
1820
|
addExtensionTerminalInputListener(handler) {
|
|
1696
|
-
const
|
|
1697
|
-
this.
|
|
1821
|
+
const subscription = { handler, unsubscribe: this.ui.addInputListener(handler) };
|
|
1822
|
+
this.extensionTerminalInputSubscriptions.add(subscription);
|
|
1698
1823
|
return () => {
|
|
1699
|
-
unsubscribe();
|
|
1700
|
-
this.
|
|
1824
|
+
subscription.unsubscribe();
|
|
1825
|
+
this.extensionTerminalInputSubscriptions.delete(subscription);
|
|
1701
1826
|
};
|
|
1702
1827
|
}
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1828
|
+
rebindScrollbackPreservationInputListener() {
|
|
1829
|
+
this.scrollbackPreservationInputUnsubscribe?.();
|
|
1830
|
+
this.scrollbackPreservationInputUnsubscribe = this.ui.addInputListener(this.scrollbackPreservationInputHandler);
|
|
1831
|
+
}
|
|
1832
|
+
rebindExtensionTerminalInputListeners() {
|
|
1833
|
+
for (const subscription of this.extensionTerminalInputSubscriptions) {
|
|
1834
|
+
subscription.unsubscribe();
|
|
1835
|
+
subscription.unsubscribe = this.ui.addInputListener(subscription.handler);
|
|
1706
1836
|
}
|
|
1707
|
-
|
|
1837
|
+
}
|
|
1838
|
+
clearExtensionTerminalInputListeners() {
|
|
1839
|
+
for (const subscription of this.extensionTerminalInputSubscriptions)
|
|
1840
|
+
subscription.unsubscribe();
|
|
1841
|
+
this.extensionTerminalInputSubscriptions.clear();
|
|
1708
1842
|
}
|
|
1709
1843
|
/**
|
|
1710
1844
|
* Create the ExtensionUIContext for extensions.
|
|
@@ -1805,6 +1939,7 @@ export class InteractiveMode {
|
|
|
1805
1939
|
cancelHint: opts?.cancelHint,
|
|
1806
1940
|
onToggleToolsExpanded: () => this.toggleToolOutputExpansion(),
|
|
1807
1941
|
});
|
|
1942
|
+
this.disposeActiveSelector();
|
|
1808
1943
|
this.editorContainer.clear();
|
|
1809
1944
|
this.editorContainer.addChild(this.extensionSelector);
|
|
1810
1945
|
this.ui.setFocus(this.extensionSelector);
|
|
@@ -1826,7 +1961,9 @@ export class InteractiveMode {
|
|
|
1826
1961
|
* Show a confirmation dialog for extensions.
|
|
1827
1962
|
*/
|
|
1828
1963
|
async showExtensionConfirm(title, message, opts) {
|
|
1829
|
-
|
|
1964
|
+
// The message is context, not a heading: render it as the selector's muted
|
|
1965
|
+
// subtitle instead of folding it into the accent-bold title.
|
|
1966
|
+
const result = await this.showExtensionSelector(title, ["Yes", "No"], { ...opts, subtitle: message });
|
|
1830
1967
|
return result === "Yes";
|
|
1831
1968
|
}
|
|
1832
1969
|
async promptForMissingSessionCwd(error) {
|
|
@@ -1856,6 +1993,7 @@ export class InteractiveMode {
|
|
|
1856
1993
|
this.hideExtensionInput();
|
|
1857
1994
|
resolve(undefined);
|
|
1858
1995
|
}, { tui: this.ui, timeout: opts?.timeout });
|
|
1996
|
+
this.disposeActiveSelector();
|
|
1859
1997
|
this.editorContainer.clear();
|
|
1860
1998
|
this.editorContainer.addChild(this.extensionInput);
|
|
1861
1999
|
this.ui.setFocus(this.extensionInput);
|
|
@@ -1885,6 +2023,7 @@ export class InteractiveMode {
|
|
|
1885
2023
|
this.hideExtensionEditor();
|
|
1886
2024
|
resolve(undefined);
|
|
1887
2025
|
}, undefined, this.settingsManager.getExternalEditorCommand());
|
|
2026
|
+
this.disposeActiveSelector();
|
|
1888
2027
|
this.editorContainer.clear();
|
|
1889
2028
|
this.editorContainer.addChild(this.extensionEditor);
|
|
1890
2029
|
this.ui.setFocus(this.extensionEditor);
|
|
@@ -1909,6 +2048,7 @@ export class InteractiveMode {
|
|
|
1909
2048
|
this.editorComponentFactory = factory;
|
|
1910
2049
|
// Save text from current editor before switching
|
|
1911
2050
|
const currentText = this.editor.getText();
|
|
2051
|
+
this.disposeActiveSelector();
|
|
1912
2052
|
this.editorContainer.clear();
|
|
1913
2053
|
if (factory) {
|
|
1914
2054
|
// Create the custom editor with tui, theme, and keybindings
|
|
@@ -1925,6 +2065,9 @@ export class InteractiveMode {
|
|
|
1925
2065
|
if (newEditor.setPaddingX !== undefined) {
|
|
1926
2066
|
newEditor.setPaddingX(this.defaultEditor.getPaddingX());
|
|
1927
2067
|
}
|
|
2068
|
+
if (newEditor.setAutocompleteMaxVisible !== undefined) {
|
|
2069
|
+
newEditor.setAutocompleteMaxVisible(this.defaultEditor.getAutocompleteMaxVisible());
|
|
2070
|
+
}
|
|
1928
2071
|
// Set autocomplete if supported
|
|
1929
2072
|
if (newEditor.setAutocompleteProvider && this.autocompleteProvider) {
|
|
1930
2073
|
newEditor.setAutocompleteProvider(this.autocompleteProvider);
|
|
@@ -2029,6 +2172,7 @@ export class InteractiveMode {
|
|
|
2029
2172
|
options?.onHandle?.(handle);
|
|
2030
2173
|
}
|
|
2031
2174
|
else {
|
|
2175
|
+
this.disposeActiveSelector();
|
|
2032
2176
|
this.editorContainer.clear();
|
|
2033
2177
|
this.editorContainer.addChild(component);
|
|
2034
2178
|
this.ui.setFocus(component);
|
|
@@ -2115,7 +2259,7 @@ export class InteractiveMode {
|
|
|
2115
2259
|
this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
|
|
2116
2260
|
this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
|
|
2117
2261
|
this.defaultEditor.onAction("app.editor.external", () => void this.handleOpenExternalEditor());
|
|
2118
|
-
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand());
|
|
2262
|
+
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true }));
|
|
2119
2263
|
this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
|
|
2120
2264
|
this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
|
|
2121
2265
|
this.defaultEditor.onAction("app.session.new", () => this.handleClearCommand());
|
|
@@ -2416,17 +2560,17 @@ export class InteractiveMode {
|
|
|
2416
2560
|
this.ui.requestRender();
|
|
2417
2561
|
}
|
|
2418
2562
|
else if (event.message.role === "assistant") {
|
|
2419
|
-
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad);
|
|
2563
|
+
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
2420
2564
|
this.streamingMessage = event.message;
|
|
2421
2565
|
this.chatContainer.addChild(this.streamingComponent);
|
|
2422
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2566
|
+
this.streamingComponent.updateContent(this.streamingMessage, true);
|
|
2423
2567
|
this.ui.requestRender();
|
|
2424
2568
|
}
|
|
2425
2569
|
break;
|
|
2426
2570
|
case "message_update":
|
|
2427
2571
|
if (this.streamingComponent && event.message.role === "assistant") {
|
|
2428
2572
|
this.streamingMessage = event.message;
|
|
2429
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2573
|
+
this.streamingComponent.updateContent(this.streamingMessage, true);
|
|
2430
2574
|
for (const content of this.streamingMessage.content) {
|
|
2431
2575
|
if (content.type === "toolCall") {
|
|
2432
2576
|
if (!this.pendingTools.has(content.id)) {
|
|
@@ -2459,7 +2603,7 @@ export class InteractiveMode {
|
|
|
2459
2603
|
: "Operation aborted";
|
|
2460
2604
|
this.streamingMessage.errorMessage = errorMessage;
|
|
2461
2605
|
}
|
|
2462
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
2606
|
+
this.streamingComponent.updateContent(this.streamingMessage, false);
|
|
2463
2607
|
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
|
2464
2608
|
if (!errorMessage) {
|
|
2465
2609
|
errorMessage = this.streamingMessage.errorMessage || "Error";
|
|
@@ -2735,12 +2879,12 @@ export class InteractiveMode {
|
|
|
2735
2879
|
// Render user message separately if present
|
|
2736
2880
|
if (skillBlock.userMessage) {
|
|
2737
2881
|
this.chatContainer.addChild(new Spacer(1));
|
|
2738
|
-
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
2882
|
+
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad, this.getMarkdownTransformers());
|
|
2739
2883
|
this.chatContainer.addChild(userComponent);
|
|
2740
2884
|
}
|
|
2741
2885
|
}
|
|
2742
2886
|
else {
|
|
2743
|
-
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
2887
|
+
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad, this.getMarkdownTransformers());
|
|
2744
2888
|
this.chatContainer.addChild(userComponent);
|
|
2745
2889
|
}
|
|
2746
2890
|
if (options?.populateHistory) {
|
|
@@ -2750,7 +2894,7 @@ export class InteractiveMode {
|
|
|
2750
2894
|
break;
|
|
2751
2895
|
}
|
|
2752
2896
|
case "assistant": {
|
|
2753
|
-
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad);
|
|
2897
|
+
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
2754
2898
|
this.chatContainer.addChild(assistantComponent);
|
|
2755
2899
|
break;
|
|
2756
2900
|
}
|
|
@@ -2933,12 +3077,6 @@ export class InteractiveMode {
|
|
|
2933
3077
|
// Only called when editor is empty (enforced by CustomEditor)
|
|
2934
3078
|
void this.shutdown();
|
|
2935
3079
|
}
|
|
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
3080
|
async shutdown(options) {
|
|
2943
3081
|
if (this.isShuttingDown)
|
|
2944
3082
|
return;
|
|
@@ -3180,6 +3318,8 @@ export class InteractiveMode {
|
|
|
3180
3318
|
this.setToolsExpanded(!this.toolOutputExpanded);
|
|
3181
3319
|
}
|
|
3182
3320
|
setToolsExpanded(expanded) {
|
|
3321
|
+
if (expanded === this.toolOutputExpanded)
|
|
3322
|
+
return;
|
|
3183
3323
|
this.toolOutputExpanded = expanded;
|
|
3184
3324
|
// An explicit toggle prefers upstream's clean wipe-and-replay even
|
|
3185
3325
|
// mid-run: the user just pressed the key, so they are interacting at
|
|
@@ -3242,7 +3382,7 @@ export class InteractiveMode {
|
|
|
3242
3382
|
}
|
|
3243
3383
|
showError(errorMessage) {
|
|
3244
3384
|
this.chatContainer.addChild(new Spacer(1));
|
|
3245
|
-
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`),
|
|
3385
|
+
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`), this.outputPad, 0));
|
|
3246
3386
|
this.ui.requestRender();
|
|
3247
3387
|
}
|
|
3248
3388
|
showWarning(warningMessage) {
|
|
@@ -3448,52 +3588,50 @@ export class InteractiveMode {
|
|
|
3448
3588
|
// =========================================================================
|
|
3449
3589
|
// Selectors
|
|
3450
3590
|
// =========================================================================
|
|
3591
|
+
disposeActiveSelector() {
|
|
3592
|
+
const dispose = this.activeSelectorDispose;
|
|
3593
|
+
this.activeSelectorToken = undefined;
|
|
3594
|
+
this.activeSelectorDispose = undefined;
|
|
3595
|
+
dispose?.();
|
|
3596
|
+
}
|
|
3451
3597
|
/**
|
|
3452
3598
|
* Shows a selector component in place of the editor.
|
|
3453
3599
|
* @param create Factory that receives a `done` callback and returns the component and focus target
|
|
3454
3600
|
*/
|
|
3455
3601
|
showSelector(create) {
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
this.activeSelector = null;
|
|
3459
|
-
let selector;
|
|
3602
|
+
const token = {};
|
|
3603
|
+
let dispose;
|
|
3460
3604
|
let disposed = false;
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
if (disposed || !selector)
|
|
3605
|
+
const disposeOnce = () => {
|
|
3606
|
+
if (disposed)
|
|
3464
3607
|
return;
|
|
3465
3608
|
disposed = true;
|
|
3466
|
-
|
|
3609
|
+
dispose?.();
|
|
3467
3610
|
};
|
|
3468
3611
|
const done = () => {
|
|
3469
|
-
|
|
3612
|
+
disposeOnce();
|
|
3613
|
+
if (this.activeSelectorToken !== token)
|
|
3470
3614
|
return;
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
this.editorContainer.clear();
|
|
3477
|
-
this.editorContainer.addChild(this.editor);
|
|
3478
|
-
this.ui.setFocus(this.editor);
|
|
3479
|
-
}
|
|
3615
|
+
this.activeSelectorToken = undefined;
|
|
3616
|
+
this.activeSelectorDispose = undefined;
|
|
3617
|
+
this.editorContainer.clear();
|
|
3618
|
+
this.editorContainer.addChild(this.editor);
|
|
3619
|
+
this.ui.setFocus(this.editor);
|
|
3480
3620
|
};
|
|
3481
3621
|
const created = create(done);
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
}
|
|
3487
|
-
this.activeSelector = selector;
|
|
3488
|
-
this.activeSelectorCleanup = dispose;
|
|
3622
|
+
dispose = created.dispose;
|
|
3623
|
+
this.disposeActiveSelector();
|
|
3624
|
+
this.activeSelectorToken = token;
|
|
3625
|
+
this.activeSelectorDispose = disposeOnce;
|
|
3489
3626
|
this.editorContainer.clear();
|
|
3490
|
-
this.editorContainer.addChild(
|
|
3627
|
+
this.editorContainer.addChild(created.component);
|
|
3491
3628
|
this.ui.setFocus(created.focus);
|
|
3492
3629
|
this.ui.requestRender();
|
|
3493
3630
|
}
|
|
3494
3631
|
showSettingsSelector() {
|
|
3495
3632
|
this.showSelector((done) => {
|
|
3496
|
-
|
|
3633
|
+
let selector;
|
|
3634
|
+
selector = new SettingsSelectorComponent({
|
|
3497
3635
|
autoCompact: this.session.autoCompactionEnabled,
|
|
3498
3636
|
showImages: this.settingsManager.getShowImages(),
|
|
3499
3637
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
@@ -3510,6 +3648,7 @@ export class InteractiveMode {
|
|
|
3510
3648
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3511
3649
|
availableThemes: getAvailableThemes(),
|
|
3512
3650
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
3651
|
+
mermaidRenderingMode: this.settingsManager.getMermaidRenderingMode(),
|
|
3513
3652
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
3514
3653
|
enableInstallTelemetry: this.settingsManager.getEnableInstallTelemetry(),
|
|
3515
3654
|
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
@@ -3523,6 +3662,8 @@ export class InteractiveMode {
|
|
|
3523
3662
|
quietStartup: this.settingsManager.getQuietStartup(),
|
|
3524
3663
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
3525
3664
|
showTerminalProgress: this.settingsManager.getShowTerminalProgress(),
|
|
3665
|
+
tuiMode: this.ui.mode,
|
|
3666
|
+
fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
3526
3667
|
warnings: this.settingsManager.getWarnings(),
|
|
3527
3668
|
}, {
|
|
3528
3669
|
onAutoCompactChange: (enabled) => {
|
|
@@ -3591,6 +3732,11 @@ export class InteractiveMode {
|
|
|
3591
3732
|
this.clearChat();
|
|
3592
3733
|
this.rebuildChatFromMessages();
|
|
3593
3734
|
},
|
|
3735
|
+
onMermaidRenderingModeChange: (mode) => {
|
|
3736
|
+
this.settingsManager.setMermaidRenderingMode(mode);
|
|
3737
|
+
this.chatContainer.invalidate();
|
|
3738
|
+
this.ui.requestRender();
|
|
3739
|
+
},
|
|
3594
3740
|
onShowCacheMissNoticesChange: (shown) => {
|
|
3595
3741
|
this.settingsManager.setShowCacheMissNotices(shown);
|
|
3596
3742
|
this.rebuildChatFromMessages();
|
|
@@ -3660,6 +3806,21 @@ export class InteractiveMode {
|
|
|
3660
3806
|
onShowTerminalProgressChange: (enabled) => {
|
|
3661
3807
|
this.settingsManager.setShowTerminalProgress(enabled);
|
|
3662
3808
|
},
|
|
3809
|
+
onTuiModeChange: (mode) => {
|
|
3810
|
+
if (!this.switchTuiMode(mode)) {
|
|
3811
|
+
selector?.getSettingsList().updateValue("tui-mode", this.ui.mode);
|
|
3812
|
+
this.showStatus("Close active overlays before changing TUI mode");
|
|
3813
|
+
return;
|
|
3814
|
+
}
|
|
3815
|
+
this.settingsManager.setTuiMode(mode);
|
|
3816
|
+
if (!this.activeStatusIndicator)
|
|
3817
|
+
this.statusContainer.clear();
|
|
3818
|
+
this.showStatus(`TUI mode: ${mode}`);
|
|
3819
|
+
},
|
|
3820
|
+
onFullscreenScrollbarChange: (mode) => {
|
|
3821
|
+
this.settingsManager.setFullscreenScrollbar(mode);
|
|
3822
|
+
this.applyFullscreenScrollbarSetting();
|
|
3823
|
+
},
|
|
3663
3824
|
onWarningsChange: (warnings) => {
|
|
3664
3825
|
this.settingsManager.setWarnings(warnings);
|
|
3665
3826
|
},
|
|
@@ -3694,20 +3855,37 @@ export class InteractiveMode {
|
|
|
3694
3855
|
this.showModelSelector(searchTerm);
|
|
3695
3856
|
}
|
|
3696
3857
|
async findExactModelMatch(searchTerm) {
|
|
3697
|
-
const
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
if (this.session.scopedModels.length > 0)
|
|
3702
|
-
return
|
|
3703
|
-
|
|
3858
|
+
const cachedModels = this.session.scopedModels.length > 0
|
|
3859
|
+
? this.session.scopedModels.map((scoped) => scoped.model)
|
|
3860
|
+
: [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
3861
|
+
const cachedMatch = findExactModelReferenceMatch(searchTerm, cachedModels);
|
|
3862
|
+
if (cachedMatch || this.session.scopedModels.length > 0)
|
|
3863
|
+
return cachedMatch;
|
|
3864
|
+
this.showStatus("Refreshing model catalogs…");
|
|
3865
|
+
const controller = new AbortController();
|
|
3866
|
+
let timedOut = false;
|
|
3867
|
+
const timeout = setTimeout(() => {
|
|
3868
|
+
timedOut = true;
|
|
3869
|
+
controller.abort();
|
|
3870
|
+
}, 15_000);
|
|
3704
3871
|
try {
|
|
3705
|
-
await this.session.modelRuntime.refresh();
|
|
3706
|
-
|
|
3872
|
+
const result = await this.session.modelRuntime.refresh({ signal: controller.signal });
|
|
3873
|
+
if (result.aborted && timedOut) {
|
|
3874
|
+
this.showWarning("Model refresh timed out; searching cached models.");
|
|
3875
|
+
}
|
|
3876
|
+
else if (result.errors.size > 0) {
|
|
3877
|
+
this.showWarning(`Could not refresh ${[...result.errors.keys()].join(", ")}; searching cached models.`);
|
|
3878
|
+
}
|
|
3707
3879
|
}
|
|
3708
|
-
catch {
|
|
3709
|
-
|
|
3880
|
+
catch (error) {
|
|
3881
|
+
this.showWarning(timedOut
|
|
3882
|
+
? "Model refresh timed out; searching cached models."
|
|
3883
|
+
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`);
|
|
3710
3884
|
}
|
|
3885
|
+
finally {
|
|
3886
|
+
clearTimeout(timeout);
|
|
3887
|
+
}
|
|
3888
|
+
return findExactModelReferenceMatch(searchTerm, [...this.session.modelRuntime.getAvailableSnapshot()]);
|
|
3711
3889
|
}
|
|
3712
3890
|
/** Update the footer's available provider count from the current snapshot without refreshing catalogs. */
|
|
3713
3891
|
updateAvailableProviderCount() {
|
|
@@ -3809,73 +3987,67 @@ export class InteractiveMode {
|
|
|
3809
3987
|
done();
|
|
3810
3988
|
this.ui.requestRender();
|
|
3811
3989
|
}, initialSearchInput);
|
|
3812
|
-
return { component: selector, focus: selector };
|
|
3990
|
+
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
3813
3991
|
});
|
|
3814
3992
|
}
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
const allModels = [...(await this.session.modelRuntime.getAvailable())];
|
|
3819
|
-
const allModelIds = new Set(allModels.map((model) => `${model.provider}/${model.id}`));
|
|
3993
|
+
showModelsSelector() {
|
|
3994
|
+
let availableModels = [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
3995
|
+
let availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));
|
|
3820
3996
|
const configuredPatterns = this.settingsManager.getEnabledModels();
|
|
3821
3997
|
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) => {
|
|
3998
|
+
const configuredEnabledIds = (models) => {
|
|
3999
|
+
if (!configuredPatterns?.length)
|
|
4000
|
+
return null;
|
|
4001
|
+
const resolved = resolveModelScopeFromModels(configuredPatterns, models);
|
|
4002
|
+
const ids = resolved.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);
|
|
4003
|
+
for (const diagnostic of resolved.diagnostics) {
|
|
4004
|
+
if (diagnostic.code === "no-match" && !ids.includes(diagnostic.pattern))
|
|
4005
|
+
ids.push(diagnostic.pattern);
|
|
4006
|
+
}
|
|
4007
|
+
return ids;
|
|
4008
|
+
};
|
|
4009
|
+
let currentEnabledIds = sessionScopedModels.length > 0
|
|
4010
|
+
? sessionScopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`)
|
|
4011
|
+
: configuredEnabledIds(availableModels);
|
|
4012
|
+
let selectionChanged = false;
|
|
4013
|
+
const updateSessionModels = (enabledIds) => {
|
|
3849
4014
|
currentEnabledIds = enabledIds === null ? null : [...enabledIds];
|
|
3850
|
-
const hasEnabledAvailableModel = enabledIds?.some((id) =>
|
|
3851
|
-
const allAvailableModelsEnabled = enabledIds !== null && [...
|
|
4015
|
+
const hasEnabledAvailableModel = enabledIds?.some((id) => availableModelIds.has(id)) ?? false;
|
|
4016
|
+
const allAvailableModelsEnabled = enabledIds !== null && [...availableModelIds].every((id) => enabledIds.includes(id));
|
|
3852
4017
|
if (enabledIds && hasEnabledAvailableModel && !allAvailableModelsEnabled) {
|
|
3853
|
-
const newScopedModels =
|
|
3854
|
-
this.session.setScopedModels(newScopedModels.map((
|
|
3855
|
-
model:
|
|
3856
|
-
thinkingLevel:
|
|
4018
|
+
const newScopedModels = resolveModelScopeFromModels(enabledIds, availableModels).scopedModels;
|
|
4019
|
+
this.session.setScopedModels(newScopedModels.map((scoped) => ({
|
|
4020
|
+
model: scoped.model,
|
|
4021
|
+
thinkingLevel: scoped.thinkingLevel,
|
|
3857
4022
|
})));
|
|
3858
4023
|
}
|
|
3859
4024
|
else {
|
|
3860
|
-
// All enabled or none enabled = no filter
|
|
3861
4025
|
this.session.setScopedModels([]);
|
|
3862
4026
|
}
|
|
3863
|
-
|
|
4027
|
+
this.updateAvailableProviderCount();
|
|
3864
4028
|
this.ui.requestRender();
|
|
3865
4029
|
};
|
|
3866
4030
|
this.showSelector((done) => {
|
|
4031
|
+
let disposed = false;
|
|
4032
|
+
let timedOut = false;
|
|
4033
|
+
const controller = new AbortController();
|
|
4034
|
+
const timeout = setTimeout(() => {
|
|
4035
|
+
timedOut = true;
|
|
4036
|
+
controller.abort();
|
|
4037
|
+
}, 15_000);
|
|
3867
4038
|
const selector = new ScopedModelsSelectorComponent({
|
|
3868
|
-
allModels,
|
|
4039
|
+
allModels: availableModels,
|
|
3869
4040
|
enabledModelIds: currentEnabledIds,
|
|
4041
|
+
refreshStatus: "Refreshing model catalogs…",
|
|
3870
4042
|
}, {
|
|
3871
|
-
onChange:
|
|
3872
|
-
|
|
4043
|
+
onChange: (enabledIds) => {
|
|
4044
|
+
selectionChanged = true;
|
|
4045
|
+
updateSessionModels(enabledIds);
|
|
3873
4046
|
},
|
|
3874
4047
|
onPersist: (enabledIds) => {
|
|
3875
|
-
// Persist to settings
|
|
3876
4048
|
const allEnabled = enabledIds !== null &&
|
|
3877
|
-
enabledIds.length ===
|
|
3878
|
-
enabledIds.every((id) =>
|
|
4049
|
+
enabledIds.length === availableModels.length &&
|
|
4050
|
+
enabledIds.every((id) => availableModelIds.has(id));
|
|
3879
4051
|
const newPatterns = enabledIds === null || allEnabled ? undefined : enabledIds;
|
|
3880
4052
|
this.settingsManager.setEnabledModels(newPatterns ? [...newPatterns] : undefined);
|
|
3881
4053
|
this.showStatus("Model selection saved to settings");
|
|
@@ -3885,7 +4057,51 @@ export class InteractiveMode {
|
|
|
3885
4057
|
this.ui.requestRender();
|
|
3886
4058
|
},
|
|
3887
4059
|
});
|
|
3888
|
-
|
|
4060
|
+
void this.session.modelRuntime
|
|
4061
|
+
.refresh({ signal: controller.signal })
|
|
4062
|
+
.then((result) => {
|
|
4063
|
+
if (disposed)
|
|
4064
|
+
return;
|
|
4065
|
+
availableModels = [...this.session.modelRuntime.getAvailableSnapshot()];
|
|
4066
|
+
availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));
|
|
4067
|
+
if (!selectionChanged && sessionScopedModels.length === 0) {
|
|
4068
|
+
currentEnabledIds = configuredEnabledIds(availableModels);
|
|
4069
|
+
selector.updateModels(availableModels, currentEnabledIds);
|
|
4070
|
+
}
|
|
4071
|
+
else {
|
|
4072
|
+
selector.updateModels(availableModels);
|
|
4073
|
+
}
|
|
4074
|
+
if (currentEnabledIds !== null)
|
|
4075
|
+
updateSessionModels(currentEnabledIds);
|
|
4076
|
+
if (result.aborted && timedOut) {
|
|
4077
|
+
selector.setRefreshStatus("Model refresh timed out; showing cached models.", "warning");
|
|
4078
|
+
}
|
|
4079
|
+
else if (result.errors.size > 0) {
|
|
4080
|
+
selector.setRefreshStatus(`Could not refresh ${[...result.errors.keys()].join(", ")}; showing cached models.`, "warning");
|
|
4081
|
+
}
|
|
4082
|
+
else {
|
|
4083
|
+
selector.setRefreshStatus("Model catalogs refreshed.", "success");
|
|
4084
|
+
}
|
|
4085
|
+
this.ui.requestRender();
|
|
4086
|
+
})
|
|
4087
|
+
.catch((error) => {
|
|
4088
|
+
if (disposed)
|
|
4089
|
+
return;
|
|
4090
|
+
selector.setRefreshStatus(timedOut
|
|
4091
|
+
? "Model refresh timed out; showing cached models."
|
|
4092
|
+
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
4093
|
+
this.ui.requestRender();
|
|
4094
|
+
})
|
|
4095
|
+
.finally(() => clearTimeout(timeout));
|
|
4096
|
+
return {
|
|
4097
|
+
component: selector,
|
|
4098
|
+
focus: selector,
|
|
4099
|
+
dispose: () => {
|
|
4100
|
+
disposed = true;
|
|
4101
|
+
clearTimeout(timeout);
|
|
4102
|
+
controller.abort();
|
|
4103
|
+
},
|
|
4104
|
+
};
|
|
3889
4105
|
});
|
|
3890
4106
|
}
|
|
3891
4107
|
showUserMessageSelector() {
|
|
@@ -4014,6 +4230,9 @@ export class InteractiveMode {
|
|
|
4014
4230
|
this.showStatus("Navigation cancelled");
|
|
4015
4231
|
return;
|
|
4016
4232
|
}
|
|
4233
|
+
// User-committed tree navigation rebuilds the transcript; its
|
|
4234
|
+
// full redraw bypasses scrollback preservation.
|
|
4235
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
4017
4236
|
// Update UI
|
|
4018
4237
|
this.clearChat();
|
|
4019
4238
|
this.renderInitialMessages();
|
|
@@ -4147,7 +4366,7 @@ export class InteractiveMode {
|
|
|
4147
4366
|
return options.sort((a, b) => a.name.localeCompare(b.name));
|
|
4148
4367
|
}
|
|
4149
4368
|
async getLogoutProviderOptions() {
|
|
4150
|
-
return (await this.session.modelRuntime.listCredentials())
|
|
4369
|
+
return (await this.session.modelRuntime.listCredentials({ signal: AbortSignal.timeout(15_000) }))
|
|
4151
4370
|
.map(({ providerId, type }) => ({
|
|
4152
4371
|
id: providerId,
|
|
4153
4372
|
name: this.session.modelRuntime.getProvider(providerId)?.name ?? providerId,
|
|
@@ -4165,7 +4384,6 @@ export class InteractiveMode {
|
|
|
4165
4384
|
provider.name.toLowerCase() === normalizedProviderRef);
|
|
4166
4385
|
}
|
|
4167
4386
|
async handleLoginCommand(providerRef) {
|
|
4168
|
-
await this.session.modelRuntime.getAvailable();
|
|
4169
4387
|
if (!providerRef) {
|
|
4170
4388
|
this.showLoginAuthTypeSelector();
|
|
4171
4389
|
return;
|
|
@@ -4279,7 +4497,14 @@ export class InteractiveMode {
|
|
|
4279
4497
|
this.showLoginAuthTypeSelector();
|
|
4280
4498
|
return;
|
|
4281
4499
|
}
|
|
4282
|
-
|
|
4500
|
+
let providerOptions;
|
|
4501
|
+
try {
|
|
4502
|
+
providerOptions = await this.getLogoutProviderOptions();
|
|
4503
|
+
}
|
|
4504
|
+
catch (error) {
|
|
4505
|
+
this.showError(`Could not read stored credentials: ${error instanceof Error ? error.message : String(error)}`);
|
|
4506
|
+
return;
|
|
4507
|
+
}
|
|
4283
4508
|
if (providerOptions.length === 0) {
|
|
4284
4509
|
this.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");
|
|
4285
4510
|
return;
|
|
@@ -4292,7 +4517,9 @@ export class InteractiveMode {
|
|
|
4292
4517
|
return;
|
|
4293
4518
|
}
|
|
4294
4519
|
try {
|
|
4295
|
-
await this.session.modelRuntime.logout(providerOption.id
|
|
4520
|
+
await this.session.modelRuntime.logout(providerOption.id, {
|
|
4521
|
+
signal: AbortSignal.timeout(15_000),
|
|
4522
|
+
});
|
|
4296
4523
|
await this.updateAvailableProviderCount();
|
|
4297
4524
|
const message = providerOption.authType === "oauth"
|
|
4298
4525
|
? `Logged out of ${providerOption.name}`
|
|
@@ -4300,7 +4527,10 @@ export class InteractiveMode {
|
|
|
4300
4527
|
this.showStatus(message);
|
|
4301
4528
|
}
|
|
4302
4529
|
catch (error) {
|
|
4303
|
-
|
|
4530
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4531
|
+
this.showError(error instanceof CredentialSynchronizationError
|
|
4532
|
+
? `Credentials removed for ${providerOption.name}, but local model state could not be synchronized: ${message}`
|
|
4533
|
+
: `Logout failed: ${message}`);
|
|
4304
4534
|
}
|
|
4305
4535
|
}, () => {
|
|
4306
4536
|
done();
|
|
@@ -4310,12 +4540,11 @@ export class InteractiveMode {
|
|
|
4310
4540
|
});
|
|
4311
4541
|
}
|
|
4312
4542
|
async completeProviderAuthentication(providerId, providerName, authType, previousModel) {
|
|
4313
|
-
await this.session.modelRuntime.getAvailable();
|
|
4314
4543
|
const actionLabel = authType === "oauth" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;
|
|
4315
4544
|
let selectedModel;
|
|
4316
4545
|
let selectionError;
|
|
4317
4546
|
if (isUnknownModel(previousModel)) {
|
|
4318
|
-
const availableModels =
|
|
4547
|
+
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4319
4548
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4320
4549
|
if (!hasDefaultModelProvider(providerId)) {
|
|
4321
4550
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
@@ -4358,6 +4587,25 @@ export class InteractiveMode {
|
|
|
4358
4587
|
void this.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
4359
4588
|
}
|
|
4360
4589
|
}
|
|
4590
|
+
const controller = new AbortController();
|
|
4591
|
+
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
4592
|
+
void this.session.modelRuntime
|
|
4593
|
+
.refresh({ providers: [providerId], signal: controller.signal })
|
|
4594
|
+
.then((result) => {
|
|
4595
|
+
if (result.aborted) {
|
|
4596
|
+
this.showWarning(`${actionLabel}, but its model catalog refresh timed out; using cached models.`);
|
|
4597
|
+
}
|
|
4598
|
+
else if (result.errors.size > 0) {
|
|
4599
|
+
this.showWarning(`${actionLabel}, but its model catalog could not be refreshed; using cached models.`);
|
|
4600
|
+
}
|
|
4601
|
+
this.updateAvailableProviderCount();
|
|
4602
|
+
this.footer.invalidate();
|
|
4603
|
+
this.ui.requestRender();
|
|
4604
|
+
})
|
|
4605
|
+
.catch((error) => {
|
|
4606
|
+
this.showWarning(`${actionLabel}, but its model catalog could not be refreshed: ${error instanceof Error ? error.message : String(error)}`);
|
|
4607
|
+
})
|
|
4608
|
+
.finally(() => clearTimeout(timeout));
|
|
4361
4609
|
}
|
|
4362
4610
|
showAmbientAuthDialog(providerOption) {
|
|
4363
4611
|
const restoreEditor = () => {
|
|
@@ -4403,7 +4651,10 @@ export class InteractiveMode {
|
|
|
4403
4651
|
catch (error) {
|
|
4404
4652
|
restoreEditor();
|
|
4405
4653
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4406
|
-
if (
|
|
4654
|
+
if (error instanceof CredentialSynchronizationError) {
|
|
4655
|
+
this.showError(`Saved API key for ${providerName}, but local model state could not be synchronized: ${errorMsg}`);
|
|
4656
|
+
}
|
|
4657
|
+
else if (errorMsg !== "Login cancelled") {
|
|
4407
4658
|
this.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);
|
|
4408
4659
|
}
|
|
4409
4660
|
}
|
|
@@ -4506,7 +4757,10 @@ export class InteractiveMode {
|
|
|
4506
4757
|
catch (error) {
|
|
4507
4758
|
restoreEditor();
|
|
4508
4759
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4509
|
-
if (
|
|
4760
|
+
if (error instanceof CredentialSynchronizationError) {
|
|
4761
|
+
this.showError(`Logged in to ${providerName}, but local model state could not be synchronized: ${errorMsg}`);
|
|
4762
|
+
}
|
|
4763
|
+
else if (errorMsg !== "Login cancelled") {
|
|
4510
4764
|
this.showError(`Failed to login to ${providerName}: ${errorMsg}`);
|
|
4511
4765
|
}
|
|
4512
4766
|
}
|
|
@@ -4551,13 +4805,16 @@ export class InteractiveMode {
|
|
|
4551
4805
|
}
|
|
4552
4806
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
4553
4807
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
4808
|
+
// The user asked for this rebuild; its full redraw keeps the
|
|
4809
|
+
// upstream wipe-and-replay even if preservation is still windowed
|
|
4810
|
+
// on from the previous run.
|
|
4811
|
+
this.coalescingTerminal.passNextFullRedraw();
|
|
4554
4812
|
this.rebuildChatFromMessages();
|
|
4555
4813
|
chatRestoredBeforeSessionStart = true;
|
|
4556
4814
|
};
|
|
4557
4815
|
try {
|
|
4558
4816
|
await this.session.reload({ beforeSessionStart: restoreChatBeforeSessionStart });
|
|
4559
4817
|
restoreChatBeforeSessionStart();
|
|
4560
|
-
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
4561
4818
|
this.keybindings.reload();
|
|
4562
4819
|
const activeHeader = this.customHeader ?? this.builtInHeader;
|
|
4563
4820
|
if (isExpandable(activeHeader)) {
|
|
@@ -4565,20 +4822,7 @@ export class InteractiveMode {
|
|
|
4565
4822
|
}
|
|
4566
4823
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
4567
4824
|
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
|
-
}
|
|
4825
|
+
this.applyRuntimeSettings();
|
|
4582
4826
|
this.setupAutocompleteProvider();
|
|
4583
4827
|
const runner = this.session.extensionRunner;
|
|
4584
4828
|
this.setupExtensionShortcuts(runner);
|
|
@@ -4774,7 +5018,7 @@ export class InteractiveMode {
|
|
|
4774
5018
|
}
|
|
4775
5019
|
}
|
|
4776
5020
|
}
|
|
4777
|
-
async handleCopyCommand() {
|
|
5021
|
+
async handleCopyCommand(options = {}) {
|
|
4778
5022
|
const text = this.session.getLastAssistantText();
|
|
4779
5023
|
if (!text) {
|
|
4780
5024
|
this.showError("No agent messages to copy yet.");
|
|
@@ -4782,7 +5026,12 @@ export class InteractiveMode {
|
|
|
4782
5026
|
}
|
|
4783
5027
|
try {
|
|
4784
5028
|
await copyToClipboard(text);
|
|
4785
|
-
|
|
5029
|
+
if (options.flashConfirmation && this.ui instanceof TuiAltScreen) {
|
|
5030
|
+
this.ui.flash("Copied!");
|
|
5031
|
+
}
|
|
5032
|
+
else {
|
|
5033
|
+
this.showStatus("Copied last agent message to clipboard");
|
|
5034
|
+
}
|
|
4786
5035
|
}
|
|
4787
5036
|
catch (error) {
|
|
4788
5037
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
@@ -5145,15 +5394,15 @@ export class InteractiveMode {
|
|
|
5145
5394
|
}
|
|
5146
5395
|
}
|
|
5147
5396
|
stop() {
|
|
5148
|
-
this.
|
|
5149
|
-
this.activeSelectorCleanup = null;
|
|
5150
|
-
this.activeSelector = null;
|
|
5397
|
+
this.disposeActiveSelector();
|
|
5151
5398
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
5152
5399
|
this.ui.terminal.setProgress(false);
|
|
5153
5400
|
}
|
|
5154
5401
|
this.clearStatusIndicator();
|
|
5155
5402
|
this.themeController.disableAutoSync();
|
|
5156
5403
|
this.clearExtensionTerminalInputListeners();
|
|
5404
|
+
this.scrollbackPreservationInputUnsubscribe?.();
|
|
5405
|
+
this.scrollbackPreservationInputUnsubscribe = undefined;
|
|
5157
5406
|
this.clearPendingTools();
|
|
5158
5407
|
this.disposeChatToolComponents();
|
|
5159
5408
|
this.footer.dispose();
|
|
@@ -5162,7 +5411,7 @@ export class InteractiveMode {
|
|
|
5162
5411
|
this.unsubscribe();
|
|
5163
5412
|
}
|
|
5164
5413
|
if (this.isInitialized) {
|
|
5165
|
-
this.
|
|
5414
|
+
this.stopInteractiveTui();
|
|
5166
5415
|
this.isInitialized = false;
|
|
5167
5416
|
}
|
|
5168
5417
|
this.unregisterSignalHandlers();
|