@caupulican/pi-adaptative 0.80.102 → 0.81.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 +131 -0
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -3
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +6 -6
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +152 -512
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +635 -4590
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
- package/dist/core/autonomy/session-lane-record.js.map +1 -1
- package/dist/core/autonomy/status.d.ts +1 -0
- package/dist/core/autonomy/status.d.ts.map +1 -1
- package/dist/core/autonomy/status.js +1 -0
- package/dist/core/autonomy/status.js.map +1 -1
- package/dist/core/autonomy-telemetry.d.ts +80 -0
- package/dist/core/autonomy-telemetry.d.ts.map +1 -0
- package/dist/core/autonomy-telemetry.js +266 -0
- package/dist/core/autonomy-telemetry.js.map +1 -0
- package/dist/core/background-lane-controller.d.ts +186 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -0
- package/dist/core/background-lane-controller.js +691 -0
- package/dist/core/background-lane-controller.js.map +1 -0
- package/dist/core/bash-execution-controller.d.ts +51 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -0
- package/dist/core/bash-execution-controller.js +96 -0
- package/dist/core/bash-execution-controller.js.map +1 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +9 -2
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction-support.d.ts +56 -0
- package/dist/core/compaction-support.d.ts.map +1 -0
- package/dist/core/compaction-support.js +99 -0
- package/dist/core/compaction-support.js.map +1 -0
- package/dist/core/context/artifact-retrieval.d.ts +1 -1
- package/dist/core/context/artifact-retrieval.d.ts.map +1 -1
- package/dist/core/context/artifact-retrieval.js +1 -1
- package/dist/core/context/artifact-retrieval.js.map +1 -1
- package/dist/core/context/context-composition.d.ts.map +1 -1
- package/dist/core/context/context-composition.js +1 -1
- package/dist/core/context/context-composition.js.map +1 -1
- package/dist/core/context/tool-output-packer.d.ts +1 -1
- package/dist/core/context/tool-output-packer.d.ts.map +1 -1
- package/dist/core/context/tool-output-packer.js +1 -1
- package/dist/core/context/tool-output-packer.js.map +1 -1
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +1 -1
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +223 -0
- package/dist/core/context-pipeline.d.ts.map +1 -0
- package/dist/core/context-pipeline.js +594 -0
- package/dist/core/context-pipeline.js.map +1 -0
- package/dist/core/cost/daily-usage.d.ts +1 -1
- package/dist/core/cost/daily-usage.d.ts.map +1 -1
- package/dist/core/cost/daily-usage.js +1 -1
- package/dist/core/cost/daily-usage.js.map +1 -1
- package/dist/core/cost/session-usage.d.ts +1 -1
- package/dist/core/cost/session-usage.d.ts.map +1 -1
- package/dist/core/cost/session-usage.js +1 -1
- package/dist/core/cost/session-usage.js.map +1 -1
- package/dist/core/delegation/session-worker-result.d.ts +1 -1
- package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-result.js.map +1 -1
- package/dist/core/exec.d.ts +2 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +15 -9
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +2 -2
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/builtin.d.ts.map +1 -1
- package/dist/core/extensions/builtin.js +2 -2
- package/dist/core/extensions/builtin.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +24 -0
- package/dist/core/goal-loop-controller.d.ts.map +1 -0
- package/dist/core/goal-loop-controller.js +83 -0
- package/dist/core/goal-loop-controller.js.map +1 -0
- package/dist/core/goals/goal-runtime-snapshot.d.ts +1 -1
- package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +1 -1
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/learning/learning-audit.d.ts +1 -1
- package/dist/core/learning/learning-audit.d.ts.map +1 -1
- package/dist/core/learning/learning-audit.js.map +1 -1
- package/dist/core/learning/session-learning-decision.d.ts +1 -1
- package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
- package/dist/core/learning/session-learning-decision.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +99 -0
- package/dist/core/local-runtime-controller.d.ts.map +1 -0
- package/dist/core/local-runtime-controller.js +214 -0
- package/dist/core/local-runtime-controller.js.map +1 -0
- package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
- package/dist/core/memory/providers/transcript-recall.js +1 -1
- package/dist/core/memory/providers/transcript-recall.js.map +1 -1
- package/dist/core/memory-controller.d.ts +139 -0
- package/dist/core/memory-controller.d.ts.map +1 -0
- package/dist/core/memory-controller.js +323 -0
- package/dist/core/memory-controller.js.map +1 -0
- package/dist/core/model-router/status.d.ts +1 -1
- package/dist/core/model-router/status.d.ts.map +1 -1
- package/dist/core/model-router/status.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +140 -0
- package/dist/core/model-router-controller.d.ts.map +1 -0
- package/dist/core/model-router-controller.js +623 -0
- package/dist/core/model-router-controller.js.map +1 -0
- package/dist/core/model-selection-controller.d.ts +95 -0
- package/dist/core/model-selection-controller.d.ts.map +1 -0
- package/dist/core/model-selection-controller.js +252 -0
- package/dist/core/model-selection-controller.js.map +1 -0
- package/dist/core/models/model-ref.d.ts +13 -0
- package/dist/core/models/model-ref.d.ts.map +1 -1
- package/dist/core/models/model-ref.js +22 -0
- package/dist/core/models/model-ref.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +77 -0
- package/dist/core/profile-filter-controller.d.ts.map +1 -0
- package/dist/core/profile-filter-controller.js +159 -0
- package/dist/core/profile-filter-controller.js.map +1 -0
- package/dist/core/reflection-controller.d.ts +111 -0
- package/dist/core/reflection-controller.d.ts.map +1 -0
- package/dist/core/reflection-controller.js +412 -0
- package/dist/core/reflection-controller.js.map +1 -0
- package/dist/core/research/model-fitness.d.ts +12 -0
- package/dist/core/research/model-fitness.d.ts.map +1 -1
- package/dist/core/research/model-fitness.js +21 -0
- package/dist/core/research/model-fitness.js.map +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/session-evidence-bundle.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +222 -0
- package/dist/core/runtime-builder.d.ts.map +1 -0
- package/dist/core/runtime-builder.js +640 -0
- package/dist/core/runtime-builder.js.map +1 -0
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-analytics.d.ts +96 -0
- package/dist/core/session-analytics.d.ts.map +1 -0
- package/dist/core/session-analytics.js +331 -0
- package/dist/core/session-analytics.js.map +1 -0
- package/dist/core/session-manager-factory.d.ts +18 -0
- package/dist/core/session-manager-factory.d.ts.map +1 -0
- package/dist/core/session-manager-factory.js +32 -0
- package/dist/core/session-manager-factory.js.map +1 -0
- package/dist/core/session-tree-navigator.d.ts +68 -0
- package/dist/core/session-tree-navigator.d.ts.map +1 -0
- package/dist/core/session-tree-navigator.js +217 -0
- package/dist/core/session-tree-navigator.js.map +1 -0
- package/dist/core/system-prompt-builder.d.ts +63 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -0
- package/dist/core/system-prompt-builder.js +181 -0
- package/dist/core/system-prompt-builder.js.map +1 -0
- package/dist/core/tool-gate-controller.d.ts +36 -0
- package/dist/core/tool-gate-controller.d.ts.map +1 -0
- package/dist/core/tool-gate-controller.js +94 -0
- package/dist/core/tool-gate-controller.js.map +1 -0
- package/dist/core/tools/artifact-retrieve.d.ts.map +1 -1
- package/dist/core/tools/artifact-retrieve.js +1 -1
- package/dist/core/tools/artifact-retrieve.js.map +1 -1
- package/dist/core/tools/bash.d.ts +4 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +49 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +61 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts +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 +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +13 -12
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.d.ts +59 -0
- package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auth-dialogs-controller.js +398 -0
- package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts +168 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.js +1239 -0
- package/dist/modes/interactive/auto-learn-controller.js.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts +26 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.js +103 -0
- package/dist/modes/interactive/autocomplete-provider.js.map +1 -0
- package/dist/modes/interactive/autonomy-commands.d.ts +38 -0
- package/dist/modes/interactive/autonomy-commands.d.ts.map +1 -0
- package/dist/modes/interactive/autonomy-commands.js +142 -0
- package/dist/modes/interactive/autonomy-commands.js.map +1 -0
- package/dist/modes/interactive/clipboard-input.d.ts +37 -0
- package/dist/modes/interactive/clipboard-input.d.ts.map +1 -0
- package/dist/modes/interactive/clipboard-input.js +59 -0
- package/dist/modes/interactive/clipboard-input.js.map +1 -0
- package/dist/modes/interactive/compaction-queue.d.ts +30 -0
- package/dist/modes/interactive/compaction-queue.d.ts.map +1 -0
- package/dist/modes/interactive/compaction-queue.js +91 -0
- package/dist/modes/interactive/compaction-queue.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +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 +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-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 +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/config-backup.d.ts +27 -0
- package/dist/modes/interactive/config-backup.d.ts.map +1 -0
- package/dist/modes/interactive/config-backup.js +146 -0
- package/dist/modes/interactive/config-backup.js.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts +48 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.js +43 -0
- package/dist/modes/interactive/editor-overlay-host.js.map +1 -0
- package/dist/modes/interactive/extension-ui-host.d.ts +165 -0
- package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -0
- package/dist/modes/interactive/extension-ui-host.js +610 -0
- package/dist/modes/interactive/extension-ui-host.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts +18 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +107 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/history-reload-math.d.ts +24 -0
- package/dist/modes/interactive/history-reload-math.d.ts.map +1 -0
- package/dist/modes/interactive/history-reload-math.js +129 -0
- package/dist/modes/interactive/history-reload-math.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +22 -238
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +714 -5910
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/key-handlers.d.ts +46 -0
- package/dist/modes/interactive/key-handlers.d.ts.map +1 -0
- package/dist/modes/interactive/key-handlers.js +80 -0
- package/dist/modes/interactive/key-handlers.js.map +1 -0
- package/dist/modes/interactive/local-model-commands.d.ts +68 -0
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -0
- package/dist/modes/interactive/local-model-commands.js +288 -0
- package/dist/modes/interactive/local-model-commands.js.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts +77 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.js +917 -0
- package/dist/modes/interactive/profile-menu-controller.js.map +1 -0
- package/dist/modes/interactive/report-commands.d.ts +46 -0
- package/dist/modes/interactive/report-commands.d.ts.map +1 -0
- package/dist/modes/interactive/report-commands.js +255 -0
- package/dist/modes/interactive/report-commands.js.map +1 -0
- package/dist/modes/interactive/resource-display.d.ts +73 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -0
- package/dist/modes/interactive/resource-display.js +278 -0
- package/dist/modes/interactive/resource-display.js.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts +64 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.js +202 -0
- package/dist/modes/interactive/resource-shell-commands.js.map +1 -0
- package/dist/modes/interactive/session-flow-commands.d.ts +139 -0
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-flow-commands.js +458 -0
- package/dist/modes/interactive/session-flow-commands.js.map +1 -0
- package/dist/modes/interactive/session-io-commands.d.ts +73 -0
- package/dist/modes/interactive/session-io-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-io-commands.js +202 -0
- package/dist/modes/interactive/session-io-commands.js.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts +42 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.js +287 -0
- package/dist/modes/interactive/settings-selector-flow.js.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts +55 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.js +177 -0
- package/dist/modes/interactive/signal-lifecycle.js.map +1 -0
- package/dist/modes/interactive/startup-checks.d.ts +38 -0
- package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
- package/dist/modes/interactive/startup-checks.js +189 -0
- package/dist/modes/interactive/startup-checks.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -14
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -30
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/process-memory.d.ts +8 -0
- package/dist/utils/process-memory.d.ts.map +1 -0
- package/dist/utils/process-memory.js +11 -0
- package/dist/utils/process-memory.js.map +1 -0
- package/dist/utils/shell.d.ts +0 -9
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +0 -37
- package/dist/utils/shell.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/11-sessions.ts +8 -8
- package/examples/sdk/13-session-runtime.ts +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/dist/core/compaction/branch-summarization.d.ts +0 -88
- package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/core/compaction/branch-summarization.js +0 -243
- package/dist/core/compaction/branch-summarization.js.map +0 -1
- package/dist/core/compaction/compaction.d.ts +0 -143
- package/dist/core/compaction/compaction.d.ts.map +0 -1
- package/dist/core/compaction/compaction.js +0 -659
- package/dist/core/compaction/compaction.js.map +0 -1
- package/dist/core/compaction/index.d.ts +0 -7
- package/dist/core/compaction/index.d.ts.map +0 -1
- package/dist/core/compaction/index.js +0 -7
- package/dist/core/compaction/index.js.map +0 -1
- package/dist/core/compaction/utils.d.ts +0 -38
- package/dist/core/compaction/utils.d.ts.map +0 -1
- package/dist/core/compaction/utils.js +0 -153
- package/dist/core/compaction/utils.js.map +0 -1
- package/dist/core/message-retention.d.ts +0 -26
- package/dist/core/message-retention.d.ts.map +0 -1
- package/dist/core/message-retention.js +0 -95
- package/dist/core/message-retention.js.map +0 -1
- package/dist/core/messages.d.ts +0 -77
- package/dist/core/messages.d.ts.map +0 -1
- package/dist/core/messages.js +0 -123
- package/dist/core/messages.js.map +0 -1
- package/dist/core/session-manager.d.ts +0 -337
- package/dist/core/session-manager.d.ts.map +0 -1
- package/dist/core/session-manager.js +0 -1328
- package/dist/core/session-manager.js.map +0 -1
- package/dist/core/tools/truncate.d.ts +0 -70
- package/dist/core/tools/truncate.d.ts.map +0 -1
- package/dist/core/tools/truncate.js +0 -215
- package/dist/core/tools/truncate.js.map +0 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth / login / OAuth dialog controller.
|
|
3
|
+
*
|
|
4
|
+
* Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the /login and /logout
|
|
5
|
+
* command flows: provider selection, subscription (OAuth) login dialogs, API-key login dialogs, the
|
|
6
|
+
* Amazon Bedrock setup notice, the OAuth in-dialog select prompt, and post-login model adoption. It
|
|
7
|
+
* holds NO state of its own — every credential/provider fact lives in session.modelRegistry.authStorage
|
|
8
|
+
* — so it takes narrow deps (a live session accessor plus a UI callback surface, including the
|
|
9
|
+
* editor-overlay-backed showSelector and the shared EditorOverlayHost for dialog swaps) rather than
|
|
10
|
+
* the whole InteractiveMode instance.
|
|
11
|
+
*/
|
|
12
|
+
import { type Model } from "@caupulican/pi-ai";
|
|
13
|
+
import type { Component, TUI } from "@caupulican/pi-tui";
|
|
14
|
+
import type { AgentSession } from "../../core/agent-session.ts";
|
|
15
|
+
import type { EditorOverlayHost } from "./editor-overlay-host.ts";
|
|
16
|
+
export declare function isApiKeyLoginProvider(providerId: string, oauthProviderIds: ReadonlySet<string>, builtInProviderIds?: ReadonlySet<string>): boolean;
|
|
17
|
+
export interface AuthDialogsControllerUi {
|
|
18
|
+
showSelector(create: (done: () => void) => {
|
|
19
|
+
component: Component;
|
|
20
|
+
focus: Component;
|
|
21
|
+
}): void;
|
|
22
|
+
showStatus(message: string): void;
|
|
23
|
+
showError(message: string): void;
|
|
24
|
+
requestRender(): void;
|
|
25
|
+
readonly tui: TUI;
|
|
26
|
+
readonly overlayHost: EditorOverlayHost;
|
|
27
|
+
getEditor(): Component;
|
|
28
|
+
updateAvailableProviderCount(): Promise<void>;
|
|
29
|
+
invalidateFooter(): void;
|
|
30
|
+
updateEditorBorderColor(): void;
|
|
31
|
+
maybeWarnAboutAnthropicSubscriptionAuth(model?: Model<any>): void;
|
|
32
|
+
checkDaxnutsEasterEgg(model: {
|
|
33
|
+
provider: string;
|
|
34
|
+
id: string;
|
|
35
|
+
}): void;
|
|
36
|
+
}
|
|
37
|
+
export interface AuthDialogsControllerDeps {
|
|
38
|
+
getSession(): AgentSession;
|
|
39
|
+
ui: AuthDialogsControllerUi;
|
|
40
|
+
}
|
|
41
|
+
export declare class AuthDialogsController {
|
|
42
|
+
private readonly deps;
|
|
43
|
+
constructor(deps: AuthDialogsControllerDeps);
|
|
44
|
+
private get session();
|
|
45
|
+
private get ui();
|
|
46
|
+
private getLoginProviderOptions;
|
|
47
|
+
private getLogoutProviderOptions;
|
|
48
|
+
private resolveAuthProviderOption;
|
|
49
|
+
private startProviderLogin;
|
|
50
|
+
private showLoginAuthTypeSelector;
|
|
51
|
+
private showLoginProviderSelector;
|
|
52
|
+
showOAuthSelector(mode: "login" | "logout", providerReference?: string): Promise<void>;
|
|
53
|
+
private completeProviderAuthentication;
|
|
54
|
+
private showBedrockSetupDialog;
|
|
55
|
+
private showApiKeyLoginDialog;
|
|
56
|
+
private showOAuthLoginSelect;
|
|
57
|
+
private showLoginDialog;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=auth-dialogs-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-dialogs-controller.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/auth-dialogs-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAgB,KAAK,KAAK,EAAgD,MAAM,mBAAmB,CAAC;AAC3G,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAMhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAelE,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,EACrC,kBAAkB,GAAE,WAAW,CAAC,MAAM,CAA4B,GAChE,OAAO,CAQT;AAED,MAAM,WAAW,uBAAuB;IACvC,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK;QAAE,SAAS,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7F,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,IAAI,IAAI,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,SAAS,IAAI,SAAS,CAAC;IACvB,4BAA4B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,gBAAgB,IAAI,IAAI,CAAC;IACzB,uBAAuB,IAAI,IAAI,CAAC;IAChC,uCAAuC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAClE,qBAAqB,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACrE;AAED,MAAM,WAAW,yBAAyB;IACzC,UAAU,IAAI,YAAY,CAAC;IAC3B,EAAE,EAAE,uBAAuB,CAAC;CAC5B;AAED,qBAAa,qBAAqB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IAEjD,YAAY,IAAI,EAAE,yBAAyB,EAE1C;IAED,OAAO,KAAK,OAAO,GAElB;IACD,OAAO,KAAK,EAAE,GAEb;IAED,OAAO,CAAC,uBAAuB;IA0B/B,OAAO,CAAC,wBAAwB;IAmBhC,OAAO,CAAC,yBAAyB;YAoBnB,kBAAkB;IAUhC,OAAO,CAAC,yBAAyB;IAqBjC,OAAO,CAAC,yBAAyB;IAkC3B,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkF3F;YAEa,8BAA8B;IAqD5C,OAAO,CAAC,sBAAsB;YAsBhB,qBAAqB;IAqCnC,OAAO,CAAC,oBAAoB;YAsBd,eAAe;CA2F7B","sourcesContent":["/**\n * Auth / login / OAuth dialog controller.\n *\n * Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the /login and /logout\n * command flows: provider selection, subscription (OAuth) login dialogs, API-key login dialogs, the\n * Amazon Bedrock setup notice, the OAuth in-dialog select prompt, and post-login model adoption. It\n * holds NO state of its own — every credential/provider fact lives in session.modelRegistry.authStorage\n * — so it takes narrow deps (a live session accessor plus a UI callback surface, including the\n * editor-overlay-backed showSelector and the shared EditorOverlayHost for dialog swaps) rather than\n * the whole InteractiveMode instance.\n */\n\nimport * as path from \"node:path\";\nimport { getProviders, type Model, type OAuthProviderId, type OAuthSelectPrompt } from \"@caupulican/pi-ai\";\nimport type { Component, TUI } from \"@caupulican/pi-tui\";\nimport { getAuthPath, getDocsPath } from \"../../config.ts\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport { cliProviderAliases, defaultModelPerProvider } from \"../../core/model-resolver.ts\";\nimport { BUILT_IN_PROVIDER_DISPLAY_NAMES } from \"../../core/provider-display-names.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport { LoginDialogComponent } from \"./components/login-dialog.ts\";\nimport { type AuthSelectorProvider, OAuthSelectorComponent } from \"./components/oauth-selector.ts\";\nimport type { EditorOverlayHost } from \"./editor-overlay-host.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nfunction isUnknownModel(model: Model<any> | undefined): boolean {\n\treturn !!model && model.provider === \"unknown\" && model.id === \"unknown\" && model.api === \"unknown\";\n}\n\nfunction hasDefaultModelProvider(providerId: string): providerId is keyof typeof defaultModelPerProvider {\n\treturn providerId in defaultModelPerProvider;\n}\n\nconst BEDROCK_PROVIDER_ID = \"amazon-bedrock\";\n\nconst BUILT_IN_MODEL_PROVIDERS = new Set<string>(getProviders());\n\nexport function isApiKeyLoginProvider(\n\tproviderId: string,\n\toauthProviderIds: ReadonlySet<string>,\n\tbuiltInProviderIds: ReadonlySet<string> = BUILT_IN_MODEL_PROVIDERS,\n): boolean {\n\tif (BUILT_IN_PROVIDER_DISPLAY_NAMES[providerId]) {\n\t\treturn true;\n\t}\n\tif (builtInProviderIds.has(providerId)) {\n\t\treturn false;\n\t}\n\treturn !oauthProviderIds.has(providerId);\n}\n\nexport interface AuthDialogsControllerUi {\n\tshowSelector(create: (done: () => void) => { component: Component; focus: Component }): void;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\trequestRender(): void;\n\treadonly tui: TUI;\n\treadonly overlayHost: EditorOverlayHost;\n\tgetEditor(): Component;\n\tupdateAvailableProviderCount(): Promise<void>;\n\tinvalidateFooter(): void;\n\tupdateEditorBorderColor(): void;\n\tmaybeWarnAboutAnthropicSubscriptionAuth(model?: Model<any>): void;\n\tcheckDaxnutsEasterEgg(model: { provider: string; id: string }): void;\n}\n\nexport interface AuthDialogsControllerDeps {\n\tgetSession(): AgentSession;\n\tui: AuthDialogsControllerUi;\n}\n\nexport class AuthDialogsController {\n\tprivate readonly deps: AuthDialogsControllerDeps;\n\n\tconstructor(deps: AuthDialogsControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.getSession();\n\t}\n\tprivate get ui(): AuthDialogsControllerUi {\n\t\treturn this.deps.ui;\n\t}\n\n\tprivate getLoginProviderOptions(authType?: \"oauth\" | \"api_key\"): AuthSelectorProvider[] {\n\t\tconst authStorage = this.session.modelRegistry.authStorage;\n\t\tconst oauthProviders = authStorage.getOAuthProviders();\n\t\tconst oauthProviderIds = new Set(oauthProviders.map((provider) => provider.id));\n\t\tconst options: AuthSelectorProvider[] = oauthProviders.map((provider) => ({\n\t\t\tid: provider.id,\n\t\t\tname: provider.name,\n\t\t\tauthType: \"oauth\",\n\t\t}));\n\n\t\tconst modelProviders = new Set(this.session.modelRegistry.getAll().map((model) => model.provider));\n\t\tfor (const providerId of modelProviders) {\n\t\t\tif (!isApiKeyLoginProvider(providerId, oauthProviderIds)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname: this.session.modelRegistry.getProviderDisplayName(providerId),\n\t\t\t\tauthType: \"api_key\",\n\t\t\t});\n\t\t}\n\n\t\tconst filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;\n\t\treturn filteredOptions.sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tprivate getLogoutProviderOptions(): AuthSelectorProvider[] {\n\t\tconst authStorage = this.session.modelRegistry.authStorage;\n\t\tconst options: AuthSelectorProvider[] = [];\n\n\t\tfor (const providerId of authStorage.list()) {\n\t\t\tconst credential = authStorage.get(providerId);\n\t\t\tif (!credential) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname: this.session.modelRegistry.getProviderDisplayName(providerId),\n\t\t\t\tauthType: credential.type,\n\t\t\t});\n\t\t}\n\n\t\treturn options.sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tprivate resolveAuthProviderOption(\n\t\tproviderReference: string,\n\t\tproviderOptions: AuthSelectorProvider[],\n\t): AuthSelectorProvider | undefined {\n\t\tconst normalized = providerReference.trim().toLowerCase();\n\t\tif (!normalized) return undefined;\n\t\tconst exactMatch = providerOptions.find((provider) => {\n\t\t\tconst id = provider.id.toLowerCase();\n\t\t\tconst name = provider.name.toLowerCase();\n\t\t\treturn id === normalized || name === normalized;\n\t\t});\n\t\tif (exactMatch) return exactMatch;\n\t\tconst aliasTarget = cliProviderAliases[normalized] ?? normalized;\n\t\treturn providerOptions.find((provider) => {\n\t\t\tconst id = provider.id.toLowerCase();\n\t\t\tconst name = provider.name.toLowerCase();\n\t\t\treturn id === aliasTarget || name === aliasTarget;\n\t\t});\n\t}\n\n\tprivate async startProviderLogin(providerOption: AuthSelectorProvider): Promise<void> {\n\t\tif (providerOption.authType === \"oauth\") {\n\t\t\tawait this.showLoginDialog(providerOption.id, providerOption.name);\n\t\t} else if (providerOption.id === BEDROCK_PROVIDER_ID) {\n\t\t\tthis.showBedrockSetupDialog(providerOption.id, providerOption.name);\n\t\t} else {\n\t\t\tawait this.showApiKeyLoginDialog(providerOption.id, providerOption.name);\n\t\t}\n\t}\n\n\tprivate showLoginAuthTypeSelector(): void {\n\t\tconst subscriptionLabel = \"Use a subscription\";\n\t\tconst apiKeyLabel = \"Use an API key\";\n\t\tthis.ui.showSelector((done) => {\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\t\"Select authentication method:\",\n\t\t\t\t[subscriptionLabel, apiKeyLabel],\n\t\t\t\t(option) => {\n\t\t\t\t\tdone();\n\t\t\t\t\tconst authType = option === subscriptionLabel ? \"oauth\" : \"api_key\";\n\t\t\t\t\tthis.showLoginProviderSelector(authType);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tdone();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn { component: selector, focus: selector };\n\t\t});\n\t}\n\n\tprivate showLoginProviderSelector(authType: \"oauth\" | \"api_key\"): void {\n\t\tconst providerOptions = this.getLoginProviderOptions(authType);\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.ui.showStatus(\n\t\t\t\tauthType === \"oauth\" ? \"No subscription providers available.\" : \"No API key providers available.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ui.showSelector((done) => {\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\t\"login\",\n\t\t\t\tthis.session.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerId: string) => {\n\t\t\t\t\tdone();\n\n\t\t\t\t\tconst providerOption = providerOptions.find((provider) => provider.id === providerId);\n\t\t\t\t\tif (!providerOption) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait this.startProviderLogin(providerOption);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tdone();\n\t\t\t\t\tthis.showLoginAuthTypeSelector();\n\t\t\t\t},\n\t\t\t\t(providerId) => this.session.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t);\n\t\t\treturn { component: selector, focus: selector };\n\t\t});\n\t}\n\n\tasync showOAuthSelector(mode: \"login\" | \"logout\", providerReference?: string): Promise<void> {\n\t\tif (mode === \"login\") {\n\t\t\tif (providerReference) {\n\t\t\t\tconst providerOptions = this.getLoginProviderOptions();\n\t\t\t\tconst providerOption = this.resolveAuthProviderOption(providerReference, providerOptions);\n\t\t\t\tif (!providerOption) {\n\t\t\t\t\tthis.ui.showError(\n\t\t\t\t\t\t`Unknown login provider \"${providerReference}\". Use /login to select from available providers.`,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait this.startProviderLogin(providerOption);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.showLoginAuthTypeSelector();\n\t\t\treturn;\n\t\t}\n\n\t\tconst providerOptions = this.getLogoutProviderOptions();\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.ui.showStatus(\n\t\t\t\t\"No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (providerReference) {\n\t\t\tconst providerOption = this.resolveAuthProviderOption(providerReference, providerOptions);\n\t\t\tif (!providerOption) {\n\t\t\t\tthis.ui.showError(\n\t\t\t\t\t`No stored credentials found for \"${providerReference}\". Use /logout to select a saved provider.`,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tthis.session.modelRegistry.authStorage.logout(providerOption.id);\n\t\t\t\tthis.session.modelRegistry.refresh();\n\t\t\t\tawait this.ui.updateAvailableProviderCount();\n\t\t\t\tconst message =\n\t\t\t\t\tproviderOption.authType === \"oauth\"\n\t\t\t\t\t\t? `Logged out of ${providerOption.name}`\n\t\t\t\t\t\t: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;\n\t\t\t\tthis.ui.showStatus(message);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tthis.ui.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ui.showSelector((done) => {\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\tmode,\n\t\t\t\tthis.session.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerId: string) => {\n\t\t\t\t\tdone();\n\n\t\t\t\t\tconst providerOption = providerOptions.find((provider) => provider.id === providerId);\n\t\t\t\t\tif (!providerOption) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.session.modelRegistry.authStorage.logout(providerOption.id);\n\t\t\t\t\t\tthis.session.modelRegistry.refresh();\n\t\t\t\t\t\tawait this.ui.updateAvailableProviderCount();\n\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\tproviderOption.authType === \"oauth\"\n\t\t\t\t\t\t\t\t? `Logged out of ${providerOption.name}`\n\t\t\t\t\t\t\t\t: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;\n\t\t\t\t\t\tthis.ui.showStatus(message);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tthis.ui.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tdone();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn { component: selector, focus: selector };\n\t\t});\n\t}\n\n\tprivate async completeProviderAuthentication(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tauthType: \"oauth\" | \"api_key\",\n\t\tpreviousModel: Model<any> | undefined,\n\t): Promise<void> {\n\t\tthis.session.modelRegistry.refresh();\n\n\t\tconst actionLabel = authType === \"oauth\" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;\n\n\t\tlet selectedModel: Model<any> | undefined;\n\t\tlet selectionError: string | undefined;\n\t\tif (isUnknownModel(previousModel)) {\n\t\t\tconst availableModels = this.session.modelRegistry.getAvailable();\n\t\t\tconst providerModels = availableModels.filter((model) => model.provider === providerId);\n\t\t\tif (!hasDefaultModelProvider(providerId)) {\n\t\t\t\tselectionError = `${actionLabel}, but no default model is configured for provider \"${providerId}\". Use /model to select a model.`;\n\t\t\t} else if (providerModels.length === 0) {\n\t\t\t\tselectionError = `${actionLabel}, but no models are available for that provider. Use /model to select a model.`;\n\t\t\t} else {\n\t\t\t\tconst defaultModelId = defaultModelPerProvider[providerId];\n\t\t\t\tselectedModel = providerModels.find((model) => model.id === defaultModelId);\n\t\t\t\tif (!selectedModel) {\n\t\t\t\t\tselectionError = `${actionLabel}, but its default model \"${defaultModelId}\" is not available. Use /model to select a model.`;\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this.session.setModel(selectedModel);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tselectedModel = undefined;\n\t\t\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\t\t\tselectionError = `${actionLabel}, but selecting its default model failed: ${errorMessage}. Use /model to select a model.`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait this.ui.updateAvailableProviderCount();\n\t\tthis.ui.invalidateFooter();\n\t\tthis.ui.updateEditorBorderColor();\n\t\tif (selectedModel) {\n\t\t\tthis.ui.showStatus(`${actionLabel}. Selected ${selectedModel.id}. Credentials saved to ${getAuthPath()}`);\n\t\t\tvoid this.ui.maybeWarnAboutAnthropicSubscriptionAuth(selectedModel);\n\t\t\tthis.ui.checkDaxnutsEasterEgg(selectedModel);\n\t\t} else {\n\t\t\tthis.ui.showStatus(`${actionLabel}. Credentials saved to ${getAuthPath()}`);\n\t\t\tif (selectionError) {\n\t\t\t\tthis.ui.showError(selectionError);\n\t\t\t} else {\n\t\t\t\tvoid this.ui.maybeWarnAboutAnthropicSubscriptionAuth();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate showBedrockSetupDialog(providerId: string, providerName: string): void {\n\t\tconst restoreEditor = () => {\n\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor());\n\t\t};\n\n\t\tconst dialog = new LoginDialogComponent(\n\t\t\tthis.ui.tui,\n\t\t\tproviderId,\n\t\t\t() => restoreEditor(),\n\t\t\tproviderName,\n\t\t\t\"Amazon Bedrock setup\",\n\t\t);\n\t\tdialog.showInfo([\n\t\t\ttheme.fg(\"text\", \"Amazon Bedrock uses AWS credentials instead of a single API key.\"),\n\t\t\ttheme.fg(\"text\", \"Configure an AWS profile, IAM keys, bearer token, or role-based credentials.\"),\n\t\t\ttheme.fg(\"muted\", \"See:\"),\n\t\t\ttheme.fg(\"accent\", ` ${path.join(getDocsPath(), \"providers.md\")}`),\n\t\t]);\n\n\t\tthis.ui.overlayHost.swap(dialog);\n\t}\n\n\tprivate async showApiKeyLoginDialog(providerId: string, providerName: string): Promise<void> {\n\t\tconst previousModel = this.session.model;\n\n\t\tconst dialog = new LoginDialogComponent(\n\t\t\tthis.ui.tui,\n\t\t\tproviderId,\n\t\t\t(_success, _message) => {\n\t\t\t\t// Completion handled below\n\t\t\t},\n\t\t\tproviderName,\n\t\t);\n\n\t\tthis.ui.overlayHost.swap(dialog);\n\n\t\tconst restoreEditor = () => {\n\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor());\n\t\t};\n\n\t\ttry {\n\t\t\tconst apiKey = (await dialog.showPrompt(\"Enter API key:\")).trim();\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(\"API key cannot be empty.\");\n\t\t\t}\n\n\t\t\tthis.session.modelRegistry.authStorage.set(providerId, { type: \"api_key\", key: apiKey });\n\n\t\t\trestoreEditor();\n\t\t\tawait this.completeProviderAuthentication(providerId, providerName, \"api_key\", previousModel);\n\t\t} catch (error: unknown) {\n\t\t\trestoreEditor();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.ui.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate showOAuthLoginSelect(dialog: LoginDialogComponent, prompt: OAuthSelectPrompt): Promise<string | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst restoreDialog = () => {\n\t\t\t\tthis.ui.overlayHost.swap(dialog);\n\t\t\t};\n\t\t\tconst labels = prompt.options.map((option) => option.label);\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\tprompt.message,\n\t\t\t\tlabels,\n\t\t\t\t(optionLabel) => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(prompt.options.find((option) => option.label === optionLabel)?.id);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.ui.overlayHost.swap(selector);\n\t\t});\n\t}\n\n\tprivate async showLoginDialog(providerId: string, providerName: string): Promise<void> {\n\t\tconst providerInfo = this.session.modelRegistry.authStorage\n\t\t\t.getOAuthProviders()\n\t\t\t.find((provider) => provider.id === providerId);\n\t\tconst previousModel = this.session.model;\n\n\t\t// Providers that use callback servers (can paste redirect URL)\n\t\tconst usesCallbackServer = providerInfo?.usesCallbackServer ?? false;\n\n\t\t// Create login dialog component\n\t\tconst dialog = new LoginDialogComponent(\n\t\t\tthis.ui.tui,\n\t\t\tproviderId,\n\t\t\t(_success, _message) => {\n\t\t\t\t// Completion handled below\n\t\t\t},\n\t\t\tproviderName,\n\t\t);\n\n\t\t// Show dialog in editor container\n\t\tthis.ui.overlayHost.swap(dialog);\n\n\t\t// Promise for manual code input (racing with callback server)\n\t\tlet manualCodeResolve: ((code: string) => void) | undefined;\n\t\tlet manualCodeReject: ((err: Error) => void) | undefined;\n\t\tconst manualCodePromise = new Promise<string>((resolve, reject) => {\n\t\t\tmanualCodeResolve = resolve;\n\t\t\tmanualCodeReject = reject;\n\t\t});\n\n\t\t// Restore editor helper\n\t\tconst restoreEditor = () => {\n\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor());\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.session.modelRegistry.authStorage.login(providerId as OAuthProviderId, {\n\t\t\t\tonAuth: (info: { url: string; instructions?: string }) => {\n\t\t\t\t\tdialog.showAuth(info.url, info.instructions);\n\n\t\t\t\t\tif (usesCallbackServer) {\n\t\t\t\t\t\t// Show input for manual paste, racing with callback\n\t\t\t\t\t\tdialog\n\t\t\t\t\t\t\t.showManualInput(\"Paste redirect URL below, or complete login in browser:\")\n\t\t\t\t\t\t\t.then((value) => {\n\t\t\t\t\t\t\t\tif (value && manualCodeResolve) {\n\t\t\t\t\t\t\t\t\tmanualCodeResolve(value);\n\t\t\t\t\t\t\t\t\tmanualCodeResolve = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\t\t\tif (manualCodeReject) {\n\t\t\t\t\t\t\t\t\tmanualCodeReject(new Error(\"Login cancelled\"));\n\t\t\t\t\t\t\t\t\tmanualCodeReject = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// For Anthropic: onPrompt is called immediately after\n\t\t\t\t},\n\n\t\t\t\tonDeviceCode: (info) => {\n\t\t\t\t\tdialog.showDeviceCode(info);\n\t\t\t\t\tdialog.showWaiting(\"Waiting for authentication...\");\n\t\t\t\t},\n\n\t\t\t\tonPrompt: async (prompt: { message: string; placeholder?: string }) => {\n\t\t\t\t\treturn dialog.showPrompt(prompt.message, prompt.placeholder);\n\t\t\t\t},\n\n\t\t\t\tonProgress: (message: string) => {\n\t\t\t\t\tdialog.showProgress(message);\n\t\t\t\t},\n\n\t\t\t\tonSelect: (prompt: OAuthSelectPrompt) => this.showOAuthLoginSelect(dialog, prompt),\n\n\t\t\t\tonManualCodeInput: () => manualCodePromise,\n\n\t\t\t\tsignal: dialog.signal,\n\t\t\t});\n\n\t\t\t// Success\n\t\t\trestoreEditor();\n\t\t\tawait this.completeProviderAuthentication(providerId, providerName, \"oauth\", previousModel);\n\t\t} catch (error: unknown) {\n\t\t\trestoreEditor();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.ui.showError(`Failed to login to ${providerName}: ${errorMsg}`);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth / login / OAuth dialog controller.
|
|
3
|
+
*
|
|
4
|
+
* Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the /login and /logout
|
|
5
|
+
* command flows: provider selection, subscription (OAuth) login dialogs, API-key login dialogs, the
|
|
6
|
+
* Amazon Bedrock setup notice, the OAuth in-dialog select prompt, and post-login model adoption. It
|
|
7
|
+
* holds NO state of its own — every credential/provider fact lives in session.modelRegistry.authStorage
|
|
8
|
+
* — so it takes narrow deps (a live session accessor plus a UI callback surface, including the
|
|
9
|
+
* editor-overlay-backed showSelector and the shared EditorOverlayHost for dialog swaps) rather than
|
|
10
|
+
* the whole InteractiveMode instance.
|
|
11
|
+
*/
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import { getProviders } from "@caupulican/pi-ai";
|
|
14
|
+
import { getAuthPath, getDocsPath } from "../../config.js";
|
|
15
|
+
import { cliProviderAliases, defaultModelPerProvider } from "../../core/model-resolver.js";
|
|
16
|
+
import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "../../core/provider-display-names.js";
|
|
17
|
+
import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
18
|
+
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
19
|
+
import { OAuthSelectorComponent } from "./components/oauth-selector.js";
|
|
20
|
+
import { theme } from "./theme/theme.js";
|
|
21
|
+
function isUnknownModel(model) {
|
|
22
|
+
return !!model && model.provider === "unknown" && model.id === "unknown" && model.api === "unknown";
|
|
23
|
+
}
|
|
24
|
+
function hasDefaultModelProvider(providerId) {
|
|
25
|
+
return providerId in defaultModelPerProvider;
|
|
26
|
+
}
|
|
27
|
+
const BEDROCK_PROVIDER_ID = "amazon-bedrock";
|
|
28
|
+
const BUILT_IN_MODEL_PROVIDERS = new Set(getProviders());
|
|
29
|
+
export function isApiKeyLoginProvider(providerId, oauthProviderIds, builtInProviderIds = BUILT_IN_MODEL_PROVIDERS) {
|
|
30
|
+
if (BUILT_IN_PROVIDER_DISPLAY_NAMES[providerId]) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (builtInProviderIds.has(providerId)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return !oauthProviderIds.has(providerId);
|
|
37
|
+
}
|
|
38
|
+
export class AuthDialogsController {
|
|
39
|
+
deps;
|
|
40
|
+
constructor(deps) {
|
|
41
|
+
this.deps = deps;
|
|
42
|
+
}
|
|
43
|
+
get session() {
|
|
44
|
+
return this.deps.getSession();
|
|
45
|
+
}
|
|
46
|
+
get ui() {
|
|
47
|
+
return this.deps.ui;
|
|
48
|
+
}
|
|
49
|
+
getLoginProviderOptions(authType) {
|
|
50
|
+
const authStorage = this.session.modelRegistry.authStorage;
|
|
51
|
+
const oauthProviders = authStorage.getOAuthProviders();
|
|
52
|
+
const oauthProviderIds = new Set(oauthProviders.map((provider) => provider.id));
|
|
53
|
+
const options = oauthProviders.map((provider) => ({
|
|
54
|
+
id: provider.id,
|
|
55
|
+
name: provider.name,
|
|
56
|
+
authType: "oauth",
|
|
57
|
+
}));
|
|
58
|
+
const modelProviders = new Set(this.session.modelRegistry.getAll().map((model) => model.provider));
|
|
59
|
+
for (const providerId of modelProviders) {
|
|
60
|
+
if (!isApiKeyLoginProvider(providerId, oauthProviderIds)) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
options.push({
|
|
64
|
+
id: providerId,
|
|
65
|
+
name: this.session.modelRegistry.getProviderDisplayName(providerId),
|
|
66
|
+
authType: "api_key",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;
|
|
70
|
+
return filteredOptions.sort((a, b) => a.name.localeCompare(b.name));
|
|
71
|
+
}
|
|
72
|
+
getLogoutProviderOptions() {
|
|
73
|
+
const authStorage = this.session.modelRegistry.authStorage;
|
|
74
|
+
const options = [];
|
|
75
|
+
for (const providerId of authStorage.list()) {
|
|
76
|
+
const credential = authStorage.get(providerId);
|
|
77
|
+
if (!credential) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
options.push({
|
|
81
|
+
id: providerId,
|
|
82
|
+
name: this.session.modelRegistry.getProviderDisplayName(providerId),
|
|
83
|
+
authType: credential.type,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return options.sort((a, b) => a.name.localeCompare(b.name));
|
|
87
|
+
}
|
|
88
|
+
resolveAuthProviderOption(providerReference, providerOptions) {
|
|
89
|
+
const normalized = providerReference.trim().toLowerCase();
|
|
90
|
+
if (!normalized)
|
|
91
|
+
return undefined;
|
|
92
|
+
const exactMatch = providerOptions.find((provider) => {
|
|
93
|
+
const id = provider.id.toLowerCase();
|
|
94
|
+
const name = provider.name.toLowerCase();
|
|
95
|
+
return id === normalized || name === normalized;
|
|
96
|
+
});
|
|
97
|
+
if (exactMatch)
|
|
98
|
+
return exactMatch;
|
|
99
|
+
const aliasTarget = cliProviderAliases[normalized] ?? normalized;
|
|
100
|
+
return providerOptions.find((provider) => {
|
|
101
|
+
const id = provider.id.toLowerCase();
|
|
102
|
+
const name = provider.name.toLowerCase();
|
|
103
|
+
return id === aliasTarget || name === aliasTarget;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async startProviderLogin(providerOption) {
|
|
107
|
+
if (providerOption.authType === "oauth") {
|
|
108
|
+
await this.showLoginDialog(providerOption.id, providerOption.name);
|
|
109
|
+
}
|
|
110
|
+
else if (providerOption.id === BEDROCK_PROVIDER_ID) {
|
|
111
|
+
this.showBedrockSetupDialog(providerOption.id, providerOption.name);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
await this.showApiKeyLoginDialog(providerOption.id, providerOption.name);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
showLoginAuthTypeSelector() {
|
|
118
|
+
const subscriptionLabel = "Use a subscription";
|
|
119
|
+
const apiKeyLabel = "Use an API key";
|
|
120
|
+
this.ui.showSelector((done) => {
|
|
121
|
+
const selector = new ExtensionSelectorComponent("Select authentication method:", [subscriptionLabel, apiKeyLabel], (option) => {
|
|
122
|
+
done();
|
|
123
|
+
const authType = option === subscriptionLabel ? "oauth" : "api_key";
|
|
124
|
+
this.showLoginProviderSelector(authType);
|
|
125
|
+
}, () => {
|
|
126
|
+
done();
|
|
127
|
+
this.ui.requestRender();
|
|
128
|
+
});
|
|
129
|
+
return { component: selector, focus: selector };
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
showLoginProviderSelector(authType) {
|
|
133
|
+
const providerOptions = this.getLoginProviderOptions(authType);
|
|
134
|
+
if (providerOptions.length === 0) {
|
|
135
|
+
this.ui.showStatus(authType === "oauth" ? "No subscription providers available." : "No API key providers available.");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.ui.showSelector((done) => {
|
|
139
|
+
const selector = new OAuthSelectorComponent("login", this.session.modelRegistry.authStorage, providerOptions, async (providerId) => {
|
|
140
|
+
done();
|
|
141
|
+
const providerOption = providerOptions.find((provider) => provider.id === providerId);
|
|
142
|
+
if (!providerOption) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
await this.startProviderLogin(providerOption);
|
|
146
|
+
}, () => {
|
|
147
|
+
done();
|
|
148
|
+
this.showLoginAuthTypeSelector();
|
|
149
|
+
}, (providerId) => this.session.modelRegistry.getProviderAuthStatus(providerId));
|
|
150
|
+
return { component: selector, focus: selector };
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async showOAuthSelector(mode, providerReference) {
|
|
154
|
+
if (mode === "login") {
|
|
155
|
+
if (providerReference) {
|
|
156
|
+
const providerOptions = this.getLoginProviderOptions();
|
|
157
|
+
const providerOption = this.resolveAuthProviderOption(providerReference, providerOptions);
|
|
158
|
+
if (!providerOption) {
|
|
159
|
+
this.ui.showError(`Unknown login provider "${providerReference}". Use /login to select from available providers.`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
await this.startProviderLogin(providerOption);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
this.showLoginAuthTypeSelector();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const providerOptions = this.getLogoutProviderOptions();
|
|
169
|
+
if (providerOptions.length === 0) {
|
|
170
|
+
this.ui.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (providerReference) {
|
|
174
|
+
const providerOption = this.resolveAuthProviderOption(providerReference, providerOptions);
|
|
175
|
+
if (!providerOption) {
|
|
176
|
+
this.ui.showError(`No stored credentials found for "${providerReference}". Use /logout to select a saved provider.`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
this.session.modelRegistry.authStorage.logout(providerOption.id);
|
|
181
|
+
this.session.modelRegistry.refresh();
|
|
182
|
+
await this.ui.updateAvailableProviderCount();
|
|
183
|
+
const message = providerOption.authType === "oauth"
|
|
184
|
+
? `Logged out of ${providerOption.name}`
|
|
185
|
+
: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;
|
|
186
|
+
this.ui.showStatus(message);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
this.ui.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
190
|
+
}
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this.ui.showSelector((done) => {
|
|
194
|
+
const selector = new OAuthSelectorComponent(mode, this.session.modelRegistry.authStorage, providerOptions, async (providerId) => {
|
|
195
|
+
done();
|
|
196
|
+
const providerOption = providerOptions.find((provider) => provider.id === providerId);
|
|
197
|
+
if (!providerOption) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
this.session.modelRegistry.authStorage.logout(providerOption.id);
|
|
202
|
+
this.session.modelRegistry.refresh();
|
|
203
|
+
await this.ui.updateAvailableProviderCount();
|
|
204
|
+
const message = providerOption.authType === "oauth"
|
|
205
|
+
? `Logged out of ${providerOption.name}`
|
|
206
|
+
: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;
|
|
207
|
+
this.ui.showStatus(message);
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
this.ui.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
211
|
+
}
|
|
212
|
+
}, () => {
|
|
213
|
+
done();
|
|
214
|
+
this.ui.requestRender();
|
|
215
|
+
});
|
|
216
|
+
return { component: selector, focus: selector };
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async completeProviderAuthentication(providerId, providerName, authType, previousModel) {
|
|
220
|
+
this.session.modelRegistry.refresh();
|
|
221
|
+
const actionLabel = authType === "oauth" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;
|
|
222
|
+
let selectedModel;
|
|
223
|
+
let selectionError;
|
|
224
|
+
if (isUnknownModel(previousModel)) {
|
|
225
|
+
const availableModels = this.session.modelRegistry.getAvailable();
|
|
226
|
+
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
227
|
+
if (!hasDefaultModelProvider(providerId)) {
|
|
228
|
+
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
229
|
+
}
|
|
230
|
+
else if (providerModels.length === 0) {
|
|
231
|
+
selectionError = `${actionLabel}, but no models are available for that provider. Use /model to select a model.`;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
const defaultModelId = defaultModelPerProvider[providerId];
|
|
235
|
+
selectedModel = providerModels.find((model) => model.id === defaultModelId);
|
|
236
|
+
if (!selectedModel) {
|
|
237
|
+
selectionError = `${actionLabel}, but its default model "${defaultModelId}" is not available. Use /model to select a model.`;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
try {
|
|
241
|
+
await this.session.setModel(selectedModel);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
selectedModel = undefined;
|
|
245
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
246
|
+
selectionError = `${actionLabel}, but selecting its default model failed: ${errorMessage}. Use /model to select a model.`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
await this.ui.updateAvailableProviderCount();
|
|
252
|
+
this.ui.invalidateFooter();
|
|
253
|
+
this.ui.updateEditorBorderColor();
|
|
254
|
+
if (selectedModel) {
|
|
255
|
+
this.ui.showStatus(`${actionLabel}. Selected ${selectedModel.id}. Credentials saved to ${getAuthPath()}`);
|
|
256
|
+
void this.ui.maybeWarnAboutAnthropicSubscriptionAuth(selectedModel);
|
|
257
|
+
this.ui.checkDaxnutsEasterEgg(selectedModel);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
this.ui.showStatus(`${actionLabel}. Credentials saved to ${getAuthPath()}`);
|
|
261
|
+
if (selectionError) {
|
|
262
|
+
this.ui.showError(selectionError);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
void this.ui.maybeWarnAboutAnthropicSubscriptionAuth();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
showBedrockSetupDialog(providerId, providerName) {
|
|
270
|
+
const restoreEditor = () => {
|
|
271
|
+
this.ui.overlayHost.swap(this.ui.getEditor());
|
|
272
|
+
};
|
|
273
|
+
const dialog = new LoginDialogComponent(this.ui.tui, providerId, () => restoreEditor(), providerName, "Amazon Bedrock setup");
|
|
274
|
+
dialog.showInfo([
|
|
275
|
+
theme.fg("text", "Amazon Bedrock uses AWS credentials instead of a single API key."),
|
|
276
|
+
theme.fg("text", "Configure an AWS profile, IAM keys, bearer token, or role-based credentials."),
|
|
277
|
+
theme.fg("muted", "See:"),
|
|
278
|
+
theme.fg("accent", ` ${path.join(getDocsPath(), "providers.md")}`),
|
|
279
|
+
]);
|
|
280
|
+
this.ui.overlayHost.swap(dialog);
|
|
281
|
+
}
|
|
282
|
+
async showApiKeyLoginDialog(providerId, providerName) {
|
|
283
|
+
const previousModel = this.session.model;
|
|
284
|
+
const dialog = new LoginDialogComponent(this.ui.tui, providerId, (_success, _message) => {
|
|
285
|
+
// Completion handled below
|
|
286
|
+
}, providerName);
|
|
287
|
+
this.ui.overlayHost.swap(dialog);
|
|
288
|
+
const restoreEditor = () => {
|
|
289
|
+
this.ui.overlayHost.swap(this.ui.getEditor());
|
|
290
|
+
};
|
|
291
|
+
try {
|
|
292
|
+
const apiKey = (await dialog.showPrompt("Enter API key:")).trim();
|
|
293
|
+
if (!apiKey) {
|
|
294
|
+
throw new Error("API key cannot be empty.");
|
|
295
|
+
}
|
|
296
|
+
this.session.modelRegistry.authStorage.set(providerId, { type: "api_key", key: apiKey });
|
|
297
|
+
restoreEditor();
|
|
298
|
+
await this.completeProviderAuthentication(providerId, providerName, "api_key", previousModel);
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
restoreEditor();
|
|
302
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
303
|
+
if (errorMsg !== "Login cancelled") {
|
|
304
|
+
this.ui.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
showOAuthLoginSelect(dialog, prompt) {
|
|
309
|
+
return new Promise((resolve) => {
|
|
310
|
+
const restoreDialog = () => {
|
|
311
|
+
this.ui.overlayHost.swap(dialog);
|
|
312
|
+
};
|
|
313
|
+
const labels = prompt.options.map((option) => option.label);
|
|
314
|
+
const selector = new ExtensionSelectorComponent(prompt.message, labels, (optionLabel) => {
|
|
315
|
+
restoreDialog();
|
|
316
|
+
resolve(prompt.options.find((option) => option.label === optionLabel)?.id);
|
|
317
|
+
}, () => {
|
|
318
|
+
restoreDialog();
|
|
319
|
+
resolve(undefined);
|
|
320
|
+
});
|
|
321
|
+
this.ui.overlayHost.swap(selector);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
async showLoginDialog(providerId, providerName) {
|
|
325
|
+
const providerInfo = this.session.modelRegistry.authStorage
|
|
326
|
+
.getOAuthProviders()
|
|
327
|
+
.find((provider) => provider.id === providerId);
|
|
328
|
+
const previousModel = this.session.model;
|
|
329
|
+
// Providers that use callback servers (can paste redirect URL)
|
|
330
|
+
const usesCallbackServer = providerInfo?.usesCallbackServer ?? false;
|
|
331
|
+
// Create login dialog component
|
|
332
|
+
const dialog = new LoginDialogComponent(this.ui.tui, providerId, (_success, _message) => {
|
|
333
|
+
// Completion handled below
|
|
334
|
+
}, providerName);
|
|
335
|
+
// Show dialog in editor container
|
|
336
|
+
this.ui.overlayHost.swap(dialog);
|
|
337
|
+
// Promise for manual code input (racing with callback server)
|
|
338
|
+
let manualCodeResolve;
|
|
339
|
+
let manualCodeReject;
|
|
340
|
+
const manualCodePromise = new Promise((resolve, reject) => {
|
|
341
|
+
manualCodeResolve = resolve;
|
|
342
|
+
manualCodeReject = reject;
|
|
343
|
+
});
|
|
344
|
+
// Restore editor helper
|
|
345
|
+
const restoreEditor = () => {
|
|
346
|
+
this.ui.overlayHost.swap(this.ui.getEditor());
|
|
347
|
+
};
|
|
348
|
+
try {
|
|
349
|
+
await this.session.modelRegistry.authStorage.login(providerId, {
|
|
350
|
+
onAuth: (info) => {
|
|
351
|
+
dialog.showAuth(info.url, info.instructions);
|
|
352
|
+
if (usesCallbackServer) {
|
|
353
|
+
// Show input for manual paste, racing with callback
|
|
354
|
+
dialog
|
|
355
|
+
.showManualInput("Paste redirect URL below, or complete login in browser:")
|
|
356
|
+
.then((value) => {
|
|
357
|
+
if (value && manualCodeResolve) {
|
|
358
|
+
manualCodeResolve(value);
|
|
359
|
+
manualCodeResolve = undefined;
|
|
360
|
+
}
|
|
361
|
+
})
|
|
362
|
+
.catch(() => {
|
|
363
|
+
if (manualCodeReject) {
|
|
364
|
+
manualCodeReject(new Error("Login cancelled"));
|
|
365
|
+
manualCodeReject = undefined;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
// For Anthropic: onPrompt is called immediately after
|
|
370
|
+
},
|
|
371
|
+
onDeviceCode: (info) => {
|
|
372
|
+
dialog.showDeviceCode(info);
|
|
373
|
+
dialog.showWaiting("Waiting for authentication...");
|
|
374
|
+
},
|
|
375
|
+
onPrompt: async (prompt) => {
|
|
376
|
+
return dialog.showPrompt(prompt.message, prompt.placeholder);
|
|
377
|
+
},
|
|
378
|
+
onProgress: (message) => {
|
|
379
|
+
dialog.showProgress(message);
|
|
380
|
+
},
|
|
381
|
+
onSelect: (prompt) => this.showOAuthLoginSelect(dialog, prompt),
|
|
382
|
+
onManualCodeInput: () => manualCodePromise,
|
|
383
|
+
signal: dialog.signal,
|
|
384
|
+
});
|
|
385
|
+
// Success
|
|
386
|
+
restoreEditor();
|
|
387
|
+
await this.completeProviderAuthentication(providerId, providerName, "oauth", previousModel);
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
restoreEditor();
|
|
391
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
392
|
+
if (errorMsg !== "Login cancelled") {
|
|
393
|
+
this.ui.showError(`Failed to login to ${providerName}: ${errorMsg}`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=auth-dialogs-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-dialogs-controller.js","sourceRoot":"","sources":["../../../src/modes/interactive/auth-dialogs-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Auth / login / OAuth dialog controller.\n *\n * Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the /login and /logout\n * command flows: provider selection, subscription (OAuth) login dialogs, API-key login dialogs, the\n * Amazon Bedrock setup notice, the OAuth in-dialog select prompt, and post-login model adoption. It\n * holds NO state of its own — every credential/provider fact lives in session.modelRegistry.authStorage\n * — so it takes narrow deps (a live session accessor plus a UI callback surface, including the\n * editor-overlay-backed showSelector and the shared EditorOverlayHost for dialog swaps) rather than\n * the whole InteractiveMode instance.\n */\n\nimport * as path from \"node:path\";\nimport { getProviders, type Model, type OAuthProviderId, type OAuthSelectPrompt } from \"@caupulican/pi-ai\";\nimport type { Component, TUI } from \"@caupulican/pi-tui\";\nimport { getAuthPath, getDocsPath } from \"../../config.ts\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport { cliProviderAliases, defaultModelPerProvider } from \"../../core/model-resolver.ts\";\nimport { BUILT_IN_PROVIDER_DISPLAY_NAMES } from \"../../core/provider-display-names.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport { LoginDialogComponent } from \"./components/login-dialog.ts\";\nimport { type AuthSelectorProvider, OAuthSelectorComponent } from \"./components/oauth-selector.ts\";\nimport type { EditorOverlayHost } from \"./editor-overlay-host.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nfunction isUnknownModel(model: Model<any> | undefined): boolean {\n\treturn !!model && model.provider === \"unknown\" && model.id === \"unknown\" && model.api === \"unknown\";\n}\n\nfunction hasDefaultModelProvider(providerId: string): providerId is keyof typeof defaultModelPerProvider {\n\treturn providerId in defaultModelPerProvider;\n}\n\nconst BEDROCK_PROVIDER_ID = \"amazon-bedrock\";\n\nconst BUILT_IN_MODEL_PROVIDERS = new Set<string>(getProviders());\n\nexport function isApiKeyLoginProvider(\n\tproviderId: string,\n\toauthProviderIds: ReadonlySet<string>,\n\tbuiltInProviderIds: ReadonlySet<string> = BUILT_IN_MODEL_PROVIDERS,\n): boolean {\n\tif (BUILT_IN_PROVIDER_DISPLAY_NAMES[providerId]) {\n\t\treturn true;\n\t}\n\tif (builtInProviderIds.has(providerId)) {\n\t\treturn false;\n\t}\n\treturn !oauthProviderIds.has(providerId);\n}\n\nexport interface AuthDialogsControllerUi {\n\tshowSelector(create: (done: () => void) => { component: Component; focus: Component }): void;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\trequestRender(): void;\n\treadonly tui: TUI;\n\treadonly overlayHost: EditorOverlayHost;\n\tgetEditor(): Component;\n\tupdateAvailableProviderCount(): Promise<void>;\n\tinvalidateFooter(): void;\n\tupdateEditorBorderColor(): void;\n\tmaybeWarnAboutAnthropicSubscriptionAuth(model?: Model<any>): void;\n\tcheckDaxnutsEasterEgg(model: { provider: string; id: string }): void;\n}\n\nexport interface AuthDialogsControllerDeps {\n\tgetSession(): AgentSession;\n\tui: AuthDialogsControllerUi;\n}\n\nexport class AuthDialogsController {\n\tprivate readonly deps: AuthDialogsControllerDeps;\n\n\tconstructor(deps: AuthDialogsControllerDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.getSession();\n\t}\n\tprivate get ui(): AuthDialogsControllerUi {\n\t\treturn this.deps.ui;\n\t}\n\n\tprivate getLoginProviderOptions(authType?: \"oauth\" | \"api_key\"): AuthSelectorProvider[] {\n\t\tconst authStorage = this.session.modelRegistry.authStorage;\n\t\tconst oauthProviders = authStorage.getOAuthProviders();\n\t\tconst oauthProviderIds = new Set(oauthProviders.map((provider) => provider.id));\n\t\tconst options: AuthSelectorProvider[] = oauthProviders.map((provider) => ({\n\t\t\tid: provider.id,\n\t\t\tname: provider.name,\n\t\t\tauthType: \"oauth\",\n\t\t}));\n\n\t\tconst modelProviders = new Set(this.session.modelRegistry.getAll().map((model) => model.provider));\n\t\tfor (const providerId of modelProviders) {\n\t\t\tif (!isApiKeyLoginProvider(providerId, oauthProviderIds)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname: this.session.modelRegistry.getProviderDisplayName(providerId),\n\t\t\t\tauthType: \"api_key\",\n\t\t\t});\n\t\t}\n\n\t\tconst filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;\n\t\treturn filteredOptions.sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tprivate getLogoutProviderOptions(): AuthSelectorProvider[] {\n\t\tconst authStorage = this.session.modelRegistry.authStorage;\n\t\tconst options: AuthSelectorProvider[] = [];\n\n\t\tfor (const providerId of authStorage.list()) {\n\t\t\tconst credential = authStorage.get(providerId);\n\t\t\tif (!credential) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname: this.session.modelRegistry.getProviderDisplayName(providerId),\n\t\t\t\tauthType: credential.type,\n\t\t\t});\n\t\t}\n\n\t\treturn options.sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tprivate resolveAuthProviderOption(\n\t\tproviderReference: string,\n\t\tproviderOptions: AuthSelectorProvider[],\n\t): AuthSelectorProvider | undefined {\n\t\tconst normalized = providerReference.trim().toLowerCase();\n\t\tif (!normalized) return undefined;\n\t\tconst exactMatch = providerOptions.find((provider) => {\n\t\t\tconst id = provider.id.toLowerCase();\n\t\t\tconst name = provider.name.toLowerCase();\n\t\t\treturn id === normalized || name === normalized;\n\t\t});\n\t\tif (exactMatch) return exactMatch;\n\t\tconst aliasTarget = cliProviderAliases[normalized] ?? normalized;\n\t\treturn providerOptions.find((provider) => {\n\t\t\tconst id = provider.id.toLowerCase();\n\t\t\tconst name = provider.name.toLowerCase();\n\t\t\treturn id === aliasTarget || name === aliasTarget;\n\t\t});\n\t}\n\n\tprivate async startProviderLogin(providerOption: AuthSelectorProvider): Promise<void> {\n\t\tif (providerOption.authType === \"oauth\") {\n\t\t\tawait this.showLoginDialog(providerOption.id, providerOption.name);\n\t\t} else if (providerOption.id === BEDROCK_PROVIDER_ID) {\n\t\t\tthis.showBedrockSetupDialog(providerOption.id, providerOption.name);\n\t\t} else {\n\t\t\tawait this.showApiKeyLoginDialog(providerOption.id, providerOption.name);\n\t\t}\n\t}\n\n\tprivate showLoginAuthTypeSelector(): void {\n\t\tconst subscriptionLabel = \"Use a subscription\";\n\t\tconst apiKeyLabel = \"Use an API key\";\n\t\tthis.ui.showSelector((done) => {\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\t\"Select authentication method:\",\n\t\t\t\t[subscriptionLabel, apiKeyLabel],\n\t\t\t\t(option) => {\n\t\t\t\t\tdone();\n\t\t\t\t\tconst authType = option === subscriptionLabel ? \"oauth\" : \"api_key\";\n\t\t\t\t\tthis.showLoginProviderSelector(authType);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tdone();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn { component: selector, focus: selector };\n\t\t});\n\t}\n\n\tprivate showLoginProviderSelector(authType: \"oauth\" | \"api_key\"): void {\n\t\tconst providerOptions = this.getLoginProviderOptions(authType);\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.ui.showStatus(\n\t\t\t\tauthType === \"oauth\" ? \"No subscription providers available.\" : \"No API key providers available.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ui.showSelector((done) => {\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\t\"login\",\n\t\t\t\tthis.session.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerId: string) => {\n\t\t\t\t\tdone();\n\n\t\t\t\t\tconst providerOption = providerOptions.find((provider) => provider.id === providerId);\n\t\t\t\t\tif (!providerOption) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait this.startProviderLogin(providerOption);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tdone();\n\t\t\t\t\tthis.showLoginAuthTypeSelector();\n\t\t\t\t},\n\t\t\t\t(providerId) => this.session.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t);\n\t\t\treturn { component: selector, focus: selector };\n\t\t});\n\t}\n\n\tasync showOAuthSelector(mode: \"login\" | \"logout\", providerReference?: string): Promise<void> {\n\t\tif (mode === \"login\") {\n\t\t\tif (providerReference) {\n\t\t\t\tconst providerOptions = this.getLoginProviderOptions();\n\t\t\t\tconst providerOption = this.resolveAuthProviderOption(providerReference, providerOptions);\n\t\t\t\tif (!providerOption) {\n\t\t\t\t\tthis.ui.showError(\n\t\t\t\t\t\t`Unknown login provider \"${providerReference}\". Use /login to select from available providers.`,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait this.startProviderLogin(providerOption);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.showLoginAuthTypeSelector();\n\t\t\treturn;\n\t\t}\n\n\t\tconst providerOptions = this.getLogoutProviderOptions();\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.ui.showStatus(\n\t\t\t\t\"No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (providerReference) {\n\t\t\tconst providerOption = this.resolveAuthProviderOption(providerReference, providerOptions);\n\t\t\tif (!providerOption) {\n\t\t\t\tthis.ui.showError(\n\t\t\t\t\t`No stored credentials found for \"${providerReference}\". Use /logout to select a saved provider.`,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tthis.session.modelRegistry.authStorage.logout(providerOption.id);\n\t\t\t\tthis.session.modelRegistry.refresh();\n\t\t\t\tawait this.ui.updateAvailableProviderCount();\n\t\t\t\tconst message =\n\t\t\t\t\tproviderOption.authType === \"oauth\"\n\t\t\t\t\t\t? `Logged out of ${providerOption.name}`\n\t\t\t\t\t\t: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;\n\t\t\t\tthis.ui.showStatus(message);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tthis.ui.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ui.showSelector((done) => {\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\tmode,\n\t\t\t\tthis.session.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerId: string) => {\n\t\t\t\t\tdone();\n\n\t\t\t\t\tconst providerOption = providerOptions.find((provider) => provider.id === providerId);\n\t\t\t\t\tif (!providerOption) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.session.modelRegistry.authStorage.logout(providerOption.id);\n\t\t\t\t\t\tthis.session.modelRegistry.refresh();\n\t\t\t\t\t\tawait this.ui.updateAvailableProviderCount();\n\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\tproviderOption.authType === \"oauth\"\n\t\t\t\t\t\t\t\t? `Logged out of ${providerOption.name}`\n\t\t\t\t\t\t\t\t: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;\n\t\t\t\t\t\tthis.ui.showStatus(message);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tthis.ui.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tdone();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn { component: selector, focus: selector };\n\t\t});\n\t}\n\n\tprivate async completeProviderAuthentication(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tauthType: \"oauth\" | \"api_key\",\n\t\tpreviousModel: Model<any> | undefined,\n\t): Promise<void> {\n\t\tthis.session.modelRegistry.refresh();\n\n\t\tconst actionLabel = authType === \"oauth\" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;\n\n\t\tlet selectedModel: Model<any> | undefined;\n\t\tlet selectionError: string | undefined;\n\t\tif (isUnknownModel(previousModel)) {\n\t\t\tconst availableModels = this.session.modelRegistry.getAvailable();\n\t\t\tconst providerModels = availableModels.filter((model) => model.provider === providerId);\n\t\t\tif (!hasDefaultModelProvider(providerId)) {\n\t\t\t\tselectionError = `${actionLabel}, but no default model is configured for provider \"${providerId}\". Use /model to select a model.`;\n\t\t\t} else if (providerModels.length === 0) {\n\t\t\t\tselectionError = `${actionLabel}, but no models are available for that provider. Use /model to select a model.`;\n\t\t\t} else {\n\t\t\t\tconst defaultModelId = defaultModelPerProvider[providerId];\n\t\t\t\tselectedModel = providerModels.find((model) => model.id === defaultModelId);\n\t\t\t\tif (!selectedModel) {\n\t\t\t\t\tselectionError = `${actionLabel}, but its default model \"${defaultModelId}\" is not available. Use /model to select a model.`;\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this.session.setModel(selectedModel);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tselectedModel = undefined;\n\t\t\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\t\t\tselectionError = `${actionLabel}, but selecting its default model failed: ${errorMessage}. Use /model to select a model.`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait this.ui.updateAvailableProviderCount();\n\t\tthis.ui.invalidateFooter();\n\t\tthis.ui.updateEditorBorderColor();\n\t\tif (selectedModel) {\n\t\t\tthis.ui.showStatus(`${actionLabel}. Selected ${selectedModel.id}. Credentials saved to ${getAuthPath()}`);\n\t\t\tvoid this.ui.maybeWarnAboutAnthropicSubscriptionAuth(selectedModel);\n\t\t\tthis.ui.checkDaxnutsEasterEgg(selectedModel);\n\t\t} else {\n\t\t\tthis.ui.showStatus(`${actionLabel}. Credentials saved to ${getAuthPath()}`);\n\t\t\tif (selectionError) {\n\t\t\t\tthis.ui.showError(selectionError);\n\t\t\t} else {\n\t\t\t\tvoid this.ui.maybeWarnAboutAnthropicSubscriptionAuth();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate showBedrockSetupDialog(providerId: string, providerName: string): void {\n\t\tconst restoreEditor = () => {\n\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor());\n\t\t};\n\n\t\tconst dialog = new LoginDialogComponent(\n\t\t\tthis.ui.tui,\n\t\t\tproviderId,\n\t\t\t() => restoreEditor(),\n\t\t\tproviderName,\n\t\t\t\"Amazon Bedrock setup\",\n\t\t);\n\t\tdialog.showInfo([\n\t\t\ttheme.fg(\"text\", \"Amazon Bedrock uses AWS credentials instead of a single API key.\"),\n\t\t\ttheme.fg(\"text\", \"Configure an AWS profile, IAM keys, bearer token, or role-based credentials.\"),\n\t\t\ttheme.fg(\"muted\", \"See:\"),\n\t\t\ttheme.fg(\"accent\", ` ${path.join(getDocsPath(), \"providers.md\")}`),\n\t\t]);\n\n\t\tthis.ui.overlayHost.swap(dialog);\n\t}\n\n\tprivate async showApiKeyLoginDialog(providerId: string, providerName: string): Promise<void> {\n\t\tconst previousModel = this.session.model;\n\n\t\tconst dialog = new LoginDialogComponent(\n\t\t\tthis.ui.tui,\n\t\t\tproviderId,\n\t\t\t(_success, _message) => {\n\t\t\t\t// Completion handled below\n\t\t\t},\n\t\t\tproviderName,\n\t\t);\n\n\t\tthis.ui.overlayHost.swap(dialog);\n\n\t\tconst restoreEditor = () => {\n\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor());\n\t\t};\n\n\t\ttry {\n\t\t\tconst apiKey = (await dialog.showPrompt(\"Enter API key:\")).trim();\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(\"API key cannot be empty.\");\n\t\t\t}\n\n\t\t\tthis.session.modelRegistry.authStorage.set(providerId, { type: \"api_key\", key: apiKey });\n\n\t\t\trestoreEditor();\n\t\t\tawait this.completeProviderAuthentication(providerId, providerName, \"api_key\", previousModel);\n\t\t} catch (error: unknown) {\n\t\t\trestoreEditor();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.ui.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate showOAuthLoginSelect(dialog: LoginDialogComponent, prompt: OAuthSelectPrompt): Promise<string | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst restoreDialog = () => {\n\t\t\t\tthis.ui.overlayHost.swap(dialog);\n\t\t\t};\n\t\t\tconst labels = prompt.options.map((option) => option.label);\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\tprompt.message,\n\t\t\t\tlabels,\n\t\t\t\t(optionLabel) => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(prompt.options.find((option) => option.label === optionLabel)?.id);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.ui.overlayHost.swap(selector);\n\t\t});\n\t}\n\n\tprivate async showLoginDialog(providerId: string, providerName: string): Promise<void> {\n\t\tconst providerInfo = this.session.modelRegistry.authStorage\n\t\t\t.getOAuthProviders()\n\t\t\t.find((provider) => provider.id === providerId);\n\t\tconst previousModel = this.session.model;\n\n\t\t// Providers that use callback servers (can paste redirect URL)\n\t\tconst usesCallbackServer = providerInfo?.usesCallbackServer ?? false;\n\n\t\t// Create login dialog component\n\t\tconst dialog = new LoginDialogComponent(\n\t\t\tthis.ui.tui,\n\t\t\tproviderId,\n\t\t\t(_success, _message) => {\n\t\t\t\t// Completion handled below\n\t\t\t},\n\t\t\tproviderName,\n\t\t);\n\n\t\t// Show dialog in editor container\n\t\tthis.ui.overlayHost.swap(dialog);\n\n\t\t// Promise for manual code input (racing with callback server)\n\t\tlet manualCodeResolve: ((code: string) => void) | undefined;\n\t\tlet manualCodeReject: ((err: Error) => void) | undefined;\n\t\tconst manualCodePromise = new Promise<string>((resolve, reject) => {\n\t\t\tmanualCodeResolve = resolve;\n\t\t\tmanualCodeReject = reject;\n\t\t});\n\n\t\t// Restore editor helper\n\t\tconst restoreEditor = () => {\n\t\t\tthis.ui.overlayHost.swap(this.ui.getEditor());\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.session.modelRegistry.authStorage.login(providerId as OAuthProviderId, {\n\t\t\t\tonAuth: (info: { url: string; instructions?: string }) => {\n\t\t\t\t\tdialog.showAuth(info.url, info.instructions);\n\n\t\t\t\t\tif (usesCallbackServer) {\n\t\t\t\t\t\t// Show input for manual paste, racing with callback\n\t\t\t\t\t\tdialog\n\t\t\t\t\t\t\t.showManualInput(\"Paste redirect URL below, or complete login in browser:\")\n\t\t\t\t\t\t\t.then((value) => {\n\t\t\t\t\t\t\t\tif (value && manualCodeResolve) {\n\t\t\t\t\t\t\t\t\tmanualCodeResolve(value);\n\t\t\t\t\t\t\t\t\tmanualCodeResolve = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\t\t\tif (manualCodeReject) {\n\t\t\t\t\t\t\t\t\tmanualCodeReject(new Error(\"Login cancelled\"));\n\t\t\t\t\t\t\t\t\tmanualCodeReject = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// For Anthropic: onPrompt is called immediately after\n\t\t\t\t},\n\n\t\t\t\tonDeviceCode: (info) => {\n\t\t\t\t\tdialog.showDeviceCode(info);\n\t\t\t\t\tdialog.showWaiting(\"Waiting for authentication...\");\n\t\t\t\t},\n\n\t\t\t\tonPrompt: async (prompt: { message: string; placeholder?: string }) => {\n\t\t\t\t\treturn dialog.showPrompt(prompt.message, prompt.placeholder);\n\t\t\t\t},\n\n\t\t\t\tonProgress: (message: string) => {\n\t\t\t\t\tdialog.showProgress(message);\n\t\t\t\t},\n\n\t\t\t\tonSelect: (prompt: OAuthSelectPrompt) => this.showOAuthLoginSelect(dialog, prompt),\n\n\t\t\t\tonManualCodeInput: () => manualCodePromise,\n\n\t\t\t\tsignal: dialog.signal,\n\t\t\t});\n\n\t\t\t// Success\n\t\t\trestoreEditor();\n\t\t\tawait this.completeProviderAuthentication(providerId, providerName, \"oauth\", previousModel);\n\t\t} catch (error: unknown) {\n\t\t\trestoreEditor();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.ui.showError(`Failed to login to ${providerName}: ${errorMsg}`);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|