@slkiser/opencode-quota 5.0.3 → 6.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -44
- package/dist/agent-tools.d.ts +24 -0
- package/dist/agent-tools.d.ts.map +1 -0
- package/dist/agent-tools.js +578 -0
- package/dist/agent-tools.js.map +1 -0
- package/dist/bin/opencode-quota.d.ts.map +1 -1
- package/dist/bin/opencode-quota.js +1 -32
- package/dist/bin/opencode-quota.js.map +1 -1
- package/dist/core/errors.d.ts +12 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +141 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/pace.d.ts +13 -0
- package/dist/core/pace.d.ts.map +1 -0
- package/dist/core/pace.js +52 -0
- package/dist/core/pace.js.map +1 -0
- package/dist/core/persist.d.ts +44 -0
- package/dist/core/persist.d.ts.map +1 -0
- package/dist/core/persist.js +210 -0
- package/dist/core/persist.js.map +1 -0
- package/dist/core/provider-source.d.ts +40 -0
- package/dist/core/provider-source.d.ts.map +1 -0
- package/dist/core/provider-source.js +210 -0
- package/dist/core/provider-source.js.map +1 -0
- package/dist/core/redact.d.ts +17 -0
- package/dist/core/redact.d.ts.map +1 -0
- package/dist/core/redact.js +217 -0
- package/dist/core/redact.js.map +1 -0
- package/dist/core/rows.d.ts +20 -0
- package/dist/core/rows.d.ts.map +1 -0
- package/dist/core/rows.js +142 -0
- package/dist/core/rows.js.map +1 -0
- package/dist/core/selection.d.ts +15 -0
- package/dist/core/selection.d.ts.map +1 -0
- package/dist/core/selection.js +43 -0
- package/dist/core/selection.js.map +1 -0
- package/dist/core/snapshot-publisher.d.ts +15 -0
- package/dist/core/snapshot-publisher.d.ts.map +1 -0
- package/dist/core/snapshot-publisher.js +57 -0
- package/dist/core/snapshot-publisher.js.map +1 -0
- package/dist/core/store.d.ts +93 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +563 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/types.d.ts +186 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/usage-ranges.d.ts +46 -0
- package/dist/core/usage-ranges.d.ts.map +1 -0
- package/dist/core/usage-ranges.js +72 -0
- package/dist/core/usage-ranges.js.map +1 -0
- package/dist/core/usage.d.ts +100 -0
- package/dist/core/usage.d.ts.map +1 -0
- package/dist/core/usage.js +373 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/core/validate.d.ts +8 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +167 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/core/windows.d.ts +24 -0
- package/dist/core/windows.d.ts.map +1 -0
- package/dist/core/windows.js +43 -0
- package/dist/core/windows.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/accounting-format.d.ts +2 -52
- package/dist/lib/accounting-format.d.ts.map +1 -1
- package/dist/lib/accounting-format.js +6 -255
- package/dist/lib/accounting-format.js.map +1 -1
- package/dist/lib/alibaba-auth.d.ts +14 -21
- package/dist/lib/alibaba-auth.d.ts.map +1 -1
- package/dist/lib/alibaba-auth.js +36 -149
- package/dist/lib/alibaba-auth.js.map +1 -1
- package/dist/lib/alibaba-coding-plan-local-quota.d.ts +1 -6
- package/dist/lib/alibaba-coding-plan-local-quota.d.ts.map +1 -1
- package/dist/lib/alibaba-coding-plan-local-quota.js +1 -1
- package/dist/lib/alibaba-coding-plan-local-quota.js.map +1 -1
- package/dist/lib/alibaba-token-plan.d.ts +18 -27
- package/dist/lib/alibaba-token-plan.d.ts.map +1 -1
- package/dist/lib/alibaba-token-plan.js +121 -285
- package/dist/lib/alibaba-token-plan.js.map +1 -1
- package/dist/lib/anthropic-auth.d.ts +3 -5
- package/dist/lib/anthropic-auth.d.ts.map +1 -1
- package/dist/lib/anthropic-auth.js +6 -9
- package/dist/lib/anthropic-auth.js.map +1 -1
- package/dist/lib/anthropic.d.ts +12 -37
- package/dist/lib/anthropic.d.ts.map +1 -1
- package/dist/lib/anthropic.js +348 -698
- package/dist/lib/anthropic.js.map +1 -1
- package/dist/lib/api-key-resolver.d.ts +165 -192
- package/dist/lib/api-key-resolver.d.ts.map +1 -1
- package/dist/lib/api-key-resolver.js +208 -234
- package/dist/lib/api-key-resolver.js.map +1 -1
- package/dist/lib/atomic-json.d.ts +4 -1
- package/dist/lib/atomic-json.d.ts.map +1 -1
- package/dist/lib/atomic-json.js +2 -3
- package/dist/lib/atomic-json.js.map +1 -1
- package/dist/lib/calendar-date.d.ts +15 -0
- package/dist/lib/calendar-date.d.ts.map +1 -0
- package/dist/lib/calendar-date.js +21 -0
- package/dist/lib/calendar-date.js.map +1 -0
- package/dist/lib/chutes.d.ts +0 -1
- package/dist/lib/chutes.d.ts.map +1 -1
- package/dist/lib/chutes.js +2 -4
- package/dist/lib/chutes.js.map +1 -1
- package/dist/lib/cli-reports.d.ts +15 -11
- package/dist/lib/cli-reports.d.ts.map +1 -1
- package/dist/lib/cli-reports.js +34 -107
- package/dist/lib/cli-reports.js.map +1 -1
- package/dist/lib/cli-show.d.ts +9 -22
- package/dist/lib/cli-show.d.ts.map +1 -1
- package/dist/lib/cli-show.js +104 -75
- package/dist/lib/cli-show.js.map +1 -1
- package/dist/lib/config-file-utils.d.ts +3 -15
- package/dist/lib/config-file-utils.d.ts.map +1 -1
- package/dist/lib/config-file-utils.js +4 -63
- package/dist/lib/config-file-utils.js.map +1 -1
- package/dist/lib/config-write-target.d.ts +4 -7
- package/dist/lib/config-write-target.d.ts.map +1 -1
- package/dist/lib/config-write-target.js +4 -18
- package/dist/lib/config-write-target.js.map +1 -1
- package/dist/lib/copilot.d.ts +29 -20
- package/dist/lib/copilot.d.ts.map +1 -1
- package/dist/lib/copilot.js +392 -649
- package/dist/lib/copilot.js.map +1 -1
- package/dist/lib/cursor-detection.d.ts +3 -3
- package/dist/lib/cursor-detection.d.ts.map +1 -1
- package/dist/lib/cursor-detection.js +44 -88
- package/dist/lib/cursor-detection.js.map +1 -1
- package/dist/lib/cursor-pricing.d.ts +71 -8
- package/dist/lib/cursor-pricing.d.ts.map +1 -1
- package/dist/lib/cursor-pricing.js +33 -125
- package/dist/lib/cursor-pricing.js.map +1 -1
- package/dist/lib/cursor-usage.d.ts +6 -4
- package/dist/lib/cursor-usage.d.ts.map +1 -1
- package/dist/lib/cursor-usage.js +27 -40
- package/dist/lib/cursor-usage.js.map +1 -1
- package/dist/lib/deepseek.d.ts +9 -17
- package/dist/lib/deepseek.d.ts.map +1 -1
- package/dist/lib/deepseek.js +24 -54
- package/dist/lib/deepseek.js.map +1 -1
- package/dist/lib/display-sanitize.d.ts +0 -8
- package/dist/lib/display-sanitize.d.ts.map +1 -1
- package/dist/lib/display-sanitize.js +0 -139
- package/dist/lib/display-sanitize.js.map +1 -1
- package/dist/lib/entries.d.ts +13 -239
- package/dist/lib/entries.d.ts.map +1 -1
- package/dist/lib/entries.js +1 -46
- package/dist/lib/entries.js.map +1 -1
- package/dist/lib/file-lock.d.ts +23 -0
- package/dist/lib/file-lock.d.ts.map +1 -0
- package/dist/lib/file-lock.js +122 -0
- package/dist/lib/file-lock.js.map +1 -0
- package/dist/lib/format-utils.d.ts +2 -82
- package/dist/lib/format-utils.d.ts.map +1 -1
- package/dist/lib/format-utils.js +2 -191
- package/dist/lib/format-utils.js.map +1 -1
- package/dist/lib/glm-coding-plan.d.ts +6 -5
- package/dist/lib/glm-coding-plan.d.ts.map +1 -1
- package/dist/lib/glm-coding-plan.js +19 -1
- package/dist/lib/glm-coding-plan.js.map +1 -1
- package/dist/lib/google-agy.d.ts +8 -40
- package/dist/lib/google-agy.d.ts.map +1 -1
- package/dist/lib/google-agy.js +88 -519
- package/dist/lib/google-agy.js.map +1 -1
- package/dist/lib/google-companion-credentials.d.ts +9 -40
- package/dist/lib/google-companion-credentials.d.ts.map +1 -1
- package/dist/lib/google-companion-credentials.js +167 -224
- package/dist/lib/google-companion-credentials.js.map +1 -1
- package/dist/lib/google-gemini-cli.d.ts +5 -38
- package/dist/lib/google-gemini-cli.d.ts.map +1 -1
- package/dist/lib/google-gemini-cli.js +71 -442
- package/dist/lib/google-gemini-cli.js.map +1 -1
- package/dist/lib/google-oauth-quota.d.ts +76 -0
- package/dist/lib/google-oauth-quota.d.ts.map +1 -0
- package/dist/lib/google-oauth-quota.js +297 -0
- package/dist/lib/google-oauth-quota.js.map +1 -0
- package/dist/lib/google-token-cache.d.ts +3 -5
- package/dist/lib/google-token-cache.d.ts.map +1 -1
- package/dist/lib/google-token-cache.js +2 -14
- package/dist/lib/google-token-cache.js.map +1 -1
- package/dist/lib/home-dir-display.d.ts.map +1 -1
- package/dist/lib/home-dir-display.js +21 -39
- package/dist/lib/home-dir-display.js.map +1 -1
- package/dist/lib/http.d.ts +4 -1
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +2 -1
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/json-guards.d.ts +11 -0
- package/dist/lib/json-guards.d.ts.map +1 -0
- package/dist/lib/json-guards.js +25 -0
- package/dist/lib/json-guards.js.map +1 -0
- package/dist/lib/kilo.d.ts +0 -2
- package/dist/lib/kilo.d.ts.map +1 -1
- package/dist/lib/kilo.js +33 -116
- package/dist/lib/kilo.js.map +1 -1
- package/dist/lib/kimi-endpoints.d.ts +2 -2
- package/dist/lib/kimi-endpoints.d.ts.map +1 -1
- package/dist/lib/kimi-endpoints.js +1 -1
- package/dist/lib/kimi-endpoints.js.map +1 -1
- package/dist/lib/kimi.d.ts.map +1 -1
- package/dist/lib/kimi.js +40 -86
- package/dist/lib/kimi.js.map +1 -1
- package/dist/lib/maintainer-announcements.d.ts +4 -17
- package/dist/lib/maintainer-announcements.d.ts.map +1 -1
- package/dist/lib/maintainer-announcements.js +7 -44
- package/dist/lib/maintainer-announcements.js.map +1 -1
- package/dist/lib/maintainer-home-notice.d.ts +19 -0
- package/dist/lib/maintainer-home-notice.d.ts.map +1 -0
- package/dist/lib/maintainer-home-notice.js +92 -0
- package/dist/lib/maintainer-home-notice.js.map +1 -0
- package/dist/lib/mimo-config.d.ts +6 -9
- package/dist/lib/mimo-config.d.ts.map +1 -1
- package/dist/lib/mimo-config.js +43 -74
- package/dist/lib/mimo-config.js.map +1 -1
- package/dist/lib/mimo.d.ts +2 -5
- package/dist/lib/mimo.d.ts.map +1 -1
- package/dist/lib/mimo.js +57 -109
- package/dist/lib/mimo.js.map +1 -1
- package/dist/lib/minimax-endpoints.d.ts +2 -2
- package/dist/lib/minimax-endpoints.d.ts.map +1 -1
- package/dist/lib/minimax-endpoints.js +1 -1
- package/dist/lib/minimax-endpoints.js.map +1 -1
- package/dist/lib/modelsdev-pricing.d.ts +22 -16
- package/dist/lib/modelsdev-pricing.d.ts.map +1 -1
- package/dist/lib/modelsdev-pricing.js +279 -560
- package/dist/lib/modelsdev-pricing.js.map +1 -1
- package/dist/lib/nanogpt.d.ts +6 -6
- package/dist/lib/nanogpt.d.ts.map +1 -1
- package/dist/lib/nanogpt.js +19 -72
- package/dist/lib/nanogpt.js.map +1 -1
- package/dist/lib/ollama-cloud.d.ts +3 -6
- package/dist/lib/ollama-cloud.d.ts.map +1 -1
- package/dist/lib/ollama-cloud.js +26 -37
- package/dist/lib/ollama-cloud.js.map +1 -1
- package/dist/lib/openai.d.ts +18 -29
- package/dist/lib/openai.d.ts.map +1 -1
- package/dist/lib/openai.js +108 -182
- package/dist/lib/openai.js.map +1 -1
- package/dist/lib/opencode-auth-sqlite.d.ts.map +1 -1
- package/dist/lib/opencode-auth-sqlite.js +22 -23
- package/dist/lib/opencode-auth-sqlite.js.map +1 -1
- package/dist/lib/opencode-auth.d.ts +17 -11
- package/dist/lib/opencode-auth.d.ts.map +1 -1
- package/dist/lib/opencode-auth.js +39 -46
- package/dist/lib/opencode-auth.js.map +1 -1
- package/dist/lib/opencode-config-editor.d.ts +3 -34
- package/dist/lib/opencode-config-editor.d.ts.map +1 -1
- package/dist/lib/opencode-config-editor.js +23 -142
- package/dist/lib/opencode-config-editor.js.map +1 -1
- package/dist/lib/opencode-config-providers.d.ts +4 -3
- package/dist/lib/opencode-config-providers.d.ts.map +1 -1
- package/dist/lib/opencode-config-providers.js +7 -11
- package/dist/lib/opencode-config-providers.js.map +1 -1
- package/dist/lib/opencode-config-read.d.ts +2 -1
- package/dist/lib/opencode-config-read.d.ts.map +1 -1
- package/dist/lib/opencode-config-read.js +3 -2
- package/dist/lib/opencode-config-read.js.map +1 -1
- package/dist/lib/opencode-console-auth.d.ts +2 -3
- package/dist/lib/opencode-console-auth.d.ts.map +1 -1
- package/dist/lib/opencode-console-auth.js +2 -2
- package/dist/lib/opencode-console-auth.js.map +1 -1
- package/dist/lib/opencode-go.d.ts.map +1 -1
- package/dist/lib/opencode-go.js +51 -79
- package/dist/lib/opencode-go.js.map +1 -1
- package/dist/lib/opencode-storage.d.ts +18 -3
- package/dist/lib/opencode-storage.d.ts.map +1 -1
- package/dist/lib/opencode-storage.js +134 -2
- package/dist/lib/opencode-storage.js.map +1 -1
- package/dist/lib/opencode-zen.d.ts +15 -12
- package/dist/lib/opencode-zen.d.ts.map +1 -1
- package/dist/lib/opencode-zen.js +139 -147
- package/dist/lib/opencode-zen.js.map +1 -1
- package/dist/lib/openrouter.d.ts.map +1 -1
- package/dist/lib/openrouter.js +1 -13
- package/dist/lib/openrouter.js.map +1 -1
- package/dist/lib/pricing-key.d.ts +48 -0
- package/dist/lib/pricing-key.d.ts.map +1 -0
- package/dist/lib/pricing-key.js +371 -0
- package/dist/lib/pricing-key.js.map +1 -0
- package/dist/lib/provider-metadata.d.ts +16 -20
- package/dist/lib/provider-metadata.d.ts.map +1 -1
- package/dist/lib/provider-metadata.js +69 -69
- package/dist/lib/provider-metadata.js.map +1 -1
- package/dist/lib/provider-model-matching.d.ts +2 -1
- package/dist/lib/provider-model-matching.d.ts.map +1 -1
- package/dist/lib/provider-registration.d.ts +1 -177
- package/dist/lib/provider-registration.d.ts.map +1 -1
- package/dist/lib/provider-registration.js +1 -163
- package/dist/lib/provider-registration.js.map +1 -1
- package/dist/lib/quota-dialog-commands.d.ts +87 -53
- package/dist/lib/quota-dialog-commands.d.ts.map +1 -1
- package/dist/lib/quota-dialog-commands.js +259 -519
- package/dist/lib/quota-dialog-commands.js.map +1 -1
- package/dist/lib/quota-export-types.d.ts +29 -23
- package/dist/lib/quota-export-types.d.ts.map +1 -1
- package/dist/lib/quota-export.d.ts +16 -26
- package/dist/lib/quota-export.d.ts.map +1 -1
- package/dist/lib/quota-export.js +105 -147
- package/dist/lib/quota-export.js.map +1 -1
- package/dist/lib/quota-providers-local.d.ts +12 -8
- package/dist/lib/quota-providers-local.d.ts.map +1 -1
- package/dist/lib/quota-providers-local.js +150 -223
- package/dist/lib/quota-providers-local.js.map +1 -1
- package/dist/lib/quota-providers-remote.d.ts +3 -8
- package/dist/lib/quota-providers-remote.d.ts.map +1 -1
- package/dist/lib/quota-providers-remote.js +309 -449
- package/dist/lib/quota-providers-remote.js.map +1 -1
- package/dist/lib/quota-providers.d.ts +57 -15
- package/dist/lib/quota-providers.d.ts.map +1 -1
- package/dist/lib/quota-providers.js +157 -64
- package/dist/lib/quota-providers.js.map +1 -1
- package/dist/lib/quota-report-message.d.ts +23 -10
- package/dist/lib/quota-report-message.d.ts.map +1 -1
- package/dist/lib/quota-report-message.js +37 -13
- package/dist/lib/quota-report-message.js.map +1 -1
- package/dist/lib/quota-retry-wait.d.ts +14 -6
- package/dist/lib/quota-retry-wait.d.ts.map +1 -1
- package/dist/lib/quota-retry-wait.js +37 -39
- package/dist/lib/quota-retry-wait.js.map +1 -1
- package/dist/lib/quota-status.d.ts +50 -33
- package/dist/lib/quota-status.d.ts.map +1 -1
- package/dist/lib/quota-status.js +1113 -773
- package/dist/lib/quota-status.js.map +1 -1
- package/dist/lib/quota-telemetry.d.ts +7 -14
- package/dist/lib/quota-telemetry.d.ts.map +1 -1
- package/dist/lib/quota-telemetry.js +46 -97
- package/dist/lib/quota-telemetry.js.map +1 -1
- package/dist/lib/report-document.d.ts +5 -65
- package/dist/lib/report-document.d.ts.map +1 -1
- package/dist/lib/report-document.js +14 -167
- package/dist/lib/report-document.js.map +1 -1
- package/dist/lib/resolved-auth-identity.d.ts +1 -2
- package/dist/lib/resolved-auth-identity.d.ts.map +1 -1
- package/dist/lib/resolved-auth-identity.js +0 -4
- package/dist/lib/resolved-auth-identity.js.map +1 -1
- package/dist/lib/session-tokens.d.ts +19 -19
- package/dist/lib/session-tokens.d.ts.map +1 -1
- package/dist/lib/session-tokens.js +58 -44
- package/dist/lib/session-tokens.js.map +1 -1
- package/dist/lib/synthetic.d.ts +0 -1
- package/dist/lib/synthetic.d.ts.map +1 -1
- package/dist/lib/synthetic.js +43 -94
- package/dist/lib/synthetic.js.map +1 -1
- package/dist/lib/token-buckets.d.ts +0 -1
- package/dist/lib/token-buckets.d.ts.map +1 -1
- package/dist/lib/token-buckets.js +0 -3
- package/dist/lib/token-buckets.js.map +1 -1
- package/dist/lib/token-cost.d.ts +2 -1
- package/dist/lib/token-cost.d.ts.map +1 -1
- package/dist/lib/types.d.ts +25 -333
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +2 -70
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/xai.d.ts +6 -6
- package/dist/lib/xai.d.ts.map +1 -1
- package/dist/lib/xai.js +51 -90
- package/dist/lib/xai.js.map +1 -1
- package/dist/plugin.d.ts +6 -3
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +315 -90
- package/dist/plugin.js.map +1 -1
- package/dist/providers/alibaba-coding-plan.d.ts +4 -0
- package/dist/providers/alibaba-coding-plan.d.ts.map +1 -1
- package/dist/providers/alibaba-coding-plan.js +47 -77
- package/dist/providers/alibaba-coding-plan.js.map +1 -1
- package/dist/providers/alibaba-token-plan.d.ts.map +1 -1
- package/dist/providers/alibaba-token-plan.js +34 -46
- package/dist/providers/alibaba-token-plan.js.map +1 -1
- package/dist/providers/anthropic.d.ts +2 -4
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +80 -162
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/cache-policies.d.ts +0 -2
- package/dist/providers/cache-policies.d.ts.map +1 -1
- package/dist/providers/cache-policies.js +38 -88
- package/dist/providers/cache-policies.js.map +1 -1
- package/dist/providers/chutes.d.ts +0 -3
- package/dist/providers/chutes.d.ts.map +1 -1
- package/dist/providers/chutes.js +16 -28
- package/dist/providers/chutes.js.map +1 -1
- package/dist/providers/contract.d.ts +128 -0
- package/dist/providers/contract.d.ts.map +1 -0
- package/dist/providers/contract.js +101 -0
- package/dist/providers/contract.js.map +1 -0
- package/dist/providers/copilot.d.ts.map +1 -1
- package/dist/providers/copilot.js +171 -175
- package/dist/providers/copilot.js.map +1 -1
- package/dist/providers/cursor.d.ts.map +1 -1
- package/dist/providers/cursor.js +56 -109
- package/dist/providers/cursor.js.map +1 -1
- package/dist/providers/deepseek.d.ts +1 -6
- package/dist/providers/deepseek.d.ts.map +1 -1
- package/dist/providers/deepseek.js +46 -81
- package/dist/providers/deepseek.js.map +1 -1
- package/dist/providers/glm-coding-plan.d.ts +8 -0
- package/dist/providers/glm-coding-plan.d.ts.map +1 -0
- package/dist/providers/glm-coding-plan.js +106 -0
- package/dist/providers/glm-coding-plan.js.map +1 -0
- package/dist/providers/google-agy.d.ts +0 -1
- package/dist/providers/google-agy.d.ts.map +1 -1
- package/dist/providers/google-agy.js +41 -192
- package/dist/providers/google-agy.js.map +1 -1
- package/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/dist/providers/google-gemini-cli.js +51 -151
- package/dist/providers/google-gemini-cli.js.map +1 -1
- package/dist/providers/google-oauth-provider.d.ts +39 -0
- package/dist/providers/google-oauth-provider.d.ts.map +1 -0
- package/dist/providers/google-oauth-provider.js +161 -0
- package/dist/providers/google-oauth-provider.js.map +1 -0
- package/dist/providers/kilo.d.ts +0 -3
- package/dist/providers/kilo.d.ts.map +1 -1
- package/dist/providers/kilo.js +69 -123
- package/dist/providers/kilo.js.map +1 -1
- package/dist/providers/kimi-code.d.ts +5 -0
- package/dist/providers/kimi-code.d.ts.map +1 -1
- package/dist/providers/kimi-code.js +91 -136
- package/dist/providers/kimi-code.js.map +1 -1
- package/dist/providers/mimo.d.ts.map +1 -1
- package/dist/providers/mimo.js +55 -94
- package/dist/providers/mimo.js.map +1 -1
- package/dist/providers/minimax-coding-plan.d.ts +2 -23
- package/dist/providers/minimax-coding-plan.d.ts.map +1 -1
- package/dist/providers/minimax-coding-plan.js +161 -277
- package/dist/providers/minimax-coding-plan.js.map +1 -1
- package/dist/providers/nanogpt.d.ts +0 -3
- package/dist/providers/nanogpt.d.ts.map +1 -1
- package/dist/providers/nanogpt.js +61 -95
- package/dist/providers/nanogpt.js.map +1 -1
- package/dist/providers/ollama-cloud.d.ts +0 -6
- package/dist/providers/ollama-cloud.d.ts.map +1 -1
- package/dist/providers/ollama-cloud.js +86 -112
- package/dist/providers/ollama-cloud.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +144 -166
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/opencode-go.d.ts.map +1 -1
- package/dist/providers/opencode-go.js +157 -199
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/providers/opencode-zen.d.ts.map +1 -1
- package/dist/providers/opencode-zen.js +100 -150
- package/dist/providers/opencode-zen.js.map +1 -1
- package/dist/providers/openrouter.d.ts +0 -3
- package/dist/providers/openrouter.d.ts.map +1 -1
- package/dist/providers/openrouter.js +26 -13
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/quota-providers.d.ts +7 -3
- package/dist/providers/quota-providers.d.ts.map +1 -1
- package/dist/providers/quota-providers.js +111 -217
- package/dist/providers/quota-providers.js.map +1 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +1 -2
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/result-helpers.d.ts +10 -37
- package/dist/providers/result-helpers.d.ts.map +1 -1
- package/dist/providers/result-helpers.js +23 -56
- package/dist/providers/result-helpers.js.map +1 -1
- package/dist/providers/synthetic.d.ts +0 -3
- package/dist/providers/synthetic.d.ts.map +1 -1
- package/dist/providers/synthetic.js +16 -58
- package/dist/providers/synthetic.js.map +1 -1
- package/dist/providers/xai.d.ts +2 -1
- package/dist/providers/xai.d.ts.map +1 -1
- package/dist/providers/xai.js +49 -71
- package/dist/providers/xai.js.map +1 -1
- package/dist/rpc.d.ts +110 -38
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +125 -37
- package/dist/rpc.js.map +1 -1
- package/dist/settings/convert.d.ts +60 -0
- package/dist/settings/convert.d.ts.map +1 -0
- package/dist/settings/convert.js +473 -0
- package/dist/settings/convert.js.map +1 -0
- package/dist/settings/file.d.ts +89 -0
- package/dist/settings/file.d.ts.map +1 -0
- package/dist/settings/file.js +452 -0
- package/dist/settings/file.js.map +1 -0
- package/dist/settings/index.d.ts +10 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +3 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/schema.d.ts +607 -0
- package/dist/settings/schema.d.ts.map +1 -0
- package/dist/settings/schema.js +479 -0
- package/dist/settings/schema.js.map +1 -0
- package/dist/tui/client.d.ts +86 -0
- package/dist/tui/client.d.ts.map +1 -0
- package/dist/tui/client.js +229 -0
- package/dist/tui/client.js.map +1 -0
- package/dist/tui/display.d.ts +127 -0
- package/dist/tui/display.d.ts.map +1 -0
- package/dist/tui/display.js +474 -0
- package/dist/tui/display.js.map +1 -0
- package/dist/tui/index.d.ts +21 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +305 -0
- package/dist/tui/server-settings.d.ts +43 -0
- package/dist/tui/server-settings.d.ts.map +1 -0
- package/dist/tui/server-settings.js +233 -0
- package/dist/tui/server-settings.js.map +1 -0
- package/dist/tui/sidebar.d.ts +41 -0
- package/dist/tui/sidebar.d.ts.map +1 -0
- package/dist/tui/sidebar.js +148 -0
- package/dist/tui/status-line.d.ts +14 -0
- package/dist/tui/status-line.d.ts.map +1 -0
- package/dist/tui/status-line.js +225 -0
- package/dist/tui/theme.d.ts +41 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +52 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/toast-colors.d.ts +37 -0
- package/dist/tui/toast-colors.d.ts.map +1 -0
- package/dist/tui/toast-colors.js +77 -0
- package/dist/tui/toasts.d.ts +59 -0
- package/dist/tui/toasts.d.ts.map +1 -0
- package/dist/tui/toasts.js +148 -0
- package/dist/tui/toasts.js.map +1 -0
- package/dist/tui/window/drag.d.ts +26 -0
- package/dist/tui/window/drag.d.ts.map +1 -0
- package/dist/tui/window/drag.js +80 -0
- package/dist/tui/window/drag.js.map +1 -0
- package/dist/tui/window/limits.d.ts +15 -0
- package/dist/tui/window/limits.d.ts.map +1 -0
- package/dist/tui/window/limits.js +227 -0
- package/dist/tui/window/limits.js.map +1 -0
- package/dist/tui/window/rail.d.ts +21 -0
- package/dist/tui/window/rail.d.ts.map +1 -0
- package/dist/tui/window/rail.js +81 -0
- package/dist/tui/window/settings.d.ts +164 -0
- package/dist/tui/window/settings.d.ts.map +1 -0
- package/dist/tui/window/settings.js +1679 -0
- package/dist/tui/window/shell.d.ts +108 -0
- package/dist/tui/window/shell.d.ts.map +1 -0
- package/dist/tui/window/shell.js +1003 -0
- package/dist/tui/window/usage.d.ts +75 -0
- package/dist/tui/window/usage.d.ts.map +1 -0
- package/dist/tui/window/usage.js +928 -0
- package/dist/tui/window/views.d.ts +61 -0
- package/dist/tui/window/views.d.ts.map +1 -0
- package/dist/tui/window/views.js +242 -0
- package/dist/tui.d.ts +1 -5
- package/dist/tui.js +1 -894
- package/dist/view/columns.d.ts +15 -0
- package/dist/view/columns.d.ts.map +1 -0
- package/dist/view/columns.js +48 -0
- package/dist/view/columns.js.map +1 -0
- package/dist/view/format.d.ts +82 -0
- package/dist/view/format.d.ts.map +1 -0
- package/dist/view/format.js +201 -0
- package/dist/view/format.js.map +1 -0
- package/dist/view/quick-look.d.ts +28 -0
- package/dist/view/quick-look.d.ts.map +1 -0
- package/dist/view/quick-look.js +150 -0
- package/dist/view/quick-look.js.map +1 -0
- package/dist/view/select.d.ts +67 -0
- package/dist/view/select.d.ts.map +1 -0
- package/dist/view/select.js +87 -0
- package/dist/view/select.js.map +1 -0
- package/dist/view/text.d.ts +153 -0
- package/dist/view/text.d.ts.map +1 -0
- package/dist/view/text.js +642 -0
- package/dist/view/text.js.map +1 -0
- package/dist/view/usage.d.ts +86 -0
- package/dist/view/usage.d.ts.map +1 -0
- package/dist/view/usage.js +724 -0
- package/dist/view/usage.js.map +1 -0
- package/package.json +4 -6
- package/dist/lib/chutes-config.d.ts +0 -15
- package/dist/lib/chutes-config.d.ts.map +0 -1
- package/dist/lib/chutes-config.js +0 -28
- package/dist/lib/chutes-config.js.map +0 -1
- package/dist/lib/cli-status.d.ts +0 -8
- package/dist/lib/cli-status.d.ts.map +0 -1
- package/dist/lib/cli-status.js +0 -98
- package/dist/lib/cli-status.js.map +0 -1
- package/dist/lib/command-parsing.d.ts +0 -43
- package/dist/lib/command-parsing.d.ts.map +0 -1
- package/dist/lib/command-parsing.js +0 -103
- package/dist/lib/command-parsing.js.map +0 -1
- package/dist/lib/config.d.ts +0 -63
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/config.js +0 -1092
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/deepseek-auth.d.ts +0 -15
- package/dist/lib/deepseek-auth.d.ts.map +0 -1
- package/dist/lib/deepseek-auth.js +0 -28
- package/dist/lib/deepseek-auth.js.map +0 -1
- package/dist/lib/format.d.ts +0 -25
- package/dist/lib/format.d.ts.map +0 -1
- package/dist/lib/format.js +0 -300
- package/dist/lib/format.js.map +0 -1
- package/dist/lib/google-agy-companion.d.ts +0 -8
- package/dist/lib/google-agy-companion.d.ts.map +0 -1
- package/dist/lib/google-agy-companion.js +0 -64
- package/dist/lib/google-agy-companion.js.map +0 -1
- package/dist/lib/google-gemini-cli-companion.d.ts +0 -8
- package/dist/lib/google-gemini-cli-companion.d.ts.map +0 -1
- package/dist/lib/google-gemini-cli-companion.js +0 -64
- package/dist/lib/google-gemini-cli-companion.js.map +0 -1
- package/dist/lib/grouped-entry-normalization.d.ts +0 -12
- package/dist/lib/grouped-entry-normalization.d.ts.map +0 -1
- package/dist/lib/grouped-entry-normalization.js +0 -124
- package/dist/lib/grouped-entry-normalization.js.map +0 -1
- package/dist/lib/grouped-header-format.d.ts +0 -5
- package/dist/lib/grouped-header-format.d.ts.map +0 -1
- package/dist/lib/grouped-header-format.js +0 -16
- package/dist/lib/grouped-header-format.js.map +0 -1
- package/dist/lib/init-installer.d.ts +0 -123
- package/dist/lib/init-installer.d.ts.map +0 -1
- package/dist/lib/init-installer.js +0 -1111
- package/dist/lib/init-installer.js.map +0 -1
- package/dist/lib/jsonc.d.ts +0 -17
- package/dist/lib/jsonc.d.ts.map +0 -1
- package/dist/lib/jsonc.js +0 -23
- package/dist/lib/jsonc.js.map +0 -1
- package/dist/lib/kilo-config.d.ts +0 -15
- package/dist/lib/kilo-config.d.ts.map +0 -1
- package/dist/lib/kilo-config.js +0 -27
- package/dist/lib/kilo-config.js.map +0 -1
- package/dist/lib/kimi-auth.d.ts +0 -49
- package/dist/lib/kimi-auth.d.ts.map +0 -1
- package/dist/lib/kimi-auth.js +0 -82
- package/dist/lib/kimi-auth.js.map +0 -1
- package/dist/lib/markdown-table.d.ts +0 -51
- package/dist/lib/markdown-table.d.ts.map +0 -1
- package/dist/lib/markdown-table.js +0 -179
- package/dist/lib/markdown-table.js.map +0 -1
- package/dist/lib/minimax-auth.d.ts +0 -62
- package/dist/lib/minimax-auth.d.ts.map +0 -1
- package/dist/lib/minimax-auth.js +0 -206
- package/dist/lib/minimax-auth.js.map +0 -1
- package/dist/lib/nanogpt-config.d.ts +0 -15
- package/dist/lib/nanogpt-config.d.ts.map +0 -1
- package/dist/lib/nanogpt-config.js +0 -31
- package/dist/lib/nanogpt-config.js.map +0 -1
- package/dist/lib/ollama-cloud-config.d.ts +0 -15
- package/dist/lib/ollama-cloud-config.d.ts.map +0 -1
- package/dist/lib/ollama-cloud-config.js +0 -27
- package/dist/lib/ollama-cloud-config.js.map +0 -1
- package/dist/lib/opencode-go-auth.d.ts +0 -16
- package/dist/lib/opencode-go-auth.d.ts.map +0 -1
- package/dist/lib/opencode-go-auth.js +0 -42
- package/dist/lib/opencode-go-auth.js.map +0 -1
- package/dist/lib/opencode-version.d.ts +0 -6
- package/dist/lib/opencode-version.d.ts.map +0 -1
- package/dist/lib/opencode-version.js +0 -26
- package/dist/lib/opencode-version.js.map +0 -1
- package/dist/lib/provider-add-command.d.ts +0 -35
- package/dist/lib/provider-add-command.d.ts.map +0 -1
- package/dist/lib/provider-add-command.js +0 -204
- package/dist/lib/provider-add-command.js.map +0 -1
- package/dist/lib/provider-add-json-v1-questionnaire.d.ts +0 -32
- package/dist/lib/provider-add-json-v1-questionnaire.d.ts.map +0 -1
- package/dist/lib/provider-add-json-v1-questionnaire.js +0 -336
- package/dist/lib/provider-add-json-v1-questionnaire.js.map +0 -1
- package/dist/lib/provider-add.d.ts +0 -21
- package/dist/lib/provider-add.d.ts.map +0 -1
- package/dist/lib/provider-add.js +0 -219
- package/dist/lib/provider-add.js.map +0 -1
- package/dist/lib/quota-accounting-projection.d.ts +0 -9
- package/dist/lib/quota-accounting-projection.d.ts.map +0 -1
- package/dist/lib/quota-accounting-projection.js +0 -254
- package/dist/lib/quota-accounting-projection.js.map +0 -1
- package/dist/lib/quota-columns.d.ts +0 -38
- package/dist/lib/quota-columns.d.ts.map +0 -1
- package/dist/lib/quota-columns.js +0 -129
- package/dist/lib/quota-columns.js.map +0 -1
- package/dist/lib/quota-command-format.d.ts +0 -34
- package/dist/lib/quota-command-format.d.ts.map +0 -1
- package/dist/lib/quota-command-format.js +0 -240
- package/dist/lib/quota-command-format.js.map +0 -1
- package/dist/lib/quota-dialog-command-specs.d.ts +0 -63
- package/dist/lib/quota-dialog-command-specs.d.ts.map +0 -1
- package/dist/lib/quota-dialog-command-specs.js +0 -145
- package/dist/lib/quota-dialog-command-specs.js.map +0 -1
- package/dist/lib/quota-entry-display.d.ts +0 -7
- package/dist/lib/quota-entry-display.d.ts.map +0 -1
- package/dist/lib/quota-entry-display.js +0 -59
- package/dist/lib/quota-entry-display.js.map +0 -1
- package/dist/lib/quota-exhaustion-projection.d.ts +0 -11
- package/dist/lib/quota-exhaustion-projection.d.ts.map +0 -1
- package/dist/lib/quota-exhaustion-projection.js +0 -105
- package/dist/lib/quota-exhaustion-projection.js.map +0 -1
- package/dist/lib/quota-format-style.d.ts +0 -21
- package/dist/lib/quota-format-style.d.ts.map +0 -1
- package/dist/lib/quota-format-style.js +0 -38
- package/dist/lib/quota-format-style.js.map +0 -1
- package/dist/lib/quota-render-data.d.ts +0 -102
- package/dist/lib/quota-render-data.d.ts.map +0 -1
- package/dist/lib/quota-render-data.js +0 -419
- package/dist/lib/quota-render-data.js.map +0 -1
- package/dist/lib/quota-reset-notifications.d.ts +0 -20
- package/dist/lib/quota-reset-notifications.d.ts.map +0 -1
- package/dist/lib/quota-reset-notifications.js +0 -331
- package/dist/lib/quota-reset-notifications.js.map +0 -1
- package/dist/lib/quota-runtime-context.d.ts +0 -54
- package/dist/lib/quota-runtime-context.d.ts.map +0 -1
- package/dist/lib/quota-runtime-context.js +0 -110
- package/dist/lib/quota-runtime-context.js.map +0 -1
- package/dist/lib/quota-state-codec.d.ts +0 -16
- package/dist/lib/quota-state-codec.d.ts.map +0 -1
- package/dist/lib/quota-state-codec.js +0 -412
- package/dist/lib/quota-state-codec.js.map +0 -1
- package/dist/lib/quota-state.d.ts +0 -28
- package/dist/lib/quota-state.d.ts.map +0 -1
- package/dist/lib/quota-state.js +0 -473
- package/dist/lib/quota-state.js.map +0 -1
- package/dist/lib/quota-stats-format.d.ts +0 -29
- package/dist/lib/quota-stats-format.d.ts.map +0 -1
- package/dist/lib/quota-stats-format.js +0 -459
- package/dist/lib/quota-stats-format.js.map +0 -1
- package/dist/lib/quota-stats.d.ts +0 -126
- package/dist/lib/quota-stats.d.ts.map +0 -1
- package/dist/lib/quota-stats.js +0 -695
- package/dist/lib/quota-stats.js.map +0 -1
- package/dist/lib/quota-surface-data.d.ts +0 -21
- package/dist/lib/quota-surface-data.d.ts.map +0 -1
- package/dist/lib/quota-surface-data.js +0 -362
- package/dist/lib/quota-surface-data.js.map +0 -1
- package/dist/lib/scoped-update-migration.d.ts +0 -103
- package/dist/lib/scoped-update-migration.d.ts.map +0 -1
- package/dist/lib/scoped-update-migration.js +0 -344
- package/dist/lib/scoped-update-migration.js.map +0 -1
- package/dist/lib/scoped-update.d.ts +0 -77
- package/dist/lib/scoped-update.d.ts.map +0 -1
- package/dist/lib/scoped-update.js +0 -590
- package/dist/lib/scoped-update.js.map +0 -1
- package/dist/lib/session-tokens-format.d.ts +0 -36
- package/dist/lib/session-tokens-format.d.ts.map +0 -1
- package/dist/lib/session-tokens-format.js +0 -111
- package/dist/lib/session-tokens-format.js.map +0 -1
- package/dist/lib/synthetic-config.d.ts +0 -15
- package/dist/lib/synthetic-config.d.ts.map +0 -1
- package/dist/lib/synthetic-config.js +0 -28
- package/dist/lib/synthetic-config.js.map +0 -1
- package/dist/lib/toast-format-grouped.d.ts +0 -25
- package/dist/lib/toast-format-grouped.d.ts.map +0 -1
- package/dist/lib/toast-format-grouped.js +0 -296
- package/dist/lib/toast-format-grouped.js.map +0 -1
- package/dist/lib/tui-compact-format.d.ts +0 -10
- package/dist/lib/tui-compact-format.d.ts.map +0 -1
- package/dist/lib/tui-compact-format.js +0 -460
- package/dist/lib/tui-compact-format.js.map +0 -1
- package/dist/lib/tui-panel-state.d.ts +0 -15
- package/dist/lib/tui-panel-state.d.ts.map +0 -1
- package/dist/lib/tui-panel-state.js +0 -2
- package/dist/lib/tui-panel-state.js.map +0 -1
- package/dist/lib/tui-prompt-bar-format.d.ts +0 -25
- package/dist/lib/tui-prompt-bar-format.d.ts.map +0 -1
- package/dist/lib/tui-prompt-bar-format.js +0 -206
- package/dist/lib/tui-prompt-bar-format.js.map +0 -1
- package/dist/lib/tui-sidebar-format.d.ts +0 -13
- package/dist/lib/tui-sidebar-format.d.ts.map +0 -1
- package/dist/lib/tui-sidebar-format.js +0 -34
- package/dist/lib/tui-sidebar-format.js.map +0 -1
- package/dist/lib/zai-auth.d.ts +0 -15
- package/dist/lib/zai-auth.d.ts.map +0 -1
- package/dist/lib/zai-auth.js +0 -37
- package/dist/lib/zai-auth.js.map +0 -1
- package/dist/lib/zai.d.ts +0 -5
- package/dist/lib/zai.d.ts.map +0 -1
- package/dist/lib/zai.js +0 -14
- package/dist/lib/zai.js.map +0 -1
- package/dist/lib/zhipu-auth.d.ts +0 -15
- package/dist/lib/zhipu-auth.d.ts.map +0 -1
- package/dist/lib/zhipu-auth.js +0 -42
- package/dist/lib/zhipu-auth.js.map +0 -1
- package/dist/lib/zhipu.d.ts +0 -5
- package/dist/lib/zhipu.d.ts.map +0 -1
- package/dist/lib/zhipu.js +0 -13
- package/dist/lib/zhipu.js.map +0 -1
- package/dist/providers/glm-coding-plan-provider.d.ts +0 -56
- package/dist/providers/glm-coding-plan-provider.d.ts.map +0 -1
- package/dist/providers/glm-coding-plan-provider.js +0 -115
- package/dist/providers/glm-coding-plan-provider.js.map +0 -1
- package/dist/providers/google-account-format.d.ts +0 -7
- package/dist/providers/google-account-format.d.ts.map +0 -1
- package/dist/providers/google-account-format.js +0 -52
- package/dist/providers/google-account-format.js.map +0 -1
- package/dist/providers/zai.d.ts +0 -2
- package/dist/providers/zai.d.ts.map +0 -1
- package/dist/providers/zai.js +0 -24
- package/dist/providers/zai.js.map +0 -1
- package/dist/providers/zhipu.d.ts +0 -2
- package/dist/providers/zhipu.d.ts.map +0 -1
- package/dist/providers/zhipu.js +0 -21
- package/dist/providers/zhipu.js.map +0 -1
- package/dist/tui-v2.d.ts +0 -5
- package/dist/tui-v2.d.ts.map +0 -1
- package/dist/tui-v2.jsx +0 -624
- package/dist/tui-v2.jsx.map +0 -1
- package/dist/tui.d.ts.map +0 -1
|
@@ -1,1111 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "fs";
|
|
2
|
-
import { readFile } from "fs/promises";
|
|
3
|
-
import { basename, join } from "path";
|
|
4
|
-
import { getQuotaToastConfigPath, QUOTA_TOAST_CONFIG_RELATIVE_PATH, QUOTA_TOAST_CONFIG_RELATIVE_PATHS, } from "./config.js";
|
|
5
|
-
import { dedupeNonEmptyStrings, findGitWorktreeRoot, getPluginSpecFromEntry, isQuotaPluginSpec, resolveEditableConfigPath, } from "./config-file-utils.js";
|
|
6
|
-
import { writeConfiguredJsonAtomic } from "./config-write-target.js";
|
|
7
|
-
import { parseJsonOrJsonc } from "./jsonc.js";
|
|
8
|
-
import { applyConfigDocumentEdit, planConfigDocumentEdit, validateConfigDocumentEdit, } from "./opencode-config-editor.js";
|
|
9
|
-
import { getOpencodeRuntimeDirs } from "./opencode-runtime-paths.js";
|
|
10
|
-
import { detectOpenCodeMajor } from "./opencode-version.js";
|
|
11
|
-
import { getQuotaProviderDisplayLabel, normalizeQuotaProviderId, QUOTA_PROVIDER_SHAPES, } from "./provider-metadata.js";
|
|
12
|
-
import { getQuotaFormatStyleLabel, isQuotaFormatStyle, resolveQuotaFormatStyle, } from "./quota-format-style.js";
|
|
13
|
-
import { QUOTA_PROVIDERS_AGGREGATE_ID } from "./quota-providers.js";
|
|
14
|
-
import { getPackageVersion } from "./version.js";
|
|
15
|
-
const OPENCODE_SCHEMA_URL = "https://opencode.ai/config.json";
|
|
16
|
-
const GITHUB_REPO_URL = "https://github.com/slkiser/opencode-quota";
|
|
17
|
-
const GITHUB_STAR_NOTE = `if this helps, stars are appreciated: ${GITHUB_REPO_URL}`;
|
|
18
|
-
const TUI_COMMAND_DISPLAY_COMMENT = "// OpenCode Quota: tuiCommandDisplay chooses whether native TUI command output appears in the session transcript or a local popup dialog.";
|
|
19
|
-
export class InitInstallerError extends Error {
|
|
20
|
-
details;
|
|
21
|
-
constructor(message, details) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.details = details;
|
|
24
|
-
this.name = "InitInstallerError";
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/** A prerelease (version with `-`) installs from the npm `next` tag; a stable release from `latest`. */
|
|
28
|
-
export function getQuotaPluginSpecForVersion(version) {
|
|
29
|
-
return version.includes("-") ? "@slkiser/opencode-quota@next" : "@slkiser/opencode-quota@latest";
|
|
30
|
-
}
|
|
31
|
-
async function resolveQuotaPluginSpec() {
|
|
32
|
-
const version = await getPackageVersion();
|
|
33
|
-
if (!version) {
|
|
34
|
-
throw new InitInstallerError("Cannot read the OpenCode Quota package version.");
|
|
35
|
-
}
|
|
36
|
-
return getQuotaPluginSpecForVersion(version);
|
|
37
|
-
}
|
|
38
|
-
function isPlainObject(value) {
|
|
39
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
40
|
-
}
|
|
41
|
-
function hasOwnKey(value, key) {
|
|
42
|
-
return Object.hasOwn(value, key);
|
|
43
|
-
}
|
|
44
|
-
function jsonEqual(left, right) {
|
|
45
|
-
return JSON.stringify(left) === JSON.stringify(right);
|
|
46
|
-
}
|
|
47
|
-
const QUOTA_UI_CHOICE_ORDER = ["sidebar", "toast", "compact_status", "none"];
|
|
48
|
-
function normalizeQuotaUiIntent(selections) {
|
|
49
|
-
const rawSelections = selections;
|
|
50
|
-
if (hasOwnKey(rawSelections, "tuiCompactStatus")) {
|
|
51
|
-
throw new InitInstallerError("Unsupported installer selection: tuiCompactStatus");
|
|
52
|
-
}
|
|
53
|
-
const quotaUi = rawSelections.quotaUi;
|
|
54
|
-
if (!Array.isArray(quotaUi)) {
|
|
55
|
-
throw new InitInstallerError("Quota UI selections must be an array.");
|
|
56
|
-
}
|
|
57
|
-
if (quotaUi.length === 0) {
|
|
58
|
-
throw new InitInstallerError("Quota UI selections must not be empty.");
|
|
59
|
-
}
|
|
60
|
-
const seen = new Set();
|
|
61
|
-
for (const rawChoice of quotaUi) {
|
|
62
|
-
if (typeof rawChoice !== "string" ||
|
|
63
|
-
!QUOTA_UI_CHOICE_ORDER.includes(rawChoice)) {
|
|
64
|
-
throw new InitInstallerError(`Unknown Quota UI option: ${String(rawChoice)}`);
|
|
65
|
-
}
|
|
66
|
-
seen.add(rawChoice);
|
|
67
|
-
}
|
|
68
|
-
if (seen.has("none") && seen.size > 1) {
|
|
69
|
-
throw new InitInstallerError("Manual commands only cannot be combined with automatic quota displays.");
|
|
70
|
-
}
|
|
71
|
-
const choices = QUOTA_UI_CHOICE_ORDER.filter((choice) => seen.has(choice));
|
|
72
|
-
const enableSidebarPanel = choices.includes("sidebar");
|
|
73
|
-
const enableCompactStatus = choices.includes("compact_status");
|
|
74
|
-
return {
|
|
75
|
-
choices,
|
|
76
|
-
enableToast: choices.includes("toast"),
|
|
77
|
-
enableSidebarPanel,
|
|
78
|
-
enableCompactStatus,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function getUiLabel(choices) {
|
|
82
|
-
const labels = choices.map((choice) => {
|
|
83
|
-
if (choice === "toast")
|
|
84
|
-
return "Toast";
|
|
85
|
-
if (choice === "sidebar")
|
|
86
|
-
return "Sidebar";
|
|
87
|
-
if (choice === "compact_status")
|
|
88
|
-
return "Compact status";
|
|
89
|
-
return "Manual commands only";
|
|
90
|
-
});
|
|
91
|
-
return labels.join(" + ");
|
|
92
|
-
}
|
|
93
|
-
function getProviderModeLabel(mode) {
|
|
94
|
-
return mode === "manual" ? "Manual" : "Auto-detect";
|
|
95
|
-
}
|
|
96
|
-
function getPercentDisplayModeLabel(mode) {
|
|
97
|
-
return mode === "used" ? "Used" : "Remaining";
|
|
98
|
-
}
|
|
99
|
-
function resolveRequestedProviders(selections) {
|
|
100
|
-
if (selections.providerMode === "auto") {
|
|
101
|
-
return "auto";
|
|
102
|
-
}
|
|
103
|
-
const normalized = dedupeNonEmptyStrings(selections.manualProviders
|
|
104
|
-
.map((providerId) => normalizeQuotaProviderId(providerId))
|
|
105
|
-
.filter((providerId) => QUOTA_PROVIDER_SHAPES.some((shape) => shape.id === providerId)));
|
|
106
|
-
if (normalized.length === 0) {
|
|
107
|
-
throw new InitInstallerError("Manual provider mode requires at least one supported provider.");
|
|
108
|
-
}
|
|
109
|
-
return normalized;
|
|
110
|
-
}
|
|
111
|
-
function pickFormatStyleToWrite(params) {
|
|
112
|
-
if (isQuotaFormatStyle(params.quotaToast.toastStyle)) {
|
|
113
|
-
return resolveQuotaFormatStyle(params.quotaToast.toastStyle);
|
|
114
|
-
}
|
|
115
|
-
return params.selectedFormatStyle;
|
|
116
|
-
}
|
|
117
|
-
function pushSkippedIfChanged(edit, pathLabel, existingValue, desiredValue) {
|
|
118
|
-
if (!jsonEqual(existingValue, desiredValue)) {
|
|
119
|
-
edit.skippedValues.push(`${pathLabel} preserved existing value`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
function ensureSchema(root, schemaUrl, edit) {
|
|
123
|
-
if (!hasOwnKey(root, "$schema")) {
|
|
124
|
-
root.$schema = schemaUrl;
|
|
125
|
-
edit.changed = true;
|
|
126
|
-
edit.addedKeys.push("$schema");
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
pushSkippedIfChanged(edit, "$schema", root.$schema, schemaUrl);
|
|
130
|
-
}
|
|
131
|
-
function isQuotaPluginEntry(entry) {
|
|
132
|
-
const spec = getPluginSpecFromEntry(entry);
|
|
133
|
-
return typeof spec === "string" && isQuotaPluginSpec(spec);
|
|
134
|
-
}
|
|
135
|
-
function appendQuotaPluginIfMissing(params) {
|
|
136
|
-
const alreadyConfigured = params.container.some(isQuotaPluginEntry);
|
|
137
|
-
if (alreadyConfigured) {
|
|
138
|
-
params.edit.skippedValues.push(`${params.pathLabel} already includes ${params.pluginSpec}`);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
params.container.push(params.pluginSpec);
|
|
142
|
-
params.edit.changed = true;
|
|
143
|
-
params.edit.addedPlugins.push(`${params.pathLabel}: ${params.pluginSpec}`);
|
|
144
|
-
}
|
|
145
|
-
function ensureTopLevelPluginArray(root, edit) {
|
|
146
|
-
if (!hasOwnKey(root, "plugin")) {
|
|
147
|
-
const next = [];
|
|
148
|
-
root.plugin = next;
|
|
149
|
-
edit.changed = true;
|
|
150
|
-
return next;
|
|
151
|
-
}
|
|
152
|
-
if (!Array.isArray(root.plugin)) {
|
|
153
|
-
throw new InitInstallerError(`Cannot update ${edit.kind} config because plugin is not an array.`, { path: edit.path });
|
|
154
|
-
}
|
|
155
|
-
return root.plugin;
|
|
156
|
-
}
|
|
157
|
-
function addSettingIfMissing(target, key, value, pathLabel, edit) {
|
|
158
|
-
if (!hasOwnKey(target, key)) {
|
|
159
|
-
target[key] = value;
|
|
160
|
-
edit.changed = true;
|
|
161
|
-
edit.addedKeys.push(pathLabel);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
pushSkippedIfChanged(edit, pathLabel, target[key], value);
|
|
165
|
-
}
|
|
166
|
-
function setInstallerOwnedSetting(target, key, value, pathLabel, edit) {
|
|
167
|
-
if (!hasOwnKey(target, key)) {
|
|
168
|
-
target[key] = value;
|
|
169
|
-
edit.changed = true;
|
|
170
|
-
edit.addedKeys.push(pathLabel);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (!jsonEqual(target[key], value)) {
|
|
174
|
-
const previousValue = target[key];
|
|
175
|
-
target[key] = value;
|
|
176
|
-
edit.changed = true;
|
|
177
|
-
edit.updatedKeys.push(pathLabel);
|
|
178
|
-
edit.valueChanges.push(`${pathLabel}: ${JSON.stringify(previousValue)} -> ${JSON.stringify(value)}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function planTuiSidebarPanelConfig(params) {
|
|
182
|
-
const pathLabel = "quotaToast.tuiSidebarPanel";
|
|
183
|
-
let tuiSidebarPanel;
|
|
184
|
-
if (!hasOwnKey(params.quotaToast, "tuiSidebarPanel")) {
|
|
185
|
-
tuiSidebarPanel = {};
|
|
186
|
-
params.quotaToast.tuiSidebarPanel = tuiSidebarPanel;
|
|
187
|
-
}
|
|
188
|
-
else if (isPlainObject(params.quotaToast.tuiSidebarPanel)) {
|
|
189
|
-
tuiSidebarPanel = params.quotaToast.tuiSidebarPanel;
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
params.edit.warnings.push(`${pathLabel} is not an object; preserved existing value.`);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
setInstallerOwnedSetting(tuiSidebarPanel, "enabled", params.quotaUiIntent.enableSidebarPanel, `${pathLabel}.enabled`, params.edit);
|
|
196
|
-
}
|
|
197
|
-
function planMaintainerAnnouncementsConfig(params) {
|
|
198
|
-
if (params.selections.maintainerAnnouncements === undefined) {
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
const enabled = params.selections.maintainerAnnouncements;
|
|
202
|
-
const pathLabel = "quotaToast.maintainerAnnouncements";
|
|
203
|
-
let maintainerAnnouncements;
|
|
204
|
-
if (!hasOwnKey(params.quotaToast, "maintainerAnnouncements")) {
|
|
205
|
-
maintainerAnnouncements = {};
|
|
206
|
-
params.quotaToast.maintainerAnnouncements = maintainerAnnouncements;
|
|
207
|
-
}
|
|
208
|
-
else if (isPlainObject(params.quotaToast.maintainerAnnouncements)) {
|
|
209
|
-
maintainerAnnouncements = params.quotaToast.maintainerAnnouncements;
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
params.edit.warnings.push(`${pathLabel} is not an object; preserved existing value.`);
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
setInstallerOwnedSetting(maintainerAnnouncements, "enabled", enabled, `${pathLabel}.enabled`, params.edit);
|
|
216
|
-
if (enabled) {
|
|
217
|
-
setInstallerOwnedSetting(maintainerAnnouncements, "home", true, `${pathLabel}.home`, params.edit);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
function planTuiCompactStatusConfig(params) {
|
|
221
|
-
const hasExistingCompactStatus = hasOwnKey(params.quotaToast, "tuiCompactStatus");
|
|
222
|
-
if (!params.quotaUiIntent.enableCompactStatus && !hasExistingCompactStatus) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
const pathLabel = "quotaToast.tuiCompactStatus";
|
|
226
|
-
let tuiCompactStatus;
|
|
227
|
-
if (!hasExistingCompactStatus) {
|
|
228
|
-
tuiCompactStatus = {};
|
|
229
|
-
params.quotaToast.tuiCompactStatus = tuiCompactStatus;
|
|
230
|
-
}
|
|
231
|
-
else if (isPlainObject(params.quotaToast.tuiCompactStatus)) {
|
|
232
|
-
tuiCompactStatus = params.quotaToast.tuiCompactStatus;
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
params.edit.warnings.push(`${pathLabel} is not an object; preserved existing value.`);
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
setInstallerOwnedSetting(tuiCompactStatus, "enabled", params.quotaUiIntent.enableCompactStatus, `${pathLabel}.enabled`, params.edit);
|
|
239
|
-
if (!params.quotaUiIntent.enableCompactStatus) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
setInstallerOwnedSetting(tuiCompactStatus, "homeBottom", true, `${pathLabel}.homeBottom`, params.edit);
|
|
243
|
-
setInstallerOwnedSetting(tuiCompactStatus, "sessionPrompt", true, `${pathLabel}.sessionPrompt`, params.edit);
|
|
244
|
-
}
|
|
245
|
-
async function readExistingConfig(params) {
|
|
246
|
-
try {
|
|
247
|
-
const content = await readFile(params.path, "utf-8");
|
|
248
|
-
const parsed = parseJsonOrJsonc(content, params.format === "jsonc");
|
|
249
|
-
if (!isPlainObject(parsed)) {
|
|
250
|
-
throw new InitInstallerError("Existing config root must be a JSON object.", {
|
|
251
|
-
path: params.path,
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
return parsed;
|
|
255
|
-
}
|
|
256
|
-
catch (error) {
|
|
257
|
-
if (error instanceof InitInstallerError) {
|
|
258
|
-
throw error;
|
|
259
|
-
}
|
|
260
|
-
throw new InitInstallerError(`Failed to parse ${basename(params.path)}.`, {
|
|
261
|
-
path: params.path,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
function cloneJsonValue(value) {
|
|
266
|
-
return JSON.parse(JSON.stringify(value));
|
|
267
|
-
}
|
|
268
|
-
function cloneJsonObject(value) {
|
|
269
|
-
return cloneJsonValue(value);
|
|
270
|
-
}
|
|
271
|
-
async function readLegacyQuotaToastSeed(baseDir) {
|
|
272
|
-
const target = resolveEditableConfigPath({ dir: baseDir, kind: "opencode" });
|
|
273
|
-
if (!target.existed) {
|
|
274
|
-
return null;
|
|
275
|
-
}
|
|
276
|
-
const root = await readExistingConfig({
|
|
277
|
-
path: target.sourcePath,
|
|
278
|
-
format: target.sourcePath.endsWith(".jsonc") ? "jsonc" : "json",
|
|
279
|
-
});
|
|
280
|
-
const experimental = isPlainObject(root.experimental) ? root.experimental : null;
|
|
281
|
-
const quotaToast = experimental && isPlainObject(experimental.quotaToast) ? experimental.quotaToast : null;
|
|
282
|
-
return quotaToast ? cloneJsonObject(quotaToast) : null;
|
|
283
|
-
}
|
|
284
|
-
function buildQuickSetupNotes(selections) {
|
|
285
|
-
if (selections.providerMode !== "manual") {
|
|
286
|
-
return [];
|
|
287
|
-
}
|
|
288
|
-
const requestedProviders = resolveRequestedProviders(selections);
|
|
289
|
-
if (requestedProviders === "auto") {
|
|
290
|
-
return [];
|
|
291
|
-
}
|
|
292
|
-
return requestedProviders
|
|
293
|
-
.map((providerId) => QUOTA_PROVIDER_SHAPES.find((shape) => shape.id === providerId))
|
|
294
|
-
.filter((shape) => Boolean(shape?.quickSetupAnchor && shape.autoSetup === "needs_quick_setup"))
|
|
295
|
-
.map((shape) => ({
|
|
296
|
-
providerId: shape.id,
|
|
297
|
-
label: getQuotaProviderDisplayLabel(shape.id),
|
|
298
|
-
anchor: shape.quickSetupAnchor,
|
|
299
|
-
}));
|
|
300
|
-
}
|
|
301
|
-
function syncLegacyQuotaToast(params) {
|
|
302
|
-
if (Object.keys(params.quotaToast).length === 0) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
let experimental;
|
|
306
|
-
if (!hasOwnKey(params.root, "experimental")) {
|
|
307
|
-
experimental = {};
|
|
308
|
-
params.root.experimental = experimental;
|
|
309
|
-
}
|
|
310
|
-
else if (isPlainObject(params.root.experimental)) {
|
|
311
|
-
experimental = params.root.experimental;
|
|
312
|
-
}
|
|
313
|
-
else {
|
|
314
|
-
throw new InitInstallerError("Cannot sync legacy config because experimental is not an object.", { path: params.edit.path });
|
|
315
|
-
}
|
|
316
|
-
let legacyQuotaToast;
|
|
317
|
-
if (!hasOwnKey(experimental, "quotaToast")) {
|
|
318
|
-
legacyQuotaToast = {};
|
|
319
|
-
experimental.quotaToast = legacyQuotaToast;
|
|
320
|
-
}
|
|
321
|
-
else if (isPlainObject(experimental.quotaToast)) {
|
|
322
|
-
legacyQuotaToast = experimental.quotaToast;
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
throw new InitInstallerError("Cannot sync legacy config because experimental.quotaToast is not an object.", { path: params.edit.path });
|
|
326
|
-
}
|
|
327
|
-
let changed = false;
|
|
328
|
-
for (const [key, value] of Object.entries(params.quotaToast)) {
|
|
329
|
-
if (!jsonEqual(legacyQuotaToast[key], value)) {
|
|
330
|
-
legacyQuotaToast[key] = cloneJsonValue(value);
|
|
331
|
-
changed = true;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
if (changed) {
|
|
335
|
-
params.edit.changed = true;
|
|
336
|
-
params.edit.addedKeys.push("experimental.quotaToast (synced from opencode-quota/quota-toast.json)");
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
async function planOpencodeEdit(params) {
|
|
340
|
-
const target = resolveEditableConfigPath({
|
|
341
|
-
dir: params.baseDir,
|
|
342
|
-
kind: "opencode",
|
|
343
|
-
preferredFormat: params.selections.configFormat ?? "jsonc",
|
|
344
|
-
convertJsonToJsonc: true,
|
|
345
|
-
});
|
|
346
|
-
const edit = {
|
|
347
|
-
kind: "opencode",
|
|
348
|
-
path: target.path,
|
|
349
|
-
existed: target.existed,
|
|
350
|
-
format: target.format,
|
|
351
|
-
changed: false,
|
|
352
|
-
addedPlugins: [],
|
|
353
|
-
addedKeys: [],
|
|
354
|
-
updatedKeys: [],
|
|
355
|
-
valueChanges: [],
|
|
356
|
-
skippedValues: [],
|
|
357
|
-
warnings: [],
|
|
358
|
-
};
|
|
359
|
-
const root = target.existed
|
|
360
|
-
? await readExistingConfig({
|
|
361
|
-
path: target.sourcePath,
|
|
362
|
-
format: target.sourcePath.endsWith(".jsonc") ? "jsonc" : "json",
|
|
363
|
-
})
|
|
364
|
-
: {};
|
|
365
|
-
if (!target.existed) {
|
|
366
|
-
ensureSchema(root, OPENCODE_SCHEMA_URL, edit);
|
|
367
|
-
}
|
|
368
|
-
// OpenCode 2 also loads plugins from the native `plugins` array; never add a second entry.
|
|
369
|
-
if (Array.isArray(root.plugins) && root.plugins.some(isQuotaPluginEntry)) {
|
|
370
|
-
edit.skippedValues.push(`plugins already includes ${params.pluginSpec}`);
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
const plugin = ensureTopLevelPluginArray(root, edit);
|
|
374
|
-
appendQuotaPluginIfMissing({
|
|
375
|
-
container: plugin,
|
|
376
|
-
pathLabel: "plugin",
|
|
377
|
-
pluginSpec: params.pluginSpec,
|
|
378
|
-
edit,
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
if (params.legacyQuotaToastToSync) {
|
|
382
|
-
syncLegacyQuotaToast({
|
|
383
|
-
root,
|
|
384
|
-
quotaToast: params.legacyQuotaToastToSync,
|
|
385
|
-
edit,
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
const documentEdit = await planConfigDocumentEdit({
|
|
389
|
-
target,
|
|
390
|
-
desiredData: root,
|
|
391
|
-
managedComments: [
|
|
392
|
-
{
|
|
393
|
-
path: ["plugin"],
|
|
394
|
-
text: TUI_COMMAND_DISPLAY_COMMENT,
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
path: ["plugin"],
|
|
398
|
-
text: "// OpenCode Quota: loads the server plugin for slash commands and quota checks.",
|
|
399
|
-
},
|
|
400
|
-
],
|
|
401
|
-
});
|
|
402
|
-
edit.changed = documentEdit.changed;
|
|
403
|
-
edit.documentEdit = documentEdit;
|
|
404
|
-
return edit;
|
|
405
|
-
}
|
|
406
|
-
function resolveQuotaConfigTarget(baseDir, preferredFormat) {
|
|
407
|
-
const jsoncPath = getQuotaToastConfigPath(baseDir, "jsonc");
|
|
408
|
-
if (existsSync(jsoncPath)) {
|
|
409
|
-
return {
|
|
410
|
-
path: jsoncPath,
|
|
411
|
-
sourcePath: jsoncPath,
|
|
412
|
-
format: "jsonc",
|
|
413
|
-
existed: true,
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
const jsonPath = getQuotaToastConfigPath(baseDir, "json");
|
|
417
|
-
if (existsSync(jsonPath)) {
|
|
418
|
-
if (preferredFormat === "jsonc") {
|
|
419
|
-
return {
|
|
420
|
-
path: jsoncPath,
|
|
421
|
-
sourcePath: jsonPath,
|
|
422
|
-
removeSourcePath: jsonPath,
|
|
423
|
-
format: "jsonc",
|
|
424
|
-
existed: true,
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
return {
|
|
428
|
-
path: jsonPath,
|
|
429
|
-
sourcePath: jsonPath,
|
|
430
|
-
format: "json",
|
|
431
|
-
existed: true,
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
const path = getQuotaToastConfigPath(baseDir, preferredFormat);
|
|
435
|
-
return {
|
|
436
|
-
path,
|
|
437
|
-
sourcePath: path,
|
|
438
|
-
format: preferredFormat,
|
|
439
|
-
existed: false,
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
async function planQuotaConfigEdit(params) {
|
|
443
|
-
const target = resolveQuotaConfigTarget(params.baseDir, params.selections.configFormat ?? "jsonc");
|
|
444
|
-
const edit = {
|
|
445
|
-
kind: "quota",
|
|
446
|
-
path: target.path,
|
|
447
|
-
existed: target.existed,
|
|
448
|
-
format: target.format,
|
|
449
|
-
changed: false,
|
|
450
|
-
addedPlugins: [],
|
|
451
|
-
addedKeys: [],
|
|
452
|
-
updatedKeys: [],
|
|
453
|
-
valueChanges: [],
|
|
454
|
-
skippedValues: [],
|
|
455
|
-
warnings: [],
|
|
456
|
-
};
|
|
457
|
-
if (target.path.endsWith(".jsonc") &&
|
|
458
|
-
existsSync(getQuotaToastConfigPath(params.baseDir, "json"))) {
|
|
459
|
-
edit.warnings.push("Both quota-toast.jsonc and quota-toast.json exist; using JSONC and preserving the JSON file.");
|
|
460
|
-
}
|
|
461
|
-
const legacyQuotaToast = target.existed ? null : await readLegacyQuotaToastSeed(params.baseDir);
|
|
462
|
-
const quotaToast = target.existed
|
|
463
|
-
? await readExistingConfig({
|
|
464
|
-
path: target.sourcePath,
|
|
465
|
-
format: target.sourcePath.endsWith(".jsonc") ? "jsonc" : "json",
|
|
466
|
-
})
|
|
467
|
-
: legacyQuotaToast
|
|
468
|
-
? cloneJsonObject(legacyQuotaToast)
|
|
469
|
-
: {};
|
|
470
|
-
if (!target.existed) {
|
|
471
|
-
edit.addedKeys.push(legacyQuotaToast
|
|
472
|
-
? `${target.path.endsWith(".jsonc") ? QUOTA_TOAST_CONFIG_RELATIVE_PATHS[0] : QUOTA_TOAST_CONFIG_RELATIVE_PATH} (seeded from experimental.quotaToast)`
|
|
473
|
-
: target.path.endsWith(".jsonc")
|
|
474
|
-
? QUOTA_TOAST_CONFIG_RELATIVE_PATHS[0]
|
|
475
|
-
: QUOTA_TOAST_CONFIG_RELATIVE_PATH);
|
|
476
|
-
}
|
|
477
|
-
setInstallerOwnedSetting(quotaToast, "enableToast", params.quotaUiIntent.enableToast, "quotaToast.enableToast", edit);
|
|
478
|
-
if (params.selections.tuiCommandDisplay !== undefined) {
|
|
479
|
-
setInstallerOwnedSetting(quotaToast, "tuiCommandDisplay", params.selections.tuiCommandDisplay, "quotaToast.tuiCommandDisplay", edit);
|
|
480
|
-
}
|
|
481
|
-
setInstallerOwnedSetting(quotaToast, "showSessionTokens", params.selections.showSessionTokens, "quotaToast.showSessionTokens", edit);
|
|
482
|
-
setInstallerOwnedSetting(quotaToast, "sessionTokenScope", params.selections.sessionTokenScope ?? "current", "quotaToast.sessionTokenScope", edit);
|
|
483
|
-
const requestedProviders = resolveRequestedProviders(params.selections);
|
|
484
|
-
const enabledProviders = requestedProviders !== "auto" &&
|
|
485
|
-
Array.isArray(quotaToast.enabledProviders) &&
|
|
486
|
-
quotaToast.enabledProviders.includes(QUOTA_PROVIDERS_AGGREGATE_ID)
|
|
487
|
-
? [...requestedProviders, QUOTA_PROVIDERS_AGGREGATE_ID]
|
|
488
|
-
: requestedProviders;
|
|
489
|
-
setInstallerOwnedSetting(quotaToast, "enabledProviders", enabledProviders, "quotaToast.enabledProviders", edit);
|
|
490
|
-
setInstallerOwnedSetting(quotaToast, "formatStyle", params.selections.formatStyle, "quotaToast.formatStyle", edit);
|
|
491
|
-
setInstallerOwnedSetting(quotaToast, "percentDisplayMode", params.selections.percentDisplayMode, "quotaToast.percentDisplayMode", edit);
|
|
492
|
-
planTuiSidebarPanelConfig({
|
|
493
|
-
quotaToast,
|
|
494
|
-
quotaUiIntent: params.quotaUiIntent,
|
|
495
|
-
edit,
|
|
496
|
-
});
|
|
497
|
-
planTuiCompactStatusConfig({
|
|
498
|
-
quotaToast,
|
|
499
|
-
quotaUiIntent: params.quotaUiIntent,
|
|
500
|
-
edit,
|
|
501
|
-
});
|
|
502
|
-
planMaintainerAnnouncementsConfig({
|
|
503
|
-
quotaToast,
|
|
504
|
-
selections: params.selections,
|
|
505
|
-
edit,
|
|
506
|
-
});
|
|
507
|
-
const documentEdit = await planConfigDocumentEdit({
|
|
508
|
-
target,
|
|
509
|
-
desiredData: quotaToast,
|
|
510
|
-
managedComments: [
|
|
511
|
-
{
|
|
512
|
-
path: ["enableToast"],
|
|
513
|
-
text: "// Automatic quota surfaces. Slash commands remain available when these are disabled.",
|
|
514
|
-
},
|
|
515
|
-
{
|
|
516
|
-
path: ["enabledProviders"],
|
|
517
|
-
text: '// Provider selection: "auto" detects providers; an array tracks only listed providers.',
|
|
518
|
-
},
|
|
519
|
-
{
|
|
520
|
-
path: ["formatStyle"],
|
|
521
|
-
text: "// Quota presentation and reset-period choices.",
|
|
522
|
-
},
|
|
523
|
-
{
|
|
524
|
-
path: ["showSessionTokens"],
|
|
525
|
-
text: "// Include or hide session input and output token totals.",
|
|
526
|
-
},
|
|
527
|
-
{
|
|
528
|
-
path: ["sessionTokenScope"],
|
|
529
|
-
text: '// Session token totals: "current" session only, or "tree" including descendants.',
|
|
530
|
-
},
|
|
531
|
-
{
|
|
532
|
-
path: ["tuiSidebarPanel"],
|
|
533
|
-
text: "// TUI-only surfaces.",
|
|
534
|
-
},
|
|
535
|
-
{
|
|
536
|
-
path: ["maintainerAnnouncements"],
|
|
537
|
-
text: "// Optional bundled maintainer Home announcements.",
|
|
538
|
-
},
|
|
539
|
-
],
|
|
540
|
-
});
|
|
541
|
-
edit.changed = documentEdit.changed;
|
|
542
|
-
edit.documentEdit = documentEdit;
|
|
543
|
-
edit.plannedData = quotaToast;
|
|
544
|
-
return edit;
|
|
545
|
-
}
|
|
546
|
-
function buildPlanSummary(plan) {
|
|
547
|
-
const quotaUiIntent = normalizeQuotaUiIntent(plan.selections);
|
|
548
|
-
const opencodeFormat = plan.edits.find((edit) => edit.kind === "opencode")?.format ??
|
|
549
|
-
plan.selections.configFormat ??
|
|
550
|
-
"jsonc";
|
|
551
|
-
const lines = [
|
|
552
|
-
`Interface: ${plan.selections.interfaces === "tui" ? "TUI" : plan.selections.interfaces === "web" ? "Web" : "Both"}`,
|
|
553
|
-
`Scope: ${plan.selections.scope} (${plan.baseDir})`,
|
|
554
|
-
`Config format: ${opencodeFormat.toUpperCase()}`,
|
|
555
|
-
];
|
|
556
|
-
if (plan.selections.interfaces !== "web") {
|
|
557
|
-
lines.push(`TUI surfaces: ${getUiLabel(quotaUiIntent.choices)}`);
|
|
558
|
-
lines.push(`Command display: ${plan.selections.tuiCommandDisplay === "inline" ? "Inline with messages" : "Popup dialog"}`);
|
|
559
|
-
}
|
|
560
|
-
lines.push(`Provider mode: ${getProviderModeLabel(plan.selections.providerMode)}`, `Quota reset periods: ${getQuotaFormatStyleLabel(plan.selections.formatStyle)}`, `Quota percentage meaning: ${getPercentDisplayModeLabel(plan.selections.percentDisplayMode)}`, `Session input/output tokens: ${plan.selections.showSessionTokens ? "Show" : "Hide"}`, `Session token scope: ${plan.selections.sessionTokenScope === "tree" ? "Current session and descendants" : "Current session"}`);
|
|
561
|
-
if (plan.selections.maintainerAnnouncements !== undefined) {
|
|
562
|
-
lines.push(`Maintainer announcements: ${plan.selections.maintainerAnnouncements ? "Enabled" : "Disabled"}`);
|
|
563
|
-
}
|
|
564
|
-
if (quotaUiIntent.enableCompactStatus) {
|
|
565
|
-
lines.push("Compact status mode: Home bottom + session prompt");
|
|
566
|
-
}
|
|
567
|
-
const requestedProviders = resolveRequestedProviders(plan.selections);
|
|
568
|
-
if (requestedProviders !== "auto") {
|
|
569
|
-
lines.push(`Manual providers: ${requestedProviders.map((providerId) => getQuotaProviderDisplayLabel(providerId)).join(", ")}`);
|
|
570
|
-
}
|
|
571
|
-
for (const edit of plan.edits) {
|
|
572
|
-
const convertedFrom = edit.documentEdit?.removeSourcePath;
|
|
573
|
-
const mode = convertedFrom
|
|
574
|
-
? "convert"
|
|
575
|
-
: !edit.existed
|
|
576
|
-
? "create"
|
|
577
|
-
: edit.changed
|
|
578
|
-
? "update"
|
|
579
|
-
: "unchanged";
|
|
580
|
-
lines.push(convertedFrom ? `${mode}: ${convertedFrom} -> ${edit.path}` : `${mode}: ${edit.path}`);
|
|
581
|
-
for (const plugin of edit.addedPlugins) {
|
|
582
|
-
lines.push(` + plugin ${plugin}`);
|
|
583
|
-
}
|
|
584
|
-
for (const key of edit.addedKeys) {
|
|
585
|
-
lines.push(` + ${key}`);
|
|
586
|
-
}
|
|
587
|
-
for (const key of edit.updatedKeys) {
|
|
588
|
-
lines.push(` ~ ${key}`);
|
|
589
|
-
}
|
|
590
|
-
for (const change of edit.valueChanges) {
|
|
591
|
-
lines.push(` ${change}`);
|
|
592
|
-
}
|
|
593
|
-
for (const skipped of edit.skippedValues) {
|
|
594
|
-
lines.push(` = ${skipped}`);
|
|
595
|
-
}
|
|
596
|
-
for (const warning of edit.warnings) {
|
|
597
|
-
lines.push(` ! ${warning}`);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
if (plan.quickSetupNotes.length > 0) {
|
|
601
|
-
lines.push("Quick setup reminders:");
|
|
602
|
-
for (const note of plan.quickSetupNotes) {
|
|
603
|
-
lines.push(` - ${note.label}: docs/readme/providers.md#${note.anchor}`);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
if (plan.warnings.length > 0) {
|
|
607
|
-
lines.push("Warnings:");
|
|
608
|
-
for (const warning of plan.warnings) {
|
|
609
|
-
lines.push(` ! ${warning}`);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return lines;
|
|
613
|
-
}
|
|
614
|
-
export function getInstallerProviderPromptOptions() {
|
|
615
|
-
return QUOTA_PROVIDER_SHAPES.map((shape) => ({
|
|
616
|
-
label: shape.autoSetup === "needs_quick_setup"
|
|
617
|
-
? `${getQuotaProviderDisplayLabel(shape.id)} (quick setup)`
|
|
618
|
-
: getQuotaProviderDisplayLabel(shape.id),
|
|
619
|
-
value: shape.id,
|
|
620
|
-
}));
|
|
621
|
-
}
|
|
622
|
-
export function resolveInitInstallerBaseDir(params) {
|
|
623
|
-
if (params.scope === "global") {
|
|
624
|
-
return getOpencodeRuntimeDirs({ env: params.env, homeDir: params.homeDir }).configDir;
|
|
625
|
-
}
|
|
626
|
-
const cwd = params.cwd ?? process.cwd();
|
|
627
|
-
return findGitWorktreeRoot(cwd) ?? cwd;
|
|
628
|
-
}
|
|
629
|
-
export async function planInitInstaller(params) {
|
|
630
|
-
const requestedSelections = {
|
|
631
|
-
...params.selections,
|
|
632
|
-
quotaUi: params.selections.interfaces === "web" ? ["none"] : params.selections.quotaUi,
|
|
633
|
-
};
|
|
634
|
-
const quotaUiIntent = normalizeQuotaUiIntent(requestedSelections);
|
|
635
|
-
const selections = {
|
|
636
|
-
...requestedSelections,
|
|
637
|
-
configFormat: params.selections.configFormat ?? "jsonc",
|
|
638
|
-
quotaUi: quotaUiIntent.choices,
|
|
639
|
-
tuiCommandDisplay: params.selections.interfaces === "web"
|
|
640
|
-
? undefined
|
|
641
|
-
: (params.selections.tuiCommandDisplay ?? "dialog"),
|
|
642
|
-
maintainerAnnouncements: params.selections.maintainerAnnouncements,
|
|
643
|
-
manualProviders: params.selections.providerMode === "manual"
|
|
644
|
-
? resolveRequestedProviders(params.selections)
|
|
645
|
-
: [],
|
|
646
|
-
};
|
|
647
|
-
const baseDir = resolveInitInstallerBaseDir({
|
|
648
|
-
scope: selections.scope,
|
|
649
|
-
cwd: params.cwd,
|
|
650
|
-
env: params.env,
|
|
651
|
-
homeDir: params.homeDir,
|
|
652
|
-
});
|
|
653
|
-
const quotaEdit = await planQuotaConfigEdit({ selections, quotaUiIntent, baseDir });
|
|
654
|
-
const edits = [
|
|
655
|
-
await planOpencodeEdit({
|
|
656
|
-
selections,
|
|
657
|
-
baseDir,
|
|
658
|
-
pluginSpec: await resolveQuotaPluginSpec(),
|
|
659
|
-
legacyQuotaToastToSync: params.syncLegacyConfig ? quotaEdit.plannedData : undefined,
|
|
660
|
-
}),
|
|
661
|
-
quotaEdit,
|
|
662
|
-
];
|
|
663
|
-
const quickSetupNotes = buildQuickSetupNotes(selections);
|
|
664
|
-
const warnings = edits.flatMap((edit) => edit.warnings);
|
|
665
|
-
const plan = {
|
|
666
|
-
selections,
|
|
667
|
-
baseDir,
|
|
668
|
-
edits,
|
|
669
|
-
warnings,
|
|
670
|
-
quickSetupNotes,
|
|
671
|
-
summaryLines: [],
|
|
672
|
-
};
|
|
673
|
-
plan.summaryLines = buildPlanSummary(plan);
|
|
674
|
-
return plan;
|
|
675
|
-
}
|
|
676
|
-
export async function applyInitInstallerPlan(plan) {
|
|
677
|
-
const writtenPaths = [];
|
|
678
|
-
const unchangedPaths = [];
|
|
679
|
-
try {
|
|
680
|
-
await Promise.all(plan.edits.flatMap((edit) => edit.documentEdit ? [validateConfigDocumentEdit(edit.documentEdit)] : []));
|
|
681
|
-
}
|
|
682
|
-
catch (error) {
|
|
683
|
-
const path = error && typeof error === "object" && "path" in error
|
|
684
|
-
? String(error.path ?? "")
|
|
685
|
-
: "";
|
|
686
|
-
throw new InitInstallerError(`Config changed since preview${path ? `: ${path}` : "."}`, {
|
|
687
|
-
path: path || undefined,
|
|
688
|
-
writtenPaths,
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
for (const edit of plan.edits) {
|
|
692
|
-
if (!edit.changed || (!edit.nextData && !edit.documentEdit)) {
|
|
693
|
-
unchangedPaths.push(edit.path);
|
|
694
|
-
continue;
|
|
695
|
-
}
|
|
696
|
-
try {
|
|
697
|
-
if (edit.documentEdit) {
|
|
698
|
-
await applyConfigDocumentEdit(edit.documentEdit);
|
|
699
|
-
}
|
|
700
|
-
else {
|
|
701
|
-
await writeConfiguredJsonAtomic(edit.path, edit.nextData, { trailingNewline: true });
|
|
702
|
-
}
|
|
703
|
-
writtenPaths.push(edit.path);
|
|
704
|
-
}
|
|
705
|
-
catch (error) {
|
|
706
|
-
throw new InitInstallerError(`Failed writing ${edit.path}.`, {
|
|
707
|
-
path: edit.path,
|
|
708
|
-
writtenPaths,
|
|
709
|
-
});
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
return {
|
|
713
|
-
writtenPaths,
|
|
714
|
-
unchangedPaths,
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
async function readExistingInstallerAnswers(baseDir) {
|
|
718
|
-
const existingQuotaPath = QUOTA_TOAST_CONFIG_RELATIVE_PATHS.map((relativePath) => join(baseDir, relativePath)).find((path) => existsSync(path));
|
|
719
|
-
const existingHostPath = ["opencode.jsonc", "opencode.json"]
|
|
720
|
-
.map((name) => join(baseDir, name))
|
|
721
|
-
.find((path) => existsSync(path));
|
|
722
|
-
const answers = {
|
|
723
|
-
configFormat: existingQuotaPath?.endsWith(".jsonc") || existingHostPath?.endsWith(".jsonc")
|
|
724
|
-
? "jsonc"
|
|
725
|
-
: existingQuotaPath || existingHostPath
|
|
726
|
-
? "json"
|
|
727
|
-
: undefined,
|
|
728
|
-
};
|
|
729
|
-
if (!existingQuotaPath)
|
|
730
|
-
return answers;
|
|
731
|
-
const quotaToast = await readExistingConfig({
|
|
732
|
-
path: existingQuotaPath,
|
|
733
|
-
format: existingQuotaPath.endsWith(".jsonc") ? "jsonc" : "json",
|
|
734
|
-
});
|
|
735
|
-
const quotaUi = [];
|
|
736
|
-
if (isPlainObject(quotaToast.tuiSidebarPanel) && quotaToast.tuiSidebarPanel.enabled === true) {
|
|
737
|
-
quotaUi.push("sidebar");
|
|
738
|
-
}
|
|
739
|
-
if (quotaToast.enableToast === true)
|
|
740
|
-
quotaUi.push("toast");
|
|
741
|
-
if (isPlainObject(quotaToast.tuiCompactStatus) && quotaToast.tuiCompactStatus.enabled === true) {
|
|
742
|
-
quotaUi.push("compact_status");
|
|
743
|
-
}
|
|
744
|
-
answers.quotaUi = quotaUi.length > 0 ? quotaUi : ["none"];
|
|
745
|
-
if (quotaToast.enabledProviders === "auto") {
|
|
746
|
-
answers.providerMode = "auto";
|
|
747
|
-
answers.manualProviders = [];
|
|
748
|
-
}
|
|
749
|
-
else if (Array.isArray(quotaToast.enabledProviders)) {
|
|
750
|
-
answers.providerMode = "manual";
|
|
751
|
-
answers.manualProviders = quotaToast.enabledProviders.filter((value) => typeof value === "string" &&
|
|
752
|
-
QUOTA_PROVIDER_SHAPES.some((shape) => shape.id === normalizeQuotaProviderId(value)));
|
|
753
|
-
}
|
|
754
|
-
if (isQuotaFormatStyle(quotaToast.formatStyle)) {
|
|
755
|
-
answers.formatStyle = resolveQuotaFormatStyle(quotaToast.formatStyle);
|
|
756
|
-
}
|
|
757
|
-
if (quotaToast.percentDisplayMode === "remaining" || quotaToast.percentDisplayMode === "used") {
|
|
758
|
-
answers.percentDisplayMode = quotaToast.percentDisplayMode;
|
|
759
|
-
}
|
|
760
|
-
if (typeof quotaToast.showSessionTokens === "boolean") {
|
|
761
|
-
answers.showSessionTokens = quotaToast.showSessionTokens;
|
|
762
|
-
}
|
|
763
|
-
if (quotaToast.sessionTokenScope === "current" || quotaToast.sessionTokenScope === "tree") {
|
|
764
|
-
answers.sessionTokenScope = quotaToast.sessionTokenScope;
|
|
765
|
-
}
|
|
766
|
-
if (quotaToast.tuiCommandDisplay === "inline" || quotaToast.tuiCommandDisplay === "dialog") {
|
|
767
|
-
answers.tuiCommandDisplay = quotaToast.tuiCommandDisplay;
|
|
768
|
-
}
|
|
769
|
-
if (isPlainObject(quotaToast.maintainerAnnouncements) &&
|
|
770
|
-
typeof quotaToast.maintainerAnnouncements.enabled === "boolean") {
|
|
771
|
-
answers.maintainerAnnouncements = quotaToast.maintainerAnnouncements.enabled;
|
|
772
|
-
}
|
|
773
|
-
return answers;
|
|
774
|
-
}
|
|
775
|
-
async function promptForSelections(prompts, context) {
|
|
776
|
-
const interfaces = await prompts.select({
|
|
777
|
-
message: "Which OpenCode interfaces do you use?",
|
|
778
|
-
options: [
|
|
779
|
-
{ label: "TUI", value: "tui", hint: "terminal interface" },
|
|
780
|
-
{ label: "Web", value: "web", hint: "browser interface" },
|
|
781
|
-
{
|
|
782
|
-
label: "Both",
|
|
783
|
-
value: "both",
|
|
784
|
-
hint: "configure terminal and browser interfaces",
|
|
785
|
-
},
|
|
786
|
-
],
|
|
787
|
-
});
|
|
788
|
-
if (prompts.isCancel(interfaces))
|
|
789
|
-
return null;
|
|
790
|
-
if (interfaces === "web") {
|
|
791
|
-
prompts.log.info("Web and Desktop have quota slash commands but no toasts or panels. A command posts its report in the chat as your message; the AI never answers it.");
|
|
792
|
-
}
|
|
793
|
-
const scope = await prompts.select({
|
|
794
|
-
message: "Where should OpenCode Quota be configured?",
|
|
795
|
-
initialValue: "global",
|
|
796
|
-
options: [
|
|
797
|
-
{
|
|
798
|
-
label: "Global OpenCode config (recommended)",
|
|
799
|
-
value: "global",
|
|
800
|
-
hint: "install for all projects using your global config",
|
|
801
|
-
},
|
|
802
|
-
{ label: "Project config", value: "project", hint: "install only for this repo/worktree" },
|
|
803
|
-
],
|
|
804
|
-
});
|
|
805
|
-
if (prompts.isCancel(scope))
|
|
806
|
-
return null;
|
|
807
|
-
const baseDir = resolveInitInstallerBaseDir({
|
|
808
|
-
scope: scope,
|
|
809
|
-
cwd: context.cwd,
|
|
810
|
-
env: context.env,
|
|
811
|
-
homeDir: context.homeDir,
|
|
812
|
-
});
|
|
813
|
-
const existing = await readExistingInstallerAnswers(baseDir);
|
|
814
|
-
const configFormat = await prompts.select({
|
|
815
|
-
message: "OpenCode config format",
|
|
816
|
-
initialValue: existing.configFormat ?? "jsonc",
|
|
817
|
-
options: [
|
|
818
|
-
{
|
|
819
|
-
label: "JSONC (recommended)",
|
|
820
|
-
value: "jsonc",
|
|
821
|
-
hint: "keeps useful section comments and trailing commas",
|
|
822
|
-
},
|
|
823
|
-
{ label: "JSON", value: "json", hint: "strict JSON without comments" },
|
|
824
|
-
],
|
|
825
|
-
});
|
|
826
|
-
if (prompts.isCancel(configFormat))
|
|
827
|
-
return null;
|
|
828
|
-
let quotaUi = ["none"];
|
|
829
|
-
let tuiCommandDisplay;
|
|
830
|
-
let maintainerAnnouncements;
|
|
831
|
-
if (interfaces !== "web") {
|
|
832
|
-
while (true) {
|
|
833
|
-
quotaUi = await prompts.multiselect({
|
|
834
|
-
message: "Which automatic quota displays do you want?",
|
|
835
|
-
required: true,
|
|
836
|
-
initialValues: existing.quotaUi ?? ["sidebar"],
|
|
837
|
-
options: [
|
|
838
|
-
{
|
|
839
|
-
label: "Sidebar panel (TUI)",
|
|
840
|
-
value: "sidebar",
|
|
841
|
-
hint: "recommended; full Quota panel in the session sidebar",
|
|
842
|
-
},
|
|
843
|
-
{ label: "Toast (TUI)", value: "toast", hint: "popup quota summaries" },
|
|
844
|
-
{
|
|
845
|
-
label: "Compact status line (TUI)",
|
|
846
|
-
value: "compact_status",
|
|
847
|
-
hint: "short quota summary below the message input",
|
|
848
|
-
},
|
|
849
|
-
{
|
|
850
|
-
label: "Manual commands only",
|
|
851
|
-
value: "none",
|
|
852
|
-
hint: "no automatic surfaces; slash commands remain available",
|
|
853
|
-
},
|
|
854
|
-
],
|
|
855
|
-
});
|
|
856
|
-
if (prompts.isCancel(quotaUi))
|
|
857
|
-
return null;
|
|
858
|
-
if (!Array.isArray(quotaUi)) {
|
|
859
|
-
throw new InitInstallerError("Automatic quota surfaces require selected options.");
|
|
860
|
-
}
|
|
861
|
-
if (!(quotaUi.includes("none") && quotaUi.length > 1))
|
|
862
|
-
break;
|
|
863
|
-
prompts.log.error("Manual commands only cannot be combined with automatic surfaces.");
|
|
864
|
-
}
|
|
865
|
-
tuiCommandDisplay = await prompts.select({
|
|
866
|
-
message: "Where should slash commands (e.g. /quota) appear?",
|
|
867
|
-
initialValue: existing.tuiCommandDisplay ?? "dialog",
|
|
868
|
-
options: [
|
|
869
|
-
{
|
|
870
|
-
label: "Inline with messages",
|
|
871
|
-
value: "inline",
|
|
872
|
-
hint: "persist output in the message transcript",
|
|
873
|
-
},
|
|
874
|
-
{
|
|
875
|
-
label: "Popup dialog",
|
|
876
|
-
value: "dialog",
|
|
877
|
-
hint: "show output in a temporary TUI popup",
|
|
878
|
-
},
|
|
879
|
-
],
|
|
880
|
-
});
|
|
881
|
-
if (prompts.isCancel(tuiCommandDisplay))
|
|
882
|
-
return null;
|
|
883
|
-
}
|
|
884
|
-
const providerMode = await prompts.select({
|
|
885
|
-
message: "How should pre-configured providers be selected?",
|
|
886
|
-
initialValue: existing.providerMode ?? "auto",
|
|
887
|
-
options: [
|
|
888
|
-
{
|
|
889
|
-
label: "Auto-detect providers",
|
|
890
|
-
value: "auto",
|
|
891
|
-
hint: "use providers found in your OpenCode configuration and authentication",
|
|
892
|
-
},
|
|
893
|
-
{
|
|
894
|
-
label: "Choose providers manually",
|
|
895
|
-
value: "manual",
|
|
896
|
-
hint: "track only the pre-configured providers you select",
|
|
897
|
-
},
|
|
898
|
-
],
|
|
899
|
-
});
|
|
900
|
-
if (prompts.isCancel(providerMode))
|
|
901
|
-
return null;
|
|
902
|
-
let manualProviders = [];
|
|
903
|
-
if (providerMode === "manual") {
|
|
904
|
-
const selected = await prompts.multiselect({
|
|
905
|
-
message: "Which pre-configured providers should be tracked?",
|
|
906
|
-
required: true,
|
|
907
|
-
initialValues: existing.manualProviders,
|
|
908
|
-
options: getInstallerProviderPromptOptions(),
|
|
909
|
-
});
|
|
910
|
-
if (prompts.isCancel(selected))
|
|
911
|
-
return null;
|
|
912
|
-
if (!Array.isArray(selected) || selected.length === 0) {
|
|
913
|
-
throw new InitInstallerError("Manual provider mode requires at least one selected provider.");
|
|
914
|
-
}
|
|
915
|
-
manualProviders = selected.filter((value) => typeof value === "string");
|
|
916
|
-
}
|
|
917
|
-
prompts.log.info("Custom providers are configured after installation.");
|
|
918
|
-
prompts.log.info(`npx ${context.pluginSpec} provider add`);
|
|
919
|
-
const formatStyle = await prompts.select({
|
|
920
|
-
message: "Quota reset periods",
|
|
921
|
-
initialValue: existing.formatStyle ?? "allWindows",
|
|
922
|
-
options: [
|
|
923
|
-
{
|
|
924
|
-
label: "All reset periods",
|
|
925
|
-
value: "allWindows",
|
|
926
|
-
hint: "show every available quota window",
|
|
927
|
-
},
|
|
928
|
-
{
|
|
929
|
-
label: "One reset period (expiring soonest)",
|
|
930
|
-
value: "singleWindow",
|
|
931
|
-
hint: "show only the next quota window to expire",
|
|
932
|
-
},
|
|
933
|
-
],
|
|
934
|
-
});
|
|
935
|
-
if (prompts.isCancel(formatStyle))
|
|
936
|
-
return null;
|
|
937
|
-
const percentDisplayMode = await prompts.select({
|
|
938
|
-
message: "What should quota percentages show?",
|
|
939
|
-
initialValue: existing.percentDisplayMode ?? "remaining",
|
|
940
|
-
options: [
|
|
941
|
-
{ label: "Remaining quota", value: "remaining", hint: "show how much quota is left" },
|
|
942
|
-
{ label: "Used quota", value: "used", hint: "show how much quota has been consumed" },
|
|
943
|
-
],
|
|
944
|
-
});
|
|
945
|
-
if (prompts.isCancel(percentDisplayMode))
|
|
946
|
-
return null;
|
|
947
|
-
const showSessionTokens = await prompts.select({
|
|
948
|
-
message: "Session input/output tokens",
|
|
949
|
-
initialValue: existing.showSessionTokens === true ? "yes" : "no",
|
|
950
|
-
options: [
|
|
951
|
-
{ label: "Hide", value: "no", hint: "keep output shorter" },
|
|
952
|
-
{
|
|
953
|
-
label: "Show",
|
|
954
|
-
value: "yes",
|
|
955
|
-
hint: "include current-session input and output totals",
|
|
956
|
-
},
|
|
957
|
-
],
|
|
958
|
-
});
|
|
959
|
-
if (prompts.isCancel(showSessionTokens))
|
|
960
|
-
return null;
|
|
961
|
-
const sessionTokenScope = await prompts.select({
|
|
962
|
-
message: "Session token scope",
|
|
963
|
-
initialValue: existing.sessionTokenScope ?? "current",
|
|
964
|
-
options: [
|
|
965
|
-
{
|
|
966
|
-
label: "Current session",
|
|
967
|
-
value: "current",
|
|
968
|
-
hint: "preserve the existing session-only totals",
|
|
969
|
-
},
|
|
970
|
-
{
|
|
971
|
-
label: "Current session and descendants",
|
|
972
|
-
value: "tree",
|
|
973
|
-
hint: "include child and subagent sessions once",
|
|
974
|
-
},
|
|
975
|
-
],
|
|
976
|
-
});
|
|
977
|
-
if (prompts.isCancel(sessionTokenScope))
|
|
978
|
-
return null;
|
|
979
|
-
if (interfaces !== "web") {
|
|
980
|
-
maintainerAnnouncements = await prompts.confirm({
|
|
981
|
-
message: "Show maintainer announcements on the TUI Home screen when available?",
|
|
982
|
-
initialValue: existing.maintainerAnnouncements ?? true,
|
|
983
|
-
});
|
|
984
|
-
if (prompts.isCancel(maintainerAnnouncements))
|
|
985
|
-
return null;
|
|
986
|
-
}
|
|
987
|
-
return {
|
|
988
|
-
interfaces: interfaces,
|
|
989
|
-
scope: scope,
|
|
990
|
-
quotaUi: Array.isArray(quotaUi)
|
|
991
|
-
? quotaUi.filter((value) => typeof value === "string")
|
|
992
|
-
: ["none"],
|
|
993
|
-
providerMode: providerMode,
|
|
994
|
-
manualProviders,
|
|
995
|
-
formatStyle: formatStyle,
|
|
996
|
-
percentDisplayMode: percentDisplayMode,
|
|
997
|
-
showSessionTokens: showSessionTokens === "yes",
|
|
998
|
-
sessionTokenScope: sessionTokenScope,
|
|
999
|
-
tuiCommandDisplay: interfaces === "web" ? undefined : tuiCommandDisplay,
|
|
1000
|
-
maintainerAnnouncements: interfaces === "web" ? undefined : maintainerAnnouncements !== false,
|
|
1001
|
-
configFormat: configFormat,
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
export async function runInitInstaller(params) {
|
|
1005
|
-
const prompts = params?.prompts ?? (await import("@clack/prompts"));
|
|
1006
|
-
prompts.intro("Configure @slkiser/opencode-quota");
|
|
1007
|
-
try {
|
|
1008
|
-
let openCodeMajor = await detectOpenCodeMajor();
|
|
1009
|
-
if (openCodeMajor === undefined) {
|
|
1010
|
-
const answer = await prompts.select({
|
|
1011
|
-
message: "Could not detect your OpenCode version. Which OpenCode do you use?",
|
|
1012
|
-
initialValue: "2",
|
|
1013
|
-
options: [
|
|
1014
|
-
{ label: "OpenCode 2", value: "2", hint: "default" },
|
|
1015
|
-
{ label: "OpenCode 1", value: "1" },
|
|
1016
|
-
],
|
|
1017
|
-
});
|
|
1018
|
-
if (prompts.isCancel(answer)) {
|
|
1019
|
-
prompts.outro("OpenCode Quota setup cancelled — no files changed.");
|
|
1020
|
-
return 0;
|
|
1021
|
-
}
|
|
1022
|
-
openCodeMajor = answer === "1" ? 1 : 2;
|
|
1023
|
-
}
|
|
1024
|
-
if (openCodeMajor === 1) {
|
|
1025
|
-
prompts.log.error("You're on OpenCode 1. OpenCode Quota 5 needs OpenCode 2.");
|
|
1026
|
-
prompts.outro("For OpenCode 1, run: npx @slkiser/opencode-quota@4 init — no files changed.");
|
|
1027
|
-
return 1;
|
|
1028
|
-
}
|
|
1029
|
-
const pluginSpec = await resolveQuotaPluginSpec();
|
|
1030
|
-
const selections = await promptForSelections(prompts, {
|
|
1031
|
-
cwd: params?.cwd,
|
|
1032
|
-
env: params?.env,
|
|
1033
|
-
homeDir: params?.homeDir,
|
|
1034
|
-
pluginSpec,
|
|
1035
|
-
});
|
|
1036
|
-
if (!selections) {
|
|
1037
|
-
prompts.outro("OpenCode Quota setup cancelled — no files changed.");
|
|
1038
|
-
return 0;
|
|
1039
|
-
}
|
|
1040
|
-
const plan = await planInitInstaller({
|
|
1041
|
-
selections,
|
|
1042
|
-
cwd: params?.cwd,
|
|
1043
|
-
env: params?.env,
|
|
1044
|
-
homeDir: params?.homeDir,
|
|
1045
|
-
syncLegacyConfig: params?.syncLegacyConfig,
|
|
1046
|
-
});
|
|
1047
|
-
for (const line of plan.summaryLines) {
|
|
1048
|
-
prompts.log.info(line);
|
|
1049
|
-
}
|
|
1050
|
-
if (!plan.edits.some((edit) => edit.changed)) {
|
|
1051
|
-
prompts.outro(`OpenCode Quota is already configured and current. No files changed. ${GITHUB_STAR_NOTE}`);
|
|
1052
|
-
return 0;
|
|
1053
|
-
}
|
|
1054
|
-
if (params?.dryRun) {
|
|
1055
|
-
prompts.outro(`OpenCode Quota setup preview complete — no files changed. Run npx ${pluginSpec} init to apply.`);
|
|
1056
|
-
return 0;
|
|
1057
|
-
}
|
|
1058
|
-
const confirmed = await prompts.confirm({
|
|
1059
|
-
message: "Apply these changes?",
|
|
1060
|
-
initialValue: true,
|
|
1061
|
-
});
|
|
1062
|
-
if (prompts.isCancel(confirmed) || !confirmed) {
|
|
1063
|
-
prompts.outro("OpenCode Quota setup cancelled — no files changed.");
|
|
1064
|
-
return 0;
|
|
1065
|
-
}
|
|
1066
|
-
const result = await applyInitInstallerPlan(plan);
|
|
1067
|
-
for (const path of result.writtenPaths) {
|
|
1068
|
-
prompts.log.success(`Wrote ${path}`);
|
|
1069
|
-
}
|
|
1070
|
-
for (const path of result.unchangedPaths) {
|
|
1071
|
-
prompts.log.info(`Unchanged ${path}`);
|
|
1072
|
-
}
|
|
1073
|
-
if (plan.quickSetupNotes.length > 0) {
|
|
1074
|
-
prompts.log.info("Manual quick-setup still needed:");
|
|
1075
|
-
for (const note of plan.quickSetupNotes) {
|
|
1076
|
-
prompts.log.info(`- ${note.label}: docs/readme/providers.md#${note.anchor}`);
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
const interfaceLabel = plan.selections.interfaces === "tui"
|
|
1080
|
-
? "TUI"
|
|
1081
|
-
: plan.selections.interfaces === "web"
|
|
1082
|
-
? "Web"
|
|
1083
|
-
: "TUI and Web";
|
|
1084
|
-
const configuredPaths = [...result.writtenPaths, ...result.unchangedPaths];
|
|
1085
|
-
prompts.outro([
|
|
1086
|
-
"OpenCode Quota setup complete.",
|
|
1087
|
-
`Interfaces: ${interfaceLabel}`,
|
|
1088
|
-
"Configured paths:",
|
|
1089
|
-
...configuredPaths.map((path) => `- ${path}`),
|
|
1090
|
-
plan.selections.interfaces === "web"
|
|
1091
|
-
? "Run `npx @slkiser/opencode-quota show` in a terminal to check quota."
|
|
1092
|
-
: "Restart OpenCode and run /quota.",
|
|
1093
|
-
`If OpenCode Quota helps, please consider a star: ${GITHUB_REPO_URL}`,
|
|
1094
|
-
].join("\n"));
|
|
1095
|
-
return 0;
|
|
1096
|
-
}
|
|
1097
|
-
catch (error) {
|
|
1098
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
1099
|
-
prompts.log.error(reason);
|
|
1100
|
-
const writtenPaths = error instanceof InitInstallerError ? (error.details?.writtenPaths ?? []) : [];
|
|
1101
|
-
if (writtenPaths.length > 0) {
|
|
1102
|
-
prompts.log.info(`Files changed before failure: ${writtenPaths.join(", ")}`);
|
|
1103
|
-
prompts.outro("OpenCode Quota setup failed after some files changed. Review the listed files, fix the reason above, then rerun init.");
|
|
1104
|
-
}
|
|
1105
|
-
else {
|
|
1106
|
-
prompts.outro("OpenCode Quota setup failed before any files changed. Fix the reason above, then rerun init.");
|
|
1107
|
-
}
|
|
1108
|
-
return 1;
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
//# sourceMappingURL=init-installer.js.map
|