@slkiser/opencode-quota 2.4.1 → 2.5.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.
Files changed (44) hide show
  1. package/README.md +189 -234
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/copilot.d.ts +24 -18
  6. package/dist/lib/copilot.d.ts.map +1 -1
  7. package/dist/lib/copilot.js +472 -350
  8. package/dist/lib/copilot.js.map +1 -1
  9. package/dist/lib/entries.d.ts +11 -3
  10. package/dist/lib/entries.d.ts.map +1 -1
  11. package/dist/lib/entries.js.map +1 -1
  12. package/dist/lib/format.js.map +1 -1
  13. package/dist/lib/grouped-entry-normalization.d.ts +7 -0
  14. package/dist/lib/grouped-entry-normalization.d.ts.map +1 -0
  15. package/dist/lib/grouped-entry-normalization.js +50 -0
  16. package/dist/lib/grouped-entry-normalization.js.map +1 -0
  17. package/dist/lib/grouped-header-format.d.ts +5 -0
  18. package/dist/lib/grouped-header-format.d.ts.map +1 -0
  19. package/dist/lib/grouped-header-format.js +16 -0
  20. package/dist/lib/grouped-header-format.js.map +1 -0
  21. package/dist/lib/quota-command-format.d.ts +2 -3
  22. package/dist/lib/quota-command-format.d.ts.map +1 -1
  23. package/dist/lib/quota-command-format.js +14 -43
  24. package/dist/lib/quota-command-format.js.map +1 -1
  25. package/dist/lib/quota-status.d.ts.map +1 -1
  26. package/dist/lib/quota-status.js +30 -0
  27. package/dist/lib/quota-status.js.map +1 -1
  28. package/dist/lib/toast-format-grouped.d.ts +1 -9
  29. package/dist/lib/toast-format-grouped.d.ts.map +1 -1
  30. package/dist/lib/toast-format-grouped.js +8 -25
  31. package/dist/lib/toast-format-grouped.js.map +1 -1
  32. package/dist/lib/types.d.ts +53 -37
  33. package/dist/lib/types.d.ts.map +1 -1
  34. package/dist/lib/types.js.map +1 -1
  35. package/dist/providers/copilot.d.ts.map +1 -1
  36. package/dist/providers/copilot.js +69 -8
  37. package/dist/providers/copilot.js.map +1 -1
  38. package/dist/providers/openai.d.ts.map +1 -1
  39. package/dist/providers/openai.js.map +1 -1
  40. package/dist/providers/qwen-code.d.ts.map +1 -1
  41. package/dist/providers/qwen-code.js.map +1 -1
  42. package/dist/providers/zai.d.ts.map +1 -1
  43. package/dist/providers/zai.js.map +1 -1
  44. package/package.json +1 -1
package/README.md CHANGED
@@ -1,189 +1,214 @@
1
1
  # Opencode Quota
2
2
 
3
- Track OpenCode quota & tokens via Toasts/Commands with zero context window pollution.
3
+ Local quota toasts and token reports for OpenCode, with zero LLM/model API calls.
4
4
 
5
- **Quota provider supports**: GitHub Copilot, OpenAI (Plus/Pro), Qwen Code, Chutes AI, Firmware AI, Google Antigravity, and Z.ai coding plan.
5
+ `opencode-quota` gives you two things:
6
6
 
7
- **Token provider supports**: All models and providers in [models.dev](https://models.dev).
7
+ - Automatic quota toasts after assistant responses
8
+ - Manual `/quota` and `/tokens_*` commands for deeper local reporting
8
9
 
9
- ## What It Does
10
-
11
- **Quota Toasts** - See your remaining quota at a glance after each assistant response.
10
+ Supported quota providers: GitHub Copilot, OpenAI, Qwen Code, Chutes AI, Firmware AI, Google Antigravity, and Z.ai.
11
+ Supported token pricing: any provider/model present in the local `models.dev` snapshot shipped with the plugin.
12
12
 
13
13
  ![Image of quota toasts](https://github.com/slkiser/opencode-quota/blob/main/toast.png)
14
14
 
15
- **Token Report Commands** - Track token usage and estimated costs across sessions using local OpenCode SQLite history plus a local models.dev pricing snapshot. The plugin can refresh that local snapshot at runtime when stale.
16
-
17
15
  ![Image of /quota and /tokens_daily outputs](https://github.com/slkiser/opencode-quota/blob/main/quota.png)
18
16
 
19
- ## Requirements
20
-
21
- - OpenCode >= 1.2.0 (uses SQLite `opencode.db` for session/message history)
22
-
23
- This plugin no longer supports the legacy folder-based JSON session storage used by older OpenCode versions.
17
+ ## Quick Start
24
18
 
25
- ## Installation
19
+ OpenCode `>= 1.2.0` is required.
26
20
 
27
- Add to your `opencode.json` (strict JSON) or `opencode.jsonc` (JSONC with comments/trailing commas):
21
+ Add the plugin to your `opencode.json` or `opencode.jsonc`:
28
22
 
29
- ```json
23
+ ```jsonc
30
24
  {
31
25
  "plugin": ["@slkiser/opencode-quota"]
32
26
  }
33
27
  ```
34
28
 
35
- That's it. Providers are auto-detected based on your OpenCode configuration. Toasts appear automatically after assistant responses.
29
+ Then:
36
30
 
37
- **Optional:** To restrict which providers are queried, set `enabledProviders` explicitly:
31
+ 1. Restart or reload OpenCode.
32
+ 2. Run `/quota_status` to confirm provider detection.
33
+ 3. Run `/quota` to see the manual grouped report.
38
34
 
39
- ```json
35
+ That is enough for most installs. Providers are auto-detected from your existing OpenCode setup.
36
+
37
+ ## What You Get
38
+
39
+ - Toasts after assistant responses, idle transitions, and compaction events
40
+ - `/quota` for a grouped manual quota report such as `[OpenAI] (Pro)` or `[Copilot] (business)`
41
+ - `/tokens_*` commands backed by local OpenCode history and a local pricing snapshot
42
+ - No model calls to compute the toast or report output
43
+
44
+ ## Common Install Patterns
45
+
46
+ ### Basic install
47
+
48
+ If you already use Copilot, OpenAI, Firmware, Chutes, or Z.ai in OpenCode, start here:
49
+
50
+ ```jsonc
40
51
  {
41
- "experimental": {
42
- "quotaToast": {
43
- "enabledProviders": ["copilot", "openai", "qwen-code", "google-antigravity"]
44
- }
45
- }
52
+ "plugin": ["@slkiser/opencode-quota"]
46
53
  }
47
54
  ```
48
55
 
49
- > **LLM Agents:** Ask your agent to install `https://github.com/slkiser/opencode-quota` with the providers you have enabled. See [LLM Agent Installation Instructions](#llm-agent-installation-instructions) for details.
56
+ ### Google Antigravity
50
57
 
51
- ## Commands
58
+ Google quota support depends on the companion auth plugin:
52
59
 
53
- | Command | Description |
54
- | ----------------- | --------------------------------------------------------------- |
55
- | `/quota` | Show quota toast (verbose) |
56
- | `/quota_status` | Show diagnostics (config, providers, accounts) + pricing health |
57
- | | |
58
- | `/tokens_today` | Tokens used today (calendar day) |
59
- | `/tokens_daily` | Tokens used in last 24 hours |
60
- | `/tokens_weekly` | Tokens used in last 7 days |
61
- | `/tokens_monthly` | Tokens used in last 30 days (incl. pricing sections) |
62
- | `/tokens_all` | Tokens used all time |
63
- | `/tokens_session` | Tokens used in current session |
64
- | `/tokens_between` | Tokens between two dates (YYYY-MM-DD) |
60
+ ```jsonc
61
+ {
62
+ "plugin": ["opencode-antigravity-auth", "@slkiser/opencode-quota"]
63
+ }
64
+ ```
65
65
 
66
- Token reporting commands are the `/tokens_*` family (there is no `/token` command).
66
+ ### Qwen Code
67
67
 
68
- ## Supported Quota Providers
68
+ Qwen quota support depends on the companion auth plugin:
69
69
 
70
- | Provider | Config ID | Auth Source |
71
- | ------------------ | -------------------- | --------------------------------------------- |
72
- | GitHub Copilot | `copilot` | OpenCode auth (automatic) |
73
- | OpenAI (Plus/Pro) | `openai` | OpenCode auth (automatic) |
74
- | Qwen Code (OAuth) | `qwen-code` | OpenCode auth via `opencode-qwencode-auth` |
75
- | Firmware AI | `firmware` | OpenCode auth or API key |
76
- | Chutes AI | `chutes` | OpenCode auth or API key |
77
- | Google Antigravity | `google-antigravity` | Multi-account via `opencode-antigravity-auth` |
78
- | Z.ai | `zai` | OpenCode auth (automatic) |
70
+ ```jsonc
71
+ {
72
+ "plugin": ["opencode-qwencode-auth", "@slkiser/opencode-quota"]
73
+ }
74
+ ```
79
75
 
80
- Token pricing coverage is broader than quota provider support: `/tokens_*` maps usage against provider/model entries in the active local models.dev pricing snapshot.
76
+ ## Commands
81
77
 
82
- Pricing refresh ownership is now runtime-based:
78
+ | Command | What it shows |
79
+ | --- | --- |
80
+ | `/quota` | Manual grouped quota report |
81
+ | `/quota_status` | Diagnostics: config, provider availability, account detection, pricing snapshot health |
82
+ | `/tokens_today` | Tokens used today (calendar day) |
83
+ | `/tokens_daily` | Tokens used in the last 24 hours |
84
+ | `/tokens_weekly` | Tokens used in the last 7 days |
85
+ | `/tokens_monthly` | Tokens used in the last 30 days, including pricing sections |
86
+ | `/tokens_all` | Tokens used across all local history |
87
+ | `/tokens_session` | Tokens used in the current session |
88
+ | `/tokens_between` | Tokens used between two dates: `YYYY-MM-DD YYYY-MM-DD` |
83
89
 
84
- - A bundled snapshot (`src/data/modelsdev-pricing.min.json`) is always shipped as bootstrap/offline fallback.
85
- - At plugin runtime, when `experimental.quotaToast.enabled` is `true`, pricing refresh runs as a bounded best-effort check (once per process window, plus persisted attempt tracking) during init and before `/tokens_*` / `/quota_status` report paths.
86
- - If the active snapshot is older than 3 days, the plugin attempts to fetch `https://models.dev/api.json`, keeps only `input`, `output`, `cache_read`, `cache_write`, and writes a refreshed local runtime snapshot.
87
- - If fetch fails, reports continue using the last local snapshot (no hard failure).
90
+ There is no `/token` command. The reporting commands are the `/tokens_*` family.
88
91
 
89
- Runtime snapshot files are stored under the OpenCode cache directory:
92
+ ## Minimal Config
90
93
 
91
- - `.../opencode/opencode-quota/modelsdev-pricing.runtime.min.json`
92
- - `.../opencode/opencode-quota/modelsdev-pricing.refresh-state.json`
94
+ You do not need extra config to get started. If you want to narrow the plugin to specific providers, use:
93
95
 
94
- Runtime refresh toggles:
96
+ ```jsonc
97
+ {
98
+ "experimental": {
99
+ "quotaToast": {
100
+ "enabledProviders": ["copilot", "openai", "google-antigravity"]
101
+ }
102
+ }
103
+ }
104
+ ```
95
105
 
96
- ```sh
97
- # Disable runtime pricing refresh
98
- OPENCODE_QUOTA_PRICING_AUTO_REFRESH=0
106
+ If you want grouped toast layout instead of the default classic toast:
99
107
 
100
- # Change stale threshold (default: 3 days)
101
- OPENCODE_QUOTA_PRICING_MAX_AGE_DAYS=5
108
+ ```jsonc
109
+ {
110
+ "experimental": {
111
+ "quotaToast": {
112
+ "toastStyle": "grouped"
113
+ }
114
+ }
115
+ }
102
116
  ```
103
117
 
104
- Maintainer-only bundled snapshot refresh (manual):
118
+ `/quota` already uses grouped formatting by default, even if toast style stays `classic`.
105
119
 
106
- ```sh
107
- npm run pricing:refresh
108
- npm run pricing:refresh:if-stale
109
- npm run build
110
- ```
120
+ ## Provider Setup At A Glance
111
121
 
112
- `pricing:refresh:if-stale` uses the same env knobs as runtime refresh (`OPENCODE_QUOTA_PRICING_AUTO_REFRESH`, `OPENCODE_QUOTA_PRICING_MAX_AGE_DAYS`).
122
+ | Provider | Works automatically | Extra setup when needed |
123
+ | --- | --- | --- |
124
+ | GitHub Copilot | Personal usage via existing OpenCode auth | Add `copilot-quota-token.json` for managed org or enterprise billing |
125
+ | OpenAI | Yes | None |
126
+ | Qwen Code | Needs `opencode-qwencode-auth` | Local-only quota estimation, no remote Qwen quota API |
127
+ | Firmware AI | Usually yes | Optional API key |
128
+ | Chutes AI | Usually yes | Optional API key |
129
+ | Google Antigravity | Needs `opencode-antigravity-auth` | Multi-account account file lives in OpenCode runtime config |
130
+ | Z.ai | Yes | None |
113
131
 
114
- ### Provider-Specific Setup
132
+ ## Provider-Specific Notes
115
133
 
116
134
  <details>
117
135
  <summary><strong>GitHub Copilot</strong></summary>
118
136
 
119
- **Setup:** Works automatically if OpenCode has Copilot configured and logged in.
137
+ Personal Copilot quota works automatically when OpenCode is already signed in.
120
138
 
121
- **Optional:** For more reliable quota reporting, provide a fine-grained PAT:
139
+ For managed billing, create `copilot-quota-token.json` under the OpenCode runtime config directory. You can find the directory with `opencode debug paths`.
122
140
 
123
- 1. Create a fine-grained PAT at GitHub with **Account permissions > Plan > Read**
124
- 2. Create `copilot-quota-token.json` under OpenCode's runtime config directory (see `opencode debug paths`):
141
+ Organization example:
125
142
 
126
143
  ```json
127
144
  {
128
145
  "token": "github_pat_...",
129
- "tier": "pro"
146
+ "tier": "business",
147
+ "organization": "your-org-slug"
130
148
  }
131
149
  ```
132
150
 
133
- `username` is optional (kept for backwards compatibility). If provided, it is used only as a fallback for legacy GitHub REST paths.
134
-
135
- Both fine-grained PATs (`github_pat_...`) and classic PATs (`ghp_...`) should work. Fine-grained PATs must include **Account permissions > Plan > Read**.
151
+ Enterprise example:
136
152
 
137
- Tier options: `free`, `pro`, `pro+`, `business`, `enterprise`
153
+ ```json
154
+ {
155
+ "token": "ghp_...",
156
+ "tier": "enterprise",
157
+ "enterprise": "your-enterprise-slug",
158
+ "organization": "optional-org-filter",
159
+ "username": "optional-user-filter"
160
+ }
161
+ ```
138
162
 
139
- PAT scope guidance (read-only first):
163
+ Behavior notes:
140
164
 
141
- - Personal/user-billed Copilot usage: fine-grained PAT with **Account permissions > Plan > Read**.
142
- - Organization-managed Copilot usage metrics: classic token with **`read:org`** (or fine-grained org permission **Organization Copilot metrics: read** when using org metrics endpoints).
143
- - Enterprise-managed Copilot usage metrics: classic token with **`read:enterprise`**.
165
+ - Personal output is labeled `[Copilot] (personal)`.
166
+ - Managed organization and enterprise output is labeled `[Copilot] (business)`.
167
+ - Managed output includes the org or enterprise slug in the value line so the billing scope is still visible.
168
+ - If both OpenCode OAuth and `copilot-quota-token.json` exist, the PAT config wins.
169
+ - If the PAT config is invalid, the plugin reports that error and does not silently fall back to OAuth.
170
+ - `business` requires `organization`.
171
+ - Enterprise premium usage does not support fine-grained PATs or GitHub App tokens. Use a supported enterprise token such as a classic PAT.
144
172
 
145
- GitHub notes that user-level billing endpoints may not include usage for org/enterprise-managed seats; use org/enterprise metrics endpoints in that case.
173
+ Useful checks:
146
174
 
147
- When both Copilot OAuth auth and `copilot-quota-token.json` are present, the plugin prefers the PAT billing path for quota metrics.
148
- Run `/quota_status` and check `copilot_quota_auth` to confirm `pat_state`, candidate paths checked, and `effective_source`/`override`.
175
+ - Run `/quota_status` and inspect `copilot_quota_auth`.
176
+ - Look for `billing_mode`, `billing_scope`, `effective_source`, and `billing_api_access_likely`.
149
177
 
150
178
  </details>
151
179
 
152
180
  <details>
153
181
  <summary><strong>OpenAI</strong></summary>
154
182
 
155
- **Setup:** Works automatically if OpenCode has OpenAI/ChatGPT configured.
183
+ No extra setup is required if OpenCode already has OpenAI or ChatGPT auth configured.
156
184
 
157
185
  </details>
158
186
 
159
187
  <details>
160
188
  <summary><strong>Qwen Code</strong></summary>
161
189
 
162
- **Setup:** Requires OAuth credentials from the `opencode-qwencode-auth` plugin.
190
+ Qwen support is local-only estimation. The plugin does not call an Alibaba quota API.
163
191
 
164
- Quota output for Qwen is **local-only estimation**:
192
+ Current behavior:
165
193
 
166
- - 1000 requests per UTC day (resets at UTC midnight)
194
+ - 1000 requests per UTC day
167
195
  - 60 requests per rolling minute
168
- - Counter increments on successful question-tool completions while plugin is enabled and current model is `qwen-code/*`
196
+ - Counters increment on successful question-tool completions while the current model is `qwen-code/*`
169
197
 
170
- No remote quota endpoint is called for Qwen and Alibaba API is not used.
198
+ State file path:
171
199
 
172
- Local state file path:
200
+ - `.../opencode/opencode-quota/qwen-local-quota.json`
173
201
 
174
- - `.../opencode/opencode-quota/qwen-local-quota.json` (under OpenCode state dir)
175
-
176
- Use `/quota_status` to verify auth detection and local Qwen counter status.
177
- If the local Qwen state file is missing, `/quota_status` reports usage from a default empty state.
202
+ Run `/quota_status` to verify auth detection and local counter status.
178
203
 
179
204
  </details>
180
205
 
181
206
  <details>
182
207
  <summary><strong>Firmware AI</strong></summary>
183
208
 
184
- **Setup:** Works automatically if OpenCode has Firmware configured. Alternatively, provide an API key:
209
+ If OpenCode already has Firmware configured, it usually works automatically. You can also provide an API key:
185
210
 
186
- ```json
211
+ ```jsonc
187
212
  {
188
213
  "provider": {
189
214
  "firmware": {
@@ -200,16 +225,16 @@ If the local Qwen state file is missing, `/quota_status` reports usage from a de
200
225
  }
201
226
  ```
202
227
 
203
- The `apiKey` field supports `{env:VAR_NAME}` syntax or a direct key.
228
+ `{env:VAR_NAME}` and direct keys are both supported.
204
229
 
205
230
  </details>
206
231
 
207
232
  <details>
208
233
  <summary><strong>Chutes AI</strong></summary>
209
234
 
210
- **Setup:** Works automatically if OpenCode has Chutes configured. Alternatively, provide an API key:
235
+ If OpenCode already has Chutes configured, it usually works automatically. You can also provide an API key:
211
236
 
212
- ```json
237
+ ```jsonc
213
238
  {
214
239
  "provider": {
215
240
  "chutes": {
@@ -231,179 +256,109 @@ The `apiKey` field supports `{env:VAR_NAME}` syntax or a direct key.
231
256
  <details>
232
257
  <summary><strong>Google Antigravity</strong></summary>
233
258
 
234
- **Setup:** Requires the `opencode-antigravity-auth` plugin for multi-account support:
235
-
236
- ```json
237
- {
238
- "plugin": ["opencode-antigravity-auth", "@slkiser/opencode-quota"]
239
- }
240
- ```
259
+ This provider requires the `opencode-antigravity-auth` plugin. Account credentials are stored under the OpenCode runtime config directory.
241
260
 
242
- Account credentials are stored under OpenCode's runtime config directory (see `opencode debug paths`).
243
-
244
- If you are troubleshooting, `/quota_status` prints the candidate paths checked for `antigravity-accounts.json`.
261
+ If you are debugging detection, `/quota_status` prints the candidate paths checked for `antigravity-accounts.json`.
245
262
 
246
263
  </details>
247
264
 
248
265
  <details>
249
266
  <summary><strong>Z.ai</strong></summary>
250
267
 
251
- **Setup:** Works automatically if OpenCode has Z.ai (Coding Plan) configured.
268
+ No extra setup is required if OpenCode already has Z.ai configured.
252
269
 
253
270
  </details>
254
271
 
255
272
  ## Configuration Reference
256
273
 
257
- All options go under `experimental.quotaToast` in `opencode.json` or `opencode.jsonc`:
274
+ All plugin settings live under `experimental.quotaToast`.
258
275
 
259
- | Option | Default | Description |
260
- | ------------------- | ------------ | ---------------------------------------------------------------------------------------------------- |
261
- | `enabled` | `true` | Enable/disable plugin. When `false`, `/quota`, `/quota_status`, and `/tokens_*` are strict no-ops. |
262
- | `enableToast` | `true` | Show popup toasts |
263
- | `toastStyle` | `classic` | Toast layout style: `classic` or `grouped` |
264
- | `enabledProviders` | `"auto"` | Provider IDs to query, or `"auto"` to detect |
265
- | `minIntervalMs` | `300000` | Minimum ms between provider fetches (default: 5 min); Qwen local RPM stays live on question triggers |
266
- | `toastDurationMs` | `9000` | How long toasts display (ms) |
267
- | `showOnIdle` | `true` | Show toast on idle trigger |
268
- | `showOnQuestion` | `true` | Show toast after a question/assistant response |
269
- | `showOnCompact` | `true` | Show toast after session compaction |
270
- | `showOnBothFail` | `true` | If providers attempt and fail, show a fallback toast |
271
- | `onlyCurrentModel` | `false` | Only show quota for the current model (best-effort) |
272
- | `showSessionTokens` | `true` | Show per-model input/output tokens in toast |
273
- | `layout.maxWidth` | `50` | Formatting target width |
274
- | `layout.narrowAt` | `42` | Compact layout breakpoint |
275
- | `layout.tinyAt` | `32` | Ultra-compact layout breakpoint |
276
- | `googleModels` | `["CLAUDE"]` | Google models: `CLAUDE`, `G3PRO`, `G3FLASH`, `G3IMAGE` |
277
- | `debug` | `false` | Show debug info in toasts (and a debug-only toast when otherwise suppressed) |
276
+ | Option | Default | Meaning |
277
+ | --- | --- | --- |
278
+ | `enabled` | `true` | Master switch for the plugin. When `false`, `/quota`, `/quota_status`, and `/tokens_*` are no-ops. |
279
+ | `enableToast` | `true` | Show popup toasts |
280
+ | `toastStyle` | `classic` | Toast layout: `classic` or `grouped` |
281
+ | `enabledProviders` | `"auto"` | Auto-detect providers, or set an explicit provider list |
282
+ | `minIntervalMs` | `300000` | Minimum fetch interval between provider updates |
283
+ | `toastDurationMs` | `9000` | Toast duration in milliseconds |
284
+ | `showOnIdle` | `true` | Show toast on idle trigger |
285
+ | `showOnQuestion` | `true` | Show toast after a question/assistant response |
286
+ | `showOnCompact` | `true` | Show toast after session compaction |
287
+ | `showOnBothFail` | `true` | Show a fallback toast when providers attempt and all fail |
288
+ | `onlyCurrentModel` | `false` | Filter to the current model when possible |
289
+ | `showSessionTokens` | `true` | Append current-session token totals to toast output |
290
+ | `layout.maxWidth` | `50` | Main formatting width target |
291
+ | `layout.narrowAt` | `42` | Compact layout breakpoint |
292
+ | `layout.tinyAt` | `32` | Tiny layout breakpoint |
293
+ | `googleModels` | `["CLAUDE"]` | Google model keys: `CLAUDE`, `G3PRO`, `G3FLASH`, `G3IMAGE` |
294
+ | `debug` | `false` | Include debug context in toast output |
278
295
 
279
- ## Contributing
296
+ ## Token Pricing Snapshot
280
297
 
281
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full policy and workflow.
298
+ `/tokens_*` uses a local `models.dev` pricing snapshot.
282
299
 
283
- This project prefers an issue-first contribution model for features, bug fixes, refactors, and behavioral changes. Local pre-commit checks run formatting, typecheck, and tests; PR CI currently runs typecheck and build across Node versions.
300
+ Behavior:
284
301
 
285
- Issue/PR templates are enforced in `.github/ISSUE_TEMPLATE/` and `.github/pull_request_template.md` for consistent titles and required validation details.
302
+ - A bundled snapshot ships with the plugin for offline use.
303
+ - The plugin can refresh the local runtime snapshot when the data is stale.
304
+ - Reports continue to work if refresh fails.
286
305
 
287
- ## Development
306
+ Useful environment variables:
288
307
 
289
308
  ```sh
290
- npm install
291
- npm run typecheck
292
- npm test
293
- npm run test:watch
294
- npm run build
309
+ OPENCODE_QUOTA_PRICING_AUTO_REFRESH=0
310
+ OPENCODE_QUOTA_PRICING_MAX_AGE_DAYS=5
295
311
  ```
296
312
 
297
- ## Troubleshooting
298
-
299
- Toast not appearing? Run `/quota_status` to check config, provider availability, and whether `opencode.db` is detected.
300
-
301
- If `opencode.db` is missing, run OpenCode once (OpenCode performs a one-time migration into SQLite on first run after upgrade).
302
-
303
- ---
304
-
305
- <details id="llm-agent-installation-instructions">
306
- <summary><strong>LLM Agent Installation Instructions</strong></summary>
307
-
308
- ### For LLM Agents: How to Install and Configure
309
-
310
- This section provides instructions for LLM agents to install and configure `opencode-quota` based on the user's current OpenCode setup.
313
+ Maintainer refresh commands:
311
314
 
312
- #### Step 1: Check Current Configuration
313
-
314
- First, determine what providers the user has connected. You can:
315
-
316
- 1. Read the user's `opencode.json` or `opencode.jsonc` (typically at `~/.config/opencode/`)
317
- 2. Run `/connected` in OpenCode to see active providers
318
- 3. Ask the user which providers they use
319
-
320
- #### Step 2: Install the Plugin
315
+ ```sh
316
+ npm run pricing:refresh
317
+ npm run pricing:refresh:if-stale
318
+ npm run build
319
+ ```
321
320
 
322
- Add the plugin to the user's `opencode.json` (or `opencode.jsonc`):
321
+ ## Troubleshooting
323
322
 
324
- ```json
325
- {
326
- "plugin": ["@slkiser/opencode-quota"]
327
- }
328
- ```
323
+ If something is missing or looks wrong:
329
324
 
330
- If the user already has plugins, append to the existing array.
325
+ 1. Run `/quota_status`.
326
+ 2. Confirm the expected provider appears in the detected provider list.
327
+ 3. If token reports are empty, make sure OpenCode has already created `opencode.db`.
328
+ 4. If Copilot managed billing is expected, confirm `copilot-quota-token.json` is present and valid.
329
+ 5. If Google or Qwen support is expected, confirm the companion auth plugin is installed.
331
330
 
332
- #### Step 3: Configure Providers (Optional)
331
+ If `opencode.db` is missing, start OpenCode once and let its local migration complete.
333
332
 
334
- By default, providers are auto-detected. If the user wants to restrict which providers are queried, add explicit `enabledProviders`:
333
+ ## Development
335
334
 
336
- ```jsonc
337
- {
338
- "experimental": {
339
- "quotaToast": {
340
- "enabledProviders": [
341
- // Add only the providers the user has configured:
342
- // "copilot" - if using GitHub Copilot
343
- // "openai" - if using OpenAI/ChatGPT
344
- // "qwen-code" - if using Qwen Code OAuth (requires opencode-qwencode-auth)
345
- // "firmware" - if using Firmware AI
346
- // "chutes" - if using Chutes AI
347
- // "google-antigravity" - if using Google Antigravity (requires opencode-antigravity-auth)
348
- ],
349
- },
350
- },
351
- }
335
+ ```sh
336
+ npm install
337
+ npm run typecheck
338
+ npm test
339
+ npm run build
352
340
  ```
353
341
 
354
- #### Provider Detection Guide
342
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution workflow and repository policy.
355
343
 
356
- | If user's config has... | Add to enabledProviders |
357
- | ------------------------------------------- | ----------------------- |
358
- | `github-copilot` provider or Copilot models | `"copilot"` |
359
- | `openai` / `chatgpt` provider | `"openai"` |
360
- | `qwen-code` provider | `"qwen-code"` |
361
- | `firmware` / `firmware-ai` provider | `"firmware"` |
362
- | `chutes` provider | `"chutes"` |
363
- | `google` provider with antigravity models | `"google-antigravity"` |
364
- | `opencode-antigravity-auth` in plugins | `"google-antigravity"` |
365
- | `opencode-qwencode-auth` in plugins | `"qwen-code"` |
344
+ ## LLM Agent Installation Notes
366
345
 
367
- #### Example: Full Configuration
368
-
369
- For a user with Copilot and Google Antigravity:
346
+ If you are using an agent to install the plugin for you, the safe default is:
370
347
 
371
348
  ```jsonc
372
349
  {
373
- "plugin": [
374
- "opencode-antigravity-auth", // Required for google-antigravity
375
- "@slkiser/opencode-quota",
376
- ],
377
- "experimental": {
378
- "quotaToast": {
379
- "enabledProviders": ["copilot", "google-antigravity"],
380
- "googleModels": ["CLAUDE"], // Options: CLAUDE, G3PRO, G3FLASH
381
- "minIntervalMs": 300000, // 5 minutes between fetches
382
- "toastDurationMs": 9000, // Toast shows for 9 seconds
383
- },
384
- },
350
+ "plugin": ["@slkiser/opencode-quota"]
385
351
  }
386
352
  ```
387
353
 
388
- #### Step 4: Verify Installation
389
-
390
- After configuration, instruct the user to:
391
-
392
- 1. Restart OpenCode (or reload the window)
393
- 2. Run `/quota_status` to verify providers are detected
394
- 3. Run `/quota` to manually trigger a toast
395
-
396
- #### Common Issues
354
+ Then verify with `/quota_status`.
397
355
 
398
- - **Toast not showing**: Run `/quota_status` to diagnose
399
- - **Google Antigravity not working**: Ensure `opencode-antigravity-auth` plugin is installed and accounts are configured
400
- - **Copilot quota unreliable**: Consider setting up a fine-grained PAT (see Provider-Specific Setup above)
401
-
402
- </details>
356
+ Only add explicit `enabledProviders` if you want to limit which providers are queried. Only add companion plugins when the user actually uses Google Antigravity or Qwen Code.
403
357
 
404
358
  ## License
405
359
 
406
360
  MIT
407
361
 
408
362
  ## Remarks
409
- Opencode Quota is not built by the OpenCode team and is not affiliated with them in any way. It is not affiliated with any providers listed above.
363
+
364
+ Opencode Quota is not built by the OpenCode team and is not affiliated with OpenCode or any provider listed above.
package/dist/index.d.ts CHANGED
@@ -6,5 +6,5 @@
6
6
  * @packageDocumentation
7
7
  */
8
8
  export { QuotaToastPlugin } from "./plugin.js";
9
- export type { QuotaToastConfig, GoogleModelId, CopilotQuotaResult, GoogleQuotaResult, GoogleModelQuota, } from "./lib/types.js";
9
+ export type { QuotaToastConfig, GoogleModelId, CopilotEnterpriseUsageResult, CopilotOrganizationUsageResult, CopilotQuotaResult, GoogleQuotaResult, GoogleModelQuota, } from "./lib/types.js";
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,4BAA4B,EAC5B,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8EAA8E;AAC9E,iFAAiF;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAW/C,yEAAyE;AACzE,wCAAwC;AAExC,6EAA6E;AAC7E,uFAAuF"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8EAA8E;AAC9E,iFAAiF;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAa/C,yEAAyE;AACzE,wCAAwC;AAExC,6EAA6E;AAC7E,uFAAuF"}