@slkiser/opencode-quota 2.6.2 → 2.9.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 +225 -168
- package/dist/data/modelsdev-pricing.min.json +51 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +32 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/cursor-detection.d.ts +17 -0
- package/dist/lib/cursor-detection.d.ts.map +1 -0
- package/dist/lib/cursor-detection.js +169 -0
- package/dist/lib/cursor-detection.js.map +1 -0
- package/dist/lib/cursor-pricing.d.ts +34 -0
- package/dist/lib/cursor-pricing.d.ts.map +1 -0
- package/dist/lib/cursor-pricing.js +133 -0
- package/dist/lib/cursor-pricing.js.map +1 -0
- package/dist/lib/cursor-usage.d.ts +32 -0
- package/dist/lib/cursor-usage.d.ts.map +1 -0
- package/dist/lib/cursor-usage.js +127 -0
- package/dist/lib/cursor-usage.js.map +1 -0
- package/dist/lib/entries.d.ts +5 -0
- package/dist/lib/entries.d.ts.map +1 -1
- package/dist/lib/entries.js +0 -6
- package/dist/lib/entries.js.map +1 -1
- package/dist/lib/jsonc.d.ts +8 -1
- package/dist/lib/jsonc.d.ts.map +1 -1
- package/dist/lib/jsonc.js +12 -2
- package/dist/lib/jsonc.js.map +1 -1
- package/dist/lib/modelsdev-pricing.d.ts +8 -2
- package/dist/lib/modelsdev-pricing.d.ts.map +1 -1
- package/dist/lib/modelsdev-pricing.js +84 -29
- package/dist/lib/modelsdev-pricing.js.map +1 -1
- package/dist/lib/provider-metadata.d.ts.map +1 -1
- package/dist/lib/provider-metadata.js +4 -0
- package/dist/lib/provider-metadata.js.map +1 -1
- package/dist/lib/quota-stats-format.d.ts.map +1 -1
- package/dist/lib/quota-stats-format.js +30 -38
- package/dist/lib/quota-stats-format.js.map +1 -1
- package/dist/lib/quota-stats.d.ts +1 -1
- package/dist/lib/quota-stats.d.ts.map +1 -1
- package/dist/lib/quota-stats.js +26 -14
- package/dist/lib/quota-stats.js.map +1 -1
- package/dist/lib/quota-status.d.ts +5 -0
- package/dist/lib/quota-status.d.ts.map +1 -1
- package/dist/lib/quota-status.js +59 -2
- package/dist/lib/quota-status.js.map +1 -1
- package/dist/lib/token-cost.d.ts +10 -0
- package/dist/lib/token-cost.d.ts.map +1 -0
- package/dist/lib/token-cost.js +16 -0
- package/dist/lib/token-cost.js.map +1 -0
- package/dist/lib/types.d.ts +18 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +5 -0
- package/dist/lib/types.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +382 -128
- package/dist/plugin.js.map +1 -1
- package/dist/providers/cursor.d.ts +3 -0
- package/dist/providers/cursor.d.ts.map +1 -0
- package/dist/providers/cursor.js +138 -0
- package/dist/providers/cursor.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/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OpenCode Quota
|
|
2
2
|
|
|
3
3
|
`opencode-quota` gives you two things:
|
|
4
4
|
|
|
5
5
|
- Automatic quota toasts after assistant responses
|
|
6
|
-
- Manual `/quota
|
|
6
|
+
- Manual `/quota`, `/pricing_refresh`, and `/tokens_*` commands for deeper local reporting with zero context window pollution
|
|
7
7
|
|
|
8
|
-
**Quota
|
|
8
|
+
**Quota providers**: GitHub Copilot, OpenAI (Plus/Pro), Cursor, Qwen Code, Alibaba Coding Plan, Chutes AI, Firmware AI, Google Antigravity, and Z.ai coding plan.
|
|
9
9
|
|
|
10
|
-
**Token
|
|
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
|
|
|
12
|
+
<table>
|
|
13
|
+
<tr>
|
|
14
|
+
<td width="50%" align="center">Example of toast</td>
|
|
15
|
+
<td width="50%" align="center">Example of <code>/tokens_weekly</code></td>
|
|
16
|
+
</tr>
|
|
17
|
+
<tr>
|
|
18
|
+
<td width="50%">
|
|
19
|
+
<img src="https://github.com/slkiser/opencode-quota/blob/main/toasts.png" alt="Image of opencode-quota toast" />
|
|
20
|
+
</td>
|
|
21
|
+
<td width="50%">
|
|
22
|
+
<img src="https://github.com/slkiser/opencode-quota/blob/main/tokens.png" alt="Image of opencode-quota /tokens_weekly output" />
|
|
23
|
+
</td>
|
|
24
|
+
</tr>
|
|
25
|
+
</table>
|
|
12
26
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-

|
|
27
|
+
Quota and `/tokens_*` output are computed from local OpenCode session history.
|
|
16
28
|
|
|
17
29
|
## Quick Start
|
|
18
30
|
|
|
19
|
-
OpenCode `>= 1.2.0` is required.
|
|
20
|
-
|
|
21
|
-
Add the plugin to your `opencode.json` or `opencode.jsonc`:
|
|
31
|
+
OpenCode `>= 1.2.0` is required. Add the plugin to your `opencode.json` or `opencode.jsonc`:
|
|
22
32
|
|
|
23
33
|
```jsonc
|
|
24
34
|
{
|
|
@@ -30,32 +40,93 @@ Then:
|
|
|
30
40
|
|
|
31
41
|
1. Restart or reload OpenCode.
|
|
32
42
|
2. Run `/quota_status` to confirm provider detection.
|
|
33
|
-
3. Run `/quota`
|
|
43
|
+
3. Run `/quota` or `/tokens_today`.
|
|
34
44
|
|
|
35
|
-
That is enough for most installs. Providers are auto-detected from your existing OpenCode setup.
|
|
45
|
+
That is enough for most installs. Providers are auto-detected from your existing OpenCode setup, and most providers work from your existing OpenCode auth. If a provider needs anything extra, use the setup table below.
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
<details>
|
|
48
|
+
<summary><strong>Example: Turn off auto-detection and choose providers</strong></summary>
|
|
38
49
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
```jsonc
|
|
51
|
+
{
|
|
52
|
+
"experimental": {
|
|
53
|
+
"quotaToast": {
|
|
54
|
+
"enabledProviders": ["copilot", "openai", "google-antigravity"]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
43
59
|
|
|
44
|
-
|
|
60
|
+
</details>
|
|
45
61
|
|
|
46
|
-
|
|
62
|
+
<details>
|
|
63
|
+
<summary><strong>Example: Grouped toast layout instead of the default classic toast</strong></summary>
|
|
47
64
|
|
|
48
|
-
|
|
65
|
+
```jsonc
|
|
66
|
+
{
|
|
67
|
+
"experimental": {
|
|
68
|
+
"quotaToast": {
|
|
69
|
+
"toastStyle": "grouped"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
</details>
|
|
76
|
+
|
|
77
|
+
### Provider Setup At A Glance
|
|
78
|
+
|
|
79
|
+
| Provider | Auto setup | How it works |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| **GitHub Copilot** | Usually | OpenCode auth; PAT only for managed billing. [**Notes**](#github-copilot-notes) |
|
|
82
|
+
| **OpenAI** | Yes | OpenCode auth. [**Notes**](#openai-notes) |
|
|
83
|
+
| **Cursor** | Needs [quick setup](#cursor-quick-setup) | Companion auth plugin + `provider.cursor`. [**Notes**](#cursor-notes) |
|
|
84
|
+
| **Qwen Code** | Needs [quick setup](#qwen-code-quick-setup) | Companion auth plugin. [**Notes**](#qwen-code-notes) |
|
|
85
|
+
| **Alibaba Coding Plan** | Yes | Native OpenCode auth with local request estimation. [**Notes**](#alibaba-coding-plan-notes) |
|
|
86
|
+
| **Firmware AI** | Usually | OpenCode config; API key optional. [**Notes**](#firmware-ai-notes) |
|
|
87
|
+
| **Chutes AI** | Usually | OpenCode config; API key optional. [**Notes**](#chutes-ai-notes) |
|
|
88
|
+
| **Google Antigravity** | Needs [quick setup](#google-antigravity-quick-setup) | Companion auth plugin. [**Notes**](#google-antigravity-notes) |
|
|
89
|
+
| **Z.ai** | Yes | OpenCode auth. [**Notes**](#zai-notes) |
|
|
90
|
+
|
|
91
|
+
<a id="cursor-quick-setup"></a>
|
|
92
|
+
<details>
|
|
93
|
+
<summary><strong>Quick setup: Cursor</strong></summary>
|
|
94
|
+
|
|
95
|
+
Cursor quota support requires the `opencode-cursor-oauth` [plugin](https://github.com/ephraimduncan/opencode-cursor):
|
|
49
96
|
|
|
50
97
|
```jsonc
|
|
51
98
|
{
|
|
52
|
-
"
|
|
99
|
+
"$schema": "https://opencode.ai/config.json",
|
|
100
|
+
"plugin": ["opencode-cursor-oauth", "@slkiser/opencode-quota"],
|
|
101
|
+
"provider": {
|
|
102
|
+
"cursor": {
|
|
103
|
+
"name": "Cursor"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"experimental": {
|
|
107
|
+
"quotaToast": {
|
|
108
|
+
"cursorPlan": "pro",
|
|
109
|
+
"cursorBillingCycleStartDay": 7
|
|
110
|
+
}
|
|
111
|
+
}
|
|
53
112
|
}
|
|
54
113
|
```
|
|
55
114
|
|
|
56
|
-
|
|
115
|
+
Then authenticate once:
|
|
57
116
|
|
|
58
|
-
|
|
117
|
+
```sh
|
|
118
|
+
opencode auth login --provider cursor
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For behavior details and troubleshooting, see [Cursor notes](#cursor-notes).
|
|
122
|
+
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
<a id="google-antigravity-quick-setup"></a>
|
|
126
|
+
<details>
|
|
127
|
+
<summary><strong>Quick setup: Google Antigravity</strong></summary>
|
|
128
|
+
|
|
129
|
+
Google quota support requires the `opencode-antigravity-auth` [plugin](https://github.com/NoeFabris/opencode-antigravity-auth):
|
|
59
130
|
|
|
60
131
|
```jsonc
|
|
61
132
|
{
|
|
@@ -63,9 +134,15 @@ Google quota support depends on the companion auth plugin:
|
|
|
63
134
|
}
|
|
64
135
|
```
|
|
65
136
|
|
|
66
|
-
|
|
137
|
+
For behavior details and troubleshooting, see [Google Antigravity notes](#google-antigravity-notes).
|
|
67
138
|
|
|
68
|
-
|
|
139
|
+
</details>
|
|
140
|
+
|
|
141
|
+
<a id="qwen-code-quick-setup"></a>
|
|
142
|
+
<details>
|
|
143
|
+
<summary><strong>Quick setup: Qwen Code</strong></summary>
|
|
144
|
+
|
|
145
|
+
Qwen quota support requires the `opencode-qwencode-auth` [plugin](https://github.com/gustavodiasdev/opencode-qwencode-auth):
|
|
69
146
|
|
|
70
147
|
```jsonc
|
|
71
148
|
{
|
|
@@ -73,12 +150,17 @@ Qwen quota support depends on the companion auth plugin:
|
|
|
73
150
|
}
|
|
74
151
|
```
|
|
75
152
|
|
|
153
|
+
For behavior details and troubleshooting, see [Qwen Code notes](#qwen-code-notes).
|
|
154
|
+
|
|
155
|
+
</details>
|
|
156
|
+
|
|
76
157
|
## Commands
|
|
77
158
|
|
|
78
159
|
| Command | What it shows |
|
|
79
160
|
| --- | --- |
|
|
80
161
|
| `/quota` | Manual grouped quota report with a local call timestamp |
|
|
81
162
|
| `/quota_status` | Concise diagnostics for config, provider availability, account detection, and pricing snapshot health |
|
|
163
|
+
| `/pricing_refresh` | Pull the local runtime pricing snapshot from `models.dev` on demand |
|
|
82
164
|
| `/tokens_today` | Tokens used today (calendar day) |
|
|
83
165
|
| `/tokens_daily` | Tokens used in the last 24 hours |
|
|
84
166
|
| `/tokens_weekly` | Tokens used in the last 7 days |
|
|
@@ -89,69 +171,21 @@ Qwen quota support depends on the companion auth plugin:
|
|
|
89
171
|
|
|
90
172
|
There is no `/token` command. The reporting commands are the `/tokens_*` family.
|
|
91
173
|
|
|
92
|
-
## Minimal Config
|
|
93
|
-
|
|
94
|
-
You do not need extra config to get started. If you want to narrow the plugin to specific providers, use:
|
|
95
|
-
|
|
96
|
-
```jsonc
|
|
97
|
-
{
|
|
98
|
-
"experimental": {
|
|
99
|
-
"quotaToast": {
|
|
100
|
-
"enabledProviders": ["copilot", "openai", "google-antigravity"]
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
If you want grouped toast layout instead of the default classic toast:
|
|
107
|
-
|
|
108
|
-
```jsonc
|
|
109
|
-
{
|
|
110
|
-
"experimental": {
|
|
111
|
-
"quotaToast": {
|
|
112
|
-
"toastStyle": "grouped"
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
If Alibaba Coding Plan auth does not include a `tier`, you can set the fallback tier here:
|
|
119
|
-
|
|
120
|
-
```jsonc
|
|
121
|
-
{
|
|
122
|
-
"experimental": {
|
|
123
|
-
"quotaToast": {
|
|
124
|
-
"alibabaCodingPlanTier": "lite"
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
`/quota` already uses grouped formatting by default, even if toast style stays `classic`.
|
|
131
|
-
|
|
132
|
-
## Provider Setup At A Glance
|
|
133
|
-
|
|
134
|
-
| Provider | Works automatically | Extra setup when needed |
|
|
135
|
-
| --- | --- | --- |
|
|
136
|
-
| GitHub Copilot | Usually yes | Add `copilot-quota-token.json` only for managed org or enterprise billing |
|
|
137
|
-
| OpenAI | Yes | None |
|
|
138
|
-
| Qwen Code | Needs `opencode-qwencode-auth` | Local free-tier request estimation |
|
|
139
|
-
| Alibaba Coding Plan | Yes | Local request-count estimation |
|
|
140
|
-
| Firmware AI | Usually yes | Optional API key |
|
|
141
|
-
| Chutes AI | Usually yes | Optional API key |
|
|
142
|
-
| Google Antigravity | Needs `opencode-antigravity-auth` | Multi-account account file lives in OpenCode runtime config |
|
|
143
|
-
| Z.ai | Yes | None |
|
|
144
|
-
|
|
145
174
|
## Provider-Specific Notes
|
|
146
175
|
|
|
176
|
+
<a id="github-copilot-notes"></a>
|
|
147
177
|
<details>
|
|
148
178
|
<summary><strong>GitHub Copilot</strong></summary>
|
|
149
179
|
|
|
150
|
-
Personal
|
|
180
|
+
Personal quota works automatically when OpenCode is already signed in. Without `copilot-quota-token.json`, the plugin reads the OpenCode Copilot OAuth token from `~/.local/share/opencode/auth.json` and calls `GET https://api.github.com/copilot_internal/user`.
|
|
151
181
|
|
|
152
|
-
|
|
182
|
+
- Managed billing uses `copilot-quota-token.json` in the OpenCode runtime config directory (`opencode debug paths`). `business` requires `organization`; `enterprise` requires `enterprise` and can also filter by `organization` or `username`.
|
|
183
|
+
- `copilot-quota-token.json` takes precedence over OAuth. If the PAT config is invalid, the plugin reports that error and does not silently fall back.
|
|
184
|
+
- Output is labeled `[Copilot] (personal)` or `[Copilot] (business)`, and managed output includes the org or enterprise slug.
|
|
185
|
+
- Enterprise premium usage does not support fine-grained PATs or GitHub App tokens.
|
|
186
|
+
- Check `/quota_status` for `copilot_quota_auth`, `billing_mode`, `billing_scope`, `quota_api`, `effective_source`, and `billing_api_access_likely`.
|
|
153
187
|
|
|
154
|
-
|
|
188
|
+
Example `copilot-quota-token.json`:
|
|
155
189
|
|
|
156
190
|
```json
|
|
157
191
|
{
|
|
@@ -161,8 +195,6 @@ Organization example:
|
|
|
161
195
|
}
|
|
162
196
|
```
|
|
163
197
|
|
|
164
|
-
Enterprise example:
|
|
165
|
-
|
|
166
198
|
```json
|
|
167
199
|
{
|
|
168
200
|
"token": "ghp_...",
|
|
@@ -173,24 +205,9 @@ Enterprise example:
|
|
|
173
205
|
}
|
|
174
206
|
```
|
|
175
207
|
|
|
176
|
-
Behavior notes:
|
|
177
|
-
|
|
178
|
-
- Personal output is labeled `[Copilot] (personal)`.
|
|
179
|
-
- Managed organization and enterprise output is labeled `[Copilot] (business)`.
|
|
180
|
-
- Managed output includes the org or enterprise slug in the value line so the billing scope is still visible.
|
|
181
|
-
- If both OpenCode OAuth and `copilot-quota-token.json` exist, the PAT config wins.
|
|
182
|
-
- If no PAT config exists, OpenCode Copilot OAuth is treated as personal quota auth via `/copilot_internal/user`.
|
|
183
|
-
- If the PAT config is invalid, the plugin reports that error and does not silently fall back to OAuth.
|
|
184
|
-
- `business` requires `organization`.
|
|
185
|
-
- Enterprise premium usage does not support fine-grained PATs or GitHub App tokens. Use a supported enterprise token such as a classic PAT.
|
|
186
|
-
|
|
187
|
-
Useful checks:
|
|
188
|
-
|
|
189
|
-
- Run `/quota_status` and inspect `copilot_quota_auth`.
|
|
190
|
-
- Look for `billing_mode`, `billing_scope`, `quota_api`, `effective_source`, and `billing_api_access_likely`.
|
|
191
|
-
|
|
192
208
|
</details>
|
|
193
209
|
|
|
210
|
+
<a id="openai-notes"></a>
|
|
194
211
|
<details>
|
|
195
212
|
<summary><strong>OpenAI</strong></summary>
|
|
196
213
|
|
|
@@ -198,49 +215,80 @@ No extra setup is required if OpenCode already has OpenAI or ChatGPT auth config
|
|
|
198
215
|
|
|
199
216
|
</details>
|
|
200
217
|
|
|
218
|
+
<a id="cursor-notes"></a>
|
|
201
219
|
<details>
|
|
202
|
-
<summary><strong>
|
|
220
|
+
<summary><strong>Cursor</strong></summary>
|
|
203
221
|
|
|
204
|
-
|
|
222
|
+
See [Cursor quick setup](#cursor-quick-setup) for auth. Quota and token reporting stays local to OpenCode history and local pricing data.
|
|
205
223
|
|
|
206
|
-
|
|
224
|
+
- Detects Cursor usage when the provider is `cursor` or the stored/current model id is `cursor/*`.
|
|
225
|
+
- `/tokens_*` maps Cursor API-pool models to official pricing and uses bundled static pricing for `auto` and `composer*`.
|
|
226
|
+
- `/quota` and toasts estimate the current billing-cycle spend from local history only. Session cookies and team APIs are not required.
|
|
227
|
+
- Remaining percentage appears only when `experimental.quotaToast.cursorPlan` or `experimental.quotaToast.cursorIncludedApiUsd` is set. Billing cycle defaults to the local calendar month unless `experimental.quotaToast.cursorBillingCycleStartDay` is set.
|
|
228
|
+
- Legacy `cursor-acp/*` history remains readable. Unknown future Cursor model ids appear in `/quota_status` under Cursor diagnostics and `unknown_pricing`.
|
|
207
229
|
|
|
208
|
-
|
|
209
|
-
- Free tier only: 60 requests per rolling minute
|
|
210
|
-
- Counters increment on successful question-tool completions while the current model is `qwen-code/*`
|
|
230
|
+
Example override:
|
|
211
231
|
|
|
212
|
-
|
|
232
|
+
```jsonc
|
|
233
|
+
{
|
|
234
|
+
"experimental": {
|
|
235
|
+
"quotaToast": {
|
|
236
|
+
"cursorPlan": "none",
|
|
237
|
+
"cursorIncludedApiUsd": 120
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
213
242
|
|
|
214
|
-
|
|
243
|
+
</details>
|
|
215
244
|
|
|
216
|
-
|
|
245
|
+
<a id="qwen-code-notes"></a>
|
|
246
|
+
<details>
|
|
247
|
+
<summary><strong>Qwen Code</strong></summary>
|
|
248
|
+
|
|
249
|
+
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.
|
|
250
|
+
|
|
251
|
+
- Free tier limits: `1000` requests per UTC day and `60` requests per rolling minute.
|
|
252
|
+
- Counters increment on successful question-tool completions while the current model is `qwen-code/*`.
|
|
253
|
+
- State file: `.../opencode/opencode-quota/qwen-local-quota.json`.
|
|
254
|
+
- Check `/quota_status` for auth detection, `qwen_local_plan`, and local counter state.
|
|
217
255
|
|
|
218
256
|
</details>
|
|
219
257
|
|
|
258
|
+
<a id="alibaba-coding-plan-notes"></a>
|
|
220
259
|
<details>
|
|
221
260
|
<summary><strong>Alibaba Coding Plan</strong></summary>
|
|
222
261
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
Supported tiers:
|
|
262
|
+
Uses native OpenCode auth from `alibaba` or `alibaba-coding-plan`. Quota is local request-count estimation with rolling windows.
|
|
226
263
|
|
|
227
|
-
- `lite`: 1200
|
|
228
|
-
- `pro`: 6000
|
|
229
|
-
- If `tier
|
|
230
|
-
- Counters increment on successful question-tool completions while the current model is `alibaba/*` or `alibaba-cn
|
|
264
|
+
- `lite`: `1200 / 5h`, `9000 / week`, `18000 / month`
|
|
265
|
+
- `pro`: `6000 / 5h`, `45000 / week`, `90000 / month`
|
|
266
|
+
- If auth omits `tier`, the plugin uses `experimental.quotaToast.alibabaCodingPlanTier`, which defaults to `lite`.
|
|
267
|
+
- Counters increment on successful question-tool completions while the current model is `alibaba/*` or `alibaba-cn/*`.
|
|
268
|
+
- State file: `.../opencode/opencode-quota/alibaba-coding-plan-local-quota.json`.
|
|
269
|
+
- `/quota_status` shows auth detection, resolved tier, state-file path, and current 5h/weekly/monthly usage.
|
|
231
270
|
|
|
232
|
-
|
|
271
|
+
Example fallback tier:
|
|
233
272
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
273
|
+
```jsonc
|
|
274
|
+
{
|
|
275
|
+
"experimental": {
|
|
276
|
+
"quotaToast": {
|
|
277
|
+
"alibabaCodingPlanTier": "lite"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
237
282
|
|
|
238
283
|
</details>
|
|
239
284
|
|
|
285
|
+
<a id="firmware-ai-notes"></a>
|
|
240
286
|
<details>
|
|
241
287
|
<summary><strong>Firmware AI</strong></summary>
|
|
242
288
|
|
|
243
|
-
If OpenCode already has Firmware configured, it usually works automatically.
|
|
289
|
+
If OpenCode already has Firmware configured, it usually works automatically. Optional API key: `provider.firmware.options.apiKey`.
|
|
290
|
+
|
|
291
|
+
`{env:FIRMWARE_API_KEY}` and literal values are both supported.
|
|
244
292
|
|
|
245
293
|
```jsonc
|
|
246
294
|
{
|
|
@@ -250,23 +298,19 @@ If OpenCode already has Firmware configured, it usually works automatically. You
|
|
|
250
298
|
"apiKey": "{env:FIRMWARE_API_KEY}"
|
|
251
299
|
}
|
|
252
300
|
}
|
|
253
|
-
},
|
|
254
|
-
"experimental": {
|
|
255
|
-
"quotaToast": {
|
|
256
|
-
"enabledProviders": ["firmware"]
|
|
257
|
-
}
|
|
258
301
|
}
|
|
259
302
|
}
|
|
260
303
|
```
|
|
261
304
|
|
|
262
|
-
`{env:VAR_NAME}` and direct keys are both supported.
|
|
263
|
-
|
|
264
305
|
</details>
|
|
265
306
|
|
|
307
|
+
<a id="chutes-ai-notes"></a>
|
|
266
308
|
<details>
|
|
267
309
|
<summary><strong>Chutes AI</strong></summary>
|
|
268
310
|
|
|
269
|
-
If OpenCode already has Chutes configured, it usually works automatically.
|
|
311
|
+
If OpenCode already has Chutes configured, it usually works automatically. Optional API key: `provider.chutes.options.apiKey`.
|
|
312
|
+
|
|
313
|
+
`{env:CHUTES_API_KEY}` and literal values are both supported.
|
|
270
314
|
|
|
271
315
|
```jsonc
|
|
272
316
|
{
|
|
@@ -276,26 +320,23 @@ If OpenCode already has Chutes configured, it usually works automatically. You c
|
|
|
276
320
|
"apiKey": "{env:CHUTES_API_KEY}"
|
|
277
321
|
}
|
|
278
322
|
}
|
|
279
|
-
},
|
|
280
|
-
"experimental": {
|
|
281
|
-
"quotaToast": {
|
|
282
|
-
"enabledProviders": ["chutes"]
|
|
283
|
-
}
|
|
284
323
|
}
|
|
285
324
|
}
|
|
286
325
|
```
|
|
287
326
|
|
|
288
327
|
</details>
|
|
289
328
|
|
|
329
|
+
<a id="google-antigravity-notes"></a>
|
|
290
330
|
<details>
|
|
291
331
|
<summary><strong>Google Antigravity</strong></summary>
|
|
292
332
|
|
|
293
|
-
|
|
333
|
+
See [Google Antigravity quick setup](#google-antigravity-quick-setup). Credentials live under the OpenCode runtime config directory.
|
|
294
334
|
|
|
295
|
-
If
|
|
335
|
+
If detection looks wrong, `/quota_status` prints the candidate paths checked for `antigravity-accounts.json`.
|
|
296
336
|
|
|
297
337
|
</details>
|
|
298
338
|
|
|
339
|
+
<a id="zai-notes"></a>
|
|
299
340
|
<details>
|
|
300
341
|
<summary><strong>Z.ai</strong></summary>
|
|
301
342
|
|
|
@@ -309,7 +350,7 @@ All plugin settings live under `experimental.quotaToast`.
|
|
|
309
350
|
|
|
310
351
|
| Option | Default | Meaning |
|
|
311
352
|
| --- | --- | --- |
|
|
312
|
-
| `enabled` | `true` | Master switch for the plugin. When `false`, `/quota`, `/quota_status`, and `/tokens_*` are no-ops. |
|
|
353
|
+
| `enabled` | `true` | Master switch for the plugin. When `false`, `/quota`, `/quota_status`, `/pricing_refresh`, and `/tokens_*` are no-ops. |
|
|
313
354
|
| `enableToast` | `true` | Show popup toasts |
|
|
314
355
|
| `toastStyle` | `classic` | Toast layout: `classic` or `grouped` |
|
|
315
356
|
| `enabledProviders` | `"auto"` | Auto-detect providers, or set an explicit provider list |
|
|
@@ -326,32 +367,29 @@ All plugin settings live under `experimental.quotaToast`.
|
|
|
326
367
|
| `layout.tinyAt` | `32` | Tiny layout breakpoint |
|
|
327
368
|
| `googleModels` | `["CLAUDE"]` | Google model keys: `CLAUDE`, `G3PRO`, `G3FLASH`, `G3IMAGE` |
|
|
328
369
|
| `alibabaCodingPlanTier` | `"lite"` | Fallback Alibaba Coding Plan tier when auth does not include `tier` |
|
|
370
|
+
| `cursorPlan` | `"none"` | Cursor included API budget preset: `none`, `pro`, `pro-plus`, `ultra` |
|
|
371
|
+
| `cursorIncludedApiUsd` | unset | Override Cursor monthly included API budget in USD |
|
|
372
|
+
| `cursorBillingCycleStartDay` | unset | Local billing-cycle anchor day `1..28`; when unset, Cursor usage resets on the local calendar month |
|
|
373
|
+
| `pricingSnapshot.source` | `"auto"` | Token pricing snapshot selection: `auto`, `bundled`, or `runtime` |
|
|
374
|
+
| `pricingSnapshot.autoRefresh` | `5` | Refresh stale local pricing data after this many days |
|
|
329
375
|
| `debug` | `false` | Include debug context in toast output |
|
|
330
376
|
|
|
331
377
|
## Token Pricing Snapshot
|
|
332
378
|
|
|
333
|
-
`/tokens_*` uses a local `models.dev` pricing snapshot.
|
|
334
|
-
|
|
335
|
-
Behavior:
|
|
336
|
-
|
|
337
|
-
- A bundled snapshot ships with the plugin for offline use.
|
|
338
|
-
- The plugin can refresh the local runtime snapshot when the data is stale.
|
|
339
|
-
- Reports continue to work if refresh fails.
|
|
379
|
+
`/tokens_*` uses a local `models.dev` pricing snapshot. A bundled snapshot ships for offline use, and Cursor `auto` and `composer*` pricing stays bundled because those ids are not on `models.dev`.
|
|
340
380
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
Maintainer refresh commands:
|
|
381
|
+
| `pricingSnapshot.source` | Active pricing behavior |
|
|
382
|
+
| --- | --- |
|
|
383
|
+
| `auto` | Newer runtime snapshot wins; otherwise bundled pricing stays active. |
|
|
384
|
+
| `bundled` | Packaged bundled snapshot stays active. |
|
|
385
|
+
| `runtime` | Runtime snapshot stays active when present; bundled pricing is fallback until one exists. |
|
|
349
386
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
387
|
+
- See [Configuration Reference](#configuration-reference) for option defaults.
|
|
388
|
+
- `pricingSnapshot.autoRefresh` controls how many days a runtime snapshot can age before background refresh.
|
|
389
|
+
- `/pricing_refresh` refreshes only the local runtime snapshot under the OpenCode cache directory. It never rewrites the packaged bundled snapshot.
|
|
390
|
+
- If `pricingSnapshot.source` is `bundled`, `/pricing_refresh` still updates the runtime cache, but active pricing stays bundled.
|
|
391
|
+
- Reports keep working if refresh fails.
|
|
392
|
+
- Pricing selection stays local and deterministic. There are no custom URLs or arbitrary pricing sources.
|
|
355
393
|
|
|
356
394
|
## Troubleshooting
|
|
357
395
|
|
|
@@ -361,7 +399,7 @@ If something is missing or looks wrong:
|
|
|
361
399
|
2. Confirm the expected provider appears in the detected provider list.
|
|
362
400
|
3. If token reports are empty, make sure OpenCode has already created `opencode.db`.
|
|
363
401
|
4. If Copilot managed billing is expected, confirm `copilot-quota-token.json` is present and valid.
|
|
364
|
-
5. If Google or Qwen
|
|
402
|
+
5. If provider setup looks wrong, check [Provider Setup At A Glance](#provider-setup-at-a-glance) and [Provider-Specific Notes](#provider-specific-notes). For Google Antigravity or Qwen Code, confirm the companion auth plugin is installed. For Alibaba Coding Plan, confirm OpenCode `alibaba` or `alibaba-coding-plan` auth is configured; `tier` may be `lite` or `pro`, and if it is missing the plugin falls back to `experimental.quotaToast.alibabaCodingPlanTier`.
|
|
365
403
|
|
|
366
404
|
If `opencode.db` is missing, start OpenCode once and let its local migration complete.
|
|
367
405
|
|
|
@@ -374,21 +412,30 @@ npm test
|
|
|
374
412
|
npm run build
|
|
375
413
|
```
|
|
376
414
|
|
|
377
|
-
|
|
415
|
+
Maintainer workflow for tracked upstream companion plugins:
|
|
378
416
|
|
|
379
|
-
|
|
417
|
+
```sh
|
|
418
|
+
npm run upstream:check
|
|
419
|
+
npm run upstream:prepare-review
|
|
420
|
+
npm run upstream:sync
|
|
421
|
+
```
|
|
380
422
|
|
|
381
|
-
|
|
423
|
+
- `npm run upstream:check` compares the committed references in `references/upstream-plugins/lock.json` with the latest npm releases for `opencode-qwencode-auth`, `opencode-antigravity-auth`, and `opencode-cursor-oauth`.
|
|
424
|
+
- `.github/workflows/upstream-plugin-update-check.yml` runs that check daily and keeps at most one open `[check] <plugin> had update` issue per plugin. If a newer npm release arrives before you act, that same issue is updated and gets a comment instead of piling up more issues.
|
|
425
|
+
- `npm run upstream:prepare-review` is the normal maintainer command. It syncs the latest published package copies, runs `npm test`, runs `npm run typecheck`, and prints a ready-to-paste prompt for another agent with changed relative paths and diff previews.
|
|
426
|
+
- `npm run upstream:sync` downloads the latest published package contents into `references/upstream-plugins/<plugin>/` and rewrites `references/upstream-plugins/lock.json`.
|
|
427
|
+
- Known embedded upstream credentials are redacted deterministically during sync before the reference copies are committed. Update issues still come from `references/upstream-plugins/lock.json` version comparisons.
|
|
428
|
+
- Syncing does not close the GitHub issue. The issue stays open until you finish review/fix/release work and close it manually.
|
|
429
|
+
- These reference copies are committed for maintainer review only. They are not published in this package because `package.json` ships only `dist`, `README.md`, and `LICENSE`.
|
|
382
430
|
|
|
383
|
-
|
|
384
|
-
{
|
|
385
|
-
"plugin": ["@slkiser/opencode-quota"]
|
|
386
|
-
}
|
|
387
|
-
```
|
|
431
|
+
If you maintain this repo through an agentic `/command` workflow, keep your normal-language maintainer prompt rules in local `AGENTS.md`. The current local prompt patterns are:
|
|
388
432
|
|
|
389
|
-
|
|
433
|
+
- `please help me add feature: <short description>`
|
|
434
|
+
- `please handle bug issue #<number>`
|
|
435
|
+
- `please handle feature request issue #<number>`
|
|
436
|
+
- `please sync our plugin updates`
|
|
390
437
|
|
|
391
|
-
|
|
438
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution workflow and repository policy.
|
|
392
439
|
|
|
393
440
|
## License
|
|
394
441
|
|
|
@@ -396,4 +443,14 @@ MIT
|
|
|
396
443
|
|
|
397
444
|
## Remarks
|
|
398
445
|
|
|
399
|
-
|
|
446
|
+
OpenCode Quota is not built by the OpenCode team and is not affiliated with OpenCode or any provider listed above.
|
|
447
|
+
|
|
448
|
+
## Star History
|
|
449
|
+
|
|
450
|
+
<a href="https://www.star-history.com/?repos=slkiser%2Fopencode-quota&type=date&legend=bottom-right">
|
|
451
|
+
<picture>
|
|
452
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/image?repos=slkiser/opencode-quota&type=date&theme=dark&legend=bottom-right" />
|
|
453
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/image?repos=slkiser/opencode-quota&type=date&legend=bottom-right" />
|
|
454
|
+
<img alt="Star History Chart" src="https://api.star-history.com/image?repos=slkiser/opencode-quota&type=date&legend=bottom-right" />
|
|
455
|
+
</picture>
|
|
456
|
+
</a>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_meta": {
|
|
3
|
-
"generatedAt":
|
|
3
|
+
"generatedAt": 1773949200336,
|
|
4
4
|
"providers": [
|
|
5
5
|
"anthropic",
|
|
6
6
|
"google",
|
|
@@ -256,6 +256,16 @@
|
|
|
256
256
|
"output": 12,
|
|
257
257
|
"cache_read": 0.2
|
|
258
258
|
},
|
|
259
|
+
"gemini-3.1-flash-image-preview": {
|
|
260
|
+
"input": 0.25,
|
|
261
|
+
"output": 60
|
|
262
|
+
},
|
|
263
|
+
"gemini-3.1-flash-lite-preview": {
|
|
264
|
+
"input": 0.25,
|
|
265
|
+
"output": 1.5,
|
|
266
|
+
"cache_read": 0.025,
|
|
267
|
+
"cache_write": 1
|
|
268
|
+
},
|
|
259
269
|
"gemini-3.1-pro-preview": {
|
|
260
270
|
"input": 2,
|
|
261
271
|
"output": 12,
|
|
@@ -461,6 +471,25 @@
|
|
|
461
471
|
"output": 14,
|
|
462
472
|
"cache_read": 0.175
|
|
463
473
|
},
|
|
474
|
+
"gpt-5.4": {
|
|
475
|
+
"input": 2.5,
|
|
476
|
+
"output": 15,
|
|
477
|
+
"cache_read": 0.25
|
|
478
|
+
},
|
|
479
|
+
"gpt-5.4-mini": {
|
|
480
|
+
"input": 0.75,
|
|
481
|
+
"output": 4.5,
|
|
482
|
+
"cache_read": 0.075
|
|
483
|
+
},
|
|
484
|
+
"gpt-5.4-nano": {
|
|
485
|
+
"input": 0.2,
|
|
486
|
+
"output": 1.25,
|
|
487
|
+
"cache_read": 0.02
|
|
488
|
+
},
|
|
489
|
+
"gpt-5.4-pro": {
|
|
490
|
+
"input": 30,
|
|
491
|
+
"output": 180
|
|
492
|
+
},
|
|
464
493
|
"o1": {
|
|
465
494
|
"input": 15,
|
|
466
495
|
"output": 60,
|
|
@@ -618,6 +647,21 @@
|
|
|
618
647
|
"output": 0.5,
|
|
619
648
|
"cache_read": 0.05
|
|
620
649
|
},
|
|
650
|
+
"grok-4.20-beta-latest-non-reasoning": {
|
|
651
|
+
"input": 2,
|
|
652
|
+
"output": 6,
|
|
653
|
+
"cache_read": 0.2
|
|
654
|
+
},
|
|
655
|
+
"grok-4.20-beta-latest-reasoning": {
|
|
656
|
+
"input": 2,
|
|
657
|
+
"output": 6,
|
|
658
|
+
"cache_read": 0.2
|
|
659
|
+
},
|
|
660
|
+
"grok-4.20-multi-agent-beta-latest": {
|
|
661
|
+
"input": 2,
|
|
662
|
+
"output": 6,
|
|
663
|
+
"cache_read": 0.2
|
|
664
|
+
},
|
|
621
665
|
"grok-beta": {
|
|
622
666
|
"input": 5,
|
|
623
667
|
"output": 15,
|
|
@@ -684,6 +728,12 @@
|
|
|
684
728
|
"output": 3.2,
|
|
685
729
|
"cache_read": 0.2,
|
|
686
730
|
"cache_write": 0
|
|
731
|
+
},
|
|
732
|
+
"glm-5-turbo": {
|
|
733
|
+
"input": 1.2,
|
|
734
|
+
"output": 4,
|
|
735
|
+
"cache_read": 0.24,
|
|
736
|
+
"cache_write": 0
|
|
687
737
|
}
|
|
688
738
|
}
|
|
689
739
|
}
|