@ashx-j/lunr 0.2.26 → 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 +16 -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/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/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.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +10 -2
- 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 +8 -1
- 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 +106 -24
- 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/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/render.d.ts +1 -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 +17 -8
- 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.map +1 -1
- package/dist/core/computer-use/adapter.js +7 -2
- package/dist/core/computer-use/adapter.js.map +1 -1
- package/dist/core/computer-use/image.d.ts.map +1 -1
- package/dist/core/computer-use/image.js +17 -5
- package/dist/core/computer-use/image.js.map +1 -1
- package/dist/core/computer-use/schemas.d.ts.map +1 -1
- package/dist/core/computer-use/schemas.js +23 -6
- package/dist/core/computer-use/schemas.js.map +1 -1
- package/dist/core/computer-use/workflow.d.ts.map +1 -1
- package/dist/core/computer-use/workflow.js +459 -119
- package/dist/core/computer-use/workflow.js.map +1 -1
- 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/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 +3 -3
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +11 -35
- 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 +126 -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/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/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/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 +10 -4
- 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 +65 -56
- package/dist/gateway/cron.js.map +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +2 -1
- 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 +56 -14
- 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 +73 -38
- 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 +17 -2
- 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/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/interactive-mode.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +96 -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/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-VFG7WNPX.js → adapter-247RTYLS.js} +4 -5
- 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-I2HIFEMY.js → builtin-extensions-OX6KELNX.js} +8 -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-SPVDBUOS.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-WIF24I7G.js → chunk-APVM5NEU.js} +149 -144
- package/dist/node-runtime/{chunk-RCR3XAQY.js → chunk-AYHH7YSD.js} +177 -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-UVWCDQYF.js → chunk-C3P6Q3B2.js} +455 -278
- package/dist/node-runtime/{chunk-SN2KSMPQ.js → chunk-DQSCFU7R.js} +13 -7
- package/dist/node-runtime/{chunk-4SBQAI4T.js → chunk-EBLAZVSA.js} +2058 -73
- 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-IKU6Y7DL.js → chunk-FE3WZI7F.js} +9 -6
- 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-RGQAEOM5.js → chunk-FYIFPFXE.js} +23 -6
- 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-I74LN5JG.js → chunk-HUD2RFJW.js} +2 -2
- package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
- package/dist/node-runtime/{chunk-XHIRAZ26.js → chunk-IAZSK7KK.js} +1 -1
- package/dist/node-runtime/{chunk-X3PGBLQ7.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-L24TPBS4.js → chunk-JWEVT363.js} +37 -29
- 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-T4DA4XE7.js → chunk-MQPKUHRN.js} +162 -82
- 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-P7XBVXGT.js → chunk-QNVMKNNN.js} +18 -14
- package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
- package/dist/node-runtime/{chunk-DVQSHCVP.js → chunk-R4WSB2MQ.js} +5 -5
- package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
- package/dist/node-runtime/{chunk-2CFDTH5B.js → chunk-RLGY2QIL.js} +45 -59
- package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
- package/dist/node-runtime/{chunk-5Q4A37RB.js → chunk-TCT6PCUR.js} +32 -11
- package/dist/node-runtime/{chunk-D5UCKPBQ.js → chunk-UBWW2PID.js} +1 -1
- package/dist/node-runtime/{chunk-E75WFZ33.js → chunk-UNUZICC4.js} +3 -3
- package/dist/node-runtime/{chunk-RAK2QA2B.js → chunk-UYRKUKFE.js} +4 -4
- package/dist/node-runtime/{chunk-LWJXTA6Z.js → chunk-VSUEAI7O.js} +1377 -45
- 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-LJTIVM7I.js → chunk-ZDJUR45D.js} +427 -126
- package/dist/node-runtime/{chunk-YWOJIGFY.js → chunk-ZEVFBFNF.js} +95 -142
- package/dist/node-runtime/{chunk-5B6VKFEV.js → chunk-ZIQUS5QO.js} +1 -1
- package/dist/node-runtime/cli-runtime.js +4 -4
- package/dist/node-runtime/{command-FSBU2EVZ.js → command-3HMSY6W2.js} +5 -5
- package/dist/node-runtime/{commands-EMBQQVVT.js → commands-D6A6H4TS.js} +11 -18
- package/dist/node-runtime/{commands-NAAL7KNT.js → commands-OCSSEEWJ.js} +16 -16
- 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-4D7UXYU4.js → direct-tool-executor-2QJXVQD2.js} +6 -11
- 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-DQM333YV.js → gateway-6623C2U3.js} +51 -42
- 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 +50 -48
- package/dist/node-runtime/{init-P5AUV77I.js → init-JBQJIPYI.js} +3 -6
- package/dist/node-runtime/{install-cli-NN4YAU44.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-Y23CCDIJ.js → lunr-computer-use-VDP2QNRQ.js} +9 -9
- package/dist/node-runtime/{lunr-cron-USHC4LXH.js → lunr-cron-LKVA5CZZ.js} +93 -80
- package/dist/node-runtime/main.js +42 -41
- package/dist/node-runtime/{mobile-commands-O5LCHL32.js → mobile-commands-XT3NQXLD.js} +12 -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-Q7BL6KZO.js → package-manager-cli-CYM262SI.js} +20 -20
- 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-3PHF4KZ4.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-7IBSSGEW.js → pi-subagents-LT3CTO4E.js} +98 -106
- package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
- package/dist/node-runtime/{print-mode-XQ76CYMT.js → print-mode-2XHN5SUA.js} +3 -3
- package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
- package/dist/node-runtime/{proxy-modes-5FAPSZEZ.js → proxy-modes-VEGC6QG5.js} +8 -15
- package/dist/node-runtime/rpc-entry.js +42 -41
- 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-EFPPD2UW.js → runtime-UGXM4NPQ.js} +2 -2
- package/dist/node-runtime/{runtime-bridges-7WVCLI76.js → runtime-bridges-DNKMNJCF.js} +7 -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-DJDM5AHM.js → settings-manager-P2TKGYTR.js} +5 -5
- package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
- package/dist/node-runtime/{setup-PFBWRNUI.js → setup-OLQ4GXWS.js} +17 -17
- package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
- package/dist/node-runtime/{subagent-executor-LPZ4BHWE.js → subagent-executor-Q5F7DBVM.js} +119 -58
- 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-HNMOTNGX.js → update-cli-F3XXJANQ.js} +6 -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-OHPBEFO4.js → workflow-ICDI4N3J.js} +208 -78
- 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.map +1 -1
- package/dist/utils/image-resize-core.js +2 -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/custom-provider.md +3 -3
- package/docs/extensions.md +8 -4
- package/docs/features.md +15 -7
- 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 +24 -24
- package/install-lock/package.json +2 -2
- package/npm-shrinkwrap.json +60 -24
- package/package.json +9 -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-5YXS2PLF.js +0 -51
- package/dist/node-runtime/chunk-2IDTZAG5.js +0 -1415
- package/dist/node-runtime/chunk-3MISGG4S.js +0 -769
- package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
- package/dist/node-runtime/chunk-5B5QN3ZQ.js +0 -356
- package/dist/node-runtime/chunk-7IQGBKBJ.js +0 -2033
- package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
- package/dist/node-runtime/chunk-PTFBPO3C.js +0 -50
- package/dist/node-runtime/interactive-mode-YOHZVMKX.js +0 -74
- package/dist/node-runtime/mcp-auth-flow-QVLFVLEO.js +0 -33
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/core/update-check.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACvD,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,cAAc,GAAG,8BAA8B,eAAe,SAAS,CAAC;AAerF,MAAM,UAAU,kBAAkB,
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/core/update-check.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Published-install version check against the npm registry for @ashx-j/lunr.\n * Workspace checkouts (PACKAGE_NAME !== NPM_CLI_PACKAGE) never nag or self-update.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { gt } from \"semver\";\nimport { NPM_CLI_PACKAGE, PACKAGE_NAME } from \"../config.ts\";\n\nexport const UPDATE_CHECK_TTL_MS = 24 * 60 * 60 * 1000;\nexport const UPDATE_CHECK_TIMEOUT_MS = 4000;\nexport const NPM_LATEST_URL = `https://registry.npmjs.org/${NPM_CLI_PACKAGE}/latest`;\n\nexport interface UpdateCheckRecord {\n\tcheckedAt: number;\n\tlatest: string;\n\tnotifiedVersion?: string;\n}\n\nexport interface UpdateCheckResult {\n\tlatest: string;\n\tcurrent: string;\n\tnewer: boolean;\n\tnotice?: string;\n}\n\nexport function isPublishedInstall(packageName: string = PACKAGE_NAME, npmName: string = NPM_CLI_PACKAGE): boolean {\n\treturn packageName === npmName;\n}\n\nexport function updateCheckPath(agentDir: string): string {\n\treturn join(agentDir, \"update-check.json\");\n}\n\nfunction readRecord(path: string): UpdateCheckRecord | undefined {\n\ttry {\n\t\tconst raw = JSON.parse(readFileSync(path, \"utf8\")) as UpdateCheckRecord;\n\t\tif (typeof raw.checkedAt !== \"number\" || typeof raw.latest !== \"string\" || !raw.latest.trim()) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tcheckedAt: raw.checkedAt,\n\t\t\tlatest: raw.latest.trim(),\n\t\t\tnotifiedVersion: typeof raw.notifiedVersion === \"string\" ? raw.notifiedVersion : undefined,\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction writeRecord(path: string, record: UpdateCheckRecord): void {\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, `${JSON.stringify(record)}\\n`, \"utf8\");\n}\n\nasync function fetchLatest(fetchImpl: typeof fetch): Promise<string | undefined> {\n\tconst controller = new AbortController();\n\tconst timeout = setTimeout(() => controller.abort(), UPDATE_CHECK_TIMEOUT_MS);\n\ttry {\n\t\tconst response = await fetchImpl(NPM_LATEST_URL, {\n\t\t\theaders: { Accept: \"application/json\" },\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!response.ok) return undefined;\n\t\tconst payload = (await response.json()) as { version?: unknown };\n\t\treturn typeof payload.version === \"string\" && payload.version.trim() ? payload.version.trim() : undefined;\n\t} catch {\n\t\treturn undefined;\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n}\n\nexport async function checkForUpdate(options: {\n\tcurrentVersion: string;\n\tagentDir: string;\n\tnow?: number;\n\tfetchImpl?: typeof fetch;\n\tpublished?: boolean;\n\toffline?: boolean;\n\tforce?: boolean;\n}): Promise<UpdateCheckResult | undefined> {\n\tif (options.offline) return undefined;\n\tif (!(options.published ?? isPublishedInstall())) return undefined;\n\n\tconst now = options.now ?? Date.now();\n\tconst path = updateCheckPath(options.agentDir);\n\tlet record = existsSync(path) ? readRecord(path) : undefined;\n\tconst stale = !record || now - record.checkedAt >= UPDATE_CHECK_TTL_MS || options.force;\n\tif (stale) {\n\t\tconst latest = await fetchLatest(options.fetchImpl ?? fetch);\n\t\tif (!latest) return record ? toResult(options.currentVersion, record, false) : undefined;\n\t\trecord = { checkedAt: now, latest, notifiedVersion: record?.notifiedVersion };\n\t\ttry {\n\t\t\twriteRecord(path, record);\n\t\t} catch {\n\t\t\t// Cache write is best-effort.\n\t\t}\n\t}\n\n\tif (!record) return undefined;\n\treturn toResult(options.currentVersion, record, true);\n}\n\nfunction isNewer(latest: string, current: string): boolean {\n\ttry {\n\t\treturn gt(latest, current);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction toResult(current: string, record: UpdateCheckRecord, allowNotice: boolean): UpdateCheckResult {\n\tconst newer = isNewer(record.latest, current);\n\tconst notice =\n\t\tallowNotice && newer && record.notifiedVersion !== record.latest\n\t\t\t? `lunR ${record.latest} is available. Run lunr update.`\n\t\t\t: undefined;\n\treturn { latest: record.latest, current, newer, notice };\n}\n\n/** Persist that we already showed the TUI notice for this latest version. */\nexport function markUpdateNotified(agentDir: string, latest: string): void {\n\tconst path = updateCheckPath(agentDir);\n\tconst record = existsSync(path) ? readRecord(path) : undefined;\n\tif (!record) return;\n\trecord.notifiedVersion = latest;\n\ttry {\n\t\twriteRecord(path, record);\n\t} catch {\n\t\t// ignore\n\t}\n}\n"]}
|
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
* limits: [{ window: { duration, timeUnit }, detail: { limit, remaining, resetTime } }] }
|
|
7
7
|
*/
|
|
8
8
|
import type { ModelRuntime } from "../model-runtime.ts";
|
|
9
|
-
import type { PlanUsage } from "../usage-service.ts";
|
|
10
|
-
export declare function fetchKimiPlanUsage(runtime: ModelRuntime): Promise<PlanUsage | undefined>;
|
|
9
|
+
import type { PlanUsage, UsageAuthSnapshot } from "../usage-service.ts";
|
|
10
|
+
export declare function fetchKimiPlanUsage(runtime: ModelRuntime, auth?: UsageAuthSnapshot): Promise<PlanUsage | undefined>;
|
|
11
11
|
//# sourceMappingURL=kimi-coding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kimi-coding.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/kimi-coding.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"kimi-coding.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/kimi-coding.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAuCzF,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,YAAY,EACrB,IAAI,CAAC,EAAE,iBAAiB,GACtB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CA4BhC","sourcesContent":["/**\n * Kimi for Coding plan usage: `GET https://api.kimi.com/coding/v1/usages`\n * with the stored API key (Bearer). Response shape (undocumented, mirrors\n * other open-source quota dashboards):\n * { usage: { limit, remaining, resetTime },\n * limits: [{ window: { duration, timeUnit }, detail: { limit, remaining, resetTime } }] }\n */\n\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport { asNumber, asObject, fetchWithTimeout, toEpochMs, usedPercentFromRemaining } from \"./shared.ts\";\n\nconst KIMI_PROVIDER_ID = \"kimi-coding\";\nconst KIMI_USAGE_URL = \"https://api.kimi.com/coding/v1/usages\";\n\nconst TIME_UNIT_SECONDS: Record<string, number> = {\n\tseconds: 1,\n\tsecond: 1,\n\tminutes: 60,\n\tminute: 60,\n\thours: 3600,\n\thour: 3600,\n\tdays: 86400,\n\tday: 86400,\n\tweeks: 604800,\n\tweek: 604800,\n};\n\nfunction durationLabel(duration: unknown, timeUnit: unknown): string {\n\tconst amount = asNumber(duration);\n\tconst unit = typeof timeUnit === \"string\" ? timeUnit.toLowerCase() : undefined;\n\tconst seconds = amount !== undefined && unit ? TIME_UNIT_SECONDS[unit] : undefined;\n\tif (amount === undefined || seconds === undefined) return \"Limit\";\n\tconst totalSeconds = amount * seconds;\n\tif (totalSeconds >= 604800) return \"Weekly\";\n\tif (totalSeconds >= 86400) return `${Math.round(totalSeconds / 86400)}d`;\n\tif (totalSeconds >= 3600) return `${Math.round(totalSeconds / 3600)}h`;\n\treturn `${Math.max(1, Math.round(totalSeconds / 60))}m`;\n}\n\nfunction detailWindow(label: string, detail: unknown): PlanUsageWindow | undefined {\n\tconst object = asObject(detail);\n\tif (!object) return undefined;\n\tconst usedPercent = usedPercentFromRemaining(object.limit, object.remaining);\n\tif (usedPercent === undefined) return undefined;\n\treturn { label, usedPercent, resetsAt: toEpochMs(object.resetTime) };\n}\n\nexport async function fetchKimiPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage | undefined> {\n\tconst resolution = auth ? auth.resolution : await runtime.getAuth(KIMI_PROVIDER_ID);\n\tconst apiKey = resolution?.auth.apiKey;\n\tif (!apiKey) return undefined;\n\n\tconst response = await fetchWithTimeout(KIMI_USAGE_URL, {\n\t\theaders: { Authorization: `Bearer ${apiKey}`, Accept: \"application/json\" },\n\t});\n\tif (!response.ok) return undefined;\n\tconst payload = asObject(await response.json());\n\tif (!payload) return undefined;\n\n\tconst windows: PlanUsageWindow[] = [];\n\t// Top-level `usage` is the weekly quota; `limits[]` carries the short rate window.\n\tconst weekly = detailWindow(\"Weekly\", payload.usage);\n\tif (weekly) windows.push(weekly);\n\tconst limits = Array.isArray(payload.limits) ? payload.limits : [];\n\tfor (const item of limits) {\n\t\tconst limit = asObject(item);\n\t\tif (!limit) continue;\n\t\tconst window = detailWindow(\n\t\t\tdurationLabel(asObject(limit.window)?.duration, asObject(limit.window)?.timeUnit),\n\t\t\tlimit.detail,\n\t\t);\n\t\tif (window) windows.push(window);\n\t}\n\tif (windows.length === 0) return undefined;\n\treturn { provider: KIMI_PROVIDER_ID, windows };\n}\n"]}
|
|
@@ -44,8 +44,8 @@ function detailWindow(label, detail) {
|
|
|
44
44
|
return undefined;
|
|
45
45
|
return { label, usedPercent, resetsAt: toEpochMs(object.resetTime) };
|
|
46
46
|
}
|
|
47
|
-
export async function fetchKimiPlanUsage(runtime) {
|
|
48
|
-
const resolution = await runtime.getAuth(KIMI_PROVIDER_ID);
|
|
47
|
+
export async function fetchKimiPlanUsage(runtime, auth) {
|
|
48
|
+
const resolution = auth ? auth.resolution : await runtime.getAuth(KIMI_PROVIDER_ID);
|
|
49
49
|
const apiKey = resolution?.auth.apiKey;
|
|
50
50
|
if (!apiKey)
|
|
51
51
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kimi-coding.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/kimi-coding.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAExG,MAAM,gBAAgB,GAAG,aAAa,CAAC;AACvC,MAAM,cAAc,GAAG,uCAAuC,CAAC;AAE/D,MAAM,iBAAiB,GAA2B;IACjD,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,EAAE;IACX,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,MAAM;CACZ,CAAC;AAEF,SAAS,aAAa,CAAC,QAAiB,EAAE,QAAiB,EAAU;IACpE,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,MAAM,OAAO,GAAG,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnF,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IAClE,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;IACtC,IAAI,YAAY,IAAI,MAAM;QAAE,OAAO,QAAQ,CAAC;IAC5C,IAAI,YAAY,IAAI,KAAK;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC;IACzE,IAAI,YAAY,IAAI,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC;IACvE,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;AAAA,CACxD;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,MAAe,EAA+B;IAClF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,WAAW,GAAG,wBAAwB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAChD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;AAAA,CACrE;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,
|
|
1
|
+
{"version":3,"file":"kimi-coding.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/kimi-coding.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Kimi for Coding plan usage: `GET https://api.kimi.com/coding/v1/usages`\n * with the stored API key (Bearer). Response shape (undocumented, mirrors\n * other open-source quota dashboards):\n * { usage: { limit, remaining, resetTime },\n * limits: [{ window: { duration, timeUnit }, detail: { limit, remaining, resetTime } }] }\n */\n\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport { asNumber, asObject, fetchWithTimeout, toEpochMs, usedPercentFromRemaining } from \"./shared.ts\";\n\nconst KIMI_PROVIDER_ID = \"kimi-coding\";\nconst KIMI_USAGE_URL = \"https://api.kimi.com/coding/v1/usages\";\n\nconst TIME_UNIT_SECONDS: Record<string, number> = {\n\tseconds: 1,\n\tsecond: 1,\n\tminutes: 60,\n\tminute: 60,\n\thours: 3600,\n\thour: 3600,\n\tdays: 86400,\n\tday: 86400,\n\tweeks: 604800,\n\tweek: 604800,\n};\n\nfunction durationLabel(duration: unknown, timeUnit: unknown): string {\n\tconst amount = asNumber(duration);\n\tconst unit = typeof timeUnit === \"string\" ? timeUnit.toLowerCase() : undefined;\n\tconst seconds = amount !== undefined && unit ? TIME_UNIT_SECONDS[unit] : undefined;\n\tif (amount === undefined || seconds === undefined) return \"Limit\";\n\tconst totalSeconds = amount * seconds;\n\tif (totalSeconds >= 604800) return \"Weekly\";\n\tif (totalSeconds >= 86400) return `${Math.round(totalSeconds / 86400)}d`;\n\tif (totalSeconds >= 3600) return `${Math.round(totalSeconds / 3600)}h`;\n\treturn `${Math.max(1, Math.round(totalSeconds / 60))}m`;\n}\n\nfunction detailWindow(label: string, detail: unknown): PlanUsageWindow | undefined {\n\tconst object = asObject(detail);\n\tif (!object) return undefined;\n\tconst usedPercent = usedPercentFromRemaining(object.limit, object.remaining);\n\tif (usedPercent === undefined) return undefined;\n\treturn { label, usedPercent, resetsAt: toEpochMs(object.resetTime) };\n}\n\nexport async function fetchKimiPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage | undefined> {\n\tconst resolution = auth ? auth.resolution : await runtime.getAuth(KIMI_PROVIDER_ID);\n\tconst apiKey = resolution?.auth.apiKey;\n\tif (!apiKey) return undefined;\n\n\tconst response = await fetchWithTimeout(KIMI_USAGE_URL, {\n\t\theaders: { Authorization: `Bearer ${apiKey}`, Accept: \"application/json\" },\n\t});\n\tif (!response.ok) return undefined;\n\tconst payload = asObject(await response.json());\n\tif (!payload) return undefined;\n\n\tconst windows: PlanUsageWindow[] = [];\n\t// Top-level `usage` is the weekly quota; `limits[]` carries the short rate window.\n\tconst weekly = detailWindow(\"Weekly\", payload.usage);\n\tif (weekly) windows.push(weekly);\n\tconst limits = Array.isArray(payload.limits) ? payload.limits : [];\n\tfor (const item of limits) {\n\t\tconst limit = asObject(item);\n\t\tif (!limit) continue;\n\t\tconst window = detailWindow(\n\t\t\tdurationLabel(asObject(limit.window)?.duration, asObject(limit.window)?.timeUnit),\n\t\t\tlimit.detail,\n\t\t);\n\t\tif (window) windows.push(window);\n\t}\n\tif (windows.length === 0) return undefined;\n\treturn { provider: KIMI_PROVIDER_ID, windows };\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ModelRuntime } from "../model-runtime.ts";
|
|
2
|
-
import type { PlanUsage } from "../usage-service.ts";
|
|
3
|
-
export declare function
|
|
2
|
+
import type { PlanUsage, UsageAuthSnapshot } from "../usage-service.ts";
|
|
3
|
+
export declare function resolveCodexHeaders(runtime: ModelRuntime): Promise<Record<string, string> | undefined>;
|
|
4
|
+
export declare function fetchCodexPlanUsage(runtime: ModelRuntime, auth?: UsageAuthSnapshot): Promise<PlanUsage[] | undefined>;
|
|
4
5
|
//# sourceMappingURL=openai-codex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-codex.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/openai-codex.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-codex.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/openai-codex.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAwIzF,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAkC5G;AAkDD,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,YAAY,EACrB,IAAI,CAAC,EAAE,iBAAiB,GACtB,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAYlC","sourcesContent":["// Vendored from narumiruna-pi-codex-usage (deleted in Phase 1 of the lunr-ux plan):\n// the pi-auth HTTP query path of `query.ts` plus `normalize.ts` and the backend\n// types from `types.ts`, consolidated into one core module. The codex app-server\n// fallback was dropped; extension-API imports (ExtensionContext, modelRegistry)\n// were rewired to core's ModelRuntime. No runtime dependency on the deleted\n// extension or on extension-repos remains.\n\nimport type { Api, AuthResult, Model } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport { asNumber, asObject, asString, fetchWithTimeout, toEpochMs } from \"./shared.ts\";\n\nconst CODEX_PROVIDER_ID = \"openai-codex\";\nconst CODEX_USAGE_URL = \"https://chatgpt.com/backend-api/wham/usage\";\nconst MAX_ERROR_BODY_CHARS = 600;\n\n// ---------------------------------------------------------------------------\n// Backend payload types (vendored from types.ts)\n// ---------------------------------------------------------------------------\n\ntype RateLimitStatusPayload = {\n\tplan_type?: unknown;\n\trate_limit?: unknown;\n\tadditional_rate_limits?: unknown;\n\tcredits?: unknown;\n\trate_limit_reset_credits?: unknown;\n};\n\ntype BackendRateLimitDetails = {\n\tprimary_window?: unknown;\n\tsecondary_window?: unknown;\n};\n\ntype BackendWindowSnapshot = {\n\tused_percent?: unknown;\n\tlimit_window_seconds?: unknown;\n\treset_at?: unknown;\n};\n\ntype BackendAdditionalRateLimit = {\n\tlimit_name?: unknown;\n\tmetered_feature?: unknown;\n\trate_limit?: unknown;\n};\n\ntype BackendCreditsSnapshot = {\n\thas_credits?: unknown;\n\tunlimited?: unknown;\n\tbalance?: unknown;\n};\n\ntype NormalizedWindow = {\n\tusedPercent: number;\n\twindowMinutes?: number;\n\tresetsAt?: number;\n};\n\ntype NormalizedSnapshot = {\n\tlimitId: string;\n\tlimitName?: string;\n\tprimary?: NormalizedWindow;\n\tsecondary?: NormalizedWindow;\n};\n\ntype CodexUsageReport = {\n\tplanType?: string;\n\tsnapshots: NormalizedSnapshot[];\n};\n\n// ---------------------------------------------------------------------------\n// Payload normalization (vendored from normalize.ts, backend path only)\n// ---------------------------------------------------------------------------\n\nfunction normalizeBackendPayload(payload: RateLimitStatusPayload): CodexUsageReport {\n\tconst snapshots: NormalizedSnapshot[] = [];\n\tconst planType = asString(payload.plan_type);\n\tconst primary = normalizeBackendSnapshot(\"codex\", undefined, payload.rate_limit, payload.credits);\n\tif (primary) snapshots.push(primary);\n\n\tconst additional = Array.isArray(payload.additional_rate_limits) ? payload.additional_rate_limits : [];\n\tfor (const item of additional) {\n\t\tconst additionalLimit = asObject(item) as BackendAdditionalRateLimit | undefined;\n\t\tif (!additionalLimit) continue;\n\t\tconst limitId = asString(additionalLimit.metered_feature) ?? asString(additionalLimit.limit_name);\n\t\tif (!limitId) continue;\n\t\ttry {\n\t\t\tconst snapshot = normalizeBackendSnapshot(\n\t\t\t\tlimitId,\n\t\t\t\tasString(additionalLimit.limit_name),\n\t\t\t\tadditionalLimit.rate_limit,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (snapshot) snapshots.push(snapshot);\n\t\t} catch {\n\t\t\t// Optional additional buckets must not hide otherwise usable primary usage.\n\t\t}\n\t}\n\n\tif (snapshots.length === 0) {\n\t\tthrow new Error(\"Codex usage endpoint returned no displayable usage data.\");\n\t}\n\treturn { planType, snapshots };\n}\n\nfunction normalizeBackendSnapshot(\n\tlimitId: string,\n\tlimitName: string | undefined,\n\trateLimit: unknown,\n\tcredits: unknown,\n): NormalizedSnapshot | undefined {\n\tif (rateLimit === null || rateLimit === undefined) {\n\t\treturn normalizeBackendCredits(credits) ? { limitId, limitName } : undefined;\n\t}\n\tconst details = asObject(rateLimit) as BackendRateLimitDetails | undefined;\n\tif (!details) throw new Error(\"rate limit was not an object.\");\n\tconst primary = normalizeBackendWindow(details.primary_window);\n\tconst secondary = normalizeBackendWindow(details.secondary_window);\n\tif (!primary && !secondary && !normalizeBackendCredits(credits)) return undefined;\n\treturn { limitId, limitName, primary, secondary };\n}\n\nfunction normalizeBackendWindow(value: unknown): NormalizedWindow | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tconst window = asObject(value) as BackendWindowSnapshot | undefined;\n\tif (!window) throw new Error(\"rate-limit window was not an object.\");\n\tconst usedPercent = asNumber(window.used_percent);\n\tif (usedPercent === undefined) return undefined;\n\tconst limitSeconds = asNumber(window.limit_window_seconds);\n\treturn {\n\t\tusedPercent,\n\t\twindowMinutes: limitSeconds && limitSeconds > 0 ? Math.ceil(limitSeconds / 60) : undefined,\n\t\tresetsAt: toEpochMs(window.reset_at),\n\t};\n}\n\nfunction normalizeBackendCredits(value: unknown): boolean {\n\tconst credits = asObject(value) as BackendCreditsSnapshot | undefined;\n\tif (!credits) return false;\n\treturn credits.has_credits !== undefined && credits.unlimited !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Auth resolution via core ModelRuntime (rewired from ctx.modelRegistry)\n// ---------------------------------------------------------------------------\n\nexport async function resolveCodexHeaders(runtime: ModelRuntime): Promise<Record<string, string> | undefined> {\n\tconst candidates: Model<Api>[] = [];\n\tconst seen = new Set<string>();\n\tconst add = (model: Model<Api> | undefined) => {\n\t\tif (!model || model.provider !== CODEX_PROVIDER_ID) return;\n\t\tconst key = `${model.provider}/${model.id}`;\n\t\tif (seen.has(key)) return;\n\t\tseen.add(key);\n\t\tcandidates.push(model);\n\t};\n\tfor (const model of runtime.getAvailableSnapshot()) add(model);\n\tfor (const model of runtime.getModels()) add(model);\n\n\tfor (const model of candidates) {\n\t\tlet resolution: AuthResult | undefined;\n\t\ttry {\n\t\t\tresolution = await runtime.getAuth(model);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!resolution) continue;\n\t\tconst headers: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(resolution.auth.headers ?? {})) {\n\t\t\tif (value !== null && value !== undefined) headers[name] = String(value);\n\t\t}\n\t\tif (!hasHeader(headers, \"Authorization\") && resolution.auth.apiKey) {\n\t\t\theaders.Authorization = `Bearer ${resolution.auth.apiKey}`;\n\t\t}\n\t\tif (!hasHeader(headers, \"User-Agent\")) {\n\t\t\theaders[\"User-Agent\"] = \"lunr-usage-service\";\n\t\t}\n\t\tif (hasHeader(headers, \"Authorization\")) return headers;\n\t}\n\treturn undefined;\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string): boolean {\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === name.toLowerCase());\n}\n\nfunction redactErrorBody(body: string): string {\n\tconst redacted = body\n\t\t.replace(/Bearer\\s+[A-Za-z0-9._~+/=-]+/gi, \"Bearer <redacted>\")\n\t\t.replace(/\"access_token\"\\s*:\\s*\"[^\"]+\"/gi, '\"access_token\":\"<redacted>\"')\n\t\t.trim();\n\treturn redacted.length > MAX_ERROR_BODY_CHARS ? `${redacted.slice(0, MAX_ERROR_BODY_CHARS - 1)}…` : redacted;\n}\n\n// ---------------------------------------------------------------------------\n// PlanUsage mapping\n// ---------------------------------------------------------------------------\n\nfunction windowLabel(window: NormalizedWindow, fallback: string | undefined): string {\n\tconst minutes = window.windowMinutes;\n\tif (minutes === undefined) return fallback ?? \"Limit\";\n\tif (minutes >= 7 * 24 * 60) return \"Weekly\";\n\tif (minutes >= 24 * 60) return `${Math.round(minutes / (24 * 60))}d`;\n\tif (minutes >= 60) return `${Math.round(minutes / 60)}h`;\n\treturn `${minutes}m`;\n}\n\nfunction toPlanUsage(report: CodexUsageReport): PlanUsage[] {\n\treturn report.snapshots.flatMap((snapshot, index) => {\n\t\t// Longer window (weekly) first, shorter (5h) second — matches /usage layout.\n\t\tconst windows: PlanUsageWindow[] = [];\n\t\tfor (const window of [snapshot.secondary, snapshot.primary]) {\n\t\t\tif (!window) continue;\n\t\t\twindows.push({\n\t\t\t\tlabel: windowLabel(window, snapshot.limitName),\n\t\t\t\tusedPercent: window.usedPercent,\n\t\t\t\tresetsAt: window.resetsAt,\n\t\t\t});\n\t\t}\n\t\tif (windows.length === 0) return [];\n\t\treturn [\n\t\t\t{\n\t\t\t\tprovider: CODEX_PROVIDER_ID,\n\t\t\t\tplanLabel: index === 0 ? report.planType : (snapshot.limitName ?? snapshot.limitId),\n\t\t\t\twindows,\n\t\t\t},\n\t\t];\n\t});\n}\n\nexport async function fetchCodexPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage[] | undefined> {\n\tconst headers = auth ? auth.codexHeaders : await resolveCodexHeaders(runtime);\n\tif (!headers) return undefined;\n\n\tconst response = await fetchWithTimeout(CODEX_USAGE_URL, { headers });\n\tconst text = await response.text();\n\tif (!response.ok) {\n\t\tthrow new Error(`Codex usage endpoint returned ${response.status}: ${redactErrorBody(text)}`);\n\t}\n\tconst payload = asObject(JSON.parse(text)) as RateLimitStatusPayload | undefined;\n\tif (!payload) return undefined;\n\treturn toPlanUsage(normalizeBackendPayload(payload));\n}\n"]}
|
|
@@ -77,7 +77,7 @@ function normalizeBackendCredits(value) {
|
|
|
77
77
|
// ---------------------------------------------------------------------------
|
|
78
78
|
// Auth resolution via core ModelRuntime (rewired from ctx.modelRegistry)
|
|
79
79
|
// ---------------------------------------------------------------------------
|
|
80
|
-
async function resolveCodexHeaders(runtime) {
|
|
80
|
+
export async function resolveCodexHeaders(runtime) {
|
|
81
81
|
const candidates = [];
|
|
82
82
|
const seen = new Set();
|
|
83
83
|
const add = (model) => {
|
|
@@ -168,8 +168,8 @@ function toPlanUsage(report) {
|
|
|
168
168
|
];
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
-
export async function fetchCodexPlanUsage(runtime) {
|
|
172
|
-
const headers = await resolveCodexHeaders(runtime);
|
|
171
|
+
export async function fetchCodexPlanUsage(runtime, auth) {
|
|
172
|
+
const headers = auth ? auth.codexHeaders : await resolveCodexHeaders(runtime);
|
|
173
173
|
if (!headers)
|
|
174
174
|
return undefined;
|
|
175
175
|
const response = await fetchWithTimeout(CODEX_USAGE_URL, { headers });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-codex.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/openai-codex.ts"],"names":[],"mappings":"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","sourcesContent":["// Vendored from narumiruna-pi-codex-usage (deleted in Phase 1 of the lunr-ux plan):\n// the pi-auth HTTP query path of `query.ts` plus `normalize.ts` and the backend\n// types from `types.ts`, consolidated into one core module. The codex app-server\n// fallback was dropped; extension-API imports (ExtensionContext, modelRegistry)\n// were rewired to core's ModelRuntime. No runtime dependency on the deleted\n// extension or on extension-repos remains.\n\nimport type { Api, AuthResult, Model } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow } from \"../usage-service.ts\";\nimport { asNumber, asObject, asString, fetchWithTimeout, toEpochMs } from \"./shared.ts\";\n\nconst CODEX_PROVIDER_ID = \"openai-codex\";\nconst CODEX_USAGE_URL = \"https://chatgpt.com/backend-api/wham/usage\";\nconst MAX_ERROR_BODY_CHARS = 600;\n\n// ---------------------------------------------------------------------------\n// Backend payload types (vendored from types.ts)\n// ---------------------------------------------------------------------------\n\ntype RateLimitStatusPayload = {\n\tplan_type?: unknown;\n\trate_limit?: unknown;\n\tadditional_rate_limits?: unknown;\n\tcredits?: unknown;\n\trate_limit_reset_credits?: unknown;\n};\n\ntype BackendRateLimitDetails = {\n\tprimary_window?: unknown;\n\tsecondary_window?: unknown;\n};\n\ntype BackendWindowSnapshot = {\n\tused_percent?: unknown;\n\tlimit_window_seconds?: unknown;\n\treset_at?: unknown;\n};\n\ntype BackendAdditionalRateLimit = {\n\tlimit_name?: unknown;\n\tmetered_feature?: unknown;\n\trate_limit?: unknown;\n};\n\ntype BackendCreditsSnapshot = {\n\thas_credits?: unknown;\n\tunlimited?: unknown;\n\tbalance?: unknown;\n};\n\ntype NormalizedWindow = {\n\tusedPercent: number;\n\twindowMinutes?: number;\n\tresetsAt?: number;\n};\n\ntype NormalizedSnapshot = {\n\tlimitId: string;\n\tlimitName?: string;\n\tprimary?: NormalizedWindow;\n\tsecondary?: NormalizedWindow;\n};\n\ntype CodexUsageReport = {\n\tplanType?: string;\n\tsnapshots: NormalizedSnapshot[];\n};\n\n// ---------------------------------------------------------------------------\n// Payload normalization (vendored from normalize.ts, backend path only)\n// ---------------------------------------------------------------------------\n\nfunction normalizeBackendPayload(payload: RateLimitStatusPayload): CodexUsageReport {\n\tconst snapshots: NormalizedSnapshot[] = [];\n\tconst planType = asString(payload.plan_type);\n\tconst primary = normalizeBackendSnapshot(\"codex\", undefined, payload.rate_limit, payload.credits);\n\tif (primary) snapshots.push(primary);\n\n\tconst additional = Array.isArray(payload.additional_rate_limits) ? payload.additional_rate_limits : [];\n\tfor (const item of additional) {\n\t\tconst additionalLimit = asObject(item) as BackendAdditionalRateLimit | undefined;\n\t\tif (!additionalLimit) continue;\n\t\tconst limitId = asString(additionalLimit.metered_feature) ?? asString(additionalLimit.limit_name);\n\t\tif (!limitId) continue;\n\t\ttry {\n\t\t\tconst snapshot = normalizeBackendSnapshot(\n\t\t\t\tlimitId,\n\t\t\t\tasString(additionalLimit.limit_name),\n\t\t\t\tadditionalLimit.rate_limit,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (snapshot) snapshots.push(snapshot);\n\t\t} catch {\n\t\t\t// Optional additional buckets must not hide otherwise usable primary usage.\n\t\t}\n\t}\n\n\tif (snapshots.length === 0) {\n\t\tthrow new Error(\"Codex usage endpoint returned no displayable usage data.\");\n\t}\n\treturn { planType, snapshots };\n}\n\nfunction normalizeBackendSnapshot(\n\tlimitId: string,\n\tlimitName: string | undefined,\n\trateLimit: unknown,\n\tcredits: unknown,\n): NormalizedSnapshot | undefined {\n\tif (rateLimit === null || rateLimit === undefined) {\n\t\treturn normalizeBackendCredits(credits) ? { limitId, limitName } : undefined;\n\t}\n\tconst details = asObject(rateLimit) as BackendRateLimitDetails | undefined;\n\tif (!details) throw new Error(\"rate limit was not an object.\");\n\tconst primary = normalizeBackendWindow(details.primary_window);\n\tconst secondary = normalizeBackendWindow(details.secondary_window);\n\tif (!primary && !secondary && !normalizeBackendCredits(credits)) return undefined;\n\treturn { limitId, limitName, primary, secondary };\n}\n\nfunction normalizeBackendWindow(value: unknown): NormalizedWindow | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tconst window = asObject(value) as BackendWindowSnapshot | undefined;\n\tif (!window) throw new Error(\"rate-limit window was not an object.\");\n\tconst usedPercent = asNumber(window.used_percent);\n\tif (usedPercent === undefined) return undefined;\n\tconst limitSeconds = asNumber(window.limit_window_seconds);\n\treturn {\n\t\tusedPercent,\n\t\twindowMinutes: limitSeconds && limitSeconds > 0 ? Math.ceil(limitSeconds / 60) : undefined,\n\t\tresetsAt: toEpochMs(window.reset_at),\n\t};\n}\n\nfunction normalizeBackendCredits(value: unknown): boolean {\n\tconst credits = asObject(value) as BackendCreditsSnapshot | undefined;\n\tif (!credits) return false;\n\treturn credits.has_credits !== undefined && credits.unlimited !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Auth resolution via core ModelRuntime (rewired from ctx.modelRegistry)\n// ---------------------------------------------------------------------------\n\nasync function resolveCodexHeaders(runtime: ModelRuntime): Promise<Record<string, string> | undefined> {\n\tconst candidates: Model<Api>[] = [];\n\tconst seen = new Set<string>();\n\tconst add = (model: Model<Api> | undefined) => {\n\t\tif (!model || model.provider !== CODEX_PROVIDER_ID) return;\n\t\tconst key = `${model.provider}/${model.id}`;\n\t\tif (seen.has(key)) return;\n\t\tseen.add(key);\n\t\tcandidates.push(model);\n\t};\n\tfor (const model of runtime.getAvailableSnapshot()) add(model);\n\tfor (const model of runtime.getModels()) add(model);\n\n\tfor (const model of candidates) {\n\t\tlet resolution: AuthResult | undefined;\n\t\ttry {\n\t\t\tresolution = await runtime.getAuth(model);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!resolution) continue;\n\t\tconst headers: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(resolution.auth.headers ?? {})) {\n\t\t\tif (value !== null && value !== undefined) headers[name] = String(value);\n\t\t}\n\t\tif (!hasHeader(headers, \"Authorization\") && resolution.auth.apiKey) {\n\t\t\theaders.Authorization = `Bearer ${resolution.auth.apiKey}`;\n\t\t}\n\t\tif (!hasHeader(headers, \"User-Agent\")) {\n\t\t\theaders[\"User-Agent\"] = \"lunr-usage-service\";\n\t\t}\n\t\tif (hasHeader(headers, \"Authorization\")) return headers;\n\t}\n\treturn undefined;\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string): boolean {\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === name.toLowerCase());\n}\n\nfunction redactErrorBody(body: string): string {\n\tconst redacted = body\n\t\t.replace(/Bearer\\s+[A-Za-z0-9._~+/=-]+/gi, \"Bearer <redacted>\")\n\t\t.replace(/\"access_token\"\\s*:\\s*\"[^\"]+\"/gi, '\"access_token\":\"<redacted>\"')\n\t\t.trim();\n\treturn redacted.length > MAX_ERROR_BODY_CHARS ? `${redacted.slice(0, MAX_ERROR_BODY_CHARS - 1)}…` : redacted;\n}\n\n// ---------------------------------------------------------------------------\n// PlanUsage mapping\n// ---------------------------------------------------------------------------\n\nfunction windowLabel(window: NormalizedWindow, fallback: string | undefined): string {\n\tconst minutes = window.windowMinutes;\n\tif (minutes === undefined) return fallback ?? \"Limit\";\n\tif (minutes >= 7 * 24 * 60) return \"Weekly\";\n\tif (minutes >= 24 * 60) return `${Math.round(minutes / (24 * 60))}d`;\n\tif (minutes >= 60) return `${Math.round(minutes / 60)}h`;\n\treturn `${minutes}m`;\n}\n\nfunction toPlanUsage(report: CodexUsageReport): PlanUsage[] {\n\treturn report.snapshots.flatMap((snapshot, index) => {\n\t\t// Longer window (weekly) first, shorter (5h) second — matches /usage layout.\n\t\tconst windows: PlanUsageWindow[] = [];\n\t\tfor (const window of [snapshot.secondary, snapshot.primary]) {\n\t\t\tif (!window) continue;\n\t\t\twindows.push({\n\t\t\t\tlabel: windowLabel(window, snapshot.limitName),\n\t\t\t\tusedPercent: window.usedPercent,\n\t\t\t\tresetsAt: window.resetsAt,\n\t\t\t});\n\t\t}\n\t\tif (windows.length === 0) return [];\n\t\treturn [\n\t\t\t{\n\t\t\t\tprovider: CODEX_PROVIDER_ID,\n\t\t\t\tplanLabel: index === 0 ? report.planType : (snapshot.limitName ?? snapshot.limitId),\n\t\t\t\twindows,\n\t\t\t},\n\t\t];\n\t});\n}\n\nexport async function fetchCodexPlanUsage(runtime: ModelRuntime): Promise<PlanUsage[] | undefined> {\n\tconst headers = await resolveCodexHeaders(runtime);\n\tif (!headers) return undefined;\n\n\tconst response = await fetchWithTimeout(CODEX_USAGE_URL, { headers });\n\tconst text = await response.text();\n\tif (!response.ok) {\n\t\tthrow new Error(`Codex usage endpoint returned ${response.status}: ${redactErrorBody(text)}`);\n\t}\n\tconst payload = asObject(JSON.parse(text)) as RateLimitStatusPayload | undefined;\n\tif (!payload) return undefined;\n\treturn toPlanUsage(normalizeBackendPayload(payload));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"openai-codex.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/openai-codex.ts"],"names":[],"mappings":"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","sourcesContent":["// Vendored from narumiruna-pi-codex-usage (deleted in Phase 1 of the lunr-ux plan):\n// the pi-auth HTTP query path of `query.ts` plus `normalize.ts` and the backend\n// types from `types.ts`, consolidated into one core module. The codex app-server\n// fallback was dropped; extension-API imports (ExtensionContext, modelRegistry)\n// were rewired to core's ModelRuntime. No runtime dependency on the deleted\n// extension or on extension-repos remains.\n\nimport type { Api, AuthResult, Model } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport { asNumber, asObject, asString, fetchWithTimeout, toEpochMs } from \"./shared.ts\";\n\nconst CODEX_PROVIDER_ID = \"openai-codex\";\nconst CODEX_USAGE_URL = \"https://chatgpt.com/backend-api/wham/usage\";\nconst MAX_ERROR_BODY_CHARS = 600;\n\n// ---------------------------------------------------------------------------\n// Backend payload types (vendored from types.ts)\n// ---------------------------------------------------------------------------\n\ntype RateLimitStatusPayload = {\n\tplan_type?: unknown;\n\trate_limit?: unknown;\n\tadditional_rate_limits?: unknown;\n\tcredits?: unknown;\n\trate_limit_reset_credits?: unknown;\n};\n\ntype BackendRateLimitDetails = {\n\tprimary_window?: unknown;\n\tsecondary_window?: unknown;\n};\n\ntype BackendWindowSnapshot = {\n\tused_percent?: unknown;\n\tlimit_window_seconds?: unknown;\n\treset_at?: unknown;\n};\n\ntype BackendAdditionalRateLimit = {\n\tlimit_name?: unknown;\n\tmetered_feature?: unknown;\n\trate_limit?: unknown;\n};\n\ntype BackendCreditsSnapshot = {\n\thas_credits?: unknown;\n\tunlimited?: unknown;\n\tbalance?: unknown;\n};\n\ntype NormalizedWindow = {\n\tusedPercent: number;\n\twindowMinutes?: number;\n\tresetsAt?: number;\n};\n\ntype NormalizedSnapshot = {\n\tlimitId: string;\n\tlimitName?: string;\n\tprimary?: NormalizedWindow;\n\tsecondary?: NormalizedWindow;\n};\n\ntype CodexUsageReport = {\n\tplanType?: string;\n\tsnapshots: NormalizedSnapshot[];\n};\n\n// ---------------------------------------------------------------------------\n// Payload normalization (vendored from normalize.ts, backend path only)\n// ---------------------------------------------------------------------------\n\nfunction normalizeBackendPayload(payload: RateLimitStatusPayload): CodexUsageReport {\n\tconst snapshots: NormalizedSnapshot[] = [];\n\tconst planType = asString(payload.plan_type);\n\tconst primary = normalizeBackendSnapshot(\"codex\", undefined, payload.rate_limit, payload.credits);\n\tif (primary) snapshots.push(primary);\n\n\tconst additional = Array.isArray(payload.additional_rate_limits) ? payload.additional_rate_limits : [];\n\tfor (const item of additional) {\n\t\tconst additionalLimit = asObject(item) as BackendAdditionalRateLimit | undefined;\n\t\tif (!additionalLimit) continue;\n\t\tconst limitId = asString(additionalLimit.metered_feature) ?? asString(additionalLimit.limit_name);\n\t\tif (!limitId) continue;\n\t\ttry {\n\t\t\tconst snapshot = normalizeBackendSnapshot(\n\t\t\t\tlimitId,\n\t\t\t\tasString(additionalLimit.limit_name),\n\t\t\t\tadditionalLimit.rate_limit,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tif (snapshot) snapshots.push(snapshot);\n\t\t} catch {\n\t\t\t// Optional additional buckets must not hide otherwise usable primary usage.\n\t\t}\n\t}\n\n\tif (snapshots.length === 0) {\n\t\tthrow new Error(\"Codex usage endpoint returned no displayable usage data.\");\n\t}\n\treturn { planType, snapshots };\n}\n\nfunction normalizeBackendSnapshot(\n\tlimitId: string,\n\tlimitName: string | undefined,\n\trateLimit: unknown,\n\tcredits: unknown,\n): NormalizedSnapshot | undefined {\n\tif (rateLimit === null || rateLimit === undefined) {\n\t\treturn normalizeBackendCredits(credits) ? { limitId, limitName } : undefined;\n\t}\n\tconst details = asObject(rateLimit) as BackendRateLimitDetails | undefined;\n\tif (!details) throw new Error(\"rate limit was not an object.\");\n\tconst primary = normalizeBackendWindow(details.primary_window);\n\tconst secondary = normalizeBackendWindow(details.secondary_window);\n\tif (!primary && !secondary && !normalizeBackendCredits(credits)) return undefined;\n\treturn { limitId, limitName, primary, secondary };\n}\n\nfunction normalizeBackendWindow(value: unknown): NormalizedWindow | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tconst window = asObject(value) as BackendWindowSnapshot | undefined;\n\tif (!window) throw new Error(\"rate-limit window was not an object.\");\n\tconst usedPercent = asNumber(window.used_percent);\n\tif (usedPercent === undefined) return undefined;\n\tconst limitSeconds = asNumber(window.limit_window_seconds);\n\treturn {\n\t\tusedPercent,\n\t\twindowMinutes: limitSeconds && limitSeconds > 0 ? Math.ceil(limitSeconds / 60) : undefined,\n\t\tresetsAt: toEpochMs(window.reset_at),\n\t};\n}\n\nfunction normalizeBackendCredits(value: unknown): boolean {\n\tconst credits = asObject(value) as BackendCreditsSnapshot | undefined;\n\tif (!credits) return false;\n\treturn credits.has_credits !== undefined && credits.unlimited !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Auth resolution via core ModelRuntime (rewired from ctx.modelRegistry)\n// ---------------------------------------------------------------------------\n\nexport async function resolveCodexHeaders(runtime: ModelRuntime): Promise<Record<string, string> | undefined> {\n\tconst candidates: Model<Api>[] = [];\n\tconst seen = new Set<string>();\n\tconst add = (model: Model<Api> | undefined) => {\n\t\tif (!model || model.provider !== CODEX_PROVIDER_ID) return;\n\t\tconst key = `${model.provider}/${model.id}`;\n\t\tif (seen.has(key)) return;\n\t\tseen.add(key);\n\t\tcandidates.push(model);\n\t};\n\tfor (const model of runtime.getAvailableSnapshot()) add(model);\n\tfor (const model of runtime.getModels()) add(model);\n\n\tfor (const model of candidates) {\n\t\tlet resolution: AuthResult | undefined;\n\t\ttry {\n\t\t\tresolution = await runtime.getAuth(model);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!resolution) continue;\n\t\tconst headers: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(resolution.auth.headers ?? {})) {\n\t\t\tif (value !== null && value !== undefined) headers[name] = String(value);\n\t\t}\n\t\tif (!hasHeader(headers, \"Authorization\") && resolution.auth.apiKey) {\n\t\t\theaders.Authorization = `Bearer ${resolution.auth.apiKey}`;\n\t\t}\n\t\tif (!hasHeader(headers, \"User-Agent\")) {\n\t\t\theaders[\"User-Agent\"] = \"lunr-usage-service\";\n\t\t}\n\t\tif (hasHeader(headers, \"Authorization\")) return headers;\n\t}\n\treturn undefined;\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string): boolean {\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === name.toLowerCase());\n}\n\nfunction redactErrorBody(body: string): string {\n\tconst redacted = body\n\t\t.replace(/Bearer\\s+[A-Za-z0-9._~+/=-]+/gi, \"Bearer <redacted>\")\n\t\t.replace(/\"access_token\"\\s*:\\s*\"[^\"]+\"/gi, '\"access_token\":\"<redacted>\"')\n\t\t.trim();\n\treturn redacted.length > MAX_ERROR_BODY_CHARS ? `${redacted.slice(0, MAX_ERROR_BODY_CHARS - 1)}…` : redacted;\n}\n\n// ---------------------------------------------------------------------------\n// PlanUsage mapping\n// ---------------------------------------------------------------------------\n\nfunction windowLabel(window: NormalizedWindow, fallback: string | undefined): string {\n\tconst minutes = window.windowMinutes;\n\tif (minutes === undefined) return fallback ?? \"Limit\";\n\tif (minutes >= 7 * 24 * 60) return \"Weekly\";\n\tif (minutes >= 24 * 60) return `${Math.round(minutes / (24 * 60))}d`;\n\tif (minutes >= 60) return `${Math.round(minutes / 60)}h`;\n\treturn `${minutes}m`;\n}\n\nfunction toPlanUsage(report: CodexUsageReport): PlanUsage[] {\n\treturn report.snapshots.flatMap((snapshot, index) => {\n\t\t// Longer window (weekly) first, shorter (5h) second — matches /usage layout.\n\t\tconst windows: PlanUsageWindow[] = [];\n\t\tfor (const window of [snapshot.secondary, snapshot.primary]) {\n\t\t\tif (!window) continue;\n\t\t\twindows.push({\n\t\t\t\tlabel: windowLabel(window, snapshot.limitName),\n\t\t\t\tusedPercent: window.usedPercent,\n\t\t\t\tresetsAt: window.resetsAt,\n\t\t\t});\n\t\t}\n\t\tif (windows.length === 0) return [];\n\t\treturn [\n\t\t\t{\n\t\t\t\tprovider: CODEX_PROVIDER_ID,\n\t\t\t\tplanLabel: index === 0 ? report.planType : (snapshot.limitName ?? snapshot.limitId),\n\t\t\t\twindows,\n\t\t\t},\n\t\t];\n\t});\n}\n\nexport async function fetchCodexPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage[] | undefined> {\n\tconst headers = auth ? auth.codexHeaders : await resolveCodexHeaders(runtime);\n\tif (!headers) return undefined;\n\n\tconst response = await fetchWithTimeout(CODEX_USAGE_URL, { headers });\n\tconst text = await response.text();\n\tif (!response.ok) {\n\t\tthrow new Error(`Codex usage endpoint returned ${response.status}: ${redactErrorBody(text)}`);\n\t}\n\tconst payload = asObject(JSON.parse(text)) as RateLimitStatusPayload | undefined;\n\tif (!payload) return undefined;\n\treturn toPlanUsage(normalizeBackendPayload(payload));\n}\n"]}
|
|
@@ -16,6 +16,6 @@
|
|
|
16
16
|
* after xAI changes the billing payload.
|
|
17
17
|
*/
|
|
18
18
|
import type { ModelRuntime } from "../model-runtime.ts";
|
|
19
|
-
import type { PlanUsage } from "../usage-service.ts";
|
|
20
|
-
export declare function fetchXaiPlanUsage(runtime: ModelRuntime): Promise<PlanUsage | undefined>;
|
|
19
|
+
import type { PlanUsage, UsageAuthSnapshot } from "../usage-service.ts";
|
|
20
|
+
export declare function fetchXaiPlanUsage(runtime: ModelRuntime, auth?: UsageAuthSnapshot): Promise<PlanUsage | undefined>;
|
|
21
21
|
//# sourceMappingURL=xai.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xai.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/xai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,qBAAqB,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"xai.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/xai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AA+BzF,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,YAAY,EACrB,IAAI,CAAC,EAAE,iBAAiB,GACtB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAyChC","sourcesContent":["/**\n * xAI Grok (SuperGrok / X Premium) weekly plan usage.\n *\n * `GET https://cli-chat-proxy.grok.com/v1/billing?format=credits` with the\n * OAuth access token (Grok CLI identity header required). Official Grok\n * Build `/usage` and grok.com Settings → Usage read the same weekly pool:\n * config.creditUsagePercent + config.currentPeriod.end\n *\n * Extra Usage Credits (`onDemandCap` > 0) are a secondary window only.\n * `monthlyLimit` / `includedUsed` / `billingPeriodEnd` are the old monthly\n * Extra Usage envelope — never treated as the subscription plan.\n *\n * Pay-as-you-go API keys have no quota endpoint. OAuth-only; any failure\n * or shape mismatch resolves to `undefined` (caller hides the plan section).\n * First-party undocumented protocol — re-smoke against a real OAuth token\n * after xAI changes the billing payload.\n */\n\nimport { ModelsError } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport {\n\tasObject,\n\tasString,\n\tclampPercent,\n\tfetchWithTimeout,\n\ttoEpochMs,\n\tunwrapVal,\n\tusedPercentFromUsed,\n} from \"./shared.ts\";\n\nconst XAI_PROVIDER_ID = \"xai\";\nconst XAI_BILLING_URL = \"https://cli-chat-proxy.grok.com/v1/billing?format=credits\";\n\nfunction currentPeriod(config: Record<string, unknown>): Record<string, unknown> | undefined {\n\treturn asObject(config.currentPeriod) ?? asObject(config.current_period);\n}\n\nfunction weeklyWindow(config: Record<string, unknown>): PlanUsageWindow | undefined {\n\tconst period = currentPeriod(config);\n\tconst raw = unwrapVal(config.creditUsagePercent ?? config.credit_usage_percent);\n\t// Omitted proto3 percent + a live currentPeriod means 0% used (CodexBar).\n\tif (raw === undefined && !period) return undefined;\n\tconst usedPercent = raw === undefined ? 0 : clampPercent(raw);\n\treturn {\n\t\tlabel: \"Weekly\",\n\t\tusedPercent,\n\t\tresetsAt: toEpochMs(period?.end),\n\t};\n}\n\nexport async function fetchXaiPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage | undefined> {\n\tif (!(auth?.oauth ?? runtime.isUsingOAuth(XAI_PROVIDER_ID))) return undefined;\n\n\tconst resolution = auth ? auth.resolution : await runtime.getAuth(XAI_PROVIDER_ID);\n\tconst accessToken = resolution?.auth.apiKey;\n\tif (!accessToken) return undefined;\n\n\tconst response = await fetchWithTimeout(XAI_BILLING_URL, {\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\tAccept: \"application/json\",\n\t\t\t\"x-xai-token-auth\": \"xai-grok-cli\",\n\t\t},\n\t});\n\tif (response.status === 401 || response.status === 403) {\n\t\tthrow new ModelsError(\"oauth\", `xAI billing rejected the session (HTTP ${response.status})`);\n\t}\n\tif (!response.ok) return undefined;\n\tconst payload = asObject(await response.json());\n\tif (!payload) return undefined;\n\tconst config = asObject(payload.config) ?? payload;\n\n\tconst windows: PlanUsageWindow[] = [];\n\tconst weekly = weeklyWindow(config);\n\tif (weekly) windows.push(weekly);\n\n\tconst onDemandCap = unwrapVal(config.onDemandCap);\n\tif (onDemandCap !== undefined && onDemandCap > 0) {\n\t\tconst usedPercent = usedPercentFromUsed(onDemandCap, unwrapVal(config.onDemandUsed) ?? 0);\n\t\tif (usedPercent !== undefined) {\n\t\t\twindows.push({\n\t\t\t\tlabel: \"Extra\",\n\t\t\t\tusedPercent,\n\t\t\t\tresetsAt: weekly?.resetsAt,\n\t\t\t});\n\t\t}\n\t}\n\n\tif (windows.length === 0) return undefined;\n\tconst planLabel = asString(config.subscriptionTier) ?? asString(config.subscription_tier);\n\treturn { provider: XAI_PROVIDER_ID, planLabel, windows };\n}\n"]}
|
|
@@ -35,10 +35,10 @@ function weeklyWindow(config) {
|
|
|
35
35
|
resetsAt: toEpochMs(period?.end),
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
export async function fetchXaiPlanUsage(runtime) {
|
|
39
|
-
if (!runtime.isUsingOAuth(XAI_PROVIDER_ID))
|
|
38
|
+
export async function fetchXaiPlanUsage(runtime, auth) {
|
|
39
|
+
if (!(auth?.oauth ?? runtime.isUsingOAuth(XAI_PROVIDER_ID)))
|
|
40
40
|
return undefined;
|
|
41
|
-
const resolution = await runtime.getAuth(XAI_PROVIDER_ID);
|
|
41
|
+
const resolution = auth ? auth.resolution : await runtime.getAuth(XAI_PROVIDER_ID);
|
|
42
42
|
const accessToken = resolution?.auth.apiKey;
|
|
43
43
|
if (!accessToken)
|
|
44
44
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xai.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/xai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,mBAAmB,GACnB,MAAM,aAAa,CAAC;AAErB,MAAM,eAAe,GAAG,KAAK,CAAC;AAC9B,MAAM,eAAe,GAAG,2DAA2D,CAAC;AAEpF,SAAS,aAAa,CAAC,MAA+B,EAAuC;IAC5F,OAAO,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAAA,CACzE;AAED,SAAS,YAAY,CAAC,MAA+B,EAA+B;IACnF,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,kBAAkB,IAAI,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChF,0EAA0E;IAC1E,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACnD,MAAM,WAAW,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC9D,OAAO;QACN,KAAK,EAAE,QAAQ;QACf,WAAW;QACX,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;KAChC,CAAC;AAAA,CACF;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,
|
|
1
|
+
{"version":3,"file":"xai.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/xai.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * xAI Grok (SuperGrok / X Premium) weekly plan usage.\n *\n * `GET https://cli-chat-proxy.grok.com/v1/billing?format=credits` with the\n * OAuth access token (Grok CLI identity header required). Official Grok\n * Build `/usage` and grok.com Settings → Usage read the same weekly pool:\n * config.creditUsagePercent + config.currentPeriod.end\n *\n * Extra Usage Credits (`onDemandCap` > 0) are a secondary window only.\n * `monthlyLimit` / `includedUsed` / `billingPeriodEnd` are the old monthly\n * Extra Usage envelope — never treated as the subscription plan.\n *\n * Pay-as-you-go API keys have no quota endpoint. OAuth-only; any failure\n * or shape mismatch resolves to `undefined` (caller hides the plan section).\n * First-party undocumented protocol — re-smoke against a real OAuth token\n * after xAI changes the billing payload.\n */\n\nimport { ModelsError } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport {\n\tasObject,\n\tasString,\n\tclampPercent,\n\tfetchWithTimeout,\n\ttoEpochMs,\n\tunwrapVal,\n\tusedPercentFromUsed,\n} from \"./shared.ts\";\n\nconst XAI_PROVIDER_ID = \"xai\";\nconst XAI_BILLING_URL = \"https://cli-chat-proxy.grok.com/v1/billing?format=credits\";\n\nfunction currentPeriod(config: Record<string, unknown>): Record<string, unknown> | undefined {\n\treturn asObject(config.currentPeriod) ?? asObject(config.current_period);\n}\n\nfunction weeklyWindow(config: Record<string, unknown>): PlanUsageWindow | undefined {\n\tconst period = currentPeriod(config);\n\tconst raw = unwrapVal(config.creditUsagePercent ?? config.credit_usage_percent);\n\t// Omitted proto3 percent + a live currentPeriod means 0% used (CodexBar).\n\tif (raw === undefined && !period) return undefined;\n\tconst usedPercent = raw === undefined ? 0 : clampPercent(raw);\n\treturn {\n\t\tlabel: \"Weekly\",\n\t\tusedPercent,\n\t\tresetsAt: toEpochMs(period?.end),\n\t};\n}\n\nexport async function fetchXaiPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage | undefined> {\n\tif (!(auth?.oauth ?? runtime.isUsingOAuth(XAI_PROVIDER_ID))) return undefined;\n\n\tconst resolution = auth ? auth.resolution : await runtime.getAuth(XAI_PROVIDER_ID);\n\tconst accessToken = resolution?.auth.apiKey;\n\tif (!accessToken) return undefined;\n\n\tconst response = await fetchWithTimeout(XAI_BILLING_URL, {\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\tAccept: \"application/json\",\n\t\t\t\"x-xai-token-auth\": \"xai-grok-cli\",\n\t\t},\n\t});\n\tif (response.status === 401 || response.status === 403) {\n\t\tthrow new ModelsError(\"oauth\", `xAI billing rejected the session (HTTP ${response.status})`);\n\t}\n\tif (!response.ok) return undefined;\n\tconst payload = asObject(await response.json());\n\tif (!payload) return undefined;\n\tconst config = asObject(payload.config) ?? payload;\n\n\tconst windows: PlanUsageWindow[] = [];\n\tconst weekly = weeklyWindow(config);\n\tif (weekly) windows.push(weekly);\n\n\tconst onDemandCap = unwrapVal(config.onDemandCap);\n\tif (onDemandCap !== undefined && onDemandCap > 0) {\n\t\tconst usedPercent = usedPercentFromUsed(onDemandCap, unwrapVal(config.onDemandUsed) ?? 0);\n\t\tif (usedPercent !== undefined) {\n\t\t\twindows.push({\n\t\t\t\tlabel: \"Extra\",\n\t\t\t\tusedPercent,\n\t\t\t\tresetsAt: weekly?.resetsAt,\n\t\t\t});\n\t\t}\n\t}\n\n\tif (windows.length === 0) return undefined;\n\tconst planLabel = asString(config.subscriptionTier) ?? asString(config.subscription_tier);\n\treturn { provider: XAI_PROVIDER_ID, planLabel, windows };\n}\n"]}
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
* `unit`: 1 = days, 3 = hours, 5 = minutes, 6 = weeks.
|
|
10
10
|
*/
|
|
11
11
|
import type { ModelRuntime } from "../model-runtime.ts";
|
|
12
|
-
import type { PlanUsage } from "../usage-service.ts";
|
|
13
|
-
export declare function fetchZaiPlanUsage(runtime: ModelRuntime): Promise<PlanUsage | undefined>;
|
|
12
|
+
import type { PlanUsage, UsageAuthSnapshot } from "../usage-service.ts";
|
|
13
|
+
export declare function fetchZaiPlanUsage(runtime: ModelRuntime, auth?: UsageAuthSnapshot): Promise<PlanUsage | undefined>;
|
|
14
14
|
//# sourceMappingURL=zai.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zai.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/zai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"zai.d.ts","sourceRoot":"","sources":["../../../src/core/usage-adapters/zai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAmBzF,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,YAAY,EACrB,IAAI,CAAC,EAAE,iBAAiB,GACtB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CA8BhC","sourcesContent":["/**\n * Z.AI (GLM coding plan) usage: `GET https://api.z.ai/api/monitor/usage/quota/limit`\n * with the stored API key. Response shape (undocumented, used by the official\n * plugin and several open-source quota dashboards):\n * { success, code, msg,\n * data: { planName?/plan?/level?,\n * limits: [{ type: \"TOKENS_LIMIT\"|\"TIME_LIMIT\", unit, number,\n * percentage, nextResetTime? }] } }\n * `unit`: 1 = days, 3 = hours, 5 = minutes, 6 = weeks.\n */\n\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport { asNumber, asObject, asString, clampPercent, fetchWithTimeout, toEpochMs } from \"./shared.ts\";\n\nconst ZAI_PROVIDER_ID = \"zai\";\nconst ZAI_QUOTA_URL = \"https://api.z.ai/api/monitor/usage/quota/limit\";\n\nfunction limitLabel(limit: Record<string, unknown>): string | undefined {\n\tconst type = asString(limit.type);\n\tif (type === \"TIME_LIMIT\") return \"Monthly\";\n\tif (type !== \"TOKENS_LIMIT\") return undefined;\n\tconst unit = asNumber(limit.unit);\n\tconst number = asNumber(limit.number);\n\tif (unit === 1 && number !== undefined) return `${number}d`;\n\tif (unit === 3 && number !== undefined) return `${number}h`;\n\tif (unit === 5 && number !== undefined) return `${number}m`;\n\tif (unit === 6) return \"Weekly\";\n\treturn \"Limit\";\n}\n\nexport async function fetchZaiPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage | undefined> {\n\tconst resolution = auth ? auth.resolution : await runtime.getAuth(ZAI_PROVIDER_ID);\n\tconst apiKey = resolution?.auth.apiKey;\n\tif (!apiKey) return undefined;\n\n\tconst response = await fetchWithTimeout(ZAI_QUOTA_URL, {\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Accept-Language\": \"en-US,en\",\n\t\t},\n\t});\n\tif (!response.ok) return undefined;\n\tconst payload = asObject(await response.json());\n\tif (!payload || payload.success !== true || asNumber(payload.code) !== 200) return undefined;\n\n\tconst data = asObject(payload.data);\n\tconst limits = Array.isArray(data?.limits) ? data.limits : [];\n\tconst windows: PlanUsageWindow[] = [];\n\tfor (const item of limits) {\n\t\tconst limit = asObject(item);\n\t\tif (!limit) continue;\n\t\tconst label = limitLabel(limit);\n\t\tconst percentage = asNumber(limit.percentage);\n\t\tif (!label || percentage === undefined) continue;\n\t\twindows.push({ label, usedPercent: clampPercent(percentage), resetsAt: toEpochMs(limit.nextResetTime) });\n\t}\n\tif (windows.length === 0) return undefined;\n\tconst planLabel = asString(data?.planName) ?? asString(data?.plan) ?? asString(data?.level);\n\treturn { provider: ZAI_PROVIDER_ID, planLabel, windows };\n}\n"]}
|
|
@@ -29,8 +29,8 @@ function limitLabel(limit) {
|
|
|
29
29
|
return "Weekly";
|
|
30
30
|
return "Limit";
|
|
31
31
|
}
|
|
32
|
-
export async function fetchZaiPlanUsage(runtime) {
|
|
33
|
-
const resolution = await runtime.getAuth(ZAI_PROVIDER_ID);
|
|
32
|
+
export async function fetchZaiPlanUsage(runtime, auth) {
|
|
33
|
+
const resolution = auth ? auth.resolution : await runtime.getAuth(ZAI_PROVIDER_ID);
|
|
34
34
|
const apiKey = resolution?.auth.apiKey;
|
|
35
35
|
if (!apiKey)
|
|
36
36
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zai.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/zai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEtG,MAAM,eAAe,GAAG,KAAK,CAAC;AAC9B,MAAM,aAAa,GAAG,gDAAgD,CAAC;AAEvE,SAAS,UAAU,CAAC,KAA8B,EAAsB;IACvE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,SAAS,CAAC;IAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,GAAG,MAAM,GAAG,CAAC;IAC5D,IAAI,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,GAAG,MAAM,GAAG,CAAC;IAC5D,IAAI,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,GAAG,MAAM,GAAG,CAAC;IAC5D,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChC,OAAO,OAAO,CAAC;AAAA,CACf;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,
|
|
1
|
+
{"version":3,"file":"zai.js","sourceRoot":"","sources":["../../../src/core/usage-adapters/zai.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Z.AI (GLM coding plan) usage: `GET https://api.z.ai/api/monitor/usage/quota/limit`\n * with the stored API key. Response shape (undocumented, used by the official\n * plugin and several open-source quota dashboards):\n * { success, code, msg,\n * data: { planName?/plan?/level?,\n * limits: [{ type: \"TOKENS_LIMIT\"|\"TIME_LIMIT\", unit, number,\n * percentage, nextResetTime? }] } }\n * `unit`: 1 = days, 3 = hours, 5 = minutes, 6 = weeks.\n */\n\nimport type { ModelRuntime } from \"../model-runtime.ts\";\nimport type { PlanUsage, PlanUsageWindow, UsageAuthSnapshot } from \"../usage-service.ts\";\nimport { asNumber, asObject, asString, clampPercent, fetchWithTimeout, toEpochMs } from \"./shared.ts\";\n\nconst ZAI_PROVIDER_ID = \"zai\";\nconst ZAI_QUOTA_URL = \"https://api.z.ai/api/monitor/usage/quota/limit\";\n\nfunction limitLabel(limit: Record<string, unknown>): string | undefined {\n\tconst type = asString(limit.type);\n\tif (type === \"TIME_LIMIT\") return \"Monthly\";\n\tif (type !== \"TOKENS_LIMIT\") return undefined;\n\tconst unit = asNumber(limit.unit);\n\tconst number = asNumber(limit.number);\n\tif (unit === 1 && number !== undefined) return `${number}d`;\n\tif (unit === 3 && number !== undefined) return `${number}h`;\n\tif (unit === 5 && number !== undefined) return `${number}m`;\n\tif (unit === 6) return \"Weekly\";\n\treturn \"Limit\";\n}\n\nexport async function fetchZaiPlanUsage(\n\truntime: ModelRuntime,\n\tauth?: UsageAuthSnapshot,\n): Promise<PlanUsage | undefined> {\n\tconst resolution = auth ? auth.resolution : await runtime.getAuth(ZAI_PROVIDER_ID);\n\tconst apiKey = resolution?.auth.apiKey;\n\tif (!apiKey) return undefined;\n\n\tconst response = await fetchWithTimeout(ZAI_QUOTA_URL, {\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Accept-Language\": \"en-US,en\",\n\t\t},\n\t});\n\tif (!response.ok) return undefined;\n\tconst payload = asObject(await response.json());\n\tif (!payload || payload.success !== true || asNumber(payload.code) !== 200) return undefined;\n\n\tconst data = asObject(payload.data);\n\tconst limits = Array.isArray(data?.limits) ? data.limits : [];\n\tconst windows: PlanUsageWindow[] = [];\n\tfor (const item of limits) {\n\t\tconst limit = asObject(item);\n\t\tif (!limit) continue;\n\t\tconst label = limitLabel(limit);\n\t\tconst percentage = asNumber(limit.percentage);\n\t\tif (!label || percentage === undefined) continue;\n\t\twindows.push({ label, usedPercent: clampPercent(percentage), resetsAt: toEpochMs(limit.nextResetTime) });\n\t}\n\tif (windows.length === 0) return undefined;\n\tconst planLabel = asString(data?.planName) ?? asString(data?.plan) ?? asString(data?.level);\n\treturn { provider: ZAI_PROVIDER_ID, planLabel, windows };\n}\n"]}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* Adapter/network errors resolve to `undefined` (callers omit the plan UI).
|
|
13
13
|
* Auth failures are different: they return `error` and are not cached as empty.
|
|
14
14
|
*/
|
|
15
|
+
import type { AuthResult } from "@ashx-j/lunr-ai";
|
|
15
16
|
import type { ModelRuntime } from "./model-runtime.ts";
|
|
16
17
|
import type { SettingsManager } from "./settings-manager.ts";
|
|
17
18
|
export interface PlanUsageWindow {
|
|
@@ -39,6 +40,11 @@ export interface AllPlanUsageResult {
|
|
|
39
40
|
}
|
|
40
41
|
/** Classify adapter/getAuth failures that mean the SuperGrok session is dead. */
|
|
41
42
|
export declare function planUsageAuthError(error: unknown): string | undefined;
|
|
43
|
+
export interface UsageAuthSnapshot {
|
|
44
|
+
resolution?: AuthResult;
|
|
45
|
+
codexHeaders?: Record<string, string>;
|
|
46
|
+
oauth: boolean;
|
|
47
|
+
}
|
|
42
48
|
export declare const PLAN_USAGE_CACHE_TTL_MS: number;
|
|
43
49
|
export type PlanUsageWindowPreference = "5h" | "weekly";
|
|
44
50
|
export declare function isWeeklyPlanWindow(window: PlanUsageWindow): boolean;
|
|
@@ -55,7 +61,7 @@ export declare function getPlanUsageResult(providerId: string, runtime: ModelRun
|
|
|
55
61
|
/** Fetch every stored-credential plan plus the current provider, in parallel. */
|
|
56
62
|
export declare function getAllPlanUsageResults(currentProvider: string | undefined, runtime: ModelRuntime): Promise<AllPlanUsageResult>;
|
|
57
63
|
/** Last fetched usage, including expired cache (footer can show stale while refetching). */
|
|
58
|
-
export declare function peekPlanUsage(providerId: string): PlanUsage | undefined;
|
|
64
|
+
export declare function peekPlanUsage(providerId: string, runtime: ModelRuntime): PlanUsage | undefined;
|
|
59
65
|
/** Clear the adapter cache (tests, /login changes). */
|
|
60
66
|
export declare function clearPlanUsageCache(): void;
|
|
61
67
|
export declare const USAGE_SERVICE_BRIDGE_SYMBOL: unique symbol;
|
|
@@ -70,6 +76,7 @@ export interface UsageServiceBridge {
|
|
|
70
76
|
pickForFooter(providerId: string): FooterPlanSegment | undefined;
|
|
71
77
|
setOnUpdate(fn: (() => void) | undefined): void;
|
|
72
78
|
}
|
|
79
|
+
/** Register a bridge bound to its runtime; footer callbacks can retain it outside async scope. */
|
|
73
80
|
export declare function registerUsageServiceBridge(runtime: ModelRuntime, settingsManager: SettingsManager): void;
|
|
74
|
-
export declare function getUsageServiceBridge(): UsageServiceBridge | undefined;
|
|
81
|
+
export declare function getUsageServiceBridge(runtime?: ModelRuntime | undefined): UsageServiceBridge | undefined;
|
|
75
82
|
//# sourceMappingURL=usage-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-service.d.ts","sourceRoot":"","sources":["../../src/core/usage-service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Plan/subscription usage service. Per-provider adapters query provider quota\n * endpoints (60-second cache each) so /usage and the footer can show subscription windows\n * alongside session/context totals.\n *\n * Deliberately absent adapters:\n * - anthropic: Anthropic policy prohibits subscription usage tracking in\n * third-party coding agents (2026-07-18 decision). OAuth Anthropic sessions\n * fall back to hiding the cost meter.\n * - ollama-cloud: no usage API exists.\n *\n * Adapter/network errors resolve to `undefined` (callers omit the plan UI).\n * Auth failures are different: they return `error` and are not cached as empty.\n */\n\nimport type { ModelRuntime } from \"./model-runtime.ts\";\nimport { runtimeScope } from \"./runtime-scope.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport { fetchKimiPlanUsage } from \"./usage-adapters/kimi-coding.ts\";\nimport { fetchCodexPlanUsage } from \"./usage-adapters/openai-codex.ts\";\nimport { fetchXaiPlanUsage } from \"./usage-adapters/xai.ts\";\nimport { fetchZaiPlanUsage } from \"./usage-adapters/zai.ts\";\n\nexport interface PlanUsageWindow {\n\tlabel: string;\n\tusedPercent: number;\n\t/** Epoch ms when the window resets. */\n\tresetsAt?: number;\n}\n\nexport interface PlanUsage {\n\tprovider: string;\n\tplanLabel?: string;\n\twindows: PlanUsageWindow[];\n}\n\nexport interface PlanUsageResult {\n\t/** First plan, kept for footer and compatibility callers. */\n\tusage?: PlanUsage;\n\t/** Every plan returned by the provider. */\n\tusages?: PlanUsage[];\n\t/** Actionable auth failure. Not cached as an empty success. */\n\terror?: string;\n}\n\nexport interface AllPlanUsageResult {\n\tusages: PlanUsage[];\n\terrors: string[];\n}\n\nconst XAI_RELOGIN = \"xAI login expired. Run /login xai.\";\n\nfunction errorChain(error: unknown): string {\n\tconst parts: string[] = [];\n\tlet current: unknown = error;\n\tconst seen = new Set<unknown>();\n\twhile (current && typeof current === \"object\" && !seen.has(current)) {\n\t\tseen.add(current);\n\t\tif (current instanceof Error) {\n\t\t\tparts.push(current.message);\n\t\t\tcurrent = current.cause;\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\treturn parts.join(\" \");\n}\n\n/** Classify adapter/getAuth failures that mean the SuperGrok session is dead. */\nexport function planUsageAuthError(error: unknown): string | undefined {\n\tconst chain = errorChain(error);\n\tif (/timed out|aborted|cancelled|ECONN|ENOTFOUND|network/i.test(chain)) return undefined;\n\t// 403 on billing is often entitlement, not a dead refresh token.\n\tif (/xai billing rejected the session \\(HTTP 401\\)/i.test(chain)) return XAI_RELOGIN;\n\tif (/invalid_grant|refresh token revoked/i.test(chain)) return XAI_RELOGIN;\n\treturn undefined;\n}\n\ntype UsageAdapter = (runtime: ModelRuntime) => Promise<PlanUsage | PlanUsage[] | undefined>;\n\nconst ADAPTERS: Readonly<Record<string, UsageAdapter>> = {\n\t\"openai-codex\": fetchCodexPlanUsage,\n\t\"kimi-coding\": fetchKimiPlanUsage,\n\tzai: fetchZaiPlanUsage,\n\txai: fetchXaiPlanUsage,\n};\n\nexport const PLAN_USAGE_CACHE_TTL_MS = 60 * 1000;\n\nexport type PlanUsageWindowPreference = \"5h\" | \"weekly\";\n\nexport function isWeeklyPlanWindow(window: PlanUsageWindow): boolean {\n\treturn /week/i.test(window.label);\n}\n\nexport function isFiveHourPlanWindow(window: PlanUsageWindow): boolean {\n\treturn /5h/i.test(window.label) || window.label === \"5h\";\n}\n\n/** Preferred window, falling back to the other, skipping Extra/on-demand. */\nexport function pickPlanWindow(\n\tusage: PlanUsage | undefined,\n\tpreferred: PlanUsageWindowPreference,\n): PlanUsageWindow | undefined {\n\tif (!usage?.windows.length) return undefined;\n\tconst usable = usage.windows.filter((w) => !/extra/i.test(w.label));\n\tconst weekly = usable.find(isWeeklyPlanWindow);\n\tconst fiveH = usable.find(isFiveHourPlanWindow);\n\tif (preferred === \"5h\") return fiveH ?? weekly ?? usable[0] ?? usage.windows[0];\n\treturn weekly ?? fiveH ?? usable[0] ?? usage.windows[0];\n}\n\nexport function footerPlanLabel(window: PlanUsageWindow): string {\n\tif (isFiveHourPlanWindow(window)) return \"5h\";\n\tif (isWeeklyPlanWindow(window)) return \"wk\";\n\treturn window.label.length <= 4 ? window.label : window.label.slice(0, 4);\n}\n\nconst cache = new Map<string, { expiresAt: number; value: PlanUsage[] }>();\nconst inflight = new Map<string, Promise<PlanUsageResult>>();\n\n/** Whether a plan-usage adapter exists for this provider. */\nexport function hasPlanUsageAdapter(providerId: string): boolean {\n\treturn providerId in ADAPTERS;\n}\n\n/** Plan usage for a provider, or undefined when unsupported/unavailable. Never throws. */\nexport async function getPlanUsage(providerId: string, runtime: ModelRuntime): Promise<PlanUsage | undefined> {\n\treturn (await getPlanUsageResult(providerId, runtime)).usage;\n}\n\n/** Like getPlanUsage, but surfaces auth failures instead of hiding them. */\nexport async function getPlanUsageResult(providerId: string, runtime: ModelRuntime): Promise<PlanUsageResult> {\n\tconst adapter = ADAPTERS[providerId];\n\tif (!adapter) return {};\n\tconst now = Date.now();\n\tconst cached = cache.get(providerId);\n\tif (cached && cached.expiresAt > now) return { usage: cached.value[0], usages: cached.value };\n\tconst pending = inflight.get(providerId);\n\tif (pending) return pending;\n\tconst task = (async (): Promise<PlanUsageResult> => {\n\t\ttry {\n\t\t\tconst value = await adapter(runtime);\n\t\t\tconst usages = value === undefined ? [] : Array.isArray(value) ? value : [value];\n\t\t\tcache.set(providerId, { expiresAt: Date.now() + PLAN_USAGE_CACHE_TTL_MS, value: usages });\n\t\t\treturn { usage: usages[0], usages };\n\t\t} catch (error) {\n\t\t\tconst authError = planUsageAuthError(error);\n\t\t\tif (authError) return { error: authError };\n\t\t\tcache.set(providerId, { expiresAt: Date.now() + PLAN_USAGE_CACHE_TTL_MS, value: [] });\n\t\t\treturn {};\n\t\t} finally {\n\t\t\tinflight.delete(providerId);\n\t\t}\n\t})();\n\tinflight.set(providerId, task);\n\treturn task;\n}\n\n/** Fetch every stored-credential plan plus the current provider, in parallel. */\nexport async function getAllPlanUsageResults(\n\tcurrentProvider: string | undefined,\n\truntime: ModelRuntime,\n): Promise<AllPlanUsageResult> {\n\tconst stored = new Set((await runtime.listCredentials()).map((credential) => credential.providerId));\n\tconst providers = Object.keys(ADAPTERS).filter(\n\t\t(providerId) => stored.has(providerId) || providerId === currentProvider,\n\t);\n\tconst results = await Promise.all(providers.map((providerId) => getPlanUsageResult(providerId, runtime)));\n\treturn {\n\t\tusages: results.flatMap((result) => result.usages ?? []),\n\t\terrors: results.flatMap((result) => (result.error ? [`${result.error}`] : [])),\n\t};\n}\n\n/** Last fetched usage, including expired cache (footer can show stale while refetching). */\nexport function peekPlanUsage(providerId: string): PlanUsage | undefined {\n\treturn cache.get(providerId)?.value[0];\n}\n\n/** Clear the adapter cache (tests, /login changes). */\nexport function clearPlanUsageCache(): void {\n\tcache.clear();\n\tinflight.clear();\n}\n\n// ---------------------------------------------------------------------------\n// Extension bridge\n// ---------------------------------------------------------------------------\n\nexport const USAGE_SERVICE_BRIDGE_SYMBOL = Symbol.for(\"@lunr/usage-service\");\n\nexport interface FooterPlanSegment {\n\tlabel: string;\n\tusedPercent: number;\n}\n\nexport interface UsageServiceBridge {\n\tpeek(providerId: string): PlanUsage | undefined;\n\tprefetch(providerId: string): void;\n\tgetPreferredWindow(): PlanUsageWindowPreference;\n\tpickForFooter(providerId: string): FooterPlanSegment | undefined;\n\tsetOnUpdate(fn: (() => void) | undefined): void;\n}\n\nlet activeRuntime: ModelRuntime | undefined;\nlet activeUsageSettings: SettingsManager | undefined;\nlet onUsageUpdate: (() => void) | undefined;\n\nfunction preferredWindow(): PlanUsageWindowPreference {\n\treturn (runtimeScope.getStore()?.settingsManager ?? activeUsageSettings)?.getPlanUsageWindow() ?? \"weekly\";\n}\n\nconst usageBridge: UsageServiceBridge = {\n\tpeek(providerId: string): PlanUsage | undefined {\n\t\treturn peekPlanUsage(providerId);\n\t},\n\tprefetch(providerId: string): void {\n\t\tconst runtime = runtimeScope.getStore()?.modelRuntime ?? activeRuntime;\n\t\tif (!runtime || !hasPlanUsageAdapter(providerId)) return;\n\t\tvoid getPlanUsage(providerId, runtime).then(() => onUsageUpdate?.());\n\t},\n\tsetOnUpdate(fn: (() => void) | undefined): void {\n\t\tonUsageUpdate = fn;\n\t},\n\tgetPreferredWindow(): PlanUsageWindowPreference {\n\t\treturn preferredWindow();\n\t},\n\tpickForFooter(providerId: string): FooterPlanSegment | undefined {\n\t\tconst window = pickPlanWindow(peekPlanUsage(providerId), preferredWindow());\n\t\tif (!window) return undefined;\n\t\treturn { label: footerPlanLabel(window), usedPercent: window.usedPercent };\n\t},\n};\n\nexport function registerUsageServiceBridge(runtime: ModelRuntime, settingsManager: SettingsManager): void {\n\tactiveRuntime = runtime;\n\tactiveUsageSettings = settingsManager;\n\t(globalThis as Record<symbol, unknown>)[USAGE_SERVICE_BRIDGE_SYMBOL] = usageBridge;\n}\n\nexport function getUsageServiceBridge(): UsageServiceBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[USAGE_SERVICE_BRIDGE_SYMBOL] as UsageServiceBridge | undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"usage-service.d.ts","sourceRoot":"","sources":["../../src/core/usage-service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Plan/subscription usage service. Per-provider adapters query provider quota\n * endpoints (60-second cache each) so /usage and the footer can show subscription windows\n * alongside session/context totals.\n *\n * Deliberately absent adapters:\n * - anthropic: Anthropic policy prohibits subscription usage tracking in\n * third-party coding agents (2026-07-18 decision). OAuth Anthropic sessions\n * fall back to hiding the cost meter.\n * - ollama-cloud: no usage API exists.\n *\n * Adapter/network errors resolve to `undefined` (callers omit the plan UI).\n * Auth failures are different: they return `error` and are not cached as empty.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { AuthResult } from \"@ashx-j/lunr-ai\";\nimport type { ModelRuntime } from \"./model-runtime.ts\";\nimport { runtimeScope } from \"./runtime-scope.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\nimport { fetchKimiPlanUsage } from \"./usage-adapters/kimi-coding.ts\";\nimport { fetchCodexPlanUsage, resolveCodexHeaders } from \"./usage-adapters/openai-codex.ts\";\nimport { fetchXaiPlanUsage } from \"./usage-adapters/xai.ts\";\nimport { fetchZaiPlanUsage } from \"./usage-adapters/zai.ts\";\n\nexport interface PlanUsageWindow {\n\tlabel: string;\n\tusedPercent: number;\n\t/** Epoch ms when the window resets. */\n\tresetsAt?: number;\n}\n\nexport interface PlanUsage {\n\tprovider: string;\n\tplanLabel?: string;\n\twindows: PlanUsageWindow[];\n}\n\nexport interface PlanUsageResult {\n\t/** First plan, kept for footer and compatibility callers. */\n\tusage?: PlanUsage;\n\t/** Every plan returned by the provider. */\n\tusages?: PlanUsage[];\n\t/** Actionable auth failure. Not cached as an empty success. */\n\terror?: string;\n}\n\nexport interface AllPlanUsageResult {\n\tusages: PlanUsage[];\n\terrors: string[];\n}\n\nconst XAI_RELOGIN = \"xAI login expired. Run /login xai.\";\n\nfunction errorChain(error: unknown): string {\n\tconst parts: string[] = [];\n\tlet current: unknown = error;\n\tconst seen = new Set<unknown>();\n\twhile (current && typeof current === \"object\" && !seen.has(current)) {\n\t\tseen.add(current);\n\t\tif (current instanceof Error) {\n\t\t\tparts.push(current.message);\n\t\t\tcurrent = current.cause;\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\treturn parts.join(\" \");\n}\n\n/** Classify adapter/getAuth failures that mean the SuperGrok session is dead. */\nexport function planUsageAuthError(error: unknown): string | undefined {\n\tconst chain = errorChain(error);\n\tif (/timed out|aborted|cancelled|ECONN|ENOTFOUND|network/i.test(chain)) return undefined;\n\t// 403 on billing is often entitlement, not a dead refresh token.\n\tif (/xai billing rejected the session \\(HTTP 401\\)/i.test(chain)) return XAI_RELOGIN;\n\tif (/invalid_grant|refresh token revoked/i.test(chain)) return XAI_RELOGIN;\n\treturn undefined;\n}\n\nexport interface UsageAuthSnapshot {\n\tresolution?: AuthResult;\n\tcodexHeaders?: Record<string, string>;\n\toauth: boolean;\n}\n\ntype UsageAdapter = (runtime: ModelRuntime, auth: UsageAuthSnapshot) => Promise<PlanUsage | PlanUsage[] | undefined>;\n\nconst ADAPTERS: Readonly<Record<string, UsageAdapter>> = {\n\t\"openai-codex\": fetchCodexPlanUsage,\n\t\"kimi-coding\": fetchKimiPlanUsage,\n\tzai: fetchZaiPlanUsage,\n\txai: fetchXaiPlanUsage,\n};\n\nexport const PLAN_USAGE_CACHE_TTL_MS = 60 * 1000;\n\nexport type PlanUsageWindowPreference = \"5h\" | \"weekly\";\n\nexport function isWeeklyPlanWindow(window: PlanUsageWindow): boolean {\n\treturn /week/i.test(window.label);\n}\n\nexport function isFiveHourPlanWindow(window: PlanUsageWindow): boolean {\n\treturn /5h/i.test(window.label) || window.label === \"5h\";\n}\n\n/** Preferred window, falling back to the other, skipping Extra/on-demand. */\nexport function pickPlanWindow(\n\tusage: PlanUsage | undefined,\n\tpreferred: PlanUsageWindowPreference,\n): PlanUsageWindow | undefined {\n\tif (!usage?.windows.length) return undefined;\n\tconst usable = usage.windows.filter((w) => !/extra/i.test(w.label));\n\tconst weekly = usable.find(isWeeklyPlanWindow);\n\tconst fiveH = usable.find(isFiveHourPlanWindow);\n\tif (preferred === \"5h\") return fiveH ?? weekly ?? usable[0] ?? usage.windows[0];\n\treturn weekly ?? fiveH ?? usable[0] ?? usage.windows[0];\n}\n\nexport function footerPlanLabel(window: PlanUsageWindow): string {\n\tif (isFiveHourPlanWindow(window)) return \"5h\";\n\tif (isWeeklyPlanWindow(window)) return \"wk\";\n\treturn window.label.length <= 4 ? window.label : window.label.slice(0, 4);\n}\n\ninterface UsageState {\n\taccounts: Map<string, string>;\n\tauthReads: Map<string, { started: number; settled: number }>;\n\tcache: Map<string, { expiresAt: number; value: PlanUsage[] }>;\n\tinflight: Map<string, Promise<PlanUsageResult>>;\n}\nlet generation = 0;\nlet states = new WeakMap<ModelRuntime, UsageState>();\n\nfunction stateFor(runtime: ModelRuntime): UsageState {\n\tlet state = states.get(runtime);\n\tif (!state) {\n\t\tstate = { accounts: new Map(), authReads: new Map(), cache: new Map(), inflight: new Map() };\n\t\tstates.set(runtime, state);\n\t}\n\treturn state;\n}\n\n/** Whether a plan-usage adapter exists for this provider. */\nexport function hasPlanUsageAdapter(providerId: string): boolean {\n\treturn providerId in ADAPTERS;\n}\n\n/** Plan usage for a provider, or undefined when unsupported/unavailable. Never throws. */\nexport async function getPlanUsage(providerId: string, runtime: ModelRuntime): Promise<PlanUsage | undefined> {\n\treturn (await getPlanUsageResult(providerId, runtime)).usage;\n}\n\n/** Like getPlanUsage, but surfaces auth failures instead of hiding them. */\nexport async function getPlanUsageResult(providerId: string, runtime: ModelRuntime): Promise<PlanUsageResult> {\n\tconst adapter = ADAPTERS[providerId];\n\tif (!adapter) return {};\n\tconst state = stateFor(runtime);\n\tconst requestGeneration = generation;\n\tconst reads = state.authReads.get(providerId) ?? { started: 0, settled: 0 };\n\tstate.authReads.set(providerId, reads);\n\tconst authRead = ++reads.started;\n\tlet auth: UsageAuthSnapshot;\n\ttry {\n\t\tauth =\n\t\t\tproviderId === \"openai-codex\"\n\t\t\t\t? { codexHeaders: await resolveCodexHeaders(runtime), oauth: runtime.isUsingOAuth(providerId) }\n\t\t\t\t: { resolution: await runtime.getAuth(providerId), oauth: runtime.isUsingOAuth(providerId) };\n\t} catch (error) {\n\t\tif (reads.settled <= authRead) {\n\t\t\treads.settled = authRead;\n\t\t\tstate.accounts.delete(providerId);\n\t\t\tstate.cache.delete(providerId);\n\t\t\tstate.inflight.delete(providerId);\n\t\t}\n\t\treturn { error: planUsageAuthError(error) };\n\t}\n\tif (generation !== requestGeneration || states.get(runtime) !== state) return {};\n\t// Only a digest is retained. Neither credentials nor account identifiers are persisted.\n\tconst account = createHash(\"sha256\").update(JSON.stringify(auth)).digest(\"hex\");\n\tconst previous = state.accounts.get(providerId);\n\tif (reads.settled > authRead && previous !== account) return {};\n\treads.settled = Math.max(reads.settled, authRead);\n\tif (previous !== account) {\n\t\tstate.cache.delete(providerId);\n\t\tstate.inflight.delete(providerId);\n\t\tstate.accounts.set(providerId, account);\n\t}\n\tconst cached = state.cache.get(providerId);\n\tif (cached && cached.expiresAt > Date.now()) return { usage: cached.value[0], usages: cached.value };\n\tconst pending = state.inflight.get(providerId);\n\tif (pending) return pending;\n\tconst isCurrent = () =>\n\t\tgeneration === requestGeneration &&\n\t\tstates.get(runtime) === state &&\n\t\tstate.accounts.get(providerId) === account &&\n\t\tstate.inflight.get(providerId) === task;\n\tconst task = (async (): Promise<PlanUsageResult> => {\n\t\ttry {\n\t\t\tconst value = await adapter(runtime, auth);\n\t\t\tconst usages = value === undefined ? [] : Array.isArray(value) ? value : [value];\n\t\t\tif (isCurrent())\n\t\t\t\tstate.cache.set(providerId, { expiresAt: Date.now() + PLAN_USAGE_CACHE_TTL_MS, value: usages });\n\t\t\treturn { usage: usages[0], usages };\n\t\t} catch (error) {\n\t\t\tconst authError = planUsageAuthError(error);\n\t\t\tif (authError) return { error: authError };\n\t\t\tif (isCurrent()) state.cache.set(providerId, { expiresAt: Date.now() + PLAN_USAGE_CACHE_TTL_MS, value: [] });\n\t\t\treturn {};\n\t\t} finally {\n\t\t\tif (isCurrent()) state.inflight.delete(providerId);\n\t\t}\n\t})();\n\tstate.inflight.set(providerId, task);\n\treturn task;\n}\n\n/** Fetch every stored-credential plan plus the current provider, in parallel. */\nexport async function getAllPlanUsageResults(\n\tcurrentProvider: string | undefined,\n\truntime: ModelRuntime,\n): Promise<AllPlanUsageResult> {\n\tconst stored = new Set((await runtime.listCredentials()).map((credential) => credential.providerId));\n\tconst providers = Object.keys(ADAPTERS).filter(\n\t\t(providerId) => stored.has(providerId) || providerId === currentProvider,\n\t);\n\tconst results = await Promise.all(providers.map((providerId) => getPlanUsageResult(providerId, runtime)));\n\treturn {\n\t\tusages: results.flatMap((result) => result.usages ?? []),\n\t\terrors: results.flatMap((result) => (result.error ? [`${result.error}`] : [])),\n\t};\n}\n\n/** Last fetched usage, including expired cache (footer can show stale while refetching). */\nexport function peekPlanUsage(providerId: string, runtime: ModelRuntime): PlanUsage | undefined {\n\treturn states.get(runtime)?.cache.get(providerId)?.value[0];\n}\n\n/** Clear the adapter cache (tests, /login changes). */\nexport function clearPlanUsageCache(): void {\n\tgeneration++;\n\tstates = new WeakMap();\n}\n\n// ---------------------------------------------------------------------------\n// Extension bridge\n// ---------------------------------------------------------------------------\n\nexport const USAGE_SERVICE_BRIDGE_SYMBOL = Symbol.for(\"@lunr/usage-service\");\n\nexport interface FooterPlanSegment {\n\tlabel: string;\n\tusedPercent: number;\n}\n\nexport interface UsageServiceBridge {\n\tpeek(providerId: string): PlanUsage | undefined;\n\tprefetch(providerId: string): void;\n\tgetPreferredWindow(): PlanUsageWindowPreference;\n\tpickForFooter(providerId: string): FooterPlanSegment | undefined;\n\tsetOnUpdate(fn: (() => void) | undefined): void;\n}\n\nconst bridges = new WeakMap<ModelRuntime, UsageServiceBridge>();\n\n/** Register a bridge bound to its runtime; footer callbacks can retain it outside async scope. */\nexport function registerUsageServiceBridge(runtime: ModelRuntime, settingsManager: SettingsManager): void {\n\tlet onUpdate: (() => void) | undefined;\n\tconst bridge: UsageServiceBridge = {\n\t\tpeek: (providerId) => peekPlanUsage(providerId, runtime),\n\t\tprefetch(providerId) {\n\t\t\tif (!hasPlanUsageAdapter(providerId)) return;\n\t\t\tvoid getPlanUsage(providerId, runtime).then(() => onUpdate?.());\n\t\t},\n\t\tsetOnUpdate(fn) {\n\t\t\tonUpdate = fn;\n\t\t},\n\t\tgetPreferredWindow: () => settingsManager.getPlanUsageWindow(),\n\t\tpickForFooter(providerId) {\n\t\t\tconst window = pickPlanWindow(peekPlanUsage(providerId, runtime), settingsManager.getPlanUsageWindow());\n\t\t\treturn window ? { label: footerPlanLabel(window), usedPercent: window.usedPercent } : undefined;\n\t\t},\n\t};\n\tbridges.set(runtime, bridge);\n\t// Compatibility bridge requires an explicit async owner; it never falls back to another session.\n\t(globalThis as Record<symbol, unknown>)[USAGE_SERVICE_BRIDGE_SYMBOL] = {\n\t\tpeek: (providerId: string) => getUsageServiceBridge()?.peek(providerId),\n\t\tprefetch: (providerId: string) => getUsageServiceBridge()?.prefetch(providerId),\n\t\tpickForFooter: (providerId: string) => getUsageServiceBridge()?.pickForFooter(providerId),\n\t\tgetPreferredWindow: () => getUsageServiceBridge()?.getPreferredWindow() ?? \"weekly\",\n\t\tsetOnUpdate: (fn: (() => void) | undefined) => getUsageServiceBridge()?.setOnUpdate(fn),\n\t} satisfies UsageServiceBridge;\n}\n\nexport function getUsageServiceBridge(runtime = runtimeScope.getStore()?.modelRuntime): UsageServiceBridge | undefined {\n\treturn runtime ? bridges.get(runtime) : undefined;\n}\n"]}
|