@slkiser/opencode-quota 2.14.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -34
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/alibaba-auth.d.ts +25 -0
- package/dist/lib/alibaba-auth.d.ts.map +1 -1
- package/dist/lib/alibaba-auth.js +82 -8
- package/dist/lib/alibaba-auth.js.map +1 -1
- package/dist/lib/api-key-resolver.d.ts +37 -4
- package/dist/lib/api-key-resolver.d.ts.map +1 -1
- package/dist/lib/api-key-resolver.js +83 -23
- package/dist/lib/api-key-resolver.js.map +1 -1
- package/dist/lib/atomic-json.d.ts +5 -0
- package/dist/lib/atomic-json.d.ts.map +1 -0
- package/dist/lib/atomic-json.js +33 -0
- package/dist/lib/atomic-json.js.map +1 -0
- package/dist/lib/chutes-config.d.ts.map +1 -1
- package/dist/lib/chutes-config.js +7 -39
- package/dist/lib/chutes-config.js.map +1 -1
- package/dist/lib/chutes.d.ts +1 -2
- package/dist/lib/chutes.d.ts.map +1 -1
- package/dist/lib/chutes.js +5 -14
- package/dist/lib/chutes.js.map +1 -1
- package/dist/lib/cursor-detection.d.ts.map +1 -1
- package/dist/lib/cursor-detection.js +3 -3
- package/dist/lib/cursor-detection.js.map +1 -1
- package/dist/lib/cursor-pricing.d.ts.map +1 -1
- package/dist/lib/cursor-pricing.js +2 -2
- package/dist/lib/cursor-pricing.js.map +1 -1
- package/dist/lib/cursor-usage.d.ts.map +1 -1
- package/dist/lib/cursor-usage.js +6 -29
- package/dist/lib/cursor-usage.js.map +1 -1
- package/dist/lib/firmware-config.d.ts.map +1 -1
- package/dist/lib/firmware-config.js +7 -40
- package/dist/lib/firmware-config.js.map +1 -1
- package/dist/lib/firmware.d.ts +1 -2
- package/dist/lib/firmware.d.ts.map +1 -1
- package/dist/lib/firmware.js +7 -16
- package/dist/lib/firmware.js.map +1 -1
- package/dist/lib/google.d.ts +10 -0
- package/dist/lib/google.d.ts.map +1 -1
- package/dist/lib/google.js +82 -16
- package/dist/lib/google.js.map +1 -1
- package/dist/lib/minimax-auth.d.ts +25 -2
- package/dist/lib/minimax-auth.d.ts.map +1 -1
- package/dist/lib/minimax-auth.js +74 -7
- package/dist/lib/minimax-auth.js.map +1 -1
- package/dist/lib/modelsdev-pricing.d.ts.map +1 -1
- package/dist/lib/modelsdev-pricing.js +8 -36
- package/dist/lib/modelsdev-pricing.js.map +1 -1
- package/dist/lib/nanogpt-config.d.ts.map +1 -1
- package/dist/lib/nanogpt-config.js +7 -36
- package/dist/lib/nanogpt-config.js.map +1 -1
- package/dist/lib/nanogpt.d.ts +1 -2
- package/dist/lib/nanogpt.d.ts.map +1 -1
- package/dist/lib/nanogpt.js +5 -14
- package/dist/lib/nanogpt.js.map +1 -1
- package/dist/lib/openai.d.ts +21 -2
- package/dist/lib/openai.d.ts.map +1 -1
- package/dist/lib/openai.js +53 -15
- package/dist/lib/openai.js.map +1 -1
- package/dist/lib/opencode-go-config.d.ts +35 -0
- package/dist/lib/opencode-go-config.d.ts.map +1 -0
- package/dist/lib/opencode-go-config.js +124 -0
- package/dist/lib/opencode-go-config.js.map +1 -0
- package/dist/lib/opencode-go.d.ts +15 -0
- package/dist/lib/opencode-go.d.ts.map +1 -0
- package/dist/lib/opencode-go.js +88 -0
- package/dist/lib/opencode-go.js.map +1 -0
- package/dist/lib/provider-availability.d.ts +6 -0
- package/dist/lib/provider-availability.d.ts.map +1 -1
- package/dist/lib/provider-availability.js +9 -0
- package/dist/lib/provider-availability.js.map +1 -1
- package/dist/lib/provider-metadata.d.ts +18 -0
- package/dist/lib/provider-metadata.d.ts.map +1 -1
- package/dist/lib/provider-metadata.js +120 -1
- package/dist/lib/provider-metadata.js.map +1 -1
- package/dist/lib/quota-command-format.d.ts +0 -5
- package/dist/lib/quota-command-format.d.ts.map +1 -1
- package/dist/lib/quota-command-format.js +1 -1
- package/dist/lib/quota-command-format.js.map +1 -1
- package/dist/lib/quota-stats-format.d.ts.map +1 -1
- package/dist/lib/quota-stats-format.js +10 -13
- package/dist/lib/quota-stats-format.js.map +1 -1
- package/dist/lib/quota-stats.d.ts +2 -7
- package/dist/lib/quota-stats.d.ts.map +1 -1
- package/dist/lib/quota-stats.js +17 -43
- package/dist/lib/quota-stats.js.map +1 -1
- package/dist/lib/quota-status.d.ts.map +1 -1
- package/dist/lib/quota-status.js +214 -91
- package/dist/lib/quota-status.js.map +1 -1
- package/dist/lib/qwen-auth.d.ts +4 -0
- package/dist/lib/qwen-auth.d.ts.map +1 -1
- package/dist/lib/qwen-auth.js +6 -6
- package/dist/lib/qwen-auth.js.map +1 -1
- package/dist/lib/qwen-local-quota.d.ts.map +1 -1
- package/dist/lib/qwen-local-quota.js +5 -33
- package/dist/lib/qwen-local-quota.js.map +1 -1
- package/dist/lib/token-buckets.d.ts +24 -0
- package/dist/lib/token-buckets.d.ts.map +1 -0
- package/dist/lib/token-buckets.js +32 -0
- package/dist/lib/token-buckets.js.map +1 -0
- package/dist/lib/types.d.ts +25 -26
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +10 -2
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/zai-auth.d.ts +38 -0
- package/dist/lib/zai-auth.d.ts.map +1 -0
- package/dist/lib/zai-auth.js +107 -0
- package/dist/lib/zai-auth.js.map +1 -0
- package/dist/lib/zai.d.ts.map +1 -1
- package/dist/lib/zai.js +17 -17
- package/dist/lib/zai.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +81 -67
- package/dist/plugin.js.map +1 -1
- package/dist/providers/anthropic.js +3 -3
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/chutes.d.ts.map +1 -1
- package/dist/providers/chutes.js +8 -10
- package/dist/providers/chutes.js.map +1 -1
- package/dist/providers/copilot.d.ts.map +1 -1
- package/dist/providers/copilot.js +6 -8
- package/dist/providers/copilot.js.map +1 -1
- package/dist/providers/cursor.js +3 -3
- package/dist/providers/cursor.js.map +1 -1
- package/dist/providers/firmware.d.ts.map +1 -1
- package/dist/providers/firmware.js +8 -11
- package/dist/providers/firmware.js.map +1 -1
- package/dist/providers/google-antigravity.d.ts.map +1 -1
- package/dist/providers/google-antigravity.js +4 -14
- package/dist/providers/google-antigravity.js.map +1 -1
- package/dist/providers/minimax-coding-plan.js +3 -3
- package/dist/providers/minimax-coding-plan.js.map +1 -1
- package/dist/providers/nanogpt.d.ts.map +1 -1
- package/dist/providers/nanogpt.js +2 -13
- package/dist/providers/nanogpt.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +8 -4
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/opencode-go.d.ts +9 -0
- package/dist/providers/opencode-go.d.ts.map +1 -0
- package/dist/providers/opencode-go.js +80 -0
- package/dist/providers/opencode-go.js.map +1 -0
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +2 -0
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/zai.d.ts.map +1 -1
- package/dist/providers/zai.js +19 -12
- package/dist/providers/zai.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- Automatic quota toasts after assistant responses
|
|
6
6
|
- Manual `/quota`, `/pricing_refresh`, and `/tokens_*` commands for deeper local reporting with zero context window pollution
|
|
7
7
|
|
|
8
|
-
**Quota providers**: Anthropic (Claude), GitHub Copilot, OpenAI (Plus/Pro), Cursor, Qwen Code, Alibaba Coding Plan, MiniMax Coding Plan, Chutes AI, Firmware AI, Google Antigravity, Z.ai
|
|
8
|
+
**Quota providers**: Anthropic (Claude), GitHub Copilot, OpenAI (Plus/Pro), Cursor, Qwen Code, Alibaba Coding Plan, MiniMax Coding Plan, Chutes AI, Firmware AI, Google Antigravity, Z.ai Coding Plan, NanoGPT, and OpenCode Go.
|
|
9
9
|
|
|
10
10
|
**Token reports**: All models and providers in [models.dev](https://models.dev), plus deterministic local pricing for Cursor Auto/Composer and Cursor model aliases that are not on models.dev.
|
|
11
11
|
|
|
@@ -76,20 +76,21 @@ That is enough for most installs. Providers are auto-detected from your existing
|
|
|
76
76
|
|
|
77
77
|
### Provider Setup At A Glance
|
|
78
78
|
|
|
79
|
-
| Provider | Auto setup |
|
|
80
|
-
| --- | --- | --- |
|
|
81
|
-
| **Anthropic (Claude)** | Needs [quick setup](#anthropic-quick-setup) | Local
|
|
82
|
-
| **GitHub Copilot** | Usually | OpenCode auth
|
|
83
|
-
| **OpenAI** | Yes | OpenCode auth
|
|
84
|
-
| **Cursor** | Needs [quick setup](#cursor-quick-setup) | Companion auth
|
|
85
|
-
| **Qwen Code** | Needs [quick setup](#qwen-code-quick-setup) | Companion auth
|
|
86
|
-
| **Alibaba Coding Plan** | Yes | OpenCode auth
|
|
87
|
-
| **Firmware AI** | Usually | OpenCode auth
|
|
88
|
-
| **Chutes AI** | Usually | OpenCode auth
|
|
89
|
-
| **
|
|
90
|
-
| **
|
|
91
|
-
| **
|
|
92
|
-
| **MiniMax Coding Plan** | Yes | OpenCode auth
|
|
79
|
+
| Provider | Auto setup | Authentication | Quota |
|
|
80
|
+
| --- | --- | --- | --- |
|
|
81
|
+
| **Anthropic (Claude)** | Needs [quick setup](#anthropic-quick-setup) | Local CLI auth | Local CLI report |
|
|
82
|
+
| **GitHub Copilot** | Usually | OpenCode auth or PAT | Remote API |
|
|
83
|
+
| **OpenAI** | Yes | OpenCode auth | Remote API |
|
|
84
|
+
| **Cursor** | Needs [quick setup](#cursor-quick-setup) | Companion auth | Local runtime accounting |
|
|
85
|
+
| **Qwen Code** | Needs [quick setup](#qwen-code-quick-setup) | Companion auth | Local estimation |
|
|
86
|
+
| **Alibaba Coding Plan** | Yes | OpenCode auth/global config/env | Local estimation |
|
|
87
|
+
| **Firmware AI** | Usually | OpenCode auth/global config/env | Remote API |
|
|
88
|
+
| **Chutes AI** | Usually | OpenCode auth/global config/env | Remote API |
|
|
89
|
+
| **Google Antigravity** | Needs [quick setup](#google-antigravity-quick-setup) | Companion auth | Remote API |
|
|
90
|
+
| **Z.ai** | Yes | OpenCode auth/global config/env | Remote API |
|
|
91
|
+
| **NanoGPT** | Usually | OpenCode auth/global config/env | Remote API |
|
|
92
|
+
| **MiniMax Coding Plan** | Yes | OpenCode auth/global config/env | Remote API |
|
|
93
|
+
| **OpenCode Go** | Needs [quick setup](#opencode-go-quick-setup) | Env/config auth | Dashboard scraping |
|
|
93
94
|
|
|
94
95
|
<a id="anthropic-quick-setup"></a>
|
|
95
96
|
<details>
|
|
@@ -178,6 +179,37 @@ For behavior details and troubleshooting, see [Qwen Code notes](#qwen-code-notes
|
|
|
178
179
|
|
|
179
180
|
</details>
|
|
180
181
|
|
|
182
|
+
<a id="opencode-go-quick-setup"></a>
|
|
183
|
+
<details>
|
|
184
|
+
<summary><strong>Quick setup: OpenCode Go</strong></summary>
|
|
185
|
+
|
|
186
|
+
OpenCode Go quota scrapes the OpenCode Go dashboard. It requires a workspace ID and an auth cookie.
|
|
187
|
+
|
|
188
|
+
**Option A — Environment variables:**
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
export OPENCODE_GO_WORKSPACE_ID="your-workspace-id"
|
|
192
|
+
export OPENCODE_GO_AUTH_COOKIE="your-auth-cookie"
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Option B — Config file** (for example, `~/.config/opencode/opencode-quota/opencode-go.json` on Linux or legacy macOS installs):
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"workspaceId": "your-workspace-id",
|
|
200
|
+
"authCookie": "your-auth-cookie"
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
To find these values:
|
|
205
|
+
|
|
206
|
+
1. **workspaceId** — Visit [opencode.ai](https://opencode.ai), open your workspace, and copy the workspace ID from the URL: `https://opencode.ai/workspace/<workspaceId>/go`.
|
|
207
|
+
2. **authCookie** — Open your browser DevTools on `opencode.ai`, go to Application → Cookies, and copy the value of the `auth` cookie.
|
|
208
|
+
|
|
209
|
+
Environment variables take precedence over the config file. Run `/quota_status` to see the exact config paths checked on your machine. For behavior details and troubleshooting, see [OpenCode Go notes](#opencode-go-notes).
|
|
210
|
+
|
|
211
|
+
</details>
|
|
212
|
+
|
|
181
213
|
## Commands
|
|
182
214
|
|
|
183
215
|
| Command | What it shows |
|
|
@@ -257,7 +289,7 @@ Example `copilot-quota-token.json`:
|
|
|
257
289
|
<details>
|
|
258
290
|
<summary><strong>Cursor</strong></summary>
|
|
259
291
|
|
|
260
|
-
See [Cursor quick setup](#cursor-quick-setup) for auth. Quota and token reporting stays local to OpenCode history and local pricing data.
|
|
292
|
+
See [Cursor quick setup](#cursor-quick-setup) for companion-plugin OAuth auth. Quota and token reporting stays local to OpenCode history and local pricing data.
|
|
261
293
|
|
|
262
294
|
- Detects Cursor usage when the provider is `cursor` or the stored/current model id is `cursor/*`.
|
|
263
295
|
- `/tokens_*` maps Cursor API-pool models to official pricing and uses bundled static pricing for `auto` and `composer*`.
|
|
@@ -280,6 +312,18 @@ Example override:
|
|
|
280
312
|
|
|
281
313
|
</details>
|
|
282
314
|
|
|
315
|
+
<a id="openai-notes"></a>
|
|
316
|
+
<details>
|
|
317
|
+
<summary><strong>OpenAI</strong></summary>
|
|
318
|
+
|
|
319
|
+
OpenAI uses native OpenCode OAuth from `auth.json`. The canonical auth family is OpenCode auth, not companion-plugin auth.
|
|
320
|
+
|
|
321
|
+
- Quota is fetched from the OpenAI usage API using the native OpenCode OAuth token stored under `openai` in `auth.json`.
|
|
322
|
+
- Older OpenCode installs may still have compatible OpenAI OAuth entries under `codex`, `chatgpt`, or `opencode`. Those remain supported for backward compatibility.
|
|
323
|
+
- `/quota_status` includes an `openai` section with the detected auth source, token status, expiry, and account details derived from the token when available.
|
|
324
|
+
|
|
325
|
+
</details>
|
|
326
|
+
|
|
283
327
|
<a id="qwen-code-notes"></a>
|
|
284
328
|
<details>
|
|
285
329
|
<summary><strong>Qwen Code</strong></summary>
|
|
@@ -287,9 +331,10 @@ Example override:
|
|
|
287
331
|
See [Qwen Code quick setup](#qwen-code-quick-setup) for auth. Usage is local-only estimation for the free plan; the plugin does not call an Alibaba quota API.
|
|
288
332
|
|
|
289
333
|
- Free tier limits: `1000` requests per UTC day and `60` requests per rolling minute.
|
|
334
|
+
- The canonical companion auth key is `qwen-code`. Older installs may still use `opencode-qwencode-auth`, which remains a supported fallback.
|
|
290
335
|
- Counters increment on successful question-tool completions while the current model is `qwen-code/*`.
|
|
291
336
|
- State file: `.../opencode/opencode-quota/qwen-local-quota.json`.
|
|
292
|
-
- Check `/quota_status` for auth detection, `qwen_local_plan`, and local counter state.
|
|
337
|
+
- Check `/quota_status` for auth detection, `qwen_oauth_source`, `qwen_local_plan`, and local counter state.
|
|
293
338
|
|
|
294
339
|
</details>
|
|
295
340
|
|
|
@@ -297,11 +342,14 @@ See [Qwen Code quick setup](#qwen-code-quick-setup) for auth. Usage is local-onl
|
|
|
297
342
|
<details>
|
|
298
343
|
<summary><strong>Alibaba Coding Plan</strong></summary>
|
|
299
344
|
|
|
300
|
-
|
|
345
|
+
Alibaba Coding Plan uses trusted env vars or trusted user/global OpenCode config first, then native OpenCode auth from `alibaba-coding-plan` or `alibaba` in `auth.json`. Quota is local request-count estimation with rolling windows.
|
|
301
346
|
|
|
302
347
|
- `lite`: `1200 / 5h`, `9000 / week`, `18000 / month`
|
|
303
348
|
- `pro`: `6000 / 5h`, `45000 / week`, `90000 / month`
|
|
304
|
-
-
|
|
349
|
+
- API key sources are `ALIBABA_CODING_PLAN_API_KEY`, `ALIBABA_API_KEY`, trusted user/global `provider["alibaba-coding-plan"].options.apiKey` or `provider.alibaba.options.apiKey`, then `auth.json`.
|
|
350
|
+
- Repo-local `opencode.json` / `opencode.jsonc` is ignored for Alibaba secrets.
|
|
351
|
+
- Allowed env templates are limited to `{env:ALIBABA_CODING_PLAN_API_KEY}` and `{env:ALIBABA_API_KEY}`.
|
|
352
|
+
- If auth fallback wins and omits `tier`, or if env/config wins, the plugin uses `experimental.quotaToast.alibabaCodingPlanTier`, which defaults to `lite`.
|
|
305
353
|
- Counters increment on successful question-tool completions while the current model is `alibaba/*` or `alibaba-cn/*`.
|
|
306
354
|
- State file: `.../opencode/opencode-quota/alibaba-coding-plan-local-quota.json`.
|
|
307
355
|
- `/quota_status` shows auth detection, resolved tier, state-file path, and current 5h/weekly/monthly usage.
|
|
@@ -325,23 +373,28 @@ Example fallback tier:
|
|
|
325
373
|
<details>
|
|
326
374
|
<summary><strong>MiniMax Coding Plan</strong></summary>
|
|
327
375
|
|
|
328
|
-
|
|
376
|
+
MiniMax Coding Plan uses trusted env vars or trusted user/global OpenCode config first, then native OpenCode auth from `auth.json["minimax-coding-plan"]`. No additional plugin is required.
|
|
329
377
|
|
|
330
|
-
|
|
378
|
+
- `MiniMax-M*` models — rolling 5-hour interval + weekly
|
|
379
|
+
- API key sources are `MINIMAX_CODING_PLAN_API_KEY`, `MINIMAX_API_KEY`, trusted user/global `provider["minimax-coding-plan"].options.apiKey` or `provider.minimax.options.apiKey`, then `auth.json`.
|
|
380
|
+
- Repo-local `opencode.json` / `opencode.jsonc` is ignored for MiniMax secrets.
|
|
381
|
+
- Allowed env templates are limited to `{env:MINIMAX_CODING_PLAN_API_KEY}` and `{env:MINIMAX_API_KEY}`.
|
|
382
|
+
- When `auth.json` fallback wins, the plugin reads `key` first and falls back to `access`.
|
|
383
|
+
- `/quota_status` shows auth detection, API-key diagnostics, live quota state, and endpoint errors
|
|
331
384
|
|
|
332
|
-
|
|
385
|
+
</details>
|
|
333
386
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
"type": "api",
|
|
338
|
-
"key": "YOUR_MINIMAX_API_KEY"
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
```
|
|
387
|
+
<a id="zai-notes"></a>
|
|
388
|
+
<details>
|
|
389
|
+
<summary><strong>Z.ai</strong></summary>
|
|
342
390
|
|
|
343
|
-
|
|
344
|
-
|
|
391
|
+
Z.ai uses trusted env vars or trusted user/global OpenCode config first, then native OpenCode auth from `auth.json["zai-coding-plan"]`.
|
|
392
|
+
|
|
393
|
+
- API key sources are `ZAI_API_KEY`, `ZAI_CODING_PLAN_API_KEY`, trusted user/global `provider.zai.options.apiKey`, `provider["zai-coding-plan"].options.apiKey`, or `provider.glm.options.apiKey`, then `auth.json`.
|
|
394
|
+
- Repo-local `opencode.json` / `opencode.jsonc` is ignored for Z.ai secrets.
|
|
395
|
+
- Allowed env templates are limited to `{env:ZAI_API_KEY}` and `{env:ZAI_CODING_PLAN_API_KEY}`.
|
|
396
|
+
- `/quota_status` shows auth diagnostics plus live 5-hour, weekly, and MCP quota windows when the Z.ai API reports them.
|
|
397
|
+
- Malformed `zai-coding-plan` fallback auth is surfaced as an auth error instead of being silently treated as missing.
|
|
345
398
|
|
|
346
399
|
</details>
|
|
347
400
|
|
|
@@ -401,9 +454,10 @@ Example user/global config (`~/.config/opencode/opencode.jsonc` on Linux/macOS):
|
|
|
401
454
|
<details>
|
|
402
455
|
<summary><strong>Google Antigravity</strong></summary>
|
|
403
456
|
|
|
404
|
-
See [Google Antigravity quick setup](#google-antigravity-quick-setup).
|
|
457
|
+
See [Google Antigravity quick setup](#google-antigravity-quick-setup). This companion auth flow does not use `auth.json`; it reads `antigravity-accounts.json` from the OpenCode runtime directories.
|
|
405
458
|
|
|
406
|
-
|
|
459
|
+
- `/quota_status` includes a `google_antigravity` section with the selected accounts path, all present/candidate paths, account counts, valid refresh-token counts, and the Google token-cache path.
|
|
460
|
+
- If detection looks wrong, start with the `google_antigravity` section in `/quota_status`.
|
|
407
461
|
|
|
408
462
|
</details>
|
|
409
463
|
|
|
@@ -436,6 +490,31 @@ Example user/global config (`~/.config/opencode/opencode.jsonc` on Linux/macOS):
|
|
|
436
490
|
|
|
437
491
|
</details>
|
|
438
492
|
|
|
493
|
+
<a id="opencode-go-notes"></a>
|
|
494
|
+
<details>
|
|
495
|
+
<summary><strong>OpenCode Go</strong></summary>
|
|
496
|
+
|
|
497
|
+
OpenCode Go quota scrapes the OpenCode Go dashboard at `https://opencode.ai/workspace/<workspaceId>/go` using an `auth` cookie. There is no official usage API yet; the plugin parses the SolidJS SSR hydration output for `monthlyUsage` data.
|
|
498
|
+
|
|
499
|
+
- **Config sources** (checked in order):
|
|
500
|
+
1. Environment variables: `OPENCODE_GO_WORKSPACE_ID` and `OPENCODE_GO_AUTH_COOKIE`
|
|
501
|
+
2. Config file: for example `~/.config/opencode/opencode-quota/opencode-go.json` on Linux or legacy macOS installs, with `{ "workspaceId": "...", "authCookie": "..." }`
|
|
502
|
+
- Environment variables take precedence. Both `workspaceId` and `authCookie` must come from the same source.
|
|
503
|
+
- Quota returns a usage percentage and a reset countdown. There is no absolute request count.
|
|
504
|
+
- `/quota_status` shows an `opencode_go` section with config state, config source, checked paths, and live scrape results or errors.
|
|
505
|
+
- Because this is a scraper, it may break if OpenCode changes their dashboard markup. An official API ([opencode#16513](https://github.com/anomalyco/opencode/pull/16513)) is pending.
|
|
506
|
+
|
|
507
|
+
**Troubleshooting:**
|
|
508
|
+
|
|
509
|
+
| Problem | Solution |
|
|
510
|
+
| --- | --- |
|
|
511
|
+
| Config not detected | Confirm `OPENCODE_GO_WORKSPACE_ID` and `OPENCODE_GO_AUTH_COOKIE` are set, then use `/quota_status` to inspect the exact config paths checked on your machine |
|
|
512
|
+
| Incomplete config | Both `workspaceId` and `authCookie` are required; check `/quota_status` for which field is missing |
|
|
513
|
+
| Scrape returns no data | The auth cookie may have expired; get a fresh one from your browser |
|
|
514
|
+
| Dashboard format changed | The SolidJS SSR pattern may have changed; file an issue or wait for the official API |
|
|
515
|
+
|
|
516
|
+
</details>
|
|
517
|
+
|
|
439
518
|
## Configuration Reference
|
|
440
519
|
|
|
441
520
|
All plugin settings live under `experimental.quotaToast`.
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
|
+
declare const pluginModule: {
|
|
9
|
+
id: string;
|
|
10
|
+
server: import("@opencode-ai/plugin").Plugin;
|
|
11
|
+
};
|
|
12
|
+
export default pluginModule;
|
|
8
13
|
export { QuotaToastPlugin } from "./plugin.js";
|
|
9
14
|
export type { QuotaToastConfig, GoogleModelId, PricingSnapshotSource, CopilotEnterpriseUsageResult, CopilotOrganizationUsageResult, CopilotQuotaResult, GoogleQuotaResult, GoogleModelQuota, MiniMaxResult, MiniMaxResultEntry, } from "./lib/types.js";
|
|
10
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,QAAA,MAAM,YAAY;;;CAGQ,CAAC;AAE3B,eAAe,YAAY,CAAC;AAI5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,4BAA4B,EAC5B,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GACnB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,11 +5,17 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
//
|
|
8
|
+
import { QuotaToastPlugin } from "./plugin.js";
|
|
9
|
+
// V1 plugin format: default export with id + server.
|
|
10
|
+
// This avoids the legacy getLegacyPlugins fallback path in OpenCode's plugin
|
|
11
|
+
// loader, which iterates Object.values(mod) and can conflict with other
|
|
12
|
+
// plugins that also use the legacy path.
|
|
13
|
+
const pluginModule = {
|
|
14
|
+
id: "@slkiser/opencode-quota",
|
|
15
|
+
server: QuotaToastPlugin,
|
|
16
|
+
};
|
|
17
|
+
export default pluginModule;
|
|
18
|
+
// Keep the named export for backward compatibility with consumers that import
|
|
19
|
+
// { QuotaToastPlugin } directly.
|
|
10
20
|
export { QuotaToastPlugin } from "./plugin.js";
|
|
11
|
-
// NOTE: tool exports are part of the plugin runtime contract and are not
|
|
12
|
-
// exported from the package entrypoint.
|
|
13
|
-
// NOTE: DEFAULT_CONFIG is NOT exported here because OpenCode's plugin loader
|
|
14
|
-
// would try to call it as a function. Import from "./lib/types.js" directly if needed.
|
|
15
21
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAO/C,qDAAqD;AACrD,6EAA6E;AAC7E,wEAAwE;AACxE,yCAAyC;AACzC,MAAM,YAAY,GAAG;IACnB,EAAE,EAAE,yBAAyB;IAC7B,MAAM,EAAE,gBAAgB;CACA,CAAC;AAE3B,eAAe,YAAY,CAAC;AAE5B,8EAA8E;AAC9E,iCAAiC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AlibabaCodingPlanTier, AuthData } from "./types.js";
|
|
2
2
|
export declare const DEFAULT_ALIBABA_AUTH_CACHE_MAX_AGE_MS = 5000;
|
|
3
|
+
export type AlibabaCodingPlanKeySource = "env:ALIBABA_CODING_PLAN_API_KEY" | "env:ALIBABA_API_KEY" | "opencode.json" | "opencode.jsonc" | "auth.json";
|
|
3
4
|
export type ResolvedAlibabaCodingPlanAuth = {
|
|
4
5
|
state: "none";
|
|
5
6
|
} | {
|
|
@@ -11,11 +12,35 @@ export type ResolvedAlibabaCodingPlanAuth = {
|
|
|
11
12
|
error: string;
|
|
12
13
|
rawTier?: string;
|
|
13
14
|
};
|
|
15
|
+
export type AlibabaCodingPlanAuthDiagnostics = {
|
|
16
|
+
state: "none";
|
|
17
|
+
source: null;
|
|
18
|
+
checkedPaths: string[];
|
|
19
|
+
authPaths: string[];
|
|
20
|
+
} | {
|
|
21
|
+
state: "configured";
|
|
22
|
+
source: AlibabaCodingPlanKeySource;
|
|
23
|
+
checkedPaths: string[];
|
|
24
|
+
authPaths: string[];
|
|
25
|
+
tier: AlibabaCodingPlanTier;
|
|
26
|
+
} | {
|
|
27
|
+
state: "invalid";
|
|
28
|
+
source: "auth.json";
|
|
29
|
+
checkedPaths: string[];
|
|
30
|
+
authPaths: string[];
|
|
31
|
+
error: string;
|
|
32
|
+
rawTier?: string;
|
|
33
|
+
};
|
|
34
|
+
export { getGlobalOpencodeConfigCandidatePaths as getOpencodeConfigCandidatePaths } from "./api-key-resolver.js";
|
|
14
35
|
export declare function resolveAlibabaCodingPlanAuth(auth: AuthData | null | undefined, fallbackTier?: AlibabaCodingPlanTier): ResolvedAlibabaCodingPlanAuth;
|
|
15
36
|
export declare function resolveAlibabaCodingPlanAuthCached(params?: {
|
|
16
37
|
maxAgeMs?: number;
|
|
17
38
|
fallbackTier?: AlibabaCodingPlanTier;
|
|
18
39
|
}): Promise<ResolvedAlibabaCodingPlanAuth>;
|
|
40
|
+
export declare function getAlibabaCodingPlanAuthDiagnostics(params?: {
|
|
41
|
+
maxAgeMs?: number;
|
|
42
|
+
fallbackTier?: AlibabaCodingPlanTier;
|
|
43
|
+
}): Promise<AlibabaCodingPlanAuthDiagnostics>;
|
|
19
44
|
export declare function hasAlibabaAuth(auth: AuthData | null | undefined): boolean;
|
|
20
45
|
export declare function isAlibabaModelId(model?: string): boolean;
|
|
21
46
|
//# sourceMappingURL=alibaba-auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alibaba-auth.d.ts","sourceRoot":"","sources":["../../src/lib/alibaba-auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"alibaba-auth.d.ts","sourceRoot":"","sources":["../../src/lib/alibaba-auth.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAmB,qBAAqB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEnF,eAAO,MAAM,qCAAqC,OAAQ,CAAC;AAM3D,MAAM,MAAM,0BAA0B,GAClC,iCAAiC,GACjC,qBAAqB,GACrB,eAAe,GACf,gBAAgB,GAChB,WAAW,CAAC;AAEhB,MAAM,MAAM,6BAA6B,GACrC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,qBAAqB,CAAA;CAAE,GACpE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,gCAAgC,GACxC;IACE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,GACD;IACE,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,0BAA0B,CAAC;IACnC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,qBAAqB,CAAC;CAC7B,GACD;IACE,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN,OAAO,EAAE,qCAAqC,IAAI,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AA+CjH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EACjC,YAAY,GAAE,qBAAwD,GACrE,6BAA6B,CAkC/B;AAmDD,wBAAsB,kCAAkC,CAAC,MAAM,CAAC,EAAE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,qBAAqB,CAAC;CACtC,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAEzC;AAED,wBAAsB,mCAAmC,CAAC,MAAM,CAAC,EAAE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,qBAAqB,CAAC;CACtC,GAAG,OAAO,CAAC,gCAAgC,CAAC,CAmC5C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEzE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAIxD"}
|
package/dist/lib/alibaba-auth.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { extractProviderOptionsApiKey, getApiKeyCheckedPaths, getFirstAuthEntryRecord, getGlobalOpencodeConfigCandidatePaths, resolveApiKeyFromEnvAndConfig, } from "./api-key-resolver.js";
|
|
2
|
+
import { getAuthPaths, readAuthFileCached } from "./opencode-auth.js";
|
|
2
3
|
export const DEFAULT_ALIBABA_AUTH_CACHE_MAX_AGE_MS = 5_000;
|
|
4
|
+
const ALIBABA_AUTH_KEYS = ["alibaba-coding-plan", "alibaba"];
|
|
5
|
+
const ALIBABA_PROVIDER_KEYS = ["alibaba-coding-plan", "alibaba"];
|
|
6
|
+
const ALLOWED_ALIBABA_ENV_VARS = ["ALIBABA_CODING_PLAN_API_KEY", "ALIBABA_API_KEY"];
|
|
7
|
+
const DEFAULT_ALIBABA_CODING_PLAN_TIER = "lite";
|
|
8
|
+
export { getGlobalOpencodeConfigCandidatePaths as getOpencodeConfigCandidatePaths } from "./api-key-resolver.js";
|
|
3
9
|
function getFirstString(obj, keys) {
|
|
4
10
|
for (const key of keys) {
|
|
5
11
|
const value = obj[key];
|
|
@@ -21,12 +27,12 @@ function normalizeAlibabaTier(value) {
|
|
|
21
27
|
return "pro";
|
|
22
28
|
return null;
|
|
23
29
|
}
|
|
24
|
-
const DEFAULT_ALIBABA_CODING_PLAN_TIER = "lite";
|
|
25
30
|
function getAlibabaAuth(auth) {
|
|
26
|
-
for (const key of
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
31
|
+
for (const key of ALIBABA_AUTH_KEYS) {
|
|
32
|
+
const entry = getFirstAuthEntryRecord(auth, [key]);
|
|
33
|
+
if (!entry)
|
|
29
34
|
continue;
|
|
35
|
+
const alibaba = entry;
|
|
30
36
|
const credential = typeof alibaba.key === "string" && alibaba.key.trim()
|
|
31
37
|
? alibaba.key.trim()
|
|
32
38
|
: typeof alibaba.access === "string" && alibaba.access.trim()
|
|
@@ -74,11 +80,79 @@ export function resolveAlibabaCodingPlanAuth(auth, fallbackTier = DEFAULT_ALIBAB
|
|
|
74
80
|
tier,
|
|
75
81
|
};
|
|
76
82
|
}
|
|
83
|
+
async function resolveAlibabaCodingPlanAuthWithSource(params) {
|
|
84
|
+
const fallbackTier = params?.fallbackTier ?? DEFAULT_ALIBABA_CODING_PLAN_TIER;
|
|
85
|
+
const resolvedFromEnvOrConfig = await resolveApiKeyFromEnvAndConfig({
|
|
86
|
+
envVars: [
|
|
87
|
+
{
|
|
88
|
+
name: "ALIBABA_CODING_PLAN_API_KEY",
|
|
89
|
+
source: "env:ALIBABA_CODING_PLAN_API_KEY",
|
|
90
|
+
},
|
|
91
|
+
{ name: "ALIBABA_API_KEY", source: "env:ALIBABA_API_KEY" },
|
|
92
|
+
],
|
|
93
|
+
extractFromConfig: (config) => extractProviderOptionsApiKey(config, {
|
|
94
|
+
providerKeys: ALIBABA_PROVIDER_KEYS,
|
|
95
|
+
allowedEnvVars: ALLOWED_ALIBABA_ENV_VARS,
|
|
96
|
+
}),
|
|
97
|
+
configJsonSource: "opencode.json",
|
|
98
|
+
configJsoncSource: "opencode.jsonc",
|
|
99
|
+
getConfigCandidates: getGlobalOpencodeConfigCandidatePaths,
|
|
100
|
+
});
|
|
101
|
+
if (resolvedFromEnvOrConfig) {
|
|
102
|
+
return {
|
|
103
|
+
auth: {
|
|
104
|
+
state: "configured",
|
|
105
|
+
apiKey: resolvedFromEnvOrConfig.key,
|
|
106
|
+
tier: fallbackTier,
|
|
107
|
+
},
|
|
108
|
+
source: resolvedFromEnvOrConfig.source,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const maxAgeMs = Math.max(0, params?.maxAgeMs ?? DEFAULT_ALIBABA_AUTH_CACHE_MAX_AGE_MS);
|
|
112
|
+
const authData = await readAuthFileCached({
|
|
113
|
+
maxAgeMs,
|
|
114
|
+
});
|
|
115
|
+
const auth = resolveAlibabaCodingPlanAuth(authData, fallbackTier);
|
|
116
|
+
return {
|
|
117
|
+
auth,
|
|
118
|
+
source: auth.state === "none" ? null : "auth.json",
|
|
119
|
+
};
|
|
120
|
+
}
|
|
77
121
|
export async function resolveAlibabaCodingPlanAuthCached(params) {
|
|
78
|
-
|
|
79
|
-
|
|
122
|
+
return (await resolveAlibabaCodingPlanAuthWithSource(params)).auth;
|
|
123
|
+
}
|
|
124
|
+
export async function getAlibabaCodingPlanAuthDiagnostics(params) {
|
|
125
|
+
const { auth, source } = await resolveAlibabaCodingPlanAuthWithSource(params);
|
|
126
|
+
const checkedPaths = getApiKeyCheckedPaths({
|
|
127
|
+
envVarNames: [...ALLOWED_ALIBABA_ENV_VARS],
|
|
128
|
+
getConfigCandidates: getGlobalOpencodeConfigCandidatePaths,
|
|
80
129
|
});
|
|
81
|
-
|
|
130
|
+
const authPaths = getAuthPaths();
|
|
131
|
+
if (auth.state === "none") {
|
|
132
|
+
return {
|
|
133
|
+
state: "none",
|
|
134
|
+
source: null,
|
|
135
|
+
checkedPaths,
|
|
136
|
+
authPaths,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (auth.state === "invalid") {
|
|
140
|
+
return {
|
|
141
|
+
state: "invalid",
|
|
142
|
+
source: "auth.json",
|
|
143
|
+
checkedPaths,
|
|
144
|
+
authPaths,
|
|
145
|
+
error: auth.error,
|
|
146
|
+
rawTier: auth.rawTier,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
state: "configured",
|
|
151
|
+
source: source ?? "auth.json",
|
|
152
|
+
checkedPaths,
|
|
153
|
+
authPaths,
|
|
154
|
+
tier: auth.tier,
|
|
155
|
+
};
|
|
82
156
|
}
|
|
83
157
|
export function hasAlibabaAuth(auth) {
|
|
84
158
|
return getAlibabaAuth(auth) !== null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alibaba-auth.js","sourceRoot":"","sources":["../../src/lib/alibaba-auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"alibaba-auth.js","sourceRoot":"","sources":["../../src/lib/alibaba-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,qCAAqC,EACrC,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGtE,MAAM,CAAC,MAAM,qCAAqC,GAAG,KAAK,CAAC;AAC3D,MAAM,iBAAiB,GAAG,CAAC,qBAAqB,EAAE,SAAS,CAAU,CAAC;AACtE,MAAM,qBAAqB,GAAG,CAAC,qBAAqB,EAAE,SAAS,CAAU,CAAC;AAC1E,MAAM,wBAAwB,GAAG,CAAC,6BAA6B,EAAE,iBAAiB,CAAU,CAAC;AAC7F,MAAM,gCAAgC,GAA0B,MAAM,CAAC;AAqCvE,OAAO,EAAE,qCAAqC,IAAI,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AAEjH,SAAS,cAAc,CAAC,GAA4B,EAAE,IAAc;IAClE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS;QACxC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAyB;IACrD,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,UAAU,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACzC,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,cAAc;QAAE,OAAO,KAAK,CAAC;IACxE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,IAAiC;IACvD,KAAK,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,MAAM,OAAO,GAAG,KAAwB,CAAC;QAEzC,MAAM,UAAU,GACd,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE;YACnD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE;YACpB,CAAC,CAAC,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;gBAC3D,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,CAAC,CAAC,EAAE,CAAC;QAEX,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,SAAS;QACX,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAqB;IACjD,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAW,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,IAAiC,EACjC,eAAsC,gCAAgC;IAEtE,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,CAAC,OAAkC,EAAE;QACjE,MAAM;QACN,UAAU;QACV,WAAW;QACX,kBAAkB;KACnB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,oBAAoB,CAAC,OAAO,CAAC;YACrC,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,yCAAyC,OAAO,EAAE;YACzD,OAAO;SACR,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,oBAAoB,CAAC,OAAO,CAAC;QACrC,IAAI;KACL,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,sCAAsC,CAAC,MAGrD;IAIC,MAAM,YAAY,GAAG,MAAM,EAAE,YAAY,IAAI,gCAAgC,CAAC;IAC9E,MAAM,uBAAuB,GAAG,MAAM,6BAA6B,CAA6B;QAC9F,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,6BAA6B;gBACnC,MAAM,EAAE,iCAAiC;aAC1C;YACD,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,qBAAqB,EAAE;SAC3D;QACD,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,CAC5B,4BAA4B,CAAC,MAAM,EAAE;YACnC,YAAY,EAAE,qBAAqB;YACnC,cAAc,EAAE,wBAAwB;SACzC,CAAC;QACJ,gBAAgB,EAAE,eAAe;QACjC,iBAAiB,EAAE,gBAAgB;QACnC,mBAAmB,EAAE,qCAAqC;KAC3D,CAAC,CAAC;IAEH,IAAI,uBAAuB,EAAE,CAAC;QAC5B,OAAO;YACL,IAAI,EAAE;gBACJ,KAAK,EAAE,YAAY;gBACnB,MAAM,EAAE,uBAAuB,CAAC,GAAG;gBACnC,IAAI,EAAE,YAAY;aACnB;YACD,MAAM,EAAE,uBAAuB,CAAC,MAAM;SACvC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,IAAI,qCAAqC,CAAC,CAAC;IACxF,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;QACxC,QAAQ;KACT,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,4BAA4B,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAElE,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kCAAkC,CAAC,MAGxD;IACC,OAAO,CAAC,MAAM,sCAAsC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACrE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,MAGzD;IACC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,sCAAsC,CAAC,MAAM,CAAC,CAAC;IAC9E,MAAM,YAAY,GAAG,qBAAqB,CAAC;QACzC,WAAW,EAAE,CAAC,GAAG,wBAAwB,CAAC;QAC1C,mBAAmB,EAAE,qCAAqC;KAC3D,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IAEjC,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO;YACL,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,IAAI;YACZ,YAAY;YACZ,SAAS;SACV,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,WAAW;YACnB,YAAY;YACZ,SAAS;YACT,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,MAAM,IAAI,WAAW;QAC7B,YAAY;QACZ,SAAS;QACT,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAiC;IAC9D,OAAO,cAAc,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AACnF,CAAC"}
|
|
@@ -43,8 +43,15 @@ export interface EnvVarDef<Source extends string> {
|
|
|
43
43
|
name: string;
|
|
44
44
|
source: Source;
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
export
|
|
46
|
+
export declare function getFirstAuthEntryValue(auth: unknown, authKeys: readonly string[]): unknown;
|
|
47
|
+
export declare function getFirstAuthEntryRecord(auth: unknown, authKeys: readonly string[]): Record<string, unknown> | null;
|
|
48
|
+
export declare function extractProviderOptionsApiKey(config: unknown, params: {
|
|
49
|
+
providerKeys: readonly string[];
|
|
50
|
+
allowedEnvVars?: readonly string[];
|
|
51
|
+
}): string | null;
|
|
52
|
+
export declare function extractAuthApiKeyEntry(auth: unknown, authKeys: readonly string[]): string | null;
|
|
53
|
+
/** Configuration for resolving an API key from trusted env/config sources */
|
|
54
|
+
export interface ResolveEnvAndConfigApiKeyConfig<Source extends string> {
|
|
48
55
|
/** Environment variables to check (in order) */
|
|
49
56
|
envVars: EnvVarDef<Source>[];
|
|
50
57
|
/** Extract API key from parsed config object. Returns null if not found. */
|
|
@@ -53,19 +60,45 @@ export interface ResolveApiKeyConfig<Source extends string> {
|
|
|
53
60
|
configJsonSource: Source;
|
|
54
61
|
/** Source label for opencode.jsonc */
|
|
55
62
|
configJsoncSource: Source;
|
|
63
|
+
/**
|
|
64
|
+
* Candidate config file paths to trust for provider-secret lookup.
|
|
65
|
+
*
|
|
66
|
+
* Defaults to trusted user/global OpenCode config paths only.
|
|
67
|
+
*/
|
|
68
|
+
getConfigCandidates?: () => ConfigCandidate[];
|
|
69
|
+
}
|
|
70
|
+
/** Configuration for resolving an API key from multiple sources */
|
|
71
|
+
export interface ResolveApiKeyConfig<Source extends string> extends ResolveEnvAndConfigApiKeyConfig<Source> {
|
|
56
72
|
/** Extract API key from auth.json data. Returns null if not found. */
|
|
57
73
|
extractFromAuth: (auth: unknown) => string | null;
|
|
58
74
|
/** Source label for auth.json */
|
|
59
75
|
authSource: Source;
|
|
60
|
-
|
|
76
|
+
}
|
|
77
|
+
export interface ApiKeyCheckedPathsConfig {
|
|
78
|
+
/** Environment variable names to check */
|
|
79
|
+
envVarNames: string[];
|
|
80
|
+
/**
|
|
81
|
+
* Candidate config file paths to report for provider-secret lookup.
|
|
82
|
+
*
|
|
83
|
+
* Defaults to trusted user/global OpenCode config paths only.
|
|
84
|
+
*/
|
|
61
85
|
getConfigCandidates?: () => ConfigCandidate[];
|
|
62
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Resolve an API key from trusted env vars and config files.
|
|
89
|
+
*
|
|
90
|
+
* Priority (first wins):
|
|
91
|
+
* 1. Environment variables (in order specified)
|
|
92
|
+
* 2. Trusted user/global opencode.json/opencode.jsonc candidates
|
|
93
|
+
*/
|
|
94
|
+
export declare function resolveApiKeyFromEnvAndConfig<Source extends string>(config: ResolveEnvAndConfigApiKeyConfig<Source>): Promise<ApiKeyResult<Source> | null>;
|
|
95
|
+
export declare function getApiKeyCheckedPaths(config: ApiKeyCheckedPathsConfig): string[];
|
|
63
96
|
/**
|
|
64
97
|
* Resolve an API key from multiple sources with consistent priority.
|
|
65
98
|
*
|
|
66
99
|
* Priority (first wins):
|
|
67
100
|
* 1. Environment variables (in order specified)
|
|
68
|
-
* 2. opencode.json/opencode.jsonc
|
|
101
|
+
* 2. Trusted user/global opencode.json/opencode.jsonc
|
|
69
102
|
* 3. auth.json
|
|
70
103
|
*
|
|
71
104
|
* @returns API key and source, or null if not found
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-key-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/api-key-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"api-key-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/api-key-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,IAAI,eAAe,EAAE,CAenE;AAED;;;;;GAKG;AACH,wBAAgB,qCAAqC,IAAI,eAAe,EAAE,CAUzE;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC,CASrE;AAED,mCAAmC;AACnC,MAAM,WAAW,YAAY,CAAC,MAAM,SAAS,MAAM;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yDAAyD;AACzD,MAAM,WAAW,SAAS,CAAC,MAAM,SAAS,MAAM;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,OAAO,CAWT;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEhC;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE;IACN,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,GACA,MAAM,GAAG,IAAI,CAiBf;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,MAAM,GAAG,IAAI,CAUf;AAED,6EAA6E;AAC7E,MAAM,WAAW,+BAA+B,CAAC,MAAM,SAAS,MAAM;IACpE,gDAAgD;IAChD,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAE7B,4EAA4E;IAC5E,iBAAiB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC;IAEtD,qCAAqC;IACrC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,sCAAsC;IACtC,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;CAC/C;AAED,mEAAmE;AACnE,MAAM,WAAW,mBAAmB,CAAC,MAAM,SAAS,MAAM,CACxD,SAAQ,+BAA+B,CAAC,MAAM,CAAC;IAE/C,sEAAsE;IACtE,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC;IAElD,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,wBAAsB,6BAA6B,CAAC,MAAM,SAAS,MAAM,EACvE,MAAM,EAAE,+BAA+B,CAAC,MAAM,CAAC,GAC9C,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAuBtC;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,EAAE,CAiBhF;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,MAAM,SAAS,MAAM,EACvD,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,EACnC,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GACtC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CActC;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB,CAAC,MAAM,SAAS,MAAM;IACtD,0CAA0C;IAC1C,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB,sDAAsD;IACtD,OAAO,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpD,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC;CAC/C;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,SAAS,MAAM,EAC9D,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAChC,OAAO,CAAC;IACT,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CASD"}
|