@ashx-j/lunr 0.2.25 → 0.2.27
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 +31 -1
- package/LICENSE +22 -0
- package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
- package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-thinking.js +1 -1
- package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.js +6 -10
- package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +1 -0
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
- package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-computer-use.js +179 -0
- package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
- package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
- package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-cron.js +94 -108
- package/dist/builtin-extensions/lunr-cron.js.map +1 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
- package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
- package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.js +2 -2
- package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
- package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
- package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
- package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
- package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
- package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
- package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
- package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
- package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
- package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
- package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
- package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
- package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +21 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +11 -4
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +121 -25
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
- package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
- package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +22 -11
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
- package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-tps.js +20 -17
- package/dist/builtin-extensions/pi-tps.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
- package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
- package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
- package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
- package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
- package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
- package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
- package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.js +48 -73
- package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
- package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
- package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
- package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
- package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
- package/dist/builtin-extensions/simple-pi-memory.js +1 -1
- package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
- package/dist/cli/install-cli.d.ts.map +1 -1
- package/dist/cli/install-cli.js +38 -30
- package/dist/cli/install-cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +13 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +75 -11
- 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 +40 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +309 -76
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/browser/runtime.d.ts +2 -0
- package/dist/core/browser/runtime.d.ts.map +1 -1
- package/dist/core/browser/runtime.js +80 -45
- package/dist/core/browser/runtime.js.map +1 -1
- package/dist/core/browser/setup.d.ts.map +1 -1
- package/dist/core/browser/setup.js +12 -1
- package/dist/core/browser/setup.js.map +1 -1
- package/dist/core/computer-use/adapter.d.ts +28 -0
- package/dist/core/computer-use/adapter.d.ts.map +1 -0
- package/dist/core/computer-use/adapter.js +138 -0
- package/dist/core/computer-use/adapter.js.map +1 -0
- package/dist/core/computer-use/image.d.ts +27 -0
- package/dist/core/computer-use/image.d.ts.map +1 -0
- package/dist/core/computer-use/image.js +84 -0
- package/dist/core/computer-use/image.js.map +1 -0
- package/dist/core/computer-use/lease.d.ts +18 -0
- package/dist/core/computer-use/lease.d.ts.map +1 -0
- package/dist/core/computer-use/lease.js +129 -0
- package/dist/core/computer-use/lease.js.map +1 -0
- package/dist/core/computer-use/macos-runtime.d.ts +14 -0
- package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
- package/dist/core/computer-use/macos-runtime.js +148 -0
- package/dist/core/computer-use/macos-runtime.js.map +1 -0
- package/dist/core/computer-use/policy.d.ts +19 -0
- package/dist/core/computer-use/policy.d.ts.map +1 -0
- package/dist/core/computer-use/policy.js +67 -0
- package/dist/core/computer-use/policy.js.map +1 -0
- package/dist/core/computer-use/release.generated.d.ts +31 -0
- package/dist/core/computer-use/release.generated.d.ts.map +1 -0
- package/dist/core/computer-use/release.generated.js +36 -0
- package/dist/core/computer-use/release.generated.js.map +1 -0
- package/dist/core/computer-use/runtime.d.ts +13 -0
- package/dist/core/computer-use/runtime.d.ts.map +1 -0
- package/dist/core/computer-use/runtime.js +158 -0
- package/dist/core/computer-use/runtime.js.map +1 -0
- package/dist/core/computer-use/schemas.d.ts +100 -0
- package/dist/core/computer-use/schemas.d.ts.map +1 -0
- package/dist/core/computer-use/schemas.js +96 -0
- package/dist/core/computer-use/schemas.js.map +1 -0
- package/dist/core/computer-use/windows-desktop.d.ts +3 -0
- package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
- package/dist/core/computer-use/windows-desktop.js +48 -0
- package/dist/core/computer-use/windows-desktop.js.map +1 -0
- package/dist/core/computer-use/workflow.d.ts +38 -0
- package/dist/core/computer-use/workflow.d.ts.map +1 -0
- package/dist/core/computer-use/workflow.js +900 -0
- package/dist/core/computer-use/workflow.js.map +1 -0
- package/dist/core/cron/jobs.d.ts +26 -8
- package/dist/core/cron/jobs.d.ts.map +1 -1
- package/dist/core/cron/jobs.js +357 -232
- package/dist/core/cron/jobs.js.map +1 -1
- package/dist/core/cron/origin-context.d.ts +1 -0
- package/dist/core/cron/origin-context.d.ts.map +1 -1
- package/dist/core/cron/origin-context.js.map +1 -1
- package/dist/core/cron/scheduler.d.ts +22 -17
- package/dist/core/cron/scheduler.d.ts.map +1 -1
- package/dist/core/cron/scheduler.js +153 -73
- package/dist/core/cron/scheduler.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 +4 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +8 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +8 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +4 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +22 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/large-subagent-launch.d.ts +1 -1
- package/dist/core/large-subagent-launch.d.ts.map +1 -1
- package/dist/core/large-subagent-launch.js +7 -7
- package/dist/core/large-subagent-launch.js.map +1 -1
- package/dist/core/model-registry.d.ts +2 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +5 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-runtime.d.ts +4 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +40 -4
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/permissions.d.ts +4 -4
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +25 -38
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts +5 -13
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +135 -116
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-resource-bridge.d.ts +12 -0
- package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
- package/dist/core/prompt-resource-bridge.js +9 -0
- package/dist/core/prompt-resource-bridge.js.map +1 -0
- package/dist/core/protected-targets.d.ts +6 -0
- package/dist/core/protected-targets.d.ts.map +1 -0
- package/dist/core/protected-targets.js +45 -0
- package/dist/core/protected-targets.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +7 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/rollback.d.ts +19 -3
- package/dist/core/rollback.d.ts.map +1 -1
- package/dist/core/rollback.js +172 -56
- package/dist/core/rollback.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +3 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +14 -1
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +6 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +95 -32
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-ownership.d.ts.map +1 -1
- package/dist/core/session-ownership.js +8 -3
- package/dist/core/session-ownership.js.map +1 -1
- package/dist/core/session-retention.d.ts.map +1 -1
- package/dist/core/session-retention.js +18 -7
- package/dist/core/session-retention.js.map +1 -1
- package/dist/core/session-startup-settings.d.ts +10 -0
- package/dist/core/session-startup-settings.d.ts.map +1 -0
- package/dist/core/session-startup-settings.js +70 -0
- package/dist/core/session-startup-settings.js.map +1 -0
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +19 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/subagent-event-transport.d.ts +3 -0
- package/dist/core/subagent-event-transport.d.ts.map +1 -0
- package/dist/core/subagent-event-transport.js +61 -0
- package/dist/core/subagent-event-transport.js.map +1 -0
- package/dist/core/subscriptions.d.ts +16 -7
- package/dist/core/subscriptions.d.ts.map +1 -1
- package/dist/core/subscriptions.js +96 -55
- package/dist/core/subscriptions.js.map +1 -1
- package/dist/core/trust-manager.d.ts +2 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +6 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/update-check.d.ts.map +1 -1
- package/dist/core/update-check.js.map +1 -1
- package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
- package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
- package/dist/core/usage-adapters/kimi-coding.js +2 -2
- package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
- package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
- package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
- package/dist/core/usage-adapters/openai-codex.js +3 -3
- package/dist/core/usage-adapters/openai-codex.js.map +1 -1
- package/dist/core/usage-adapters/xai.d.ts +2 -2
- package/dist/core/usage-adapters/xai.d.ts.map +1 -1
- package/dist/core/usage-adapters/xai.js +3 -3
- package/dist/core/usage-adapters/xai.js.map +1 -1
- package/dist/core/usage-adapters/zai.d.ts +2 -2
- package/dist/core/usage-adapters/zai.d.ts.map +1 -1
- package/dist/core/usage-adapters/zai.js +2 -2
- package/dist/core/usage-adapters/zai.js.map +1 -1
- package/dist/core/usage-service.d.ts +9 -2
- package/dist/core/usage-service.d.ts.map +1 -1
- package/dist/core/usage-service.js +95 -50
- package/dist/core/usage-service.js.map +1 -1
- package/dist/gateway/adapters/discord.d.ts.map +1 -1
- package/dist/gateway/adapters/discord.js +2 -2
- package/dist/gateway/adapters/discord.js.map +1 -1
- package/dist/gateway/agent-bridge.d.ts +9 -1
- package/dist/gateway/agent-bridge.d.ts.map +1 -1
- package/dist/gateway/agent-bridge.js +91 -37
- package/dist/gateway/agent-bridge.js.map +1 -1
- package/dist/gateway/approval.d.ts.map +1 -1
- package/dist/gateway/approval.js +3 -3
- package/dist/gateway/approval.js.map +1 -1
- package/dist/gateway/authz.d.ts +4 -4
- package/dist/gateway/authz.d.ts.map +1 -1
- package/dist/gateway/authz.js +8 -12
- package/dist/gateway/authz.js.map +1 -1
- package/dist/gateway/buttons.d.ts +8 -1
- package/dist/gateway/buttons.d.ts.map +1 -1
- package/dist/gateway/buttons.js +76 -18
- package/dist/gateway/buttons.js.map +1 -1
- package/dist/gateway/commands.d.ts +1 -0
- package/dist/gateway/commands.d.ts.map +1 -1
- package/dist/gateway/commands.js +12 -10
- package/dist/gateway/commands.js.map +1 -1
- package/dist/gateway/cron.d.ts +12 -11
- package/dist/gateway/cron.d.ts.map +1 -1
- package/dist/gateway/cron.js +85 -62
- package/dist/gateway/cron.js.map +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +5 -4
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/mobile-commands.d.ts +1 -0
- package/dist/gateway/mobile-commands.d.ts.map +1 -1
- package/dist/gateway/mobile-commands.js +64 -22
- package/dist/gateway/mobile-commands.js.map +1 -1
- package/dist/gateway/presenter.d.ts +12 -2
- package/dist/gateway/presenter.d.ts.map +1 -1
- package/dist/gateway/presenter.js +74 -39
- package/dist/gateway/presenter.js.map +1 -1
- package/dist/gateway/router.d.ts +2 -2
- package/dist/gateway/router.d.ts.map +1 -1
- package/dist/gateway/router.js +22 -9
- package/dist/gateway/router.js.map +1 -1
- package/dist/gateway/service.d.ts +2 -0
- package/dist/gateway/service.d.ts.map +1 -1
- package/dist/gateway/service.js +153 -0
- package/dist/gateway/service.js.map +1 -1
- package/dist/gateway/setup.d.ts.map +1 -1
- package/dist/gateway/setup.js +6 -4
- package/dist/gateway/setup.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +86 -33
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +6 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
- package/dist/modes/interactive/components/copyable-text.js +3 -2
- package/dist/modes/interactive/components/copyable-text.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 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +20 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +104 -109
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
- package/dist/modes/interactive/smooth-streaming.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +9 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/node-runtime/adapter-247RTYLS.js +16 -0
- package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
- package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
- package/dist/node-runtime/{builtin-extensions-ZLAX7TUH.js → builtin-extensions-OX6KELNX.js} +9 -7
- package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
- package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
- package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
- package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
- package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
- package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
- package/dist/node-runtime/{chunk-NRKGMJYU.js → chunk-6O3IW3IA.js} +2 -2
- package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
- package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
- package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-APVM5NEU.js} +169 -148
- package/dist/node-runtime/{chunk-RC7DMV45.js → chunk-AYHH7YSD.js} +205 -144
- package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
- package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
- package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
- package/dist/node-runtime/{chunk-KWIYUUZK.js → chunk-C3P6Q3B2.js} +469 -283
- package/dist/node-runtime/{chunk-YCUZEGJG.js → chunk-DQSCFU7R.js} +17 -8
- package/dist/node-runtime/chunk-EBLAZVSA.js +4170 -0
- package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
- package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
- package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
- package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
- package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
- package/dist/node-runtime/chunk-FE3WZI7F.js +290 -0
- package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
- package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
- package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
- package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
- package/dist/node-runtime/chunk-FYIFPFXE.js +98 -0
- package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
- package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
- package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
- package/dist/node-runtime/{chunk-6XL67VVY.js → chunk-HUD2RFJW.js} +17 -2
- package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
- package/dist/node-runtime/chunk-IAZSK7KK.js +108 -0
- package/dist/node-runtime/{chunk-2HHLJWGD.js → chunk-IHHTWSXN.js} +9 -9
- package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
- package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
- package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
- package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
- package/dist/node-runtime/{chunk-WF7PGWRZ.js → chunk-JWEVT363.js} +37 -28
- package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
- package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
- package/dist/node-runtime/{chunk-IJIFHRTB.js → chunk-MQPKUHRN.js} +165 -85
- package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
- package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
- package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
- package/dist/node-runtime/{chunk-E4D3IGP2.js → chunk-QNVMKNNN.js} +20 -17
- package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
- package/dist/node-runtime/{chunk-7S3T6YEA.js → chunk-R4WSB2MQ.js} +5 -5
- package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
- package/dist/node-runtime/{chunk-3XPLBUEM.js → chunk-RLGY2QIL.js} +49 -59
- package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
- package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-TCT6PCUR.js} +47 -115
- package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
- package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-UBWW2PID.js} +13 -2
- package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-UNUZICC4.js} +3 -3
- package/dist/node-runtime/{chunk-LQP3RB67.js → chunk-UYRKUKFE.js} +1 -1
- package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-VSUEAI7O.js} +2993 -3820
- package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
- package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
- package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
- package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
- package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
- package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
- package/dist/node-runtime/{chunk-VQFSUJJG.js → chunk-ZDJUR45D.js} +430 -129
- package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-ZEVFBFNF.js} +95 -142
- package/dist/node-runtime/chunk-ZIQUS5QO.js +180 -0
- package/dist/node-runtime/cli-runtime.js +4 -4
- package/dist/node-runtime/{command-6WDOYKS6.js → command-3HMSY6W2.js} +5 -5
- package/dist/node-runtime/{commands-NZLSOHPE.js → commands-D6A6H4TS.js} +11 -16
- package/dist/node-runtime/commands-OCSSEEWJ.js +37 -0
- package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
- package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
- package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-2QJXVQD2.js} +8 -10
- package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
- package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
- package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
- package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
- package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
- package/dist/node-runtime/{gateway-INAYBF4Q.js → gateway-6623C2U3.js} +61 -53
- package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
- package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
- package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
- package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
- package/dist/node-runtime/index.js +54 -48
- package/dist/node-runtime/{init-HS6NQXSK.js → init-JBQJIPYI.js} +3 -4
- package/dist/node-runtime/{install-cli-KL4UDDAD.js → install-cli-INGHIVBY.js} +30 -25
- package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
- package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
- package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
- package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
- package/dist/node-runtime/lunr-computer-use-VDP2QNRQ.js +158 -0
- package/dist/node-runtime/{lunr-cron-LWIZJM2N.js → lunr-cron-LKVA5CZZ.js} +94 -79
- package/dist/node-runtime/main.js +42 -39
- package/dist/node-runtime/{mobile-commands-J7OJEKFO.js → mobile-commands-XT3NQXLD.js} +13 -12
- package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
- package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
- package/dist/node-runtime/{package-manager-cli-VYZM5WHN.js → package-manager-cli-CYM262SI.js} +20 -19
- package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
- package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
- package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
- package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
- package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
- package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
- package/dist/node-runtime/{pi-subagents-DNY7EAIG.js → pi-subagents-LT3CTO4E.js} +114 -116
- package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
- package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-2XHN5SUA.js} +4 -3
- package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
- package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-VEGC6QG5.js} +9 -13
- package/dist/node-runtime/rpc-entry.js +42 -39
- package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
- package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
- package/dist/node-runtime/runtime-UGXM4NPQ.js +21 -0
- package/dist/node-runtime/{runtime-bridges-VRDDR73P.js → runtime-bridges-DNKMNJCF.js} +8 -7
- package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
- package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
- package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
- package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
- package/dist/node-runtime/{settings-manager-J4SPQPDJ.js → settings-manager-P2TKGYTR.js} +6 -5
- package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
- package/dist/node-runtime/{setup-CQ2NLVK5.js → setup-OLQ4GXWS.js} +22 -21
- package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
- package/dist/node-runtime/{subagent-executor-KZZQGAKV.js → subagent-executor-Q5F7DBVM.js} +141 -62
- package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
- package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
- package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
- package/dist/node-runtime/{update-cli-GTFJC7XK.js → update-cli-F3XXJANQ.js} +7 -6
- package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
- package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
- package/dist/node-runtime/workflow-ICDI4N3J.js +767 -0
- package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js +25 -10
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +2 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js +12 -0
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/paths.d.ts +4 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +33 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/sanitize-terminal-text.d.ts +7 -0
- package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
- package/dist/utils/sanitize-terminal-text.js +67 -0
- package/dist/utils/sanitize-terminal-text.js.map +1 -0
- package/docs/browser.md +1 -1
- package/docs/computer-use.md +362 -0
- package/docs/custom-provider.md +3 -3
- package/docs/extensions.md +8 -4
- package/docs/features.md +22 -12
- package/docs/keybindings.md +1 -1
- package/docs/models.md +5 -5
- package/docs/packages.md +1 -1
- package/docs/providers.md +2 -2
- package/docs/rpc.md +7 -7
- package/docs/security.md +10 -5
- package/docs/sessions.md +2 -2
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +7 -7
- package/docs/themes.md +1 -1
- package/docs/usage.md +1 -1
- package/examples/extensions/auto-commit-on-exit.ts +1 -1
- package/examples/extensions/bash-spawn-hook.ts +1 -1
- package/examples/extensions/built-in-tool-renderer.ts +1 -1
- package/examples/extensions/claude-rules.ts +1 -1
- package/examples/extensions/commands.ts +1 -1
- package/examples/extensions/custom-compaction.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/index.ts +1 -1
- package/examples/extensions/git-merge-and-resolve.ts +2 -2
- package/examples/extensions/gondolin/index.ts +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/hidden-thinking-label.ts +1 -1
- package/examples/extensions/inline-bash.ts +2 -2
- package/examples/extensions/input-transform-streaming.ts +2 -2
- package/examples/extensions/input-transform.ts +2 -2
- package/examples/extensions/interactive-shell.ts +1 -1
- package/examples/extensions/kimi-deferred-tools.ts +1 -1
- package/examples/extensions/mac-system-theme.ts +1 -1
- package/examples/extensions/minimal-mode.ts +1 -1
- package/examples/extensions/modal-editor.ts +1 -1
- package/examples/extensions/model-status.ts +1 -1
- package/examples/extensions/notify.ts +3 -3
- package/examples/extensions/overlay-qa-tests.ts +1 -1
- package/examples/extensions/overlay-test.ts +1 -1
- package/examples/extensions/pirate.ts +1 -1
- package/examples/extensions/preset.ts +3 -3
- package/examples/extensions/project-trust.ts +4 -4
- package/examples/extensions/prompt-customizer.ts +1 -1
- package/examples/extensions/rainbow-editor.ts +1 -1
- package/examples/extensions/rpc-demo.ts +1 -1
- package/examples/extensions/sandbox/index.ts +7 -7
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/shutdown-command.ts +5 -5
- package/examples/extensions/ssh.ts +2 -2
- package/examples/extensions/subagent/README.md +3 -3
- package/examples/extensions/subagent/index.ts +2 -2
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/tool-override.ts +1 -1
- package/examples/extensions/tools.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/working-indicator.ts +1 -1
- package/examples/extensions/working-message-test.ts +1 -1
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/03-custom-prompt.ts +1 -1
- package/examples/sdk/04-skills.ts +1 -1
- package/examples/sdk/06-extensions.ts +2 -2
- package/examples/sdk/08-prompt-templates.ts +1 -1
- package/install-lock/package-lock.json +3841 -0
- package/install-lock/package.json +18 -0
- package/native/computer-use/LICENSE.md +21 -0
- package/npm-shrinkwrap.json +3858 -0
- package/package.json +15 -9
- package/dist/modes/interactive/components/exit-card.d.ts +0 -22
- package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
- package/dist/modes/interactive/components/exit-card.js +0 -69
- package/dist/modes/interactive/components/exit-card.js.map +0 -1
- package/dist/node-runtime/agent-session-services-YXXFCP5J.js +0 -49
- package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
- package/dist/node-runtime/chunk-4TLO4PO2.js +0 -3427
- package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
- package/dist/node-runtime/chunk-OVX6X377.js +0 -50
- package/dist/node-runtime/chunk-QTU6AKNJ.js +0 -773
- package/dist/node-runtime/chunk-TORR5XBV.js +0 -356
- package/dist/node-runtime/commands-QC6VUZJQ.js +0 -36
- package/dist/node-runtime/interactive-mode-Z5M7WYYZ.js +0 -72
- package/dist/node-runtime/mcp-auth-flow-QIXHW6QN.js +0 -32
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer-data-provider.js","sourceRoot":"","sources":["../../src/core/footer-data-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ExecFileException, execFile } from \"child_process\";\nimport { existsSync, type FSWatcher, type Stats, unwatchFile, watchFile } from \"fs\";\nimport { readFile, stat } from \"fs/promises\";\nimport { dirname, join, resolve } from \"path\";\nimport { closeWatcher, FS_WATCH_RETRY_DELAY_MS, watchWithErrorHandler } from \"../utils/fs-watch.ts\";\n\ntype GitPaths = {\n\trepoDir: string;\n\tcommonGitDir: string;\n\theadPath: string;\n};\n\n/**\n * Find git metadata paths by walking up from cwd.\n * Handles both regular git repos (.git is a directory) and worktrees (.git is a file).\n */\nasync function findGitPaths(cwd: string): Promise<GitPaths | null> {\n\tlet dir = cwd;\n\twhile (true) {\n\t\tconst gitPath = join(dir, \".git\");\n\t\ttry {\n\t\t\tconst gitStat = await stat(gitPath);\n\t\t\tif (gitStat.isFile()) {\n\t\t\t\tconst content = (await readFile(gitPath, \"utf8\")).trim();\n\t\t\t\tif (content.startsWith(\"gitdir: \")) {\n\t\t\t\t\tconst gitDir = resolve(dir, content.slice(8).trim());\n\t\t\t\t\tconst headPath = join(gitDir, \"HEAD\");\n\t\t\t\t\tawait stat(headPath);\n\t\t\t\t\tlet commonGitDir = gitDir;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcommonGitDir = resolve(gitDir, (await readFile(join(gitDir, \"commondir\"), \"utf8\")).trim());\n\t\t\t\t\t} catch {}\n\t\t\t\t\treturn { repoDir: dir, commonGitDir, headPath };\n\t\t\t\t}\n\t\t\t} else if (gitStat.isDirectory()) {\n\t\t\t\tconst headPath = join(gitPath, \"HEAD\");\n\t\t\t\tawait stat(headPath);\n\t\t\t\treturn { repoDir: dir, commonGitDir: gitPath, headPath };\n\t\t\t}\n\t\t} catch {}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n}\n\n/** Sum added/removed columns from `git diff --numstat`. Binary rows (`-`) are ignored. */\nexport function parseGitNumstat(stdout: string): { added: number; removed: number } {\n\tlet added = 0;\n\tlet removed = 0;\n\tfor (const line of stdout.split(/\\r?\\n/)) {\n\t\tif (!line) continue;\n\t\tconst tab1 = line.indexOf(\"\\t\");\n\t\tif (tab1 <= 0) continue;\n\t\tconst tab2 = line.indexOf(\"\\t\", tab1 + 1);\n\t\tif (tab2 < 0) continue;\n\t\tconst addTok = line.slice(0, tab1);\n\t\tconst delTok = line.slice(tab1 + 1, tab2);\n\t\tif (addTok !== \"-\") {\n\t\t\tconst n = Number(addTok);\n\t\t\tif (Number.isFinite(n)) added += n;\n\t\t}\n\t\tif (delTok !== \"-\") {\n\t\t\tconst n = Number(delTok);\n\t\t\tif (Number.isFinite(n)) removed += n;\n\t\t}\n\t}\n\treturn { added, removed };\n}\n\nfunction resolveDiffstatWithGitAsync(repoDir: string): Promise<{ added: number; removed: number } | null> {\n\treturn new Promise((resolvePromise) => {\n\t\texecFile(\n\t\t\t\"git\",\n\t\t\t[\"--no-optional-locks\", \"diff\", \"--numstat\", \"HEAD\"],\n\t\t\t{\n\t\t\t\tcwd: repoDir,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\ttimeout: 3000,\n\t\t\t},\n\t\t\t(error: ExecFileException | null, stdout: string) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tresolvePromise(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tresolvePromise(parseGitNumstat(stdout));\n\t\t\t},\n\t\t);\n\t});\n}\n\n/** Ask git for the current branch asynchronously. Returns null on detached HEAD or if git is unavailable. */\nfunction resolveBranchWithGitAsync(repoDir: string): Promise<string | null> {\n\treturn new Promise((resolvePromise) => {\n\t\texecFile(\n\t\t\t\"git\",\n\t\t\t[\"--no-optional-locks\", \"symbolic-ref\", \"--quiet\", \"--short\", \"HEAD\"],\n\t\t\t{\n\t\t\t\tcwd: repoDir,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\ttimeout: 3000,\n\t\t\t},\n\t\t\t(error: ExecFileException | null, stdout: string) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tresolvePromise(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst branch = stdout.trim();\n\t\t\t\tresolvePromise(branch || null);\n\t\t\t},\n\t\t);\n\t});\n}\n\nfunction isWslEnvironment(): boolean {\n\treturn process.platform === \"linux\" && !!(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP);\n}\n\nfunction isWindowsMountedRepoPath(repoDir: string): boolean {\n\treturn /^\\/mnt\\/[a-z](?:\\/|$)/i.test(repoDir);\n}\n\nfunction shouldPollGitHead(repoDir: string): boolean {\n\treturn isWslEnvironment() && isWindowsMountedRepoPath(repoDir);\n}\n\n/**\n * Provides git branch and extension statuses - data not otherwise accessible to extensions.\n * Token stats, model info available via ctx.sessionManager and ctx.model.\n */\nexport class FooterDataProvider {\n\tprivate cwd: string;\n\tprivate static readonly WATCH_DEBOUNCE_MS = 500;\n\n\tprivate extensionStatuses = new Map<string, string>();\n\tprivate cachedBranch: string | null | undefined = undefined;\n\tprivate cachedDiffstat: { added: number; removed: number } | null | undefined = undefined;\n\tprivate gitPaths: GitPaths | null | undefined = undefined;\n\tprivate headWatcher: FSWatcher | null = null;\n\tprivate headWatchFilePath: string | null = null;\n\tprivate headWatchFileListener: ((current: Stats, previous: Stats) => void) | null = null;\n\tprivate reftableWatcher: FSWatcher | null = null;\n\tprivate reftableTablesListWatcher: FSWatcher | null = null;\n\tprivate reftableTablesListPath: string | null = null;\n\tprivate branchChangeCallbacks = new Set<() => void>();\n\tprivate availableProviderCount = 0;\n\tprivate refreshTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate gitWatcherRetryTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate refreshInFlight = false;\n\tprivate refreshPending = false;\n\tprivate disposed = false;\n\n\tconstructor(cwd: string) {\n\t\tthis.cwd = cwd;\n\t}\n\n\t/** Current git branch, null until the asynchronous lookup completes or when not in a repo. */\n\tgetGitBranch(): string | null {\n\t\tif (this.cachedBranch === undefined && !this.refreshInFlight) {\n\t\t\tvoid this.refreshGitData();\n\t\t}\n\t\treturn this.cachedBranch ?? null;\n\t}\n\n\t/** Staged + unstaged added/removed vs HEAD. Null until the asynchronous lookup completes. */\n\tgetGitDiffstat(): { added: number; removed: number } | null {\n\t\tif (this.cachedDiffstat === undefined && !this.refreshInFlight) {\n\t\t\tvoid this.refreshGitData();\n\t\t}\n\t\treturn this.cachedDiffstat ?? null;\n\t}\n\n\t/** Extension status texts set via ctx.ui.setStatus() */\n\tgetExtensionStatuses(): ReadonlyMap<string, string> {\n\t\treturn this.extensionStatuses;\n\t}\n\n\t/** Subscribe to git branch changes. Returns unsubscribe function. */\n\tonBranchChange(callback: () => void): () => void {\n\t\tthis.branchChangeCallbacks.add(callback);\n\t\treturn () => this.branchChangeCallbacks.delete(callback);\n\t}\n\n\t/** Internal: set extension status */\n\tsetExtensionStatus(key: string, text: string | undefined): void {\n\t\tif (text === undefined) {\n\t\t\tthis.extensionStatuses.delete(key);\n\t\t} else {\n\t\t\tthis.extensionStatuses.set(key, text);\n\t\t}\n\t}\n\n\t/** Internal: clear extension statuses */\n\tclearExtensionStatuses(): void {\n\t\tthis.extensionStatuses.clear();\n\t}\n\n\t/** Number of unique providers with available models (for footer display) */\n\tgetAvailableProviderCount(): number {\n\t\treturn this.availableProviderCount;\n\t}\n\n\t/** Internal: update available provider count */\n\tsetAvailableProviderCount(count: number): void {\n\t\tthis.availableProviderCount = count;\n\t}\n\n\tsetCwd(cwd: string): void {\n\t\tif (this.cwd === cwd) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.cwd = cwd;\n\t\tif (this.refreshTimer) {\n\t\t\tclearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = null;\n\t\t}\n\t\tthis.clearGitWatchers();\n\t\tthis.cachedBranch = undefined;\n\t\tthis.cachedDiffstat = undefined;\n\t\tthis.gitPaths = undefined;\n\t\tif (this.refreshInFlight) this.refreshPending = true;\n\t\tthis.notifyBranchChange();\n\t}\n\n\t/** Internal: cleanup */\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tif (this.refreshTimer) {\n\t\t\tclearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = null;\n\t\t}\n\t\tthis.clearGitWatchers();\n\t\tthis.branchChangeCallbacks.clear();\n\t}\n\n\tprivate notifyBranchChange(): void {\n\t\tfor (const cb of this.branchChangeCallbacks) cb();\n\t}\n\n\tprivate scheduleRefresh(): void {\n\t\tif (this.disposed || this.refreshTimer) return;\n\t\tif (this.refreshInFlight) {\n\t\t\tthis.refreshPending = true;\n\t\t\treturn;\n\t\t}\n\t\tthis.refreshTimer = setTimeout(() => {\n\t\t\tthis.refreshTimer = null;\n\t\t\tvoid this.refreshGitData();\n\t\t}, FooterDataProvider.WATCH_DEBOUNCE_MS);\n\t}\n\n\tprivate async refreshGitData(): Promise<void> {\n\t\tif (this.disposed) return;\n\t\tif (this.refreshInFlight) {\n\t\t\tthis.refreshPending = true;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.refreshInFlight = true;\n\t\tconst cwd = this.cwd;\n\t\ttry {\n\t\t\tconst gitPaths = this.gitPaths === undefined ? await findGitPaths(cwd) : this.gitPaths;\n\t\t\tif (this.disposed || this.cwd !== cwd) return;\n\t\t\tif (this.gitPaths === undefined) {\n\t\t\t\tthis.gitPaths = gitPaths;\n\t\t\t\tthis.setupGitWatcher();\n\t\t\t}\n\t\t\tconst [nextBranch, nextDiff] = await Promise.all([\n\t\t\t\tthis.resolveGitBranchAsync(),\n\t\t\t\tgitPaths ? resolveDiffstatWithGitAsync(gitPaths.repoDir) : null,\n\t\t\t]);\n\t\t\tif (this.disposed || this.cwd !== cwd) return;\n\t\t\tconst prevBranch = this.cachedBranch;\n\t\t\tconst prevDiff = this.cachedDiffstat;\n\t\t\tconst branchChanged = prevBranch !== nextBranch;\n\t\t\tconst diffChanged = prevDiff?.added !== nextDiff?.added || prevDiff?.removed !== nextDiff?.removed;\n\t\t\tthis.cachedBranch = nextBranch;\n\t\t\tthis.cachedDiffstat = nextDiff;\n\t\t\tif (branchChanged || diffChanged) {\n\t\t\t\tthis.notifyBranchChange();\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.refreshInFlight = false;\n\t\t\tif (this.refreshPending && !this.disposed) {\n\t\t\t\tthis.refreshPending = false;\n\t\t\t\tthis.scheduleRefresh();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async resolveGitBranchAsync(): Promise<string | null> {\n\t\ttry {\n\t\t\tif (!this.gitPaths) return null;\n\t\t\tconst content = (await readFile(this.gitPaths.headPath, \"utf8\")).trim();\n\t\t\tif (content.startsWith(\"ref: refs/heads/\")) {\n\t\t\t\tconst branch = content.slice(16);\n\t\t\t\treturn branch === \".invalid\"\n\t\t\t\t\t? ((await resolveBranchWithGitAsync(this.gitPaths.repoDir)) ?? \"detached\")\n\t\t\t\t\t: branch;\n\t\t\t}\n\t\t\treturn \"detached\";\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate clearGitWatchers(): void {\n\t\tcloseWatcher(this.headWatcher);\n\t\tthis.headWatcher = null;\n\t\tif (this.headWatchFilePath && this.headWatchFileListener) {\n\t\t\tunwatchFile(this.headWatchFilePath, this.headWatchFileListener);\n\t\t\tthis.headWatchFilePath = null;\n\t\t\tthis.headWatchFileListener = null;\n\t\t}\n\t\tcloseWatcher(this.reftableWatcher);\n\t\tthis.reftableWatcher = null;\n\t\tcloseWatcher(this.reftableTablesListWatcher);\n\t\tthis.reftableTablesListWatcher = null;\n\t\tif (this.reftableTablesListPath) {\n\t\t\tunwatchFile(this.reftableTablesListPath);\n\t\t\tthis.reftableTablesListPath = null;\n\t\t}\n\t\tif (this.gitWatcherRetryTimer) {\n\t\t\tclearTimeout(this.gitWatcherRetryTimer);\n\t\t\tthis.gitWatcherRetryTimer = null;\n\t\t}\n\t}\n\n\tprivate scheduleGitWatcherRetry(): void {\n\t\tif (this.disposed || this.gitWatcherRetryTimer) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.gitWatcherRetryTimer = setTimeout(() => {\n\t\t\tthis.gitWatcherRetryTimer = null;\n\t\t\tthis.setupGitWatcher();\n\t\t}, FS_WATCH_RETRY_DELAY_MS);\n\t}\n\n\tprivate handleGitWatcherError(): void {\n\t\tthis.clearGitWatchers();\n\t\tthis.scheduleGitWatcherRetry();\n\t}\n\n\tprivate setupGitWatcher(): void {\n\t\tthis.clearGitWatchers();\n\t\tif (!this.gitPaths) return;\n\n\t\tconst pollGitHead = shouldPollGitHead(this.gitPaths.repoDir);\n\n\t\t// Watch the directory containing HEAD, not HEAD itself.\n\t\t// Git uses atomic writes (write temp, rename over HEAD), which changes the inode.\n\t\t// fs.watch on a file stops working after the inode changes.\n\t\tthis.headWatcher = watchWithErrorHandler(\n\t\t\tdirname(this.gitPaths.headPath),\n\t\t\t(_eventType, filename) => {\n\t\t\t\tif (!filename || filename === \"HEAD\" || filename === \"index\") {\n\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => this.handleGitWatcherError(),\n\t\t);\n\t\tif (pollGitHead) {\n\t\t\tthis.headWatchFilePath = this.gitPaths.headPath;\n\t\t\tthis.headWatchFileListener = (current, previous) => {\n\t\t\t\tif (\n\t\t\t\t\tcurrent.mtimeMs !== previous.mtimeMs ||\n\t\t\t\t\tcurrent.ctimeMs !== previous.ctimeMs ||\n\t\t\t\t\tcurrent.size !== previous.size\n\t\t\t\t) {\n\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t}\n\t\t\t};\n\t\t\twatchFile(this.headWatchFilePath, { interval: 1000 }, this.headWatchFileListener);\n\t\t}\n\t\tif (!this.headWatcher && !pollGitHead) {\n\t\t\treturn;\n\t\t}\n\n\t\t// In reftable repos, branch switches update files in the reftable directory\n\t\t// instead of HEAD. Watch it separately so the footer picks up those changes.\n\t\tconst reftableDir = join(this.gitPaths.commonGitDir, \"reftable\");\n\t\tif (existsSync(reftableDir)) {\n\t\t\tthis.reftableWatcher = watchWithErrorHandler(\n\t\t\t\treftableDir,\n\t\t\t\t() => {\n\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t},\n\t\t\t\t() => this.handleGitWatcherError(),\n\t\t\t);\n\t\t\tif (!this.reftableWatcher) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tablesListPath = join(reftableDir, \"tables.list\");\n\t\t\tif (existsSync(tablesListPath)) {\n\t\t\t\tthis.reftableTablesListPath = tablesListPath;\n\t\t\t\tthis.reftableTablesListWatcher = watchWithErrorHandler(\n\t\t\t\t\ttablesListPath,\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t\t},\n\t\t\t\t\t() => this.handleGitWatcherError(),\n\t\t\t\t);\n\t\t\t\tif (!this.reftableTablesListWatcher) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\twatchFile(tablesListPath, { interval: 250 }, (current, previous) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tcurrent.mtimeMs !== previous.mtimeMs ||\n\t\t\t\t\t\tcurrent.ctimeMs !== previous.ctimeMs ||\n\t\t\t\t\t\tcurrent.size !== previous.size\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Read-only view for extensions - excludes setExtensionStatus, setAvailableProviderCount and dispose */\nexport type ReadonlyFooterDataProvider = Pick<\n\tFooterDataProvider,\n\t\"getGitBranch\" | \"getGitDiffstat\" | \"getExtensionStatuses\" | \"getAvailableProviderCount\" | \"onBranchChange\"\n>;\n"]}
|
|
1
|
+
{"version":3,"file":"footer-data-provider.js","sourceRoot":"","sources":["../../src/core/footer-data-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ExecFileException, execFile } from \"child_process\";\nimport { existsSync, type FSWatcher, type Stats, unwatchFile, watchFile } from \"fs\";\nimport { readFile, stat } from \"fs/promises\";\nimport { dirname, join, resolve } from \"path\";\nimport { closeWatcher, FS_WATCH_RETRY_DELAY_MS, watchWithErrorHandler } from \"../utils/fs-watch.ts\";\n\ntype GitPaths = {\n\trepoDir: string;\n\tcommonGitDir: string;\n\theadPath: string;\n};\n\n/**\n * Find git metadata paths by walking up from cwd.\n * Handles both regular git repos (.git is a directory) and worktrees (.git is a file).\n */\nasync function findGitPaths(cwd: string): Promise<GitPaths | null> {\n\tlet dir = cwd;\n\twhile (true) {\n\t\tconst gitPath = join(dir, \".git\");\n\t\ttry {\n\t\t\tconst gitStat = await stat(gitPath);\n\t\t\tif (gitStat.isFile()) {\n\t\t\t\tconst content = (await readFile(gitPath, \"utf8\")).trim();\n\t\t\t\tif (content.startsWith(\"gitdir: \")) {\n\t\t\t\t\tconst gitDir = resolve(dir, content.slice(8).trim());\n\t\t\t\t\tconst headPath = join(gitDir, \"HEAD\");\n\t\t\t\t\tawait stat(headPath);\n\t\t\t\t\tlet commonGitDir = gitDir;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcommonGitDir = resolve(gitDir, (await readFile(join(gitDir, \"commondir\"), \"utf8\")).trim());\n\t\t\t\t\t} catch {}\n\t\t\t\t\treturn { repoDir: dir, commonGitDir, headPath };\n\t\t\t\t}\n\t\t\t} else if (gitStat.isDirectory()) {\n\t\t\t\tconst headPath = join(gitPath, \"HEAD\");\n\t\t\t\tawait stat(headPath);\n\t\t\t\treturn { repoDir: dir, commonGitDir: gitPath, headPath };\n\t\t\t}\n\t\t} catch {}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n}\n\n/** Sum added/removed columns from `git diff --numstat`. Binary rows (`-`) are ignored. */\nexport function parseGitNumstat(stdout: string): { added: number; removed: number } {\n\tlet added = 0;\n\tlet removed = 0;\n\tfor (const line of stdout.split(/\\r?\\n/)) {\n\t\tif (!line) continue;\n\t\tconst tab1 = line.indexOf(\"\\t\");\n\t\tif (tab1 <= 0) continue;\n\t\tconst tab2 = line.indexOf(\"\\t\", tab1 + 1);\n\t\tif (tab2 < 0) continue;\n\t\tconst addTok = line.slice(0, tab1);\n\t\tconst delTok = line.slice(tab1 + 1, tab2);\n\t\tif (addTok !== \"-\") {\n\t\t\tconst n = Number(addTok);\n\t\t\tif (Number.isFinite(n)) added += n;\n\t\t}\n\t\tif (delTok !== \"-\") {\n\t\t\tconst n = Number(delTok);\n\t\t\tif (Number.isFinite(n)) removed += n;\n\t\t}\n\t}\n\treturn { added, removed };\n}\n\nfunction resolveDiffstatWithGitAsync(repoDir: string): Promise<{ added: number; removed: number } | null> {\n\treturn new Promise((resolvePromise) => {\n\t\texecFile(\n\t\t\t\"git\",\n\t\t\t[\"--no-optional-locks\", \"diff\", \"--numstat\", \"HEAD\"],\n\t\t\t{\n\t\t\t\tcwd: repoDir,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\ttimeout: 3000,\n\t\t\t},\n\t\t\t(error: ExecFileException | null, stdout: string) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tresolvePromise(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tresolvePromise(parseGitNumstat(stdout));\n\t\t\t},\n\t\t);\n\t});\n}\n\n/** Ask git for the current branch asynchronously. Returns null on detached HEAD or if git is unavailable. */\nfunction resolveBranchWithGitAsync(repoDir: string): Promise<string | null> {\n\treturn new Promise((resolvePromise) => {\n\t\texecFile(\n\t\t\t\"git\",\n\t\t\t[\"--no-optional-locks\", \"symbolic-ref\", \"--quiet\", \"--short\", \"HEAD\"],\n\t\t\t{\n\t\t\t\tcwd: repoDir,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\ttimeout: 3000,\n\t\t\t},\n\t\t\t(error: ExecFileException | null, stdout: string) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tresolvePromise(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst branch = stdout.trim();\n\t\t\t\tresolvePromise(branch || null);\n\t\t\t},\n\t\t);\n\t});\n}\n\nfunction isWslEnvironment(): boolean {\n\treturn process.platform === \"linux\" && !!(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP);\n}\n\nfunction isWindowsMountedRepoPath(repoDir: string): boolean {\n\treturn /^\\/mnt\\/[a-z](?:\\/|$)/i.test(repoDir);\n}\n\nfunction shouldPollGitHead(repoDir: string): boolean {\n\treturn isWslEnvironment() && isWindowsMountedRepoPath(repoDir);\n}\n\n/**\n * Provides git branch and extension statuses - data not otherwise accessible to extensions.\n * Token stats, model info available via ctx.sessionManager and ctx.model.\n */\nexport class FooterDataProvider {\n\tprivate cwd: string;\n\tprivate static readonly WATCH_DEBOUNCE_MS = 500;\n\tprivate static readonly DIFFSTAT_REFRESH_MS = 2000;\n\tprivate diffstatTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate diffstatStale = true;\n\n\tprivate extensionStatuses = new Map<string, string>();\n\tprivate cachedBranch: string | null | undefined = undefined;\n\tprivate cachedDiffstat: { added: number; removed: number } | null | undefined = undefined;\n\tprivate gitPaths: GitPaths | null | undefined = undefined;\n\tprivate headWatcher: FSWatcher | null = null;\n\tprivate headWatchFilePath: string | null = null;\n\tprivate headWatchFileListener: ((current: Stats, previous: Stats) => void) | null = null;\n\tprivate reftableWatcher: FSWatcher | null = null;\n\tprivate reftableTablesListWatcher: FSWatcher | null = null;\n\tprivate reftableTablesListPath: string | null = null;\n\tprivate branchChangeCallbacks = new Set<() => void>();\n\tprivate availableProviderCount = 0;\n\tprivate refreshTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate gitWatcherRetryTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate refreshInFlight = false;\n\tprivate refreshPending = false;\n\tprivate disposed = false;\n\n\tconstructor(cwd: string) {\n\t\tthis.cwd = cwd;\n\t}\n\n\t/** Current git branch, null until the asynchronous lookup completes or when not in a repo. */\n\tgetGitBranch(): string | null {\n\t\tif (this.cachedBranch === undefined && !this.refreshInFlight) {\n\t\t\tvoid this.refreshGitData();\n\t\t}\n\t\treturn this.cachedBranch ?? null;\n\t}\n\n\t/** Staged + unstaged added/removed vs HEAD. Null until the asynchronous lookup completes. */\n\tgetGitDiffstat(): { added: number; removed: number } | null {\n\t\tif (this.diffstatStale && !this.refreshInFlight) {\n\t\t\tvoid this.refreshGitData();\n\t\t}\n\t\tif (!this.disposed && !this.diffstatTimer) {\n\t\t\t// Invalidate lazily. Only a footer that reads totals starts the next git lookup.\n\t\t\tthis.diffstatTimer = setTimeout(() => {\n\t\t\t\tthis.diffstatTimer = null;\n\t\t\t\tthis.diffstatStale = true;\n\t\t\t\tthis.notifyBranchChange();\n\t\t\t}, FooterDataProvider.DIFFSTAT_REFRESH_MS);\n\t\t\tthis.diffstatTimer.unref();\n\t\t}\n\t\treturn this.cachedDiffstat ?? null;\n\t}\n\n\t/** Extension status texts set via ctx.ui.setStatus() */\n\tgetExtensionStatuses(): ReadonlyMap<string, string> {\n\t\treturn this.extensionStatuses;\n\t}\n\n\t/** Subscribe to git branch changes. Returns unsubscribe function. */\n\tonBranchChange(callback: () => void): () => void {\n\t\tthis.branchChangeCallbacks.add(callback);\n\t\treturn () => this.branchChangeCallbacks.delete(callback);\n\t}\n\n\t/** Internal: set extension status */\n\tsetExtensionStatus(key: string, text: string | undefined): void {\n\t\tif (text === undefined) {\n\t\t\tthis.extensionStatuses.delete(key);\n\t\t} else {\n\t\t\tthis.extensionStatuses.set(key, text);\n\t\t}\n\t}\n\n\t/** Internal: clear extension statuses */\n\tclearExtensionStatuses(): void {\n\t\tthis.extensionStatuses.clear();\n\t}\n\n\t/** Number of unique providers with available models (for footer display) */\n\tgetAvailableProviderCount(): number {\n\t\treturn this.availableProviderCount;\n\t}\n\n\t/** Internal: update available provider count */\n\tsetAvailableProviderCount(count: number): void {\n\t\tthis.availableProviderCount = count;\n\t}\n\n\tsetCwd(cwd: string): void {\n\t\tif (this.cwd === cwd) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.cwd = cwd;\n\t\tthis.clearDiffstatTimer();\n\t\tthis.diffstatStale = true;\n\t\tif (this.refreshTimer) {\n\t\t\tclearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = null;\n\t\t}\n\t\tthis.clearGitWatchers();\n\t\tthis.cachedBranch = undefined;\n\t\tthis.cachedDiffstat = undefined;\n\t\tthis.gitPaths = undefined;\n\t\tif (this.refreshInFlight) this.refreshPending = true;\n\t\tthis.notifyBranchChange();\n\t}\n\n\t/** Internal: cleanup */\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tthis.clearDiffstatTimer();\n\t\tif (this.refreshTimer) {\n\t\t\tclearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = null;\n\t\t}\n\t\tthis.clearGitWatchers();\n\t\tthis.branchChangeCallbacks.clear();\n\t}\n\n\tprivate clearDiffstatTimer(): void {\n\t\tif (this.diffstatTimer) clearTimeout(this.diffstatTimer);\n\t\tthis.diffstatTimer = null;\n\t}\n\n\tprivate notifyBranchChange(): void {\n\t\tfor (const cb of this.branchChangeCallbacks) cb();\n\t}\n\n\tprivate scheduleRefresh(): void {\n\t\tif (this.disposed || this.refreshTimer) return;\n\t\tif (this.refreshInFlight) {\n\t\t\tthis.refreshPending = true;\n\t\t\treturn;\n\t\t}\n\t\tthis.refreshTimer = setTimeout(() => {\n\t\t\tthis.refreshTimer = null;\n\t\t\tvoid this.refreshGitData();\n\t\t}, FooterDataProvider.WATCH_DEBOUNCE_MS);\n\t}\n\n\tprivate async refreshGitData(): Promise<void> {\n\t\tif (this.disposed) return;\n\t\tif (this.refreshInFlight) {\n\t\t\tthis.refreshPending = true;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.refreshInFlight = true;\n\t\tconst cwd = this.cwd;\n\t\ttry {\n\t\t\tconst gitPaths = this.gitPaths === undefined ? await findGitPaths(cwd) : this.gitPaths;\n\t\t\tif (this.disposed || this.cwd !== cwd) return;\n\t\t\tif (this.gitPaths === undefined) {\n\t\t\t\tthis.gitPaths = gitPaths;\n\t\t\t\tthis.setupGitWatcher();\n\t\t\t}\n\t\t\tconst [nextBranch, nextDiff] = await Promise.all([\n\t\t\t\tthis.resolveGitBranchAsync(),\n\t\t\t\tgitPaths ? resolveDiffstatWithGitAsync(gitPaths.repoDir) : null,\n\t\t\t]);\n\t\t\tif (this.disposed || this.cwd !== cwd) return;\n\t\t\tconst prevBranch = this.cachedBranch;\n\t\t\tconst prevDiff = this.cachedDiffstat;\n\t\t\tconst branchChanged = prevBranch !== nextBranch;\n\t\t\tconst diffChanged = prevDiff?.added !== nextDiff?.added || prevDiff?.removed !== nextDiff?.removed;\n\t\t\tthis.cachedBranch = nextBranch;\n\t\t\tthis.cachedDiffstat = nextDiff;\n\t\t\tthis.diffstatStale = false;\n\t\t\tif (branchChanged || diffChanged) {\n\t\t\t\tthis.notifyBranchChange();\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.refreshInFlight = false;\n\t\t\tif (this.refreshPending && !this.disposed) {\n\t\t\t\tthis.refreshPending = false;\n\t\t\t\tthis.scheduleRefresh();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async resolveGitBranchAsync(): Promise<string | null> {\n\t\ttry {\n\t\t\tif (!this.gitPaths) return null;\n\t\t\tconst content = (await readFile(this.gitPaths.headPath, \"utf8\")).trim();\n\t\t\tif (content.startsWith(\"ref: refs/heads/\")) {\n\t\t\t\tconst branch = content.slice(16);\n\t\t\t\treturn branch === \".invalid\"\n\t\t\t\t\t? ((await resolveBranchWithGitAsync(this.gitPaths.repoDir)) ?? \"detached\")\n\t\t\t\t\t: branch;\n\t\t\t}\n\t\t\treturn \"detached\";\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate clearGitWatchers(): void {\n\t\tcloseWatcher(this.headWatcher);\n\t\tthis.headWatcher = null;\n\t\tif (this.headWatchFilePath && this.headWatchFileListener) {\n\t\t\tunwatchFile(this.headWatchFilePath, this.headWatchFileListener);\n\t\t\tthis.headWatchFilePath = null;\n\t\t\tthis.headWatchFileListener = null;\n\t\t}\n\t\tcloseWatcher(this.reftableWatcher);\n\t\tthis.reftableWatcher = null;\n\t\tcloseWatcher(this.reftableTablesListWatcher);\n\t\tthis.reftableTablesListWatcher = null;\n\t\tif (this.reftableTablesListPath) {\n\t\t\tunwatchFile(this.reftableTablesListPath);\n\t\t\tthis.reftableTablesListPath = null;\n\t\t}\n\t\tif (this.gitWatcherRetryTimer) {\n\t\t\tclearTimeout(this.gitWatcherRetryTimer);\n\t\t\tthis.gitWatcherRetryTimer = null;\n\t\t}\n\t}\n\n\tprivate scheduleGitWatcherRetry(): void {\n\t\tif (this.disposed || this.gitWatcherRetryTimer) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.gitWatcherRetryTimer = setTimeout(() => {\n\t\t\tthis.gitWatcherRetryTimer = null;\n\t\t\tthis.setupGitWatcher();\n\t\t}, FS_WATCH_RETRY_DELAY_MS);\n\t}\n\n\tprivate handleGitWatcherError(): void {\n\t\tthis.clearGitWatchers();\n\t\tthis.scheduleGitWatcherRetry();\n\t}\n\n\tprivate setupGitWatcher(): void {\n\t\tthis.clearGitWatchers();\n\t\tif (!this.gitPaths) return;\n\n\t\tconst pollGitHead = shouldPollGitHead(this.gitPaths.repoDir);\n\n\t\t// Watch the directory containing HEAD, not HEAD itself.\n\t\t// Git uses atomic writes (write temp, rename over HEAD), which changes the inode.\n\t\t// fs.watch on a file stops working after the inode changes.\n\t\tthis.headWatcher = watchWithErrorHandler(\n\t\t\tdirname(this.gitPaths.headPath),\n\t\t\t(_eventType, filename) => {\n\t\t\t\tif (!filename || filename === \"HEAD\" || filename === \"index\") {\n\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => this.handleGitWatcherError(),\n\t\t);\n\t\tif (pollGitHead) {\n\t\t\tthis.headWatchFilePath = this.gitPaths.headPath;\n\t\t\tthis.headWatchFileListener = (current, previous) => {\n\t\t\t\tif (\n\t\t\t\t\tcurrent.mtimeMs !== previous.mtimeMs ||\n\t\t\t\t\tcurrent.ctimeMs !== previous.ctimeMs ||\n\t\t\t\t\tcurrent.size !== previous.size\n\t\t\t\t) {\n\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t}\n\t\t\t};\n\t\t\twatchFile(this.headWatchFilePath, { interval: 1000 }, this.headWatchFileListener);\n\t\t}\n\t\tif (!this.headWatcher && !pollGitHead) {\n\t\t\treturn;\n\t\t}\n\n\t\t// In reftable repos, branch switches update files in the reftable directory\n\t\t// instead of HEAD. Watch it separately so the footer picks up those changes.\n\t\tconst reftableDir = join(this.gitPaths.commonGitDir, \"reftable\");\n\t\tif (existsSync(reftableDir)) {\n\t\t\tthis.reftableWatcher = watchWithErrorHandler(\n\t\t\t\treftableDir,\n\t\t\t\t() => {\n\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t},\n\t\t\t\t() => this.handleGitWatcherError(),\n\t\t\t);\n\t\t\tif (!this.reftableWatcher) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tablesListPath = join(reftableDir, \"tables.list\");\n\t\t\tif (existsSync(tablesListPath)) {\n\t\t\t\tthis.reftableTablesListPath = tablesListPath;\n\t\t\t\tthis.reftableTablesListWatcher = watchWithErrorHandler(\n\t\t\t\t\ttablesListPath,\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t\t},\n\t\t\t\t\t() => this.handleGitWatcherError(),\n\t\t\t\t);\n\t\t\t\tif (!this.reftableTablesListWatcher) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\twatchFile(tablesListPath, { interval: 250 }, (current, previous) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tcurrent.mtimeMs !== previous.mtimeMs ||\n\t\t\t\t\t\tcurrent.ctimeMs !== previous.ctimeMs ||\n\t\t\t\t\t\tcurrent.size !== previous.size\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.scheduleRefresh();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Read-only view for extensions - excludes setExtensionStatus, setAvailableProviderCount and dispose */\nexport type ReadonlyFooterDataProvider = Pick<\n\tFooterDataProvider,\n\t\"getGitBranch\" | \"getGitDiffstat\" | \"getExtensionStatuses\" | \"getAvailableProviderCount\" | \"onBranchChange\"\n>;\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Number of children above which aggregate launch confirmation engages. */
|
|
2
2
|
export declare const LARGE_SUBAGENT_LAUNCH_THRESHOLD = 2;
|
|
3
|
-
export declare function effectiveLargeSubagentLaunchCount(
|
|
3
|
+
export declare function effectiveLargeSubagentLaunchCount(input: Record<string, unknown>): number;
|
|
4
4
|
interface AssistantMessageLike {
|
|
5
5
|
content?: ReadonlyArray<{
|
|
6
6
|
type?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"large-subagent-launch.d.ts","sourceRoot":"","sources":["../../src/core/large-subagent-launch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"large-subagent-launch.d.ts","sourceRoot":"","sources":["../../src/core/large-subagent-launch.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAWjD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAexF;AAeD,UAAU,oBAAoB;IAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC/E;AAED,wBAAgB,wCAAwC,CACvD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,gBAAgB,CAAC,EAAE,oBAAoB,GACrC,MAAM,CAWR","sourcesContent":["import { resolveSubagentRequestParams } from \"../builtin-extensions/pi-subagents/src/runs/foreground/request-params.ts\";\n\n/** Number of children above which aggregate launch confirmation engages. */\nexport const LARGE_SUBAGENT_LAUNCH_THRESHOLD = 2;\n\nfunction countEntry(item: unknown): number {\n\tconst count = item && typeof item === \"object\" ? (item as { count?: unknown }).count : undefined;\n\treturn typeof count === \"number\" && Number.isInteger(count) && count >= 1 ? count : 1;\n}\n\nfunction isManagementCall(args: Record<string, unknown>): boolean {\n\treturn typeof args.action === \"string\" && args.action.length > 0;\n}\n\nexport function effectiveLargeSubagentLaunchCount(input: Record<string, unknown>): number {\n\tconst args = resolveSubagentRequestParams(input);\n\tlet total = 0;\n\tif (Array.isArray(args.tasks)) {\n\t\tfor (const task of args.tasks) total += countEntry(task);\n\t}\n\tif (Array.isArray(args.chain)) {\n\t\tfor (const step of args.chain) {\n\t\t\tconst parallel = step && typeof step === \"object\" ? (step as { parallel?: unknown }).parallel : undefined;\n\t\t\tif (Array.isArray(parallel)) {\n\t\t\t\tfor (const child of parallel) total += countEntry(child);\n\t\t\t}\n\t\t}\n\t}\n\treturn total;\n}\n\nfunction siblingSingleCount(input: Record<string, unknown>): number {\n\tconst args = resolveSubagentRequestParams(input);\n\tif (isManagementCall(args)) return 0;\n\tif ((Array.isArray(args.tasks) && args.tasks.length > 0) || (Array.isArray(args.chain) && args.chain.length > 0))\n\t\treturn 0;\n\treturn typeof args.task === \"string\" &&\n\t\targs.task.length > 0 &&\n\t\ttypeof args.description === \"string\" &&\n\t\targs.description.length > 0\n\t\t? 1\n\t\t: 0;\n}\n\ninterface AssistantMessageLike {\n\tcontent?: ReadonlyArray<{ type?: string; name?: string; arguments?: unknown }>;\n}\n\nexport function effectiveLargeSubagentLaunchCountForTurn(\n\targs: Record<string, unknown>,\n\tassistantMessage?: AssistantMessageLike,\n): number {\n\tconst own = effectiveLargeSubagentLaunchCount(args);\n\tconst siblingSingles = (assistantMessage?.content ?? []).reduce((total, block) => {\n\t\tif (block.type !== \"toolCall\" || block.name !== \"subagent\") return total;\n\t\tconst siblingArgs =\n\t\t\tblock.arguments && typeof block.arguments === \"object\" && !Array.isArray(block.arguments)\n\t\t\t\t? (block.arguments as Record<string, unknown>)\n\t\t\t\t: undefined;\n\t\treturn siblingArgs ? total + siblingSingleCount(siblingArgs) : total;\n\t}, 0);\n\treturn Math.max(own, siblingSingles);\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveSubagentRequestParams } from "../builtin-extensions/pi-subagents/src/runs/foreground/request-params.js";
|
|
1
2
|
/** Number of children above which aggregate launch confirmation engages. */
|
|
2
3
|
export const LARGE_SUBAGENT_LAUNCH_THRESHOLD = 2;
|
|
3
4
|
function countEntry(item) {
|
|
@@ -7,10 +8,8 @@ function countEntry(item) {
|
|
|
7
8
|
function isManagementCall(args) {
|
|
8
9
|
return typeof args.action === "string" && args.action.length > 0;
|
|
9
10
|
}
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
export function effectiveLargeSubagentLaunchCount(args) {
|
|
11
|
+
export function effectiveLargeSubagentLaunchCount(input) {
|
|
12
|
+
const args = resolveSubagentRequestParams(input);
|
|
14
13
|
let total = 0;
|
|
15
14
|
if (Array.isArray(args.tasks)) {
|
|
16
15
|
for (const task of args.tasks)
|
|
@@ -27,10 +26,11 @@ export function effectiveLargeSubagentLaunchCount(args) {
|
|
|
27
26
|
}
|
|
28
27
|
return total;
|
|
29
28
|
}
|
|
30
|
-
function siblingSingleCount(
|
|
31
|
-
|
|
29
|
+
function siblingSingleCount(input) {
|
|
30
|
+
const args = resolveSubagentRequestParams(input);
|
|
31
|
+
if (isManagementCall(args))
|
|
32
32
|
return 0;
|
|
33
|
-
if (Array.isArray(args.tasks) || Array.isArray(args.chain))
|
|
33
|
+
if ((Array.isArray(args.tasks) && args.tasks.length > 0) || (Array.isArray(args.chain) && args.chain.length > 0))
|
|
34
34
|
return 0;
|
|
35
35
|
return typeof args.task === "string" &&
|
|
36
36
|
args.task.length > 0 &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"large-subagent-launch.js","sourceRoot":"","sources":["../../src/core/large-subagent-launch.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAEjD,SAAS,UAAU,CAAC,IAAa,EAAU;IAC1C,MAAM,KAAK,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAA4B,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,CACtF;AAED,SAAS,gBAAgB,CAAC,IAA6B,EAAW;IACjE,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;AAAA,CACjE;AAED,
|
|
1
|
+
{"version":3,"file":"large-subagent-launch.js","sourceRoot":"","sources":["../../src/core/large-subagent-launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,0EAA0E,CAAC;AAExH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAEjD,SAAS,UAAU,CAAC,IAAa,EAAU;IAC1C,MAAM,KAAK,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAA4B,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,CACtF;AAED,SAAS,gBAAgB,CAAC,IAA6B,EAAW;IACjE,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;AAAA,CACjE;AAED,MAAM,UAAU,iCAAiC,CAAC,KAA8B,EAAU;IACzF,MAAM,IAAI,GAAG,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK;YAAE,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAA+B,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1G,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,KAAK,MAAM,KAAK,IAAI,QAAQ;oBAAE,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;YAC1D,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,SAAS,kBAAkB,CAAC,KAA8B,EAAU;IACnE,MAAM,IAAI,GAAG,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/G,OAAO,CAAC,CAAC;IACV,OAAO,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QACnC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QACpB,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;QACpC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAC3B,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,CAAC,CAAC;AAAA,CACL;AAMD,MAAM,UAAU,wCAAwC,CACvD,IAA6B,EAC7B,gBAAuC,EAC9B;IACT,MAAM,GAAG,GAAG,iCAAiC,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QACjF,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,KAAK,CAAC;QACzE,MAAM,WAAW,GAChB,KAAK,CAAC,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;YACxF,CAAC,CAAE,KAAK,CAAC,SAAqC;YAC9C,CAAC,CAAC,SAAS,CAAC;QACd,OAAO,WAAW,CAAC,CAAC,CAAC,KAAK,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAAA,CACrE,EAAE,CAAC,CAAC,CAAC;IACN,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;AAAA,CACrC","sourcesContent":["import { resolveSubagentRequestParams } from \"../builtin-extensions/pi-subagents/src/runs/foreground/request-params.ts\";\n\n/** Number of children above which aggregate launch confirmation engages. */\nexport const LARGE_SUBAGENT_LAUNCH_THRESHOLD = 2;\n\nfunction countEntry(item: unknown): number {\n\tconst count = item && typeof item === \"object\" ? (item as { count?: unknown }).count : undefined;\n\treturn typeof count === \"number\" && Number.isInteger(count) && count >= 1 ? count : 1;\n}\n\nfunction isManagementCall(args: Record<string, unknown>): boolean {\n\treturn typeof args.action === \"string\" && args.action.length > 0;\n}\n\nexport function effectiveLargeSubagentLaunchCount(input: Record<string, unknown>): number {\n\tconst args = resolveSubagentRequestParams(input);\n\tlet total = 0;\n\tif (Array.isArray(args.tasks)) {\n\t\tfor (const task of args.tasks) total += countEntry(task);\n\t}\n\tif (Array.isArray(args.chain)) {\n\t\tfor (const step of args.chain) {\n\t\t\tconst parallel = step && typeof step === \"object\" ? (step as { parallel?: unknown }).parallel : undefined;\n\t\t\tif (Array.isArray(parallel)) {\n\t\t\t\tfor (const child of parallel) total += countEntry(child);\n\t\t\t}\n\t\t}\n\t}\n\treturn total;\n}\n\nfunction siblingSingleCount(input: Record<string, unknown>): number {\n\tconst args = resolveSubagentRequestParams(input);\n\tif (isManagementCall(args)) return 0;\n\tif ((Array.isArray(args.tasks) && args.tasks.length > 0) || (Array.isArray(args.chain) && args.chain.length > 0))\n\t\treturn 0;\n\treturn typeof args.task === \"string\" &&\n\t\targs.task.length > 0 &&\n\t\ttypeof args.description === \"string\" &&\n\t\targs.description.length > 0\n\t\t? 1\n\t\t: 0;\n}\n\ninterface AssistantMessageLike {\n\tcontent?: ReadonlyArray<{ type?: string; name?: string; arguments?: unknown }>;\n}\n\nexport function effectiveLargeSubagentLaunchCountForTurn(\n\targs: Record<string, unknown>,\n\tassistantMessage?: AssistantMessageLike,\n): number {\n\tconst own = effectiveLargeSubagentLaunchCount(args);\n\tconst siblingSingles = (assistantMessage?.content ?? []).reduce((total, block) => {\n\t\tif (block.type !== \"toolCall\" || block.name !== \"subagent\") return total;\n\t\tconst siblingArgs =\n\t\t\tblock.arguments && typeof block.arguments === \"object\" && !Array.isArray(block.arguments)\n\t\t\t\t? (block.arguments as Record<string, unknown>)\n\t\t\t\t: undefined;\n\t\treturn siblingArgs ? total + siblingSingleCount(siblingArgs) : total;\n\t}, 0);\n\treturn Math.max(own, siblingSingles);\n}\n"]}
|
|
@@ -19,6 +19,8 @@ export { clearApiKeyCache } from "./provider-composer.ts";
|
|
|
19
19
|
export declare class ModelRegistry {
|
|
20
20
|
private readonly runtime;
|
|
21
21
|
constructor(runtime: ModelRuntime);
|
|
22
|
+
/** Owner-bound usage bridge for deferred footer rendering. */
|
|
23
|
+
getUsageServiceBridge(): import("./usage-service.ts").UsageServiceBridge | undefined;
|
|
22
24
|
/** Reload models.json asynchronously. Await before making synchronous registry reads. */
|
|
23
25
|
refresh(): Promise<void>;
|
|
24
26
|
getError(): string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG9E,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAC5B;IACA,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5B,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;GAGG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC,YAAY,OAAO,EAAE,YAAY,EAEhC;IAED,8DAA8D;IAC9D,qBAAqB,gEAEpB;IAED,yFAAyF;IACzF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAEvB;IAED,QAAQ,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAErB;IAED,YAAY,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAE3B;IAED,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAE9D;IAED,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAE5C;IAEK,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqCzE;IAED,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAElD;IAED,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/C;IAEK,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAMxE;IAED,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAEvC;IAED,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAExE;IAED,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAE7C;IAED,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAEjF;IAED,wBAAwB,IAAI,SAAS,MAAM,EAAE,CAE5C;CACD","sourcesContent":["import type { Api, Model } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"./model-runtime.ts\";\nimport type { AuthStatus, ProviderConfigInput } from \"./provider-composer.ts\";\nimport { getUsageServiceBridge } from \"./usage-service.ts\";\n\nexport type { ProviderConfigInput } from \"./provider-composer.ts\";\nexport type ResolvedRequestAuth =\n\t| {\n\t\t\tok: true;\n\t\t\tapiKey?: string;\n\t\t\theaders?: Record<string, string>;\n\t\t\tenv?: Record<string, string>;\n\t }\n\t| { ok: false; error: string };\nexport { clearApiKeyCache } from \"./provider-composer.ts\";\n\n/**\n * Synchronous compatibility facade exposed to extensions.\n * Coding-agent internals use ModelRuntime directly.\n */\nexport class ModelRegistry {\n\tprivate readonly runtime: ModelRuntime;\n\n\tconstructor(runtime: ModelRuntime) {\n\t\tthis.runtime = runtime;\n\t}\n\n\t/** Owner-bound usage bridge for deferred footer rendering. */\n\tgetUsageServiceBridge() {\n\t\treturn getUsageServiceBridge(this.runtime);\n\t}\n\n\t/** Reload models.json asynchronously. Await before making synchronous registry reads. */\n\trefresh(): Promise<void> {\n\t\treturn this.runtime.reloadConfig();\n\t}\n\n\tgetError(): string | undefined {\n\t\treturn this.runtime.getError();\n\t}\n\n\tgetAll(): Model<Api>[] {\n\t\treturn [...this.runtime.getModels()];\n\t}\n\n\tgetAvailable(): Model<Api>[] {\n\t\treturn [...this.runtime.getAvailableSnapshot()];\n\t}\n\n\tfind(provider: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.runtime.getModel(provider, modelId);\n\t}\n\n\thasConfiguredAuth(model: Model<Api>): boolean {\n\t\treturn this.runtime.hasConfiguredAuth(model.provider);\n\t}\n\n\tasync getApiKeyAndHeaders(model: Model<Api>): Promise<ResolvedRequestAuth> {\n\t\ttry {\n\t\t\tconst resolution = await this.runtime.getAuth(model);\n\t\t\tif (!resolution) {\n\t\t\t\tconst compatibility = this.runtime.getCompatibilityRequestConfig(model);\n\t\t\t\tif (compatibility.authHeader) {\n\t\t\t\t\treturn { ok: false, error: `No API key found for \"${model.provider}\"` };\n\t\t\t\t}\n\t\t\t\tconst headers = compatibility.headers\n\t\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\t\tObject.entries(compatibility.headers).filter(\n\t\t\t\t\t\t\t\t(entry): entry is [string, string] => entry[1] !== null,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t: undefined;\n\t\t\t\treturn { ok: true, headers };\n\t\t\t}\n\t\t\tconst headers = resolution.auth.headers\n\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\tObject.entries(resolution.auth.headers).filter(\n\t\t\t\t\t\t\t(entry): entry is [string, string] => entry[1] !== null,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t\treturn { ok: true, apiKey: resolution.auth.apiKey, headers, env: resolution.env };\n\t\t} catch (error) {\n\t\t\tconst cause = error instanceof Error ? error.cause : undefined;\n\t\t\tconst message =\n\t\t\t\tcause instanceof Error ? cause.message : error instanceof Error ? error.message : String(error);\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror:\n\t\t\t\t\tmessage === \"authHeader requires a resolved API key\"\n\t\t\t\t\t\t? `No API key found for \"${model.provider}\"`\n\t\t\t\t\t\t: message,\n\t\t\t};\n\t\t}\n\t}\n\n\tgetProviderAuthStatus(provider: string): AuthStatus {\n\t\treturn this.runtime.getProviderAuthStatus(provider);\n\t}\n\n\tgetProviderDisplayName(provider: string): string {\n\t\treturn this.runtime.getProvider(provider)?.name ?? provider;\n\t}\n\n\tasync getApiKeyForProvider(provider: string): Promise<string | undefined> {\n\t\ttry {\n\t\t\treturn (await this.runtime.getAuth(provider))?.auth.apiKey;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tisUsingOAuth(model: Model<Api>): boolean {\n\t\treturn this.runtime.isUsingOAuth(model.provider);\n\t}\n\n\tregisterProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tthis.runtime.registerProvider(providerName, config);\n\t}\n\n\tunregisterProvider(providerName: string): void {\n\t\tthis.runtime.unregisterProvider(providerName);\n\t}\n\n\tgetRegisteredProviderConfig(providerName: string): ProviderConfigInput | undefined {\n\t\treturn this.runtime.getRegisteredProviderConfig(providerName);\n\t}\n\n\tgetRegisteredProviderIds(): readonly string[] {\n\t\treturn this.runtime.getRegisteredProviderIds();\n\t}\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getUsageServiceBridge } from "./usage-service.js";
|
|
1
2
|
export { clearApiKeyCache } from "./provider-composer.js";
|
|
2
3
|
/**
|
|
3
4
|
* Synchronous compatibility facade exposed to extensions.
|
|
@@ -8,6 +9,10 @@ export class ModelRegistry {
|
|
|
8
9
|
constructor(runtime) {
|
|
9
10
|
this.runtime = runtime;
|
|
10
11
|
}
|
|
12
|
+
/** Owner-bound usage bridge for deferred footer rendering. */
|
|
13
|
+
getUsageServiceBridge() {
|
|
14
|
+
return getUsageServiceBridge(this.runtime);
|
|
15
|
+
}
|
|
11
16
|
/** Reload models.json asynchronously. Await before making synchronous registry reads. */
|
|
12
17
|
refresh() {
|
|
13
18
|
return this.runtime.reloadConfig();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"./model-runtime.ts\";\nimport type { AuthStatus, ProviderConfigInput } from \"./provider-composer.ts\";\nimport { getUsageServiceBridge } from \"./usage-service.ts\";\n\nexport type { ProviderConfigInput } from \"./provider-composer.ts\";\nexport type ResolvedRequestAuth =\n\t| {\n\t\t\tok: true;\n\t\t\tapiKey?: string;\n\t\t\theaders?: Record<string, string>;\n\t\t\tenv?: Record<string, string>;\n\t }\n\t| { ok: false; error: string };\nexport { clearApiKeyCache } from \"./provider-composer.ts\";\n\n/**\n * Synchronous compatibility facade exposed to extensions.\n * Coding-agent internals use ModelRuntime directly.\n */\nexport class ModelRegistry {\n\tprivate readonly runtime: ModelRuntime;\n\n\tconstructor(runtime: ModelRuntime) {\n\t\tthis.runtime = runtime;\n\t}\n\n\t/** Owner-bound usage bridge for deferred footer rendering. */\n\tgetUsageServiceBridge() {\n\t\treturn getUsageServiceBridge(this.runtime);\n\t}\n\n\t/** Reload models.json asynchronously. Await before making synchronous registry reads. */\n\trefresh(): Promise<void> {\n\t\treturn this.runtime.reloadConfig();\n\t}\n\n\tgetError(): string | undefined {\n\t\treturn this.runtime.getError();\n\t}\n\n\tgetAll(): Model<Api>[] {\n\t\treturn [...this.runtime.getModels()];\n\t}\n\n\tgetAvailable(): Model<Api>[] {\n\t\treturn [...this.runtime.getAvailableSnapshot()];\n\t}\n\n\tfind(provider: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.runtime.getModel(provider, modelId);\n\t}\n\n\thasConfiguredAuth(model: Model<Api>): boolean {\n\t\treturn this.runtime.hasConfiguredAuth(model.provider);\n\t}\n\n\tasync getApiKeyAndHeaders(model: Model<Api>): Promise<ResolvedRequestAuth> {\n\t\ttry {\n\t\t\tconst resolution = await this.runtime.getAuth(model);\n\t\t\tif (!resolution) {\n\t\t\t\tconst compatibility = this.runtime.getCompatibilityRequestConfig(model);\n\t\t\t\tif (compatibility.authHeader) {\n\t\t\t\t\treturn { ok: false, error: `No API key found for \"${model.provider}\"` };\n\t\t\t\t}\n\t\t\t\tconst headers = compatibility.headers\n\t\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\t\tObject.entries(compatibility.headers).filter(\n\t\t\t\t\t\t\t\t(entry): entry is [string, string] => entry[1] !== null,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t: undefined;\n\t\t\t\treturn { ok: true, headers };\n\t\t\t}\n\t\t\tconst headers = resolution.auth.headers\n\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\tObject.entries(resolution.auth.headers).filter(\n\t\t\t\t\t\t\t(entry): entry is [string, string] => entry[1] !== null,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\t\treturn { ok: true, apiKey: resolution.auth.apiKey, headers, env: resolution.env };\n\t\t} catch (error) {\n\t\t\tconst cause = error instanceof Error ? error.cause : undefined;\n\t\t\tconst message =\n\t\t\t\tcause instanceof Error ? cause.message : error instanceof Error ? error.message : String(error);\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror:\n\t\t\t\t\tmessage === \"authHeader requires a resolved API key\"\n\t\t\t\t\t\t? `No API key found for \"${model.provider}\"`\n\t\t\t\t\t\t: message,\n\t\t\t};\n\t\t}\n\t}\n\n\tgetProviderAuthStatus(provider: string): AuthStatus {\n\t\treturn this.runtime.getProviderAuthStatus(provider);\n\t}\n\n\tgetProviderDisplayName(provider: string): string {\n\t\treturn this.runtime.getProvider(provider)?.name ?? provider;\n\t}\n\n\tasync getApiKeyForProvider(provider: string): Promise<string | undefined> {\n\t\ttry {\n\t\t\treturn (await this.runtime.getAuth(provider))?.auth.apiKey;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tisUsingOAuth(model: Model<Api>): boolean {\n\t\treturn this.runtime.isUsingOAuth(model.provider);\n\t}\n\n\tregisterProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tthis.runtime.registerProvider(providerName, config);\n\t}\n\n\tunregisterProvider(providerName: string): void {\n\t\tthis.runtime.unregisterProvider(providerName);\n\t}\n\n\tgetRegisteredProviderConfig(providerName: string): ProviderConfigInput | undefined {\n\t\treturn this.runtime.getRegisteredProviderConfig(providerName);\n\t}\n\n\tgetRegisteredProviderIds(): readonly string[] {\n\t\treturn this.runtime.getRegisteredProviderIds();\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { type Api, type AssistantMessage, type AssistantMessageEventStream, type
|
|
|
2
2
|
import { type IncompleteLiveModel, type LiveCatalogResult } from "./live-catalog.ts";
|
|
3
3
|
import { type OfficialCatalogLoadResult } from "./official-catalog.ts";
|
|
4
4
|
import { type AuthStatus, type CompatibilityRequestConfig, type ProviderConfigInput } from "./provider-composer.ts";
|
|
5
|
-
import { SubscriptionManager } from "./subscriptions.ts";
|
|
5
|
+
import { type RequestSubscriptionKey, SubscriptionManager } from "./subscriptions.ts";
|
|
6
6
|
import { type UserModelEntry } from "./user-models.ts";
|
|
7
7
|
export interface CreateModelRuntimeOptions {
|
|
8
8
|
/** Credential storage. Defaults to the file at authPath. */
|
|
@@ -42,6 +42,7 @@ export declare class ModelRuntime implements Models {
|
|
|
42
42
|
private readonly credentials;
|
|
43
43
|
/** lunr: per-provider subscription-key pools; rotation mirrors the active key into the credential store. */
|
|
44
44
|
readonly subscriptionManager: SubscriptionManager;
|
|
45
|
+
private readonly requestSubscriptionKeys;
|
|
45
46
|
private readonly defaultBuiltins;
|
|
46
47
|
private readonly builtins;
|
|
47
48
|
private readonly extensionProviders;
|
|
@@ -110,6 +111,8 @@ export declare class ModelRuntime implements Models {
|
|
|
110
111
|
listCredentials(): Promise<readonly CredentialInfo[]>;
|
|
111
112
|
getProviderAuthStatus(providerId: string): AuthStatus;
|
|
112
113
|
private prepareRequest;
|
|
114
|
+
/** The final response identity stays process-local and never enters saved chat. */
|
|
115
|
+
getRequestSubscriptionKey(message: AssistantMessage): RequestSubscriptionKey | undefined;
|
|
113
116
|
stream<TApi extends Api>(model: Model<TApi>, context: Context, options?: ModelsApiStreamOptions<TApi>): AssistantMessageEventStream;
|
|
114
117
|
complete<TApi extends Api>(model: Model<TApi>, context: Context, options?: ModelsApiStreamOptions<TApi>): Promise<AssistantMessage>;
|
|
115
118
|
streamSimple(model: Model<Api>, context: Context, options?: ModelsSimpleStreamOptions): AssistantMessageEventStream;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-runtime.d.ts","sourceRoot":"","sources":["../../src/core/model-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { dirname, join } from \"node:path\";\nimport {\n\ttype Api,\n\ttype ApiStreamOptions,\n\ttype AssistantMessage,\n\ttype AssistantMessageEventStream,\n\ttype AuthCheck,\n\ttype AuthInteraction,\n\ttype AuthResult,\n\ttype AuthType,\n\tanthropicRequestRoute,\n\ttype Context,\n\ttype Credential,\n\ttype CredentialInfo,\n\ttype CredentialStore,\n\tcreateModels,\n\tlazyStream,\n\ttype Model,\n\ttype Models,\n\ttype ModelsApiStreamOptions,\n\tModelsError,\n\ttype ModelsRefreshOptions,\n\ttype ModelsRefreshResult,\n\ttype ModelsSimpleStreamOptions,\n\ttype ModelsStore,\n\ttype ModelsStreamTransforms,\n\ttype MutableModels,\n\ttype Provider,\n\ttype ProviderHeaders,\n\ttype SimpleStreamOptions,\n\ttype StreamOptions,\n} from \"@ashx-j/lunr-ai\";\nimport * as builtinProviderCatalog from \"@ashx-j/lunr-ai/providers/all\";\nimport { getAgentDir } from \"../config.ts\";\nimport { AuthStorage as DefaultAuthStorage } from \"./auth-storage.ts\";\nimport { catalogCacheScope } from \"./catalog-cache-scope.ts\";\nimport { CatalogOverlaySource, knownModelKeys, withCatalogOverlay } from \"./catalog-merge.ts\";\nimport { readGrokCliXaiOAuth, wrapXaiGrokCliCredentials } from \"./grok-cli-auth.ts\";\nimport {\n\tbuildLiveOverlay,\n\tfetchLiveProviderModels,\n\ttype IncompleteLiveModel,\n\tLIVE_LIST_PROVIDER_IDS,\n\ttype LiveCatalogResult,\n} from \"./live-catalog.ts\";\nimport { ModelConfig } from \"./model-config.ts\";\nimport { FileModelsStore, InMemoryCodingAgentModelsStore } from \"./models-store.ts\";\nimport {\n\tloadOfficialCatalog,\n\ttype OfficialCatalogLoadResult,\n\tofficialCatalogCachePath,\n\tofficialEntryToModel,\n\tofficialModelKeys,\n\tpreferOfficialCatalog,\n} from \"./official-catalog.ts\";\nimport {\n\ttype AuthStatus,\n\ttype CompatibilityRequestConfig,\n\tcomposeModelProvider,\n\tconfiguredRequestAuthStatus,\n\ttype ProviderConfigInput,\n\tresolveCompatibilityRequestConfig,\n\tresolveConfiguredModelHeaders,\n\tvalidateExtensionProvider,\n} from \"./provider-composer.ts\";\nimport { RuntimeCredentials } from \"./runtime-credentials.ts\";\nimport { SubscriptionManager } from \"./subscriptions.ts\";\nimport { clearPlanUsageCache } from \"./usage-service.ts\";\nimport { type UserModelEntry, UserModelsStore, userEntryToModel, userModelsPath } from \"./user-models.ts\";\n\ninterface ModelRuntimeSnapshot {\n\tall: readonly Model<Api>[];\n\tavailable: readonly Model<Api>[];\n\tconfiguredProviders: ReadonlySet<string>;\n\tstoredProviders: ReadonlySet<string>;\n\tauth: ReadonlyMap<string, AuthCheck | undefined>;\n}\n\nexport interface CreateModelRuntimeOptions {\n\t/** Credential storage. Defaults to the file at authPath. */\n\tcredentials?: CredentialStore;\n\tauthPath?: string;\n\tmodelsPath?: string | null;\n\tmodelsStore?: ModelsStore;\n\tmodelsStorePath?: string;\n\tallowModelNetwork?: boolean;\n\t/** Applied by callers of `refresh()`, not by `create()` (startup is cache-only). */\n\tmodelRefreshTimeoutMs?: number;\n\t/** Unused. Kept so older callers compiling against this options bag still typecheck. */\n\tcatalogBaseUrl?: string;\n\t/** lunr: subscription-key pool. Defaults to subscriptions.json next to authPath (in-memory for custom stores). */\n\tsubscriptions?: SubscriptionManager;\n\t/**\n\t * Grok CLI home (`~/.grok`) used as a SuperGrok OAuth fallback.\n\t * `null` disables the fallback. Custom `credentials` default to disabled\n\t * unless this is an explicit path.\n\t */\n\tgrokHome?: string | null;\n}\n\nexport interface CatalogRefreshResult extends ModelsRefreshResult {\n\tofficial?: OfficialCatalogLoadResult & { evictedUserRows: number };\n\tlive: LiveCatalogResult[];\n\tincomplete: IncompleteLiveModel[];\n}\n\nexport interface ModelRuntimeAuthOverrides {\n\tapiKey?: string;\n\tenv?: Record<string, string>;\n}\n\nfunction mergeHeaders(\n\tbase: ProviderHeaders | undefined,\n\toverride: ProviderHeaders | undefined,\n): ProviderHeaders | undefined {\n\tif (!base && !override) return undefined;\n\tconst merged = { ...base };\n\tfor (const [name, value] of Object.entries(override ?? {})) {\n\t\tconst lowerName = name.toLowerCase();\n\t\tfor (const existingName of Object.keys(merged)) {\n\t\t\tif (existingName.toLowerCase() === lowerName) delete merged[existingName];\n\t\t}\n\t\tmerged[name] = value;\n\t}\n\treturn merged;\n}\n\n/** Configured pi-ai Models collection used by coding-agent and SDK consumers. */\nexport class ModelRuntime implements Models {\n\tprivate readonly models: MutableModels;\n\tprivate readonly credentials: RuntimeCredentials;\n\t/** lunr: per-provider subscription-key pools; rotation mirrors the active key into the credential store. */\n\treadonly subscriptionManager: SubscriptionManager;\n\tprivate readonly defaultBuiltins: ReadonlyMap<string, Provider>;\n\tprivate readonly builtins = new Map<string, Provider>();\n\tprivate readonly extensionProviders = new Map<string, ProviderConfigInput>();\n\tprivate readonly compositionErrors = new Map<string, string>();\n\tprivate readonly modelsPath: string | undefined;\n\tprivate readonly allowModelNetwork: boolean;\n\tprivate config: ModelConfig;\n\tprivate snapshot: ModelRuntimeSnapshot = {\n\t\tall: [],\n\t\tavailable: [],\n\t\tconfiguredProviders: new Set(),\n\t\tstoredProviders: new Set(),\n\t\tauth: new Map(),\n\t};\n\tprivate availabilityRefresh: Promise<void> | undefined;\n\tprivate availabilityError: string | undefined;\n\tprivate readonly modelsStore: ModelsStore;\n\tprivate readonly overlay = new CatalogOverlaySource();\n\tprivate readonly userModels: UserModelsStore;\n\tprivate readonly officialCachePath: string | undefined;\n\tprivate lastCatalogRefresh: CatalogRefreshResult = { aborted: false, errors: new Map(), live: [], incomplete: [] };\n\tprivate lastOfficial: OfficialCatalogLoadResult | undefined;\n\tprivate catalogRefresh: Promise<CatalogRefreshResult> | undefined;\n\tprivate catalogRefreshAllowsNetwork = false;\n\tprivate nextAutomaticRefresh = 0;\n\tprivate automaticRefreshIdentity = \"\";\n\tprivate readonly grokHome: string | undefined;\n\n\tprivate constructor(\n\t\tcredentials: RuntimeCredentials,\n\t\tconfig: ModelConfig,\n\t\tmodelsPath: string | undefined,\n\t\tmodelsStore: ModelsStore,\n\t\tproviders: readonly Provider[],\n\t\tallowModelNetwork: boolean,\n\t\tsubscriptionManager: SubscriptionManager,\n\t\tcatalogDir: string | undefined,\n\t\tgrokHome: string | undefined,\n\t) {\n\t\tthis.credentials = credentials;\n\t\tthis.config = config;\n\t\tthis.modelsPath = modelsPath;\n\t\tthis.modelsStore = modelsStore;\n\t\tthis.allowModelNetwork = allowModelNetwork;\n\t\tthis.subscriptionManager = subscriptionManager;\n\t\tthis.userModels = new UserModelsStore(catalogDir ? userModelsPath(catalogDir) : undefined);\n\t\tthis.officialCachePath = catalogDir ? officialCatalogCachePath(catalogDir) : undefined;\n\t\tthis.grokHome = grokHome;\n\t\tthis.defaultBuiltins = new Map(providers.map((provider) => [provider.id, provider]));\n\t\tfor (const [providerId, provider] of this.defaultBuiltins) this.builtins.set(providerId, provider);\n\t\tthis.models = createModels({ credentials, modelsStore });\n\t\tthis.rebuildProviders();\n\t}\n\n\tstatic async create(options: CreateModelRuntimeOptions = {}): Promise<ModelRuntime> {\n\t\t// lunr: keep the underlying store — the SubscriptionManager mirrors rotated\n\t\t// keys into it directly, NOT through the RuntimeCredentials overlay (a runtime\n\t\t// --api-key override would shadow the mirror there).\n\t\tconst rawStore = options.credentials ?? DefaultAuthStorage.create(options.authPath);\n\t\tconst grokHomeDisabled =\n\t\t\toptions.grokHome === null || (options.grokHome === undefined && options.credentials !== undefined);\n\t\tconst grokHome = grokHomeDisabled ? undefined : (options.grokHome ?? undefined);\n\t\tconst baseStore = grokHomeDisabled ? rawStore : wrapXaiGrokCliCredentials(rawStore, { grokHome });\n\t\tconst credentials = new RuntimeCredentials(baseStore);\n\t\t// Pool persistence: subscriptions.json next to auth.json. A custom credential\n\t\t// store without an authPath (tests, SDK embeddings) gets a process-local pool\n\t\t// so nothing leaks into the real agent dir.\n\t\tconst subscriptionManager =\n\t\t\toptions.subscriptions ??\n\t\t\t(options.credentials && !options.authPath\n\t\t\t\t? SubscriptionManager.inMemory(baseStore)\n\t\t\t\t: SubscriptionManager.create(\n\t\t\t\t\t\tbaseStore,\n\t\t\t\t\t\toptions.authPath ? join(dirname(options.authPath), \"subscriptions.json\") : undefined,\n\t\t\t\t\t));\n\t\tconst modelsPath =\n\t\t\toptions.modelsPath === null ? undefined : (options.modelsPath ?? join(getAgentDir(), \"models.json\"));\n\t\tconst config = await ModelConfig.load(modelsPath);\n\t\tconst modelsStore =\n\t\t\toptions.modelsStore ??\n\t\t\t(modelsPath\n\t\t\t\t? new FileModelsStore(options.modelsStorePath ?? join(dirname(modelsPath), \"models-store.json\"))\n\t\t\t\t: new InMemoryCodingAgentModelsStore());\n\t\tconst providers = builtinProviderCatalog.builtinProviders();\n\t\tconst catalogDir = modelsPath ? dirname(modelsPath) : options.authPath ? dirname(options.authPath) : undefined;\n\t\tconst runtime = new ModelRuntime(\n\t\t\tcredentials,\n\t\t\tconfig,\n\t\t\tmodelsPath,\n\t\t\tmodelsStore,\n\t\t\tproviders,\n\t\t\toptions.allowModelNetwork ?? process.env.PI_OFFLINE === undefined,\n\t\t\tsubscriptionManager,\n\t\t\tcatalogDir,\n\t\t\tgrokHome,\n\t\t);\n\t\truntime.configureRadiusProviders();\n\t\truntime.rebuildProviders();\n\t\t// lunr: create() must not wait on GitHub / provider /v1/models / a dead NIC.\n\t\t// Disk cache + baked-in + bundled official overlay are enough to start;\n\t\t// /refresh and the model picker still do a live refresh.\n\t\tawait runtime.refresh({ allowNetwork: false });\n\t\treturn runtime;\n\t}\n\n\tprivate configureRadiusProviders(): void {\n\t\tthis.builtins.clear();\n\t\tfor (const [providerId, provider] of this.defaultBuiltins) this.builtins.set(providerId, provider);\n\t\tfor (const providerId of this.config.getProviderIds()) {\n\t\t\tconst config = this.config.getProvider(providerId);\n\t\t\tif (config?.oauth !== \"radius\" || !config.baseUrl) continue;\n\t\t\tthis.builtins.set(\n\t\t\t\tproviderId,\n\t\t\t\tbuiltinProviderCatalog.radiusProvider({\n\t\t\t\t\tid: providerId,\n\t\t\t\t\tname: config.name ?? providerId,\n\t\t\t\t\tgateway: config.baseUrl.replace(/\\/v1\\/?$/u, \"\"),\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate providerIds(): Set<string> {\n\t\treturn new Set([...this.builtins.keys(), ...this.config.getProviderIds(), ...this.extensionProviders.keys()]);\n\t}\n\n\tprivate recomposeProvider(providerId: string): void {\n\t\tconst base = this.builtins.get(providerId);\n\t\tconst extension = this.extensionProviders.get(providerId);\n\t\tif (!base && !this.config.getProvider(providerId) && !extension) {\n\t\t\tthis.models.deleteProvider(providerId);\n\t\t\tthis.compositionErrors.delete(providerId);\n\t\t\treturn;\n\t\t}\n\t\tif (base && !this.config.getProvider(providerId) && !extension) {\n\t\t\t// No models.json/extension overlays: keep builtin auth/stream exact, then apply catalog layers.\n\t\t\tthis.models.setProvider(this.withLocalCatalog(base));\n\t\t\tthis.compositionErrors.delete(providerId);\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\t// Discovery is metadata beneath explicit user configuration and extension model definitions.\n\t\t\tthis.models.setProvider(\n\t\t\t\tcomposeModelProvider(providerId, base ? this.withLocalCatalog(base) : undefined, this.config, extension),\n\t\t\t);\n\t\t\tthis.compositionErrors.delete(providerId);\n\t\t} catch (error) {\n\t\t\tthis.compositionErrors.set(providerId, error instanceof Error ? error.message : String(error));\n\t\t\tif (base) this.models.setProvider(this.withLocalCatalog(base));\n\t\t\telse this.models.deleteProvider(providerId);\n\t\t}\n\t}\n\n\tprivate withLocalCatalog(provider: Provider): Provider {\n\t\treturn withCatalogOverlay(provider, this.overlay);\n\t}\n\n\tprivate bakedInModels(providerId: string): Model<Api>[] {\n\t\treturn [...(this.defaultBuiltins.get(providerId)?.getModels() ?? [])];\n\t}\n\n\tprivate rebuildProviders(): void {\n\t\tthis.models.clearProviders();\n\t\tthis.compositionErrors.clear();\n\t\tfor (const providerId of this.providerIds()) this.recomposeProvider(providerId);\n\t\tthis.updateModelSnapshot();\n\t}\n\n\tprivate updateModelSnapshot(): void {\n\t\tconst all = [...this.models.getModels()];\n\t\tthis.snapshot = {\n\t\t\t...this.snapshot,\n\t\t\tall,\n\t\t\tavailable: all.filter(\n\t\t\t\t(model) => this.snapshot.configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate isCatalogModelAvailable(model: Model<Api>): boolean {\n\t\tconst config = this.config.getProvider(model.provider);\n\t\treturn (\n\t\t\t!!config?.models?.some((row) => row.id === model.id) ||\n\t\t\t!!this.extensionProviders.get(model.provider)?.models?.some((row) => row.id === model.id) ||\n\t\t\tthis.overlay.isAvailable(model)\n\t\t);\n\t}\n\n\tprivate async listStoredProviderIds(): Promise<Set<string>> {\n\t\tconst credentials = await this.credentials.list();\n\t\treturn new Set(credentials.map((entry) => entry.providerId));\n\t}\n\n\t/** `/model` lists stored creds + models.json/extension keys, never ambient envApiKeyAuth. */\n\tprivate configuredProviderIds(storedProviders: ReadonlySet<string>): Set<string> {\n\t\tconst configured = new Set(storedProviders);\n\t\tfor (const provider of this.models.getProviders()) {\n\t\t\tif (\n\t\t\t\tconfiguredRequestAuthStatus(this.config.getProvider(provider.id), this.extensionProviders.get(provider.id))\n\t\t\t\t\t?.configured\n\t\t\t) {\n\t\t\t\tconfigured.add(provider.id);\n\t\t\t}\n\t\t}\n\t\treturn configured;\n\t}\n\n\tprivate userModelsForStoredProviders(storedProviders: ReadonlySet<string>): Model<Api>[] {\n\t\treturn this.userModels\n\t\t\t.list()\n\t\t\t.filter((row) => storedProviders.has(row.provider))\n\t\t\t.map(userEntryToModel);\n\t}\n\n\tprivate async runAvailabilityRefresh(): Promise<void> {\n\t\tconst providers = this.models.getProviders();\n\t\tconst [available, checks, storedProviders] = await Promise.all([\n\t\t\tthis.models.getAvailable(),\n\t\t\tPromise.all(\n\t\t\t\tproviders.map(\n\t\t\t\t\tasync (provider): Promise<[string, AuthCheck | undefined]> => [\n\t\t\t\t\t\tprovider.id,\n\t\t\t\t\t\tawait this.models.checkAuth(provider.id),\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t\t),\n\t\t\tthis.listStoredProviderIds(),\n\t\t]);\n\t\tconst auth = new Map(checks);\n\t\tconst configuredProviders = this.configuredProviderIds(storedProviders);\n\t\tthis.snapshot = {\n\t\t\tall: [...this.models.getModels()],\n\t\t\tavailable: available.filter(\n\t\t\t\t(model) => configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t),\n\t\t\tconfiguredProviders,\n\t\t\tstoredProviders,\n\t\t\tauth,\n\t\t};\n\t\tthis.availabilityError = undefined;\n\t}\n\n\tprivate queueAvailabilityRefresh(after: Promise<void> | undefined): Promise<void> {\n\t\tconst refresh = (after ?? Promise.resolve()).catch(() => {}).then(() => this.runAvailabilityRefresh());\n\t\tconst recorded = refresh.catch((error) => {\n\t\t\tthis.availabilityError = error instanceof Error ? error.message : String(error);\n\t\t\tthrow error;\n\t\t});\n\t\tconst tracked = recorded.finally(() => {\n\t\t\tif (this.availabilityRefresh === tracked) this.availabilityRefresh = undefined;\n\t\t});\n\t\tthis.availabilityRefresh = tracked;\n\t\treturn tracked;\n\t}\n\n\t/** Coalesce concurrent readers onto the pending refresh. */\n\tprivate refreshAvailability(): Promise<void> {\n\t\treturn this.availabilityRefresh ?? this.queueAvailabilityRefresh(undefined);\n\t}\n\n\t/** Mutations must not observe an in-flight refresh started before them. */\n\tprivate forceRefreshAvailability(): Promise<void> {\n\t\treturn this.queueAvailabilityRefresh(this.availabilityRefresh);\n\t}\n\n\tgetProviders(): readonly Provider[] {\n\t\treturn this.models.getProviders();\n\t}\n\n\tgetProvider(providerId: string): Provider | undefined {\n\t\treturn this.models.getProvider(providerId);\n\t}\n\n\tgetModels(providerId?: string): readonly Model<Api>[] {\n\t\treturn this.models.getModels(providerId);\n\t}\n\n\tgetModel(providerId: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.models.getModel(providerId, modelId);\n\t}\n\n\tasync checkAuth(providerId: string): Promise<AuthCheck | undefined> {\n\t\treturn this.models.checkAuth(providerId);\n\t}\n\n\tasync getAvailable(providerId?: string): Promise<readonly Model<Api>[]> {\n\t\tif (providerId) {\n\t\t\tif (this.availabilityRefresh) {\n\t\t\t\tawait this.availabilityRefresh;\n\t\t\t\treturn this.snapshot.available.filter((model) => model.provider === providerId);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn (await this.models.getAvailable(providerId)).filter((model) => this.isCatalogModelAvailable(model));\n\t\t\t} catch (error) {\n\t\t\t\tthis.availabilityError = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait this.refreshAvailability();\n\t\treturn this.snapshot.available;\n\t}\n\n\tgetAvailableSnapshot(): readonly Model<Api>[] {\n\t\treturn this.snapshot.available;\n\t}\n\n\tgetError(): string | undefined {\n\t\tconst errors: string[] = [];\n\t\tconst configError = this.config.getError();\n\t\tif (configError) errors.push(configError);\n\t\tfor (const [providerId, error] of this.compositionErrors) {\n\t\t\terrors.push(`Provider \"${providerId}\": ${error}`);\n\t\t}\n\t\tif (this.availabilityError) errors.push(`Availability refresh: ${this.availabilityError}`);\n\t\treturn errors.length > 0 ? errors.join(\"\\n\\n\") : undefined;\n\t}\n\n\tgetRegisteredProviderConfig(providerId: string): ProviderConfigInput | undefined {\n\t\treturn this.extensionProviders.get(providerId);\n\t}\n\n\tgetRegisteredProviderIds(): readonly string[] {\n\t\treturn [...this.extensionProviders.keys()];\n\t}\n\n\t/** @internal Compatibility fallback for ModelRegistry when provider auth is unconfigured. */\n\tgetCompatibilityRequestConfig(model: Model<Api>): CompatibilityRequestConfig {\n\t\treturn resolveCompatibilityRequestConfig(\n\t\t\tmodel,\n\t\t\tthis.config.getProvider(model.provider),\n\t\t\tthis.extensionProviders.get(model.provider),\n\t\t);\n\t}\n\n\tisUsingOAuth(providerId: string): boolean {\n\t\treturn this.snapshot.auth.get(providerId)?.type === \"oauth\";\n\t}\n\n\thasConfiguredAuth(providerId: string): boolean {\n\t\treturn this.snapshot.configuredProviders.has(providerId);\n\t}\n\n\tgetAuth(providerId: string, overrides?: ModelRuntimeAuthOverrides): Promise<AuthResult | undefined>;\n\tgetAuth(model: Model<Api>, overrides?: ModelRuntimeAuthOverrides): Promise<AuthResult | undefined>;\n\tasync getAuth(\n\t\tproviderOrModel: string | Model<Api>,\n\t\toverrides: ModelRuntimeAuthOverrides = {},\n\t): Promise<AuthResult | undefined> {\n\t\tif (typeof providerOrModel === \"string\") return this.models.getAuth(providerOrModel, overrides);\n\t\tconst resolution = await this.models.getAuth(providerOrModel, overrides);\n\t\tif (!resolution) return undefined;\n\t\tconst configuredHeaders = resolveConfiguredModelHeaders(\n\t\t\tproviderOrModel,\n\t\t\tthis.config.getProvider(providerOrModel.provider),\n\t\t\tthis.extensionProviders.get(providerOrModel.provider),\n\t\t\t{ ...(resolution.env ?? {}), ...(overrides.env ?? {}) },\n\t\t);\n\t\treturn {\n\t\t\t...resolution,\n\t\t\tauth: {\n\t\t\t\t...resolution.auth,\n\t\t\t\theaders: mergeHeaders(resolution.auth.headers, configuredHeaders),\n\t\t\t},\n\t\t};\n\t}\n\n\t/** lunr: whether a runtime --api-key override is active for the provider (it shadows auth.json). */\n\thasRuntimeApiKey(providerId: string): boolean {\n\t\treturn this.credentials.hasRuntimeApiKey(providerId);\n\t}\n\n\tasync setRuntimeApiKey(\n\t\tproviderId: string,\n\t\tapiKey: string,\n\t\toptions?: { allowNetwork?: boolean },\n\t): Promise<void> {\n\t\tthis.credentials.setRuntimeApiKey(providerId, apiKey);\n\t\tconst auth = new Map(this.snapshot.auth).set(providerId, { type: \"api_key\", source: \"runtime API key\" });\n\t\tconst configuredProviders = new Set(this.snapshot.configuredProviders).add(providerId);\n\t\tconst storedProviders = new Set(this.snapshot.storedProviders).add(providerId);\n\t\tthis.snapshot = {\n\t\t\t...this.snapshot,\n\t\t\tauth,\n\t\t\tconfiguredProviders,\n\t\t\tstoredProviders,\n\t\t\tavailable: this.snapshot.all.filter(\n\t\t\t\t(model) => configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t),\n\t\t};\n\t\tawait this.refresh({ allowNetwork: options?.allowNetwork ?? this.allowModelNetwork });\n\t}\n\n\tasync removeRuntimeApiKey(providerId: string): Promise<void> {\n\t\tthis.credentials.removeRuntimeApiKey(providerId);\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t}\n\n\t/** lunr: whether network model-catalog fetches are allowed (offline mode disables them). */\n\tisNetworkAllowed(): boolean {\n\t\treturn this.allowModelNetwork;\n\t}\n\n\tlistCredentials(): Promise<readonly CredentialInfo[]> {\n\t\treturn this.credentials.list();\n\t}\n\n\tgetProviderAuthStatus(providerId: string): AuthStatus {\n\t\tif (this.credentials.hasRuntimeApiKey(providerId)) return { configured: true, source: \"runtime\" };\n\t\tif (this.snapshot.storedProviders.has(providerId)) return { configured: true, source: \"stored\" };\n\t\tconst configured = configuredRequestAuthStatus(\n\t\t\tthis.config.getProvider(providerId),\n\t\t\tthis.extensionProviders.get(providerId),\n\t\t);\n\t\tif (configured) return configured;\n\t\tconst check = this.snapshot.auth.get(providerId);\n\t\treturn check ? { configured: true, source: \"environment\", label: check.source } : { configured: false };\n\t}\n\n\tprivate async prepareRequest(\n\t\tmodel: Model<Api>,\n\t\toptions: (StreamOptions & ModelsStreamTransforms) | undefined,\n\t): Promise<{ provider: Provider; model: Model<Api>; options: StreamOptions }> {\n\t\tconst provider = this.models.getProvider(model.provider);\n\t\tif (!provider) throw new ModelsError(\"provider\", `Unknown provider: ${model.provider}`);\n\t\tconst resolution = await this.getAuth(model, { apiKey: options?.apiKey, env: options?.env });\n\t\tif (!resolution) throw new ModelsError(\"auth\", `Provider is not configured: ${model.provider}`);\n\n\t\tconst { transformHeaders, ...providerOptions } = options ?? {};\n\t\tconst route = anthropicRequestRoute(model.provider, resolution, options);\n\t\tlet headers = mergeHeaders(resolution.auth.headers, providerOptions.headers);\n\t\tif (transformHeaders) headers = await transformHeaders(headers ?? {});\n\t\tconst env =\n\t\t\tresolution.env || providerOptions.env\n\t\t\t\t? { ...(resolution.env ?? {}), ...(providerOptions.env ?? {}) }\n\t\t\t\t: undefined;\n\t\treturn {\n\t\t\tprovider,\n\t\t\tmodel: resolution.auth.baseUrl ? { ...model, baseUrl: resolution.auth.baseUrl } : model,\n\t\t\toptions: {\n\t\t\t\t...providerOptions,\n\t\t\t\t...route,\n\t\t\t\theaders,\n\t\t\t\tenv,\n\t\t\t},\n\t\t};\n\t}\n\n\tstream<TApi extends Api>(\n\t\tmodel: Model<TApi>,\n\t\tcontext: Context,\n\t\toptions?: ModelsApiStreamOptions<TApi>,\n\t): AssistantMessageEventStream {\n\t\treturn lazyStream(model, async () => {\n\t\t\tconst prepared = await this.prepareRequest(\n\t\t\t\tmodel,\n\t\t\t\toptions as (StreamOptions & ModelsStreamTransforms) | undefined,\n\t\t\t);\n\t\t\treturn prepared.provider.stream(\n\t\t\t\tprepared.model as Model<TApi>,\n\t\t\t\tcontext,\n\t\t\t\tprepared.options as ApiStreamOptions<TApi>,\n\t\t\t);\n\t\t});\n\t}\n\n\tcomplete<TApi extends Api>(\n\t\tmodel: Model<TApi>,\n\t\tcontext: Context,\n\t\toptions?: ModelsApiStreamOptions<TApi>,\n\t): Promise<AssistantMessage> {\n\t\treturn this.stream(model, context, options).result();\n\t}\n\n\tstreamSimple(model: Model<Api>, context: Context, options?: ModelsSimpleStreamOptions): AssistantMessageEventStream {\n\t\treturn lazyStream(model, async () => {\n\t\t\tconst prepared = await this.prepareRequest(model, options);\n\t\t\treturn prepared.provider.streamSimple(prepared.model, context, prepared.options as SimpleStreamOptions);\n\t\t});\n\t}\n\n\tcompleteSimple(model: Model<Api>, context: Context, options?: ModelsSimpleStreamOptions): Promise<AssistantMessage> {\n\t\treturn this.streamSimple(model, context, options).result();\n\t}\n\n\tasync login(providerId: string, type: AuthType, interaction: AuthInteraction): Promise<Credential> {\n\t\tconst credential = await this.models.login(providerId, type, interaction);\n\t\tclearPlanUsageCache();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t\treturn credential;\n\t}\n\n\tasync logout(providerId: string): Promise<void> {\n\t\tawait this.models.logout(providerId);\n\t\tawait this.modelsStore.delete(providerId);\n\t\tthis.userModels.evictProvider(providerId);\n\t\tthis.overlay.setLive(providerId, []);\n\t\t// Reset credential-dependent compatibility projections before the unconfigured provider is skipped by refresh.\n\t\tthis.recomposeProvider(providerId);\n\t\tclearPlanUsageCache();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t}\n\n\t/** Copy a live Grok CLI SuperGrok session into lunR `auth.json`. */\n\tasync importGrokCliXaiAuth(): Promise<Credential | undefined> {\n\t\tconst grok = readGrokCliXaiOAuth({ grokHome: this.grokHome });\n\t\tif (!grok) return undefined;\n\t\tconst stored = await this.credentials.modify(\"xai\", async () => grok);\n\t\tclearPlanUsageCache();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t\treturn stored;\n\t}\n\n\tasync reloadConfig(): Promise<void> {\n\t\tthis.config = await ModelConfig.load(this.modelsPath);\n\t\tthis.configureRadiusProviders();\n\t\tthis.rebuildProviders();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t}\n\n\tasync refresh(options: ModelsRefreshOptions = {}): Promise<CatalogRefreshResult> {\n\t\tconst allowNetwork = options.allowNetwork ?? this.allowModelNetwork;\n\t\tif (this.catalogRefresh) {\n\t\t\t// Join an in-flight refresh that is at least as capable. A cache-only\n\t\t\t// flight must not swallow a later network refresh.\n\t\t\tif (this.catalogRefreshAllowsNetwork || !allowNetwork) {\n\t\t\t\treturn this.catalogRefresh;\n\t\t\t}\n\t\t\tawait this.catalogRefresh.catch(() => {});\n\t\t\treturn this.refresh({ ...options, allowNetwork });\n\t\t}\n\n\t\tconst run = this.executeCatalogRefresh({ ...options, allowNetwork }).finally(() => {\n\t\t\tif (this.catalogRefresh === run) {\n\t\t\t\tthis.catalogRefresh = undefined;\n\t\t\t\tthis.catalogRefreshAllowsNetwork = false;\n\t\t\t}\n\t\t});\n\t\tthis.catalogRefresh = run;\n\t\tthis.catalogRefreshAllowsNetwork = allowNetwork;\n\t\treturn run;\n\t}\n\n\tprivate async executeCatalogRefresh(\n\t\trefreshOptions: ModelsRefreshOptions & { allowNetwork: boolean },\n\t): Promise<CatalogRefreshResult> {\n\t\tconst official = await this.refreshOfficialCatalog(refreshOptions.allowNetwork, refreshOptions.signal);\n\t\tconst live = refreshOptions.allowNetwork\n\t\t\t? await this.refreshLiveCatalogs(\n\t\t\t\t\tofficial ? officialModelKeys(official.catalog) : new Set(),\n\t\t\t\t\trefreshOptions.signal,\n\t\t\t\t)\n\t\t\t: await this.restoreLiveCatalogs();\n\n\t\t// Radius / local-provider / extension refreshModels hooks. Live-list\n\t\t// providers have no refreshModels, so this does not hit pi.dev.\n\t\tconst result = ((await this.models.refresh(refreshOptions)) as ModelsRefreshResult | undefined) ?? {\n\t\t\taborted: refreshOptions.signal?.aborted ?? false,\n\t\t\terrors: new Map(),\n\t\t};\n\t\tconst errors = new Map(result.errors);\n\t\tfor (const [id, error] of Object.entries(official?.errors ?? {})) errors.set(id, new Error(error));\n\t\tfor (const entry of live) {\n\t\t\tif (entry.status === \"error\" || entry.status === \"timeout\") {\n\t\t\t\terrors.set(entry.providerId, new Error(entry.error ?? entry.status));\n\t\t\t}\n\t\t}\n\t\tthis.updateModelSnapshot();\n\t\ttry {\n\t\t\tawait this.forceRefreshAvailability();\n\t\t} catch {\n\t\t\t// Availability errors are recorded by forceRefreshAvailability; refreshed models remain usable.\n\t\t}\n\t\tconst catalogResult: CatalogRefreshResult = {\n\t\t\taborted: result.aborted,\n\t\t\terrors,\n\t\t\tofficial,\n\t\t\tlive,\n\t\t\tincomplete: live.flatMap((entry) => entry.incomplete),\n\t\t};\n\t\tthis.lastCatalogRefresh = catalogResult;\n\t\treturn catalogResult;\n\t}\n\n\tgetLastCatalogRefresh(): CatalogRefreshResult {\n\t\treturn this.lastCatalogRefresh;\n\t}\n\n\t/** Called after first paint and by the picker; explicit /refresh always bypasses this gate. */\n\tasync refreshIfStale(options: { signal?: AbortSignal } = {}): Promise<CatalogRefreshResult> {\n\t\tif (!this.allowModelNetwork || options.signal?.aborted) return this.lastCatalogRefresh;\n\t\tif (this.catalogRefresh) return this.refresh({ allowNetwork: true, signal: options.signal });\n\t\tconst providers = [...(await this.listStoredProviderIds())].sort();\n\t\tconst identity = (await Promise.all(providers.map(async (id) => this.scopeFor(id)))).join(\":\");\n\t\tif (identity === this.automaticRefreshIdentity && Date.now() < this.nextAutomaticRefresh)\n\t\t\treturn this.lastCatalogRefresh;\n\t\tthis.automaticRefreshIdentity = identity;\n\t\t// Bound retries on a broken source; a successful refresh extends the deadline to one hour.\n\t\tthis.nextAutomaticRefresh = Date.now() + 60_000;\n\t\tconst result = await this.refresh({ allowNetwork: true, signal: options.signal });\n\t\tif (!result.aborted && !result.errors.size) this.nextAutomaticRefresh = Date.now() + 3_600_000;\n\t\treturn result;\n\t}\n\n\tprivate async scopeFor(providerId: string): Promise<string> {\n\t\tconst provider = this.models.getProvider(providerId) ?? this.defaultBuiltins.get(providerId);\n\t\treturn catalogCacheScope(providerId, provider?.baseUrl ?? \"\", await this.credentials.read(providerId));\n\t}\n\n\tpersistUserModels(rows: readonly UserModelEntry[]): void {\n\t\tthis.userModels.upsert(rows);\n\t\tthis.overlay.setUser(this.userModelsForStoredProviders(this.snapshot.storedProviders));\n\t\tthis.updateModelSnapshot();\n\t}\n\n\tprivate async refreshOfficialCatalog(\n\t\tallowNetwork: boolean,\n\t\tsignal?: AbortSignal,\n\t): Promise<(OfficialCatalogLoadResult & { evictedUserRows: number }) | undefined> {\n\t\tconst storedProviders = await this.listStoredProviderIds();\n\t\tconst loaded = preferOfficialCatalog(\n\t\t\tthis.lastOfficial,\n\t\t\tawait loadOfficialCatalog({\n\t\t\t\tallowNetwork,\n\t\t\t\tcachePath: this.officialCachePath,\n\t\t\t\tsignal,\n\t\t\t\tproviderIds: [...storedProviders],\n\t\t\t}),\n\t\t);\n\t\tthis.lastOfficial = loaded;\n\t\tconst evicted = this.userModels.evictOfficial(officialModelKeys(loaded.catalog));\n\t\tconst templateByProvider = new Map<string, Model<Api> | undefined>();\n\t\tconst officialModels = loaded.catalog.models\n\t\t\t.filter((entry) => storedProviders.has(entry.provider))\n\t\t\t.map((entry) => {\n\t\t\t\tif (!templateByProvider.has(entry.provider)) {\n\t\t\t\t\ttemplateByProvider.set(entry.provider, this.bakedInModels(entry.provider)[0]);\n\t\t\t\t}\n\t\t\t\treturn officialEntryToModel(entry, templateByProvider.get(entry.provider));\n\t\t\t});\n\t\tthis.overlay.setOfficial(officialModels);\n\t\tthis.overlay.setUser(this.userModelsForStoredProviders(storedProviders));\n\t\treturn { ...loaded, evictedUserRows: evicted.length };\n\t}\n\n\tprivate async restoreLiveCatalogs(): Promise<LiveCatalogResult[]> {\n\t\tconst storedProviders = await this.listStoredProviderIds();\n\t\tconst results: LiveCatalogResult[] = [];\n\t\tfor (const providerId of LIVE_LIST_PROVIDER_IDS) {\n\t\t\tconst stored = storedProviders.has(providerId) ? await this.modelsStore.read(providerId) : undefined;\n\t\t\tconst valid =\n\t\t\t\t(!stored?.scope && providerId !== \"openai-codex\") || stored?.scope === (await this.scopeFor(providerId));\n\t\t\tif (valid && stored?.models) this.overlay.setLive(providerId, stored.models);\n\t\t\telse this.overlay.setLive(providerId, []);\n\t\t\tresults.push({\n\t\t\t\tproviderId,\n\t\t\t\tstatus: \"skipped\",\n\t\t\t\tdiscoveries: [],\n\t\t\t\tadded: 0,\n\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\tincomplete: [],\n\t\t\t});\n\t\t}\n\t\treturn results;\n\t}\n\n\tprivate async refreshLiveCatalogs(officialKeys: Set<string>, signal?: AbortSignal): Promise<LiveCatalogResult[]> {\n\t\tconst storedProviders = await this.listStoredProviderIds();\n\t\tconst known = knownModelKeys(\n\t\t\tLIVE_LIST_PROVIDER_IDS.flatMap((id) => this.bakedInModels(id)),\n\t\t\tofficialKeys,\n\t\t\tthis.userModels.keys(),\n\t\t);\n\n\t\tconst results = await Promise.all(\n\t\t\tLIVE_LIST_PROVIDER_IDS.map(async (providerId) => {\n\t\t\t\tif (!storedProviders.has(providerId)) {\n\t\t\t\t\tthis.overlay.setLive(providerId, []);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst stored = await this.modelsStore.read(providerId);\n\t\t\t\tconst initialScope = await this.scopeFor(providerId);\n\t\t\t\tif (stored?.models && (stored.scope === initialScope || (!stored.scope && providerId !== \"openai-codex\")))\n\t\t\t\t\tthis.overlay.setLive(providerId, stored.models);\n\t\t\t\telse this.overlay.setLive(providerId, []);\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t\terror: \"aborted\",\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst bakedIn = this.bakedInModels(providerId);\n\t\t\t\tconst provider = this.models.getProvider(providerId) ?? this.defaultBuiltins.get(providerId);\n\t\t\t\tconst baseUrl = provider?.baseUrl ?? bakedIn[0]?.baseUrl;\n\t\t\t\tif (!baseUrl) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tlet credential: Credential | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tcredential = await this.refreshCredentialFor(providerId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (!credential) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst requestScope = catalogCacheScope(providerId, baseUrl, credential);\n\t\t\t\tconst result = await fetchLiveProviderModels({\n\t\t\t\t\tdiscoveryClientVersion: stored?.scope === requestScope ? stored.discoveryClientVersion : undefined,\n\t\t\t\t\tproviderId,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\tbakedIn,\n\t\t\t\t\tcredential,\n\t\t\t\t\tknownKeys: known,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\t// A login/logout during the request must not install the previous account's result.\n\t\t\t\tconst accountChanged = (await this.scopeFor(providerId)) !== requestScope;\n\t\t\t\tif (accountChanged) this.overlay.setLive(providerId, []);\n\t\t\t\tif (signal?.aborted || accountChanged) {\n\t\t\t\t\treturn { ...result, status: \"skipped\" as const, discoveries: [], incomplete: [] };\n\t\t\t\t}\n\t\t\t\tif (result.status === \"ok\") {\n\t\t\t\t\tconst overlayModels = buildLiveOverlay(bakedIn, result.discoveries);\n\t\t\t\t\tthis.overlay.setLive(providerId, overlayModels);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this.modelsStore.write(providerId, {\n\t\t\t\t\t\t\tmodels: overlayModels,\n\t\t\t\t\t\t\tcheckedAt: Date.now(),\n\t\t\t\t\t\t\tscope: requestScope,\n\t\t\t\t\t\t\tdiscoveryClientVersion: result.discoveryClientVersion,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Store write is best-effort.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}),\n\t\t);\n\t\treturn results;\n\t}\n\n\tprivate async refreshCredentialFor(providerId: string): Promise<Credential | undefined> {\n\t\t// Same lock + persist path as chat. Returning stored OAuth here skips\n\t\t// refresh and sends expired SuperGrok tokens to GET /models (HTTP 403).\n\t\tconst resolved = await this.getAuth(providerId);\n\t\tconst stored = await this.credentials.read(providerId);\n\t\tif (stored?.type === \"oauth\") return { ...stored, access: resolved?.auth.apiKey ?? stored.access };\n\t\tif (resolved?.auth.apiKey) return { type: \"api_key\", key: resolved.auth.apiKey, env: resolved.env };\n\t\tif (stored?.type === \"api_key\" && stored.key) return stored;\n\t\treturn undefined;\n\t}\n\n\tregisterProvider(providerId: string, config: ProviderConfigInput): void {\n\t\t// Validate the incoming registration on its own, like the legacy registry:\n\t\t// a broken re-registration must throw without touching the stored config.\n\t\tvalidateExtensionProvider(providerId, this.builtins.get(providerId), this.config.getProvider(providerId), config);\n\t\t// Re-registration merges defined values over the previous registration and\n\t\t// preserves undefined ones, matching the legacy ModelRegistry contract.\n\t\tconst previous = this.extensionProviders.get(providerId);\n\t\tconst effective: ProviderConfigInput = { ...previous };\n\t\tfor (const [key, value] of Object.entries(config)) {\n\t\t\tif (value !== undefined) (effective as Record<string, unknown>)[key] = value;\n\t\t}\n\t\tthis.extensionProviders.set(providerId, effective);\n\t\tthis.recomposeProvider(providerId);\n\t\tthis.updateModelSnapshot();\n\t\tif (\n\t\t\tthis.snapshot.storedProviders.has(providerId) ||\n\t\t\tconfiguredRequestAuthStatus(this.config.getProvider(providerId), effective)?.configured\n\t\t) {\n\t\t\tconst configuredProviders = new Set(this.snapshot.configuredProviders).add(providerId);\n\t\t\tconst auth = new Map(this.snapshot.auth);\n\t\t\t// Provisional entry until the async refresh lands; never clobber a real check result.\n\t\t\tif (!auth.get(providerId)) {\n\t\t\t\tauth.set(providerId, {\n\t\t\t\t\ttype: effective.oauth && !effective.apiKey ? \"oauth\" : \"api_key\",\n\t\t\t\t\tsource: \"configured provider\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.snapshot = {\n\t\t\t\t...this.snapshot,\n\t\t\t\tauth,\n\t\t\t\tconfiguredProviders,\n\t\t\t\tavailable: this.snapshot.all.filter(\n\t\t\t\t\t(model) => configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t\tvoid this.refresh({ allowNetwork: false });\n\t}\n\n\tunregisterProvider(providerId: string): void {\n\t\tthis.extensionProviders.delete(providerId);\n\t\tthis.recomposeProvider(providerId);\n\t\tthis.updateModelSnapshot();\n\t\tvoid this.refresh({ allowNetwork: false });\n\t}\n}\n\n/** TUI init / footer / rebind: cache-only. Live refresh is `/refresh` and the model picker. */\nexport async function refreshModelCandidatesForInit(\n\truntime: Pick<ModelRuntime, \"refresh\" | \"getAvailableSnapshot\">,\n): Promise<readonly Model<Api>[]> {\n\tawait runtime.refresh({ allowNetwork: false });\n\treturn runtime.getAvailableSnapshot();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model-runtime.d.ts","sourceRoot":"","sources":["../../src/core/model-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { dirname, join } from \"node:path\";\nimport {\n\ttype Api,\n\ttype ApiStreamOptions,\n\ttype AssistantMessage,\n\ttype AssistantMessageEventStream,\n\ttype AuthCheck,\n\ttype AuthInteraction,\n\ttype AuthResult,\n\ttype AuthType,\n\tanthropicRequestRoute,\n\ttype Context,\n\ttype Credential,\n\ttype CredentialInfo,\n\ttype CredentialStore,\n\tcreateModels,\n\tlazyStream,\n\ttype Model,\n\ttype Models,\n\ttype ModelsApiStreamOptions,\n\tModelsError,\n\ttype ModelsRefreshOptions,\n\ttype ModelsRefreshResult,\n\ttype ModelsSimpleStreamOptions,\n\ttype ModelsStore,\n\ttype ModelsStreamTransforms,\n\ttype MutableModels,\n\ttype Provider,\n\ttype ProviderHeaders,\n\ttype SimpleStreamOptions,\n\ttype StreamOptions,\n} from \"@ashx-j/lunr-ai\";\nimport * as builtinProviderCatalog from \"@ashx-j/lunr-ai/providers/all\";\nimport { getAgentDir } from \"../config.ts\";\nimport { AuthStorage as DefaultAuthStorage } from \"./auth-storage.ts\";\nimport { catalogCacheScope } from \"./catalog-cache-scope.ts\";\nimport { CatalogOverlaySource, knownModelKeys, withCatalogOverlay } from \"./catalog-merge.ts\";\nimport { readGrokCliXaiOAuth, wrapXaiGrokCliCredentials } from \"./grok-cli-auth.ts\";\nimport {\n\tbuildLiveOverlay,\n\tfetchLiveProviderModels,\n\ttype IncompleteLiveModel,\n\tLIVE_LIST_PROVIDER_IDS,\n\ttype LiveCatalogResult,\n} from \"./live-catalog.ts\";\nimport { ModelConfig } from \"./model-config.ts\";\nimport { FileModelsStore, InMemoryCodingAgentModelsStore } from \"./models-store.ts\";\nimport {\n\tloadOfficialCatalog,\n\ttype OfficialCatalogLoadResult,\n\tofficialCatalogCachePath,\n\tofficialEntryToModel,\n\tofficialModelKeys,\n\tpreferOfficialCatalog,\n} from \"./official-catalog.ts\";\nimport {\n\ttype AuthStatus,\n\ttype CompatibilityRequestConfig,\n\tcomposeModelProvider,\n\tconfiguredRequestAuthStatus,\n\ttype ProviderConfigInput,\n\tresolveCompatibilityRequestConfig,\n\tresolveConfiguredModelHeaders,\n\tvalidateExtensionProvider,\n} from \"./provider-composer.ts\";\nimport { RuntimeCredentials } from \"./runtime-credentials.ts\";\nimport { type RequestSubscriptionKey, SubscriptionManager, subscriptionKeyFingerprint } from \"./subscriptions.ts\";\nimport { clearPlanUsageCache } from \"./usage-service.ts\";\nimport { type UserModelEntry, UserModelsStore, userEntryToModel, userModelsPath } from \"./user-models.ts\";\n\ninterface ModelRuntimeSnapshot {\n\tall: readonly Model<Api>[];\n\tavailable: readonly Model<Api>[];\n\tconfiguredProviders: ReadonlySet<string>;\n\tstoredProviders: ReadonlySet<string>;\n\tauth: ReadonlyMap<string, AuthCheck | undefined>;\n}\n\nexport interface CreateModelRuntimeOptions {\n\t/** Credential storage. Defaults to the file at authPath. */\n\tcredentials?: CredentialStore;\n\tauthPath?: string;\n\tmodelsPath?: string | null;\n\tmodelsStore?: ModelsStore;\n\tmodelsStorePath?: string;\n\tallowModelNetwork?: boolean;\n\t/** Applied by callers of `refresh()`, not by `create()` (startup is cache-only). */\n\tmodelRefreshTimeoutMs?: number;\n\t/** Unused. Kept so older callers compiling against this options bag still typecheck. */\n\tcatalogBaseUrl?: string;\n\t/** lunr: subscription-key pool. Defaults to subscriptions.json next to authPath (in-memory for custom stores). */\n\tsubscriptions?: SubscriptionManager;\n\t/**\n\t * Grok CLI home (`~/.grok`) used as a SuperGrok OAuth fallback.\n\t * `null` disables the fallback. Custom `credentials` default to disabled\n\t * unless this is an explicit path.\n\t */\n\tgrokHome?: string | null;\n}\n\nexport interface CatalogRefreshResult extends ModelsRefreshResult {\n\tofficial?: OfficialCatalogLoadResult & { evictedUserRows: number };\n\tlive: LiveCatalogResult[];\n\tincomplete: IncompleteLiveModel[];\n}\n\nexport interface ModelRuntimeAuthOverrides {\n\tapiKey?: string;\n\tenv?: Record<string, string>;\n}\n\nfunction mergeHeaders(\n\tbase: ProviderHeaders | undefined,\n\toverride: ProviderHeaders | undefined,\n): ProviderHeaders | undefined {\n\tif (!base && !override) return undefined;\n\tconst merged = { ...base };\n\tfor (const [name, value] of Object.entries(override ?? {})) {\n\t\tconst lowerName = name.toLowerCase();\n\t\tfor (const existingName of Object.keys(merged)) {\n\t\t\tif (existingName.toLowerCase() === lowerName) delete merged[existingName];\n\t\t}\n\t\tmerged[name] = value;\n\t}\n\treturn merged;\n}\n\n/** Configured pi-ai Models collection used by coding-agent and SDK consumers. */\nexport class ModelRuntime implements Models {\n\tprivate readonly models: MutableModels;\n\tprivate readonly credentials: RuntimeCredentials;\n\t/** lunr: per-provider subscription-key pools; rotation mirrors the active key into the credential store. */\n\treadonly subscriptionManager: SubscriptionManager;\n\tprivate readonly requestSubscriptionKeys = new WeakMap<AssistantMessage, RequestSubscriptionKey>();\n\tprivate readonly defaultBuiltins: ReadonlyMap<string, Provider>;\n\tprivate readonly builtins = new Map<string, Provider>();\n\tprivate readonly extensionProviders = new Map<string, ProviderConfigInput>();\n\tprivate readonly compositionErrors = new Map<string, string>();\n\tprivate readonly modelsPath: string | undefined;\n\tprivate readonly allowModelNetwork: boolean;\n\tprivate config: ModelConfig;\n\tprivate snapshot: ModelRuntimeSnapshot = {\n\t\tall: [],\n\t\tavailable: [],\n\t\tconfiguredProviders: new Set(),\n\t\tstoredProviders: new Set(),\n\t\tauth: new Map(),\n\t};\n\tprivate availabilityRefresh: Promise<void> | undefined;\n\tprivate availabilityError: string | undefined;\n\tprivate readonly modelsStore: ModelsStore;\n\tprivate readonly overlay = new CatalogOverlaySource();\n\tprivate readonly userModels: UserModelsStore;\n\tprivate readonly officialCachePath: string | undefined;\n\tprivate lastCatalogRefresh: CatalogRefreshResult = { aborted: false, errors: new Map(), live: [], incomplete: [] };\n\tprivate lastOfficial: OfficialCatalogLoadResult | undefined;\n\tprivate catalogRefresh: Promise<CatalogRefreshResult> | undefined;\n\tprivate catalogRefreshAllowsNetwork = false;\n\tprivate nextAutomaticRefresh = 0;\n\tprivate automaticRefreshIdentity = \"\";\n\tprivate readonly grokHome: string | undefined;\n\n\tprivate constructor(\n\t\tcredentials: RuntimeCredentials,\n\t\tconfig: ModelConfig,\n\t\tmodelsPath: string | undefined,\n\t\tmodelsStore: ModelsStore,\n\t\tproviders: readonly Provider[],\n\t\tallowModelNetwork: boolean,\n\t\tsubscriptionManager: SubscriptionManager,\n\t\tcatalogDir: string | undefined,\n\t\tgrokHome: string | undefined,\n\t) {\n\t\tthis.credentials = credentials;\n\t\tthis.config = config;\n\t\tthis.modelsPath = modelsPath;\n\t\tthis.modelsStore = modelsStore;\n\t\tthis.allowModelNetwork = allowModelNetwork;\n\t\tthis.subscriptionManager = subscriptionManager;\n\t\tthis.userModels = new UserModelsStore(catalogDir ? userModelsPath(catalogDir) : undefined);\n\t\tthis.officialCachePath = catalogDir ? officialCatalogCachePath(catalogDir) : undefined;\n\t\tthis.grokHome = grokHome;\n\t\tthis.defaultBuiltins = new Map(providers.map((provider) => [provider.id, provider]));\n\t\tfor (const [providerId, provider] of this.defaultBuiltins) this.builtins.set(providerId, provider);\n\t\tthis.models = createModels({ credentials, modelsStore });\n\t\tthis.rebuildProviders();\n\t}\n\n\tstatic async create(options: CreateModelRuntimeOptions = {}): Promise<ModelRuntime> {\n\t\t// lunr: keep the underlying store — the SubscriptionManager mirrors rotated\n\t\t// keys into it directly, NOT through the RuntimeCredentials overlay (a runtime\n\t\t// --api-key override would shadow the mirror there).\n\t\tconst rawStore = options.credentials ?? DefaultAuthStorage.create(options.authPath);\n\t\tconst grokHomeDisabled =\n\t\t\toptions.grokHome === null || (options.grokHome === undefined && options.credentials !== undefined);\n\t\tconst grokHome = grokHomeDisabled ? undefined : (options.grokHome ?? undefined);\n\t\tconst baseStore = grokHomeDisabled ? rawStore : wrapXaiGrokCliCredentials(rawStore, { grokHome });\n\t\tconst credentials = new RuntimeCredentials(baseStore);\n\t\t// Pool persistence: subscriptions.json next to auth.json. A custom credential\n\t\t// store without an authPath (tests, SDK embeddings) gets a process-local pool\n\t\t// so nothing leaks into the real agent dir.\n\t\tconst subscriptionManager =\n\t\t\toptions.subscriptions ??\n\t\t\t(options.credentials && !options.authPath\n\t\t\t\t? SubscriptionManager.inMemory(baseStore)\n\t\t\t\t: SubscriptionManager.create(\n\t\t\t\t\t\tbaseStore,\n\t\t\t\t\t\toptions.authPath ? join(dirname(options.authPath), \"subscriptions.json\") : undefined,\n\t\t\t\t\t));\n\t\tconst modelsPath =\n\t\t\toptions.modelsPath === null ? undefined : (options.modelsPath ?? join(getAgentDir(), \"models.json\"));\n\t\tconst config = await ModelConfig.load(modelsPath);\n\t\tconst modelsStore =\n\t\t\toptions.modelsStore ??\n\t\t\t(modelsPath\n\t\t\t\t? new FileModelsStore(options.modelsStorePath ?? join(dirname(modelsPath), \"models-store.json\"))\n\t\t\t\t: new InMemoryCodingAgentModelsStore());\n\t\tconst providers = builtinProviderCatalog.builtinProviders();\n\t\tconst catalogDir = modelsPath ? dirname(modelsPath) : options.authPath ? dirname(options.authPath) : undefined;\n\t\tconst runtime = new ModelRuntime(\n\t\t\tcredentials,\n\t\t\tconfig,\n\t\t\tmodelsPath,\n\t\t\tmodelsStore,\n\t\t\tproviders,\n\t\t\toptions.allowModelNetwork ?? process.env.PI_OFFLINE === undefined,\n\t\t\tsubscriptionManager,\n\t\t\tcatalogDir,\n\t\t\tgrokHome,\n\t\t);\n\t\truntime.configureRadiusProviders();\n\t\truntime.rebuildProviders();\n\t\t// lunr: create() must not wait on GitHub / provider /v1/models / a dead NIC.\n\t\t// Disk cache + baked-in + bundled official overlay are enough to start;\n\t\t// /refresh and the model picker still do a live refresh.\n\t\tawait runtime.refresh({ allowNetwork: false });\n\t\treturn runtime;\n\t}\n\n\tprivate configureRadiusProviders(): void {\n\t\tthis.builtins.clear();\n\t\tfor (const [providerId, provider] of this.defaultBuiltins) this.builtins.set(providerId, provider);\n\t\tfor (const providerId of this.config.getProviderIds()) {\n\t\t\tconst config = this.config.getProvider(providerId);\n\t\t\tif (config?.oauth !== \"radius\" || !config.baseUrl) continue;\n\t\t\tthis.builtins.set(\n\t\t\t\tproviderId,\n\t\t\t\tbuiltinProviderCatalog.radiusProvider({\n\t\t\t\t\tid: providerId,\n\t\t\t\t\tname: config.name ?? providerId,\n\t\t\t\t\tgateway: config.baseUrl.replace(/\\/v1\\/?$/u, \"\"),\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate providerIds(): Set<string> {\n\t\treturn new Set([...this.builtins.keys(), ...this.config.getProviderIds(), ...this.extensionProviders.keys()]);\n\t}\n\n\tprivate recomposeProvider(providerId: string): void {\n\t\tconst base = this.builtins.get(providerId);\n\t\tconst extension = this.extensionProviders.get(providerId);\n\t\tif (!base && !this.config.getProvider(providerId) && !extension) {\n\t\t\tthis.models.deleteProvider(providerId);\n\t\t\tthis.compositionErrors.delete(providerId);\n\t\t\treturn;\n\t\t}\n\t\tif (base && !this.config.getProvider(providerId) && !extension) {\n\t\t\t// No models.json/extension overlays: keep builtin auth/stream exact, then apply catalog layers.\n\t\t\tthis.models.setProvider(this.withLocalCatalog(base));\n\t\t\tthis.compositionErrors.delete(providerId);\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\t// Discovery is metadata beneath explicit user configuration and extension model definitions.\n\t\t\tthis.models.setProvider(\n\t\t\t\tcomposeModelProvider(providerId, base ? this.withLocalCatalog(base) : undefined, this.config, extension),\n\t\t\t);\n\t\t\tthis.compositionErrors.delete(providerId);\n\t\t} catch (error) {\n\t\t\tthis.compositionErrors.set(providerId, error instanceof Error ? error.message : String(error));\n\t\t\tif (base) this.models.setProvider(this.withLocalCatalog(base));\n\t\t\telse this.models.deleteProvider(providerId);\n\t\t}\n\t}\n\n\tprivate withLocalCatalog(provider: Provider): Provider {\n\t\treturn withCatalogOverlay(provider, this.overlay);\n\t}\n\n\tprivate bakedInModels(providerId: string): Model<Api>[] {\n\t\treturn [...(this.defaultBuiltins.get(providerId)?.getModels() ?? [])];\n\t}\n\n\tprivate rebuildProviders(): void {\n\t\tthis.models.clearProviders();\n\t\tthis.compositionErrors.clear();\n\t\tfor (const providerId of this.providerIds()) this.recomposeProvider(providerId);\n\t\tthis.updateModelSnapshot();\n\t}\n\n\tprivate updateModelSnapshot(): void {\n\t\tconst all = [...this.models.getModels()];\n\t\tthis.snapshot = {\n\t\t\t...this.snapshot,\n\t\t\tall,\n\t\t\tavailable: all.filter(\n\t\t\t\t(model) => this.snapshot.configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate isCatalogModelAvailable(model: Model<Api>): boolean {\n\t\tconst config = this.config.getProvider(model.provider);\n\t\treturn (\n\t\t\t!!config?.models?.some((row) => row.id === model.id) ||\n\t\t\t!!this.extensionProviders.get(model.provider)?.models?.some((row) => row.id === model.id) ||\n\t\t\tthis.overlay.isAvailable(model)\n\t\t);\n\t}\n\n\tprivate async listStoredProviderIds(): Promise<Set<string>> {\n\t\tconst credentials = await this.credentials.list();\n\t\treturn new Set(credentials.map((entry) => entry.providerId));\n\t}\n\n\t/** `/model` lists stored creds + models.json/extension keys, never ambient envApiKeyAuth. */\n\tprivate configuredProviderIds(storedProviders: ReadonlySet<string>): Set<string> {\n\t\tconst configured = new Set(storedProviders);\n\t\tfor (const provider of this.models.getProviders()) {\n\t\t\tif (\n\t\t\t\tconfiguredRequestAuthStatus(this.config.getProvider(provider.id), this.extensionProviders.get(provider.id))\n\t\t\t\t\t?.configured\n\t\t\t) {\n\t\t\t\tconfigured.add(provider.id);\n\t\t\t}\n\t\t}\n\t\treturn configured;\n\t}\n\n\tprivate userModelsForStoredProviders(storedProviders: ReadonlySet<string>): Model<Api>[] {\n\t\treturn this.userModels\n\t\t\t.list()\n\t\t\t.filter((row) => storedProviders.has(row.provider))\n\t\t\t.map(userEntryToModel);\n\t}\n\n\tprivate async runAvailabilityRefresh(): Promise<void> {\n\t\tconst providers = this.models.getProviders();\n\t\tconst [available, checks, storedProviders] = await Promise.all([\n\t\t\tthis.models.getAvailable(),\n\t\t\tPromise.all(\n\t\t\t\tproviders.map(\n\t\t\t\t\tasync (provider): Promise<[string, AuthCheck | undefined]> => [\n\t\t\t\t\t\tprovider.id,\n\t\t\t\t\t\tawait this.models.checkAuth(provider.id),\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t\t),\n\t\t\tthis.listStoredProviderIds(),\n\t\t]);\n\t\tconst auth = new Map(checks);\n\t\tconst configuredProviders = this.configuredProviderIds(storedProviders);\n\t\tthis.snapshot = {\n\t\t\tall: [...this.models.getModels()],\n\t\t\tavailable: available.filter(\n\t\t\t\t(model) => configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t),\n\t\t\tconfiguredProviders,\n\t\t\tstoredProviders,\n\t\t\tauth,\n\t\t};\n\t\tthis.availabilityError = undefined;\n\t}\n\n\tprivate queueAvailabilityRefresh(after: Promise<void> | undefined): Promise<void> {\n\t\tconst refresh = (after ?? Promise.resolve()).catch(() => {}).then(() => this.runAvailabilityRefresh());\n\t\tconst recorded = refresh.catch((error) => {\n\t\t\tthis.availabilityError = error instanceof Error ? error.message : String(error);\n\t\t\tthrow error;\n\t\t});\n\t\tconst tracked = recorded.finally(() => {\n\t\t\tif (this.availabilityRefresh === tracked) this.availabilityRefresh = undefined;\n\t\t});\n\t\tthis.availabilityRefresh = tracked;\n\t\treturn tracked;\n\t}\n\n\t/** Coalesce concurrent readers onto the pending refresh. */\n\tprivate refreshAvailability(): Promise<void> {\n\t\treturn this.availabilityRefresh ?? this.queueAvailabilityRefresh(undefined);\n\t}\n\n\t/** Mutations must not observe an in-flight refresh started before them. */\n\tprivate forceRefreshAvailability(): Promise<void> {\n\t\treturn this.queueAvailabilityRefresh(this.availabilityRefresh);\n\t}\n\n\tgetProviders(): readonly Provider[] {\n\t\treturn this.models.getProviders();\n\t}\n\n\tgetProvider(providerId: string): Provider | undefined {\n\t\treturn this.models.getProvider(providerId);\n\t}\n\n\tgetModels(providerId?: string): readonly Model<Api>[] {\n\t\treturn this.models.getModels(providerId);\n\t}\n\n\tgetModel(providerId: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.models.getModel(providerId, modelId);\n\t}\n\n\tasync checkAuth(providerId: string): Promise<AuthCheck | undefined> {\n\t\treturn this.models.checkAuth(providerId);\n\t}\n\n\tasync getAvailable(providerId?: string): Promise<readonly Model<Api>[]> {\n\t\tif (providerId) {\n\t\t\tif (this.availabilityRefresh) {\n\t\t\t\tawait this.availabilityRefresh;\n\t\t\t\treturn this.snapshot.available.filter((model) => model.provider === providerId);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn (await this.models.getAvailable(providerId)).filter((model) => this.isCatalogModelAvailable(model));\n\t\t\t} catch (error) {\n\t\t\t\tthis.availabilityError = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\tawait this.refreshAvailability();\n\t\treturn this.snapshot.available;\n\t}\n\n\tgetAvailableSnapshot(): readonly Model<Api>[] {\n\t\treturn this.snapshot.available;\n\t}\n\n\tgetError(): string | undefined {\n\t\tconst errors: string[] = [];\n\t\tconst configError = this.config.getError();\n\t\tif (configError) errors.push(configError);\n\t\tfor (const [providerId, error] of this.compositionErrors) {\n\t\t\terrors.push(`Provider \"${providerId}\": ${error}`);\n\t\t}\n\t\tif (this.availabilityError) errors.push(`Availability refresh: ${this.availabilityError}`);\n\t\treturn errors.length > 0 ? errors.join(\"\\n\\n\") : undefined;\n\t}\n\n\tgetRegisteredProviderConfig(providerId: string): ProviderConfigInput | undefined {\n\t\treturn this.extensionProviders.get(providerId);\n\t}\n\n\tgetRegisteredProviderIds(): readonly string[] {\n\t\treturn [...this.extensionProviders.keys()];\n\t}\n\n\t/** @internal Compatibility fallback for ModelRegistry when provider auth is unconfigured. */\n\tgetCompatibilityRequestConfig(model: Model<Api>): CompatibilityRequestConfig {\n\t\treturn resolveCompatibilityRequestConfig(\n\t\t\tmodel,\n\t\t\tthis.config.getProvider(model.provider),\n\t\t\tthis.extensionProviders.get(model.provider),\n\t\t);\n\t}\n\n\tisUsingOAuth(providerId: string): boolean {\n\t\treturn this.snapshot.auth.get(providerId)?.type === \"oauth\";\n\t}\n\n\thasConfiguredAuth(providerId: string): boolean {\n\t\treturn this.snapshot.configuredProviders.has(providerId);\n\t}\n\n\tgetAuth(providerId: string, overrides?: ModelRuntimeAuthOverrides): Promise<AuthResult | undefined>;\n\tgetAuth(model: Model<Api>, overrides?: ModelRuntimeAuthOverrides): Promise<AuthResult | undefined>;\n\tasync getAuth(\n\t\tproviderOrModel: string | Model<Api>,\n\t\toverrides: ModelRuntimeAuthOverrides = {},\n\t): Promise<AuthResult | undefined> {\n\t\tif (typeof providerOrModel === \"string\") return this.models.getAuth(providerOrModel, overrides);\n\t\tconst resolution = await this.models.getAuth(providerOrModel, overrides);\n\t\tif (!resolution) return undefined;\n\t\tconst configuredHeaders = resolveConfiguredModelHeaders(\n\t\t\tproviderOrModel,\n\t\t\tthis.config.getProvider(providerOrModel.provider),\n\t\t\tthis.extensionProviders.get(providerOrModel.provider),\n\t\t\t{ ...(resolution.env ?? {}), ...(overrides.env ?? {}) },\n\t\t);\n\t\treturn {\n\t\t\t...resolution,\n\t\t\tauth: {\n\t\t\t\t...resolution.auth,\n\t\t\t\theaders: mergeHeaders(resolution.auth.headers, configuredHeaders),\n\t\t\t},\n\t\t};\n\t}\n\n\t/** lunr: whether a runtime --api-key override is active for the provider (it shadows auth.json). */\n\thasRuntimeApiKey(providerId: string): boolean {\n\t\treturn this.credentials.hasRuntimeApiKey(providerId);\n\t}\n\n\tasync setRuntimeApiKey(providerId: string, apiKey: string, options?: { allowNetwork?: boolean }): Promise<void> {\n\t\tclearPlanUsageCache();\n\t\tthis.credentials.setRuntimeApiKey(providerId, apiKey);\n\t\tconst auth = new Map(this.snapshot.auth).set(providerId, { type: \"api_key\", source: \"runtime API key\" });\n\t\tconst configuredProviders = new Set(this.snapshot.configuredProviders).add(providerId);\n\t\tconst storedProviders = new Set(this.snapshot.storedProviders).add(providerId);\n\t\tthis.snapshot = {\n\t\t\t...this.snapshot,\n\t\t\tauth,\n\t\t\tconfiguredProviders,\n\t\t\tstoredProviders,\n\t\t\tavailable: this.snapshot.all.filter(\n\t\t\t\t(model) => configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t),\n\t\t};\n\t\tawait this.refresh({ allowNetwork: options?.allowNetwork ?? this.allowModelNetwork });\n\t}\n\n\tasync removeRuntimeApiKey(providerId: string): Promise<void> {\n\t\tclearPlanUsageCache();\n\t\tthis.credentials.removeRuntimeApiKey(providerId);\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t}\n\n\t/** lunr: whether network model-catalog fetches are allowed (offline mode disables them). */\n\tisNetworkAllowed(): boolean {\n\t\treturn this.allowModelNetwork;\n\t}\n\n\tlistCredentials(): Promise<readonly CredentialInfo[]> {\n\t\treturn this.credentials.list();\n\t}\n\n\tgetProviderAuthStatus(providerId: string): AuthStatus {\n\t\tif (this.credentials.hasRuntimeApiKey(providerId)) return { configured: true, source: \"runtime\" };\n\t\tif (this.snapshot.storedProviders.has(providerId)) return { configured: true, source: \"stored\" };\n\t\tconst configured = configuredRequestAuthStatus(\n\t\t\tthis.config.getProvider(providerId),\n\t\t\tthis.extensionProviders.get(providerId),\n\t\t);\n\t\tif (configured) return configured;\n\t\tconst check = this.snapshot.auth.get(providerId);\n\t\treturn check ? { configured: true, source: \"environment\", label: check.source } : { configured: false };\n\t}\n\n\tprivate async prepareRequest(\n\t\tmodel: Model<Api>,\n\t\toptions: (StreamOptions & ModelsStreamTransforms) | undefined,\n\t): Promise<{\n\t\tprovider: Provider;\n\t\tmodel: Model<Api>;\n\t\toptions: StreamOptions;\n\t\tsubscriptionKey?: RequestSubscriptionKey;\n\t}> {\n\t\tconst provider = this.models.getProvider(model.provider);\n\t\tif (!provider) throw new ModelsError(\"provider\", `Unknown provider: ${model.provider}`);\n\t\tlet storedKeyFingerprint: string | undefined;\n\t\tconst resolution = await this.credentials.withStoredApiKeyRead(\n\t\t\tmodel.provider,\n\t\t\t(apiKey) => {\n\t\t\t\tstoredKeyFingerprint = apiKey ? subscriptionKeyFingerprint(model.provider, apiKey) : undefined;\n\t\t\t},\n\t\t\t() => this.getAuth(model, { apiKey: options?.apiKey, env: options?.env }),\n\t\t);\n\t\tif (!resolution) throw new ModelsError(\"auth\", `Provider is not configured: ${model.provider}`);\n\n\t\tconst { transformHeaders, ...providerOptions } = options ?? {};\n\t\tconst route = anthropicRequestRoute(model.provider, resolution, options);\n\t\tlet headers = mergeHeaders(resolution.auth.headers, providerOptions.headers);\n\t\tif (transformHeaders) headers = await transformHeaders(headers ?? {});\n\t\tconst overridesAuth = Object.entries(headers ?? {}).some(\n\t\t\t([name, value]) =>\n\t\t\t\t/^(authorization|x-api-key|api-key|x-goog-api-key)$/i.test(name) &&\n\t\t\t\tvalue !== route.apiKey &&\n\t\t\t\tvalue !== `Bearer ${route.apiKey}`,\n\t\t);\n\t\tconst subscriptionKey =\n\t\t\troute.apiKey &&\n\t\t\toptions?.apiKey === undefined &&\n\t\t\tstoredKeyFingerprint === subscriptionKeyFingerprint(model.provider, route.apiKey) &&\n\t\t\t!overridesAuth\n\t\t\t\t? { providerId: model.provider, fingerprint: subscriptionKeyFingerprint(model.provider, route.apiKey) }\n\t\t\t\t: undefined;\n\t\tconst env =\n\t\t\tresolution.env || providerOptions.env\n\t\t\t\t? { ...(resolution.env ?? {}), ...(providerOptions.env ?? {}) }\n\t\t\t\t: undefined;\n\t\treturn {\n\t\t\tprovider,\n\t\t\tsubscriptionKey,\n\t\t\tmodel: resolution.auth.baseUrl ? { ...model, baseUrl: resolution.auth.baseUrl } : model,\n\t\t\toptions: {\n\t\t\t\t...providerOptions,\n\t\t\t\t...route,\n\t\t\t\theaders,\n\t\t\t\tenv,\n\t\t\t},\n\t\t};\n\t}\n\n\t/** The final response identity stays process-local and never enters saved chat. */\n\tgetRequestSubscriptionKey(message: AssistantMessage): RequestSubscriptionKey | undefined {\n\t\treturn this.requestSubscriptionKeys.get(message);\n\t}\n\n\tstream<TApi extends Api>(\n\t\tmodel: Model<TApi>,\n\t\tcontext: Context,\n\t\toptions?: ModelsApiStreamOptions<TApi>,\n\t): AssistantMessageEventStream {\n\t\tlet subscriptionKey: RequestSubscriptionKey | undefined;\n\t\tconst stream = lazyStream(model, async () => {\n\t\t\tconst prepared = await this.prepareRequest(\n\t\t\t\tmodel,\n\t\t\t\toptions as (StreamOptions & ModelsStreamTransforms) | undefined,\n\t\t\t);\n\t\t\tsubscriptionKey = prepared.subscriptionKey;\n\t\t\treturn prepared.provider.stream(\n\t\t\t\tprepared.model as Model<TApi>,\n\t\t\t\tcontext,\n\t\t\t\tprepared.options as ApiStreamOptions<TApi>,\n\t\t\t);\n\t\t});\n\t\tvoid stream.result().then((message) => {\n\t\t\tif (subscriptionKey) this.requestSubscriptionKeys.set(message, subscriptionKey);\n\t\t});\n\t\treturn stream;\n\t}\n\n\tcomplete<TApi extends Api>(\n\t\tmodel: Model<TApi>,\n\t\tcontext: Context,\n\t\toptions?: ModelsApiStreamOptions<TApi>,\n\t): Promise<AssistantMessage> {\n\t\treturn this.stream(model, context, options).result();\n\t}\n\n\tstreamSimple(model: Model<Api>, context: Context, options?: ModelsSimpleStreamOptions): AssistantMessageEventStream {\n\t\tlet subscriptionKey: RequestSubscriptionKey | undefined;\n\t\tconst stream = lazyStream(model, async () => {\n\t\t\tconst prepared = await this.prepareRequest(model, options);\n\t\t\tsubscriptionKey = prepared.subscriptionKey;\n\t\t\treturn prepared.provider.streamSimple(prepared.model, context, prepared.options as SimpleStreamOptions);\n\t\t});\n\t\tvoid stream.result().then((message) => {\n\t\t\tif (subscriptionKey) this.requestSubscriptionKeys.set(message, subscriptionKey);\n\t\t});\n\t\treturn stream;\n\t}\n\n\tcompleteSimple(model: Model<Api>, context: Context, options?: ModelsSimpleStreamOptions): Promise<AssistantMessage> {\n\t\treturn this.streamSimple(model, context, options).result();\n\t}\n\n\tasync login(providerId: string, type: AuthType, interaction: AuthInteraction): Promise<Credential> {\n\t\tclearPlanUsageCache();\n\t\tconst credential = await this.models.login(providerId, type, interaction);\n\t\tclearPlanUsageCache();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t\treturn credential;\n\t}\n\n\tasync logout(providerId: string): Promise<void> {\n\t\tclearPlanUsageCache();\n\t\tawait this.models.logout(providerId);\n\t\tawait this.modelsStore.delete(providerId);\n\t\tthis.userModels.evictProvider(providerId);\n\t\tthis.overlay.setLive(providerId, []);\n\t\t// Reset credential-dependent compatibility projections before the unconfigured provider is skipped by refresh.\n\t\tthis.recomposeProvider(providerId);\n\t\tclearPlanUsageCache();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t}\n\n\t/** Copy a live Grok CLI SuperGrok session into lunR `auth.json`. */\n\tasync importGrokCliXaiAuth(): Promise<Credential | undefined> {\n\t\tconst grok = readGrokCliXaiOAuth({ grokHome: this.grokHome });\n\t\tif (!grok) return undefined;\n\t\tconst stored = await this.credentials.modify(\"xai\", async () => grok);\n\t\tclearPlanUsageCache();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t\treturn stored;\n\t}\n\n\tasync reloadConfig(): Promise<void> {\n\t\tthis.config = await ModelConfig.load(this.modelsPath);\n\t\tthis.configureRadiusProviders();\n\t\tthis.rebuildProviders();\n\t\tawait this.refresh({ allowNetwork: this.allowModelNetwork });\n\t}\n\n\tasync refresh(options: ModelsRefreshOptions = {}): Promise<CatalogRefreshResult> {\n\t\tconst allowNetwork = options.allowNetwork ?? this.allowModelNetwork;\n\t\tif (this.catalogRefresh) {\n\t\t\t// Join an in-flight refresh that is at least as capable. A cache-only\n\t\t\t// flight must not swallow a later network refresh.\n\t\t\tif (this.catalogRefreshAllowsNetwork || !allowNetwork) {\n\t\t\t\treturn this.catalogRefresh;\n\t\t\t}\n\t\t\tawait this.catalogRefresh.catch(() => {});\n\t\t\treturn this.refresh({ ...options, allowNetwork });\n\t\t}\n\n\t\tconst run = this.executeCatalogRefresh({ ...options, allowNetwork }).finally(() => {\n\t\t\tif (this.catalogRefresh === run) {\n\t\t\t\tthis.catalogRefresh = undefined;\n\t\t\t\tthis.catalogRefreshAllowsNetwork = false;\n\t\t\t}\n\t\t});\n\t\tthis.catalogRefresh = run;\n\t\tthis.catalogRefreshAllowsNetwork = allowNetwork;\n\t\treturn run;\n\t}\n\n\tprivate async executeCatalogRefresh(\n\t\trefreshOptions: ModelsRefreshOptions & { allowNetwork: boolean },\n\t): Promise<CatalogRefreshResult> {\n\t\tconst official = await this.refreshOfficialCatalog(refreshOptions.allowNetwork, refreshOptions.signal);\n\t\tconst live = refreshOptions.allowNetwork\n\t\t\t? await this.refreshLiveCatalogs(\n\t\t\t\t\tofficial ? officialModelKeys(official.catalog) : new Set(),\n\t\t\t\t\trefreshOptions.signal,\n\t\t\t\t)\n\t\t\t: await this.restoreLiveCatalogs();\n\n\t\t// Radius / local-provider / extension refreshModels hooks. Live-list\n\t\t// providers have no refreshModels, so this does not hit pi.dev.\n\t\tconst result = ((await this.models.refresh(refreshOptions)) as ModelsRefreshResult | undefined) ?? {\n\t\t\taborted: refreshOptions.signal?.aborted ?? false,\n\t\t\terrors: new Map(),\n\t\t};\n\t\tconst errors = new Map(result.errors);\n\t\tfor (const [id, error] of Object.entries(official?.errors ?? {})) errors.set(id, new Error(error));\n\t\tfor (const entry of live) {\n\t\t\tif (entry.status === \"error\" || entry.status === \"timeout\") {\n\t\t\t\terrors.set(entry.providerId, new Error(entry.error ?? entry.status));\n\t\t\t}\n\t\t}\n\t\tthis.updateModelSnapshot();\n\t\ttry {\n\t\t\tawait this.forceRefreshAvailability();\n\t\t} catch {\n\t\t\t// Availability errors are recorded by forceRefreshAvailability; refreshed models remain usable.\n\t\t}\n\t\tconst catalogResult: CatalogRefreshResult = {\n\t\t\taborted: result.aborted,\n\t\t\terrors,\n\t\t\tofficial,\n\t\t\tlive,\n\t\t\tincomplete: live.flatMap((entry) => entry.incomplete),\n\t\t};\n\t\tthis.lastCatalogRefresh = catalogResult;\n\t\treturn catalogResult;\n\t}\n\n\tgetLastCatalogRefresh(): CatalogRefreshResult {\n\t\treturn this.lastCatalogRefresh;\n\t}\n\n\t/** Called after first paint and by the picker; explicit /refresh always bypasses this gate. */\n\tasync refreshIfStale(options: { signal?: AbortSignal } = {}): Promise<CatalogRefreshResult> {\n\t\tif (!this.allowModelNetwork || options.signal?.aborted) return this.lastCatalogRefresh;\n\t\tif (this.catalogRefresh) return this.refresh({ allowNetwork: true, signal: options.signal });\n\t\tconst providers = [...(await this.listStoredProviderIds())].sort();\n\t\tconst identity = (await Promise.all(providers.map(async (id) => this.scopeFor(id)))).join(\":\");\n\t\tif (identity === this.automaticRefreshIdentity && Date.now() < this.nextAutomaticRefresh)\n\t\t\treturn this.lastCatalogRefresh;\n\t\tthis.automaticRefreshIdentity = identity;\n\t\t// Bound retries on a broken source; a successful refresh extends the deadline to one hour.\n\t\tthis.nextAutomaticRefresh = Date.now() + 60_000;\n\t\tconst result = await this.refresh({ allowNetwork: true, signal: options.signal });\n\t\tif (!result.aborted && !result.errors.size) this.nextAutomaticRefresh = Date.now() + 3_600_000;\n\t\treturn result;\n\t}\n\n\tprivate async scopeFor(providerId: string): Promise<string> {\n\t\tconst provider = this.models.getProvider(providerId) ?? this.defaultBuiltins.get(providerId);\n\t\treturn catalogCacheScope(providerId, provider?.baseUrl ?? \"\", await this.credentials.read(providerId));\n\t}\n\n\tpersistUserModels(rows: readonly UserModelEntry[]): void {\n\t\tthis.userModels.upsert(rows);\n\t\tthis.overlay.setUser(this.userModelsForStoredProviders(this.snapshot.storedProviders));\n\t\tthis.updateModelSnapshot();\n\t}\n\n\tprivate async refreshOfficialCatalog(\n\t\tallowNetwork: boolean,\n\t\tsignal?: AbortSignal,\n\t): Promise<(OfficialCatalogLoadResult & { evictedUserRows: number }) | undefined> {\n\t\tconst storedProviders = await this.listStoredProviderIds();\n\t\tconst loaded = preferOfficialCatalog(\n\t\t\tthis.lastOfficial,\n\t\t\tawait loadOfficialCatalog({\n\t\t\t\tallowNetwork,\n\t\t\t\tcachePath: this.officialCachePath,\n\t\t\t\tsignal,\n\t\t\t\tproviderIds: [...storedProviders],\n\t\t\t}),\n\t\t);\n\t\tthis.lastOfficial = loaded;\n\t\tconst evicted = this.userModels.evictOfficial(officialModelKeys(loaded.catalog));\n\t\tconst templateByProvider = new Map<string, Model<Api> | undefined>();\n\t\tconst officialModels = loaded.catalog.models\n\t\t\t.filter((entry) => storedProviders.has(entry.provider))\n\t\t\t.map((entry) => {\n\t\t\t\tif (!templateByProvider.has(entry.provider)) {\n\t\t\t\t\ttemplateByProvider.set(entry.provider, this.bakedInModels(entry.provider)[0]);\n\t\t\t\t}\n\t\t\t\treturn officialEntryToModel(entry, templateByProvider.get(entry.provider));\n\t\t\t});\n\t\tthis.overlay.setOfficial(officialModels);\n\t\tthis.overlay.setUser(this.userModelsForStoredProviders(storedProviders));\n\t\treturn { ...loaded, evictedUserRows: evicted.length };\n\t}\n\n\tprivate async restoreLiveCatalogs(): Promise<LiveCatalogResult[]> {\n\t\tconst storedProviders = await this.listStoredProviderIds();\n\t\tconst results: LiveCatalogResult[] = [];\n\t\tfor (const providerId of LIVE_LIST_PROVIDER_IDS) {\n\t\t\tconst stored = storedProviders.has(providerId) ? await this.modelsStore.read(providerId) : undefined;\n\t\t\tconst valid =\n\t\t\t\t(!stored?.scope && providerId !== \"openai-codex\") || stored?.scope === (await this.scopeFor(providerId));\n\t\t\tif (valid && stored?.models) this.overlay.setLive(providerId, stored.models);\n\t\t\telse this.overlay.setLive(providerId, []);\n\t\t\tresults.push({\n\t\t\t\tproviderId,\n\t\t\t\tstatus: \"skipped\",\n\t\t\t\tdiscoveries: [],\n\t\t\t\tadded: 0,\n\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\tincomplete: [],\n\t\t\t});\n\t\t}\n\t\treturn results;\n\t}\n\n\tprivate async refreshLiveCatalogs(officialKeys: Set<string>, signal?: AbortSignal): Promise<LiveCatalogResult[]> {\n\t\tconst storedProviders = await this.listStoredProviderIds();\n\t\tconst known = knownModelKeys(\n\t\t\tLIVE_LIST_PROVIDER_IDS.flatMap((id) => this.bakedInModels(id)),\n\t\t\tofficialKeys,\n\t\t\tthis.userModels.keys(),\n\t\t);\n\n\t\tconst results = await Promise.all(\n\t\t\tLIVE_LIST_PROVIDER_IDS.map(async (providerId) => {\n\t\t\t\tif (!storedProviders.has(providerId)) {\n\t\t\t\t\tthis.overlay.setLive(providerId, []);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst stored = await this.modelsStore.read(providerId);\n\t\t\t\tconst initialScope = await this.scopeFor(providerId);\n\t\t\t\tif (stored?.models && (stored.scope === initialScope || (!stored.scope && providerId !== \"openai-codex\")))\n\t\t\t\t\tthis.overlay.setLive(providerId, stored.models);\n\t\t\t\telse this.overlay.setLive(providerId, []);\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t\terror: \"aborted\",\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst bakedIn = this.bakedInModels(providerId);\n\t\t\t\tconst provider = this.models.getProvider(providerId) ?? this.defaultBuiltins.get(providerId);\n\t\t\t\tconst baseUrl = provider?.baseUrl ?? bakedIn[0]?.baseUrl;\n\t\t\t\tif (!baseUrl) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tlet credential: Credential | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tcredential = await this.refreshCredentialFor(providerId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (!credential) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\tstatus: \"skipped\" as const,\n\t\t\t\t\t\tdiscoveries: [],\n\t\t\t\t\t\tadded: 0,\n\t\t\t\t\t\ttotal: stored?.models.length ?? 0,\n\t\t\t\t\t\tincomplete: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst requestScope = catalogCacheScope(providerId, baseUrl, credential);\n\t\t\t\tconst result = await fetchLiveProviderModels({\n\t\t\t\t\tdiscoveryClientVersion: stored?.scope === requestScope ? stored.discoveryClientVersion : undefined,\n\t\t\t\t\tproviderId,\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\tbakedIn,\n\t\t\t\t\tcredential,\n\t\t\t\t\tknownKeys: known,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\t// A login/logout during the request must not install the previous account's result.\n\t\t\t\tconst accountChanged = (await this.scopeFor(providerId)) !== requestScope;\n\t\t\t\tif (accountChanged) this.overlay.setLive(providerId, []);\n\t\t\t\tif (signal?.aborted || accountChanged) {\n\t\t\t\t\treturn { ...result, status: \"skipped\" as const, discoveries: [], incomplete: [] };\n\t\t\t\t}\n\t\t\t\tif (result.status === \"ok\") {\n\t\t\t\t\tconst overlayModels = buildLiveOverlay(bakedIn, result.discoveries);\n\t\t\t\t\tthis.overlay.setLive(providerId, overlayModels);\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this.modelsStore.write(providerId, {\n\t\t\t\t\t\t\tmodels: overlayModels,\n\t\t\t\t\t\t\tcheckedAt: Date.now(),\n\t\t\t\t\t\t\tscope: requestScope,\n\t\t\t\t\t\t\tdiscoveryClientVersion: result.discoveryClientVersion,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Store write is best-effort.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}),\n\t\t);\n\t\treturn results;\n\t}\n\n\tprivate async refreshCredentialFor(providerId: string): Promise<Credential | undefined> {\n\t\t// Same lock + persist path as chat. Returning stored OAuth here skips\n\t\t// refresh and sends expired SuperGrok tokens to GET /models (HTTP 403).\n\t\tconst resolved = await this.getAuth(providerId);\n\t\tconst stored = await this.credentials.read(providerId);\n\t\tif (stored?.type === \"oauth\") return { ...stored, access: resolved?.auth.apiKey ?? stored.access };\n\t\tif (resolved?.auth.apiKey) return { type: \"api_key\", key: resolved.auth.apiKey, env: resolved.env };\n\t\tif (stored?.type === \"api_key\" && stored.key) return stored;\n\t\treturn undefined;\n\t}\n\n\tregisterProvider(providerId: string, config: ProviderConfigInput): void {\n\t\t// Validate the incoming registration on its own, like the legacy registry:\n\t\t// a broken re-registration must throw without touching the stored config.\n\t\tvalidateExtensionProvider(providerId, this.builtins.get(providerId), this.config.getProvider(providerId), config);\n\t\t// Re-registration merges defined values over the previous registration and\n\t\t// preserves undefined ones, matching the legacy ModelRegistry contract.\n\t\tconst previous = this.extensionProviders.get(providerId);\n\t\tconst effective: ProviderConfigInput = { ...previous };\n\t\tfor (const [key, value] of Object.entries(config)) {\n\t\t\tif (value !== undefined) (effective as Record<string, unknown>)[key] = value;\n\t\t}\n\t\tthis.extensionProviders.set(providerId, effective);\n\t\tthis.recomposeProvider(providerId);\n\t\tthis.updateModelSnapshot();\n\t\tif (\n\t\t\tthis.snapshot.storedProviders.has(providerId) ||\n\t\t\tconfiguredRequestAuthStatus(this.config.getProvider(providerId), effective)?.configured\n\t\t) {\n\t\t\tconst configuredProviders = new Set(this.snapshot.configuredProviders).add(providerId);\n\t\t\tconst auth = new Map(this.snapshot.auth);\n\t\t\t// Provisional entry until the async refresh lands; never clobber a real check result.\n\t\t\tif (!auth.get(providerId)) {\n\t\t\t\tauth.set(providerId, {\n\t\t\t\t\ttype: effective.oauth && !effective.apiKey ? \"oauth\" : \"api_key\",\n\t\t\t\t\tsource: \"configured provider\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.snapshot = {\n\t\t\t\t...this.snapshot,\n\t\t\t\tauth,\n\t\t\t\tconfiguredProviders,\n\t\t\t\tavailable: this.snapshot.all.filter(\n\t\t\t\t\t(model) => configuredProviders.has(model.provider) && this.isCatalogModelAvailable(model),\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t\tvoid this.refresh({ allowNetwork: false });\n\t}\n\n\tunregisterProvider(providerId: string): void {\n\t\tthis.extensionProviders.delete(providerId);\n\t\tthis.recomposeProvider(providerId);\n\t\tthis.updateModelSnapshot();\n\t\tvoid this.refresh({ allowNetwork: false });\n\t}\n}\n\n/** TUI init / footer / rebind: cache-only. Live refresh is `/refresh` and the model picker. */\nexport async function refreshModelCandidatesForInit(\n\truntime: Pick<ModelRuntime, \"refresh\" | \"getAvailableSnapshot\">,\n): Promise<readonly Model<Api>[]> {\n\tawait runtime.refresh({ allowNetwork: false });\n\treturn runtime.getAvailableSnapshot();\n}\n"]}
|