opencode-quotas 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +344 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +3 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/cli.d.ts +3 -0
  7. package/dist/src/cli.d.ts.map +1 -0
  8. package/dist/src/cli.js +42 -0
  9. package/dist/src/cli.js.map +1 -0
  10. package/dist/src/constants.d.ts +9 -0
  11. package/dist/src/constants.d.ts.map +1 -0
  12. package/dist/src/constants.js +15 -0
  13. package/dist/src/constants.js.map +1 -0
  14. package/dist/src/defaults.d.ts +3 -0
  15. package/dist/src/defaults.d.ts.map +1 -0
  16. package/dist/src/defaults.js +52 -0
  17. package/dist/src/defaults.js.map +1 -0
  18. package/dist/src/index.d.ts +6 -0
  19. package/dist/src/index.d.ts.map +1 -0
  20. package/dist/src/index.js +265 -0
  21. package/dist/src/index.js.map +1 -0
  22. package/dist/src/interfaces.d.ts +197 -0
  23. package/dist/src/interfaces.d.ts.map +1 -0
  24. package/dist/src/interfaces.js +2 -0
  25. package/dist/src/interfaces.js.map +1 -0
  26. package/dist/src/logger.d.ts +14 -0
  27. package/dist/src/logger.d.ts.map +1 -0
  28. package/dist/src/logger.js +44 -0
  29. package/dist/src/logger.js.map +1 -0
  30. package/dist/src/plugin-state.d.ts +20 -0
  31. package/dist/src/plugin-state.d.ts.map +1 -0
  32. package/dist/src/plugin-state.js +53 -0
  33. package/dist/src/plugin-state.js.map +1 -0
  34. package/dist/src/providers/antigravity/auth.d.ts +12 -0
  35. package/dist/src/providers/antigravity/auth.d.ts.map +1 -0
  36. package/dist/src/providers/antigravity/auth.js +109 -0
  37. package/dist/src/providers/antigravity/auth.js.map +1 -0
  38. package/dist/src/providers/antigravity/index.d.ts +2 -0
  39. package/dist/src/providers/antigravity/index.d.ts.map +1 -0
  40. package/dist/src/providers/antigravity/index.js +2 -0
  41. package/dist/src/providers/antigravity/index.js.map +1 -0
  42. package/dist/src/providers/antigravity/provider.d.ts +34 -0
  43. package/dist/src/providers/antigravity/provider.d.ts.map +1 -0
  44. package/dist/src/providers/antigravity/provider.js +216 -0
  45. package/dist/src/providers/antigravity/provider.js.map +1 -0
  46. package/dist/src/providers/codex.d.ts +4 -0
  47. package/dist/src/providers/codex.d.ts.map +1 -0
  48. package/dist/src/providers/codex.js +242 -0
  49. package/dist/src/providers/codex.js.map +1 -0
  50. package/dist/src/providers/github.d.ts +4 -0
  51. package/dist/src/providers/github.d.ts.map +1 -0
  52. package/dist/src/providers/github.js +139 -0
  53. package/dist/src/providers/github.js.map +1 -0
  54. package/dist/src/quota-cache.d.ts +26 -0
  55. package/dist/src/quota-cache.d.ts.map +1 -0
  56. package/dist/src/quota-cache.js +107 -0
  57. package/dist/src/quota-cache.js.map +1 -0
  58. package/dist/src/registry.d.ts +3 -0
  59. package/dist/src/registry.d.ts.map +1 -0
  60. package/dist/src/registry.js +23 -0
  61. package/dist/src/registry.js.map +1 -0
  62. package/dist/src/services/aggregation-service.d.ts +34 -0
  63. package/dist/src/services/aggregation-service.d.ts.map +1 -0
  64. package/dist/src/services/aggregation-service.js +89 -0
  65. package/dist/src/services/aggregation-service.js.map +1 -0
  66. package/dist/src/services/config-loader.d.ts +25 -0
  67. package/dist/src/services/config-loader.d.ts.map +1 -0
  68. package/dist/src/services/config-loader.js +105 -0
  69. package/dist/src/services/config-loader.js.map +1 -0
  70. package/dist/src/services/history-service.d.ts +15 -0
  71. package/dist/src/services/history-service.d.ts.map +1 -0
  72. package/dist/src/services/history-service.js +99 -0
  73. package/dist/src/services/history-service.js.map +1 -0
  74. package/dist/src/services/prediction-engine.d.ts +47 -0
  75. package/dist/src/services/prediction-engine.d.ts.map +1 -0
  76. package/dist/src/services/prediction-engine.js +94 -0
  77. package/dist/src/services/prediction-engine.js.map +1 -0
  78. package/dist/src/services/quota-service.d.ts +41 -0
  79. package/dist/src/services/quota-service.d.ts.map +1 -0
  80. package/dist/src/services/quota-service.js +257 -0
  81. package/dist/src/services/quota-service.js.map +1 -0
  82. package/dist/src/tools/quotas.d.ts +11 -0
  83. package/dist/src/tools/quotas.d.ts.map +1 -0
  84. package/dist/src/tools/quotas.js +62 -0
  85. package/dist/src/tools/quotas.js.map +1 -0
  86. package/dist/src/ui/progress-bar.d.ts +20 -0
  87. package/dist/src/ui/progress-bar.d.ts.map +1 -0
  88. package/dist/src/ui/progress-bar.js +150 -0
  89. package/dist/src/ui/progress-bar.js.map +1 -0
  90. package/dist/src/ui/quota-table.d.ts +15 -0
  91. package/dist/src/ui/quota-table.d.ts.map +1 -0
  92. package/dist/src/ui/quota-table.js +136 -0
  93. package/dist/src/ui/quota-table.js.map +1 -0
  94. package/dist/src/utils/debug.d.ts +1 -0
  95. package/dist/src/utils/debug.d.ts.map +1 -0
  96. package/dist/src/utils/debug.js +3 -0
  97. package/dist/src/utils/debug.js.map +1 -0
  98. package/dist/src/utils/paths.d.ts +7 -0
  99. package/dist/src/utils/paths.d.ts.map +1 -0
  100. package/dist/src/utils/paths.js +37 -0
  101. package/dist/src/utils/paths.js.map +1 -0
  102. package/dist/src/utils/time.d.ts +3 -0
  103. package/dist/src/utils/time.d.ts.map +1 -0
  104. package/dist/src/utils/time.js +38 -0
  105. package/dist/src/utils/time.js.map +1 -0
  106. package/dist/src/utils/validation.d.ts +6 -0
  107. package/dist/src/utils/validation.d.ts.map +1 -0
  108. package/dist/src/utils/validation.js +66 -0
  109. package/dist/src/utils/validation.js.map +1 -0
  110. package/package.json +42 -0
  111. package/src/cli.ts +53 -0
  112. package/src/constants.ts +17 -0
  113. package/src/defaults.ts +53 -0
  114. package/src/index.ts +338 -0
  115. package/src/interfaces.ts +258 -0
  116. package/src/logger.ts +55 -0
  117. package/src/plugin-state.ts +65 -0
  118. package/src/providers/antigravity/auth.ts +163 -0
  119. package/src/providers/antigravity/index.ts +1 -0
  120. package/src/providers/antigravity/provider.ts +337 -0
  121. package/src/providers/codex.ts +327 -0
  122. package/src/providers/github.ts +161 -0
  123. package/src/quota-cache.ts +157 -0
  124. package/src/registry.ts +30 -0
  125. package/src/services/aggregation-service.ts +116 -0
  126. package/src/services/config-loader.ts +124 -0
  127. package/src/services/history-service.ts +116 -0
  128. package/src/services/prediction-engine.ts +133 -0
  129. package/src/services/quota-service.ts +343 -0
  130. package/src/tools/quotas.ts +78 -0
  131. package/src/ui/progress-bar.ts +204 -0
  132. package/src/ui/quota-table.ts +173 -0
  133. package/src/utils/debug.ts +1 -0
  134. package/src/utils/paths.ts +41 -0
  135. package/src/utils/time.ts +40 -0
  136. package/src/utils/validation.ts +63 -0
package/README.md ADDED
@@ -0,0 +1,344 @@
1
+ # OpenCode Quotas Plugin
2
+
3
+ **The ultimate usage dashboard plugin for your AI coding assistants.**
4
+
5
+ **OpenCode Quotas** is an OpenCode.ai plugin that aggregates usage data from Antigravity, Codex, and GitHub Copilot into a single, beautiful dashboard injected directly into your OpenCode chat footer. Never hit a rate limit unexpectedly again.
6
+
7
+ ![OpenCode Quotas](docs/QuotaDisplay.png)
8
+
9
+ > **Note**: This is a community-developed plugin and is not officially affiliated with OpenCode.ai.
10
+
11
+ ## Features
12
+
13
+ - **Unified Dashboard**: See all your AI quotas (Antigravity, Codex, Copilot) in one place.
14
+ - **Smart Predictions**: Uses linear regression on usage history to predict when you'll exhaust your quota.
15
+ - **Visual Progress Bars**: ANSI-colored bars that change from green to yellow to red as you approach limits.
16
+ - **Context Aware**: Optionally filter quotas to show only those relevant to the active model.
17
+ - **Resilient**: Provider failures are isolated and won't break your chat experience.
18
+
19
+ ## Installation
20
+
21
+ ### 1. Clone & Build
22
+ Clone the repository into your OpenCode plugins directory and build it:
23
+
24
+ ```bash
25
+ # Clone into your plugins directory
26
+ git clone https://github.com/your-org/opencode-quotas ~/.opencode/plugins/opencode-quotas
27
+
28
+ # Build the plugin
29
+ cd ~/.opencode/plugins/opencode-quotas
30
+ bun install
31
+ npm run build
32
+ ```
33
+
34
+ ### 2. Register the Plugin
35
+ Add `opencode-quotas` to your OpenCode configuration file (typically `~/.opencode/config.json`) under the `plugins` array:
36
+
37
+ ```json
38
+ {
39
+ "plugin": [
40
+ "opencode-antigravity-auth",
41
+ "opencode-quotas"
42
+ ]
43
+ }
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ Once installed and registered, a live quota summary is automatically appended to every assistant message footer in OpenCode. No further action is required.
49
+
50
+ ### CLI Mode (Optional)
51
+
52
+ You can also use OpenCode Quotas as a standalone CLI tool to check quotas directly from your terminal:
53
+
54
+ ```bash
55
+ # Show all quotas
56
+ opencode-quotas
57
+
58
+ # Filter by model (simulates what the plugin does automatically)
59
+ opencode-quotas --provider google --model antigravity-gemini-3-flash
60
+ ```
61
+
62
+ > **Tip**: During development, use `bun run opencode-quotas` to run without building.
63
+
64
+ ## Supported Providers
65
+
66
+ | Provider | Raw Quota IDs | Aggregated IDs | Description |
67
+ | :--- | :--- | :--- | :--- |
68
+ | **Antigravity** | `ag-raw-*` | `ag-flash`, `ag-pro`, `ag-premium` | Raw model quotas aggregated by pattern into Flash, Pro, and Premium tiers. |
69
+ | **Codex** | `codex-primary`, `codex-secondary` | `codex-smart` | Rate limits aggregated using most-critical strategy. |
70
+ | **GitHub Copilot** | — | — | ⚠️ Not yet implemented. |
71
+
72
+ > **Note**: Quota IDs are used in configuration options like `disabled` and `modelMapping`.
73
+
74
+ ## Column Reference
75
+
76
+ | Column | Description |
77
+ | :--- | :--- |
78
+ | `status` | Health indicator: `OK` (normal), `WRN` (warning), `ERR` (at/over limit) |
79
+ | `name` | Display name of the quota (e.g., "Antigravity Flash") |
80
+ | `bar` | Visual progress bar showing utilization |
81
+ | `percent` | Numeric percentage of quota used |
82
+ | `reset` | Time until the quota resets (e.g., "23m", "1h 30m") |
83
+ | `ettl` | **E**stimated **T**ime **T**o **L**imit - predicted time until quota exhaustion based on usage trends |
84
+ | `value` | Raw used/limit values (e.g., "150/500 credits") |
85
+ | `window` | Rate limit window duration (e.g., "5h window") |
86
+ | `info` | Additional info or alerts (e.g., "unlimited", "!!") |
87
+
88
+ ## Configuration
89
+
90
+ All configuration is done via `.opencode/quotas.json` in your project root. Settings apply to both the CLI and plugin.
91
+
92
+ ### Model Filtering
93
+
94
+ By default, `filterByCurrentModel` is enabled, showing only quotas relevant to the active model.
95
+
96
+ ```json
97
+ {
98
+ "filterByCurrentModel": true
99
+ }
100
+ ```
101
+
102
+ **How it works**: The plugin extracts tokens from the model ID (e.g., `antigravity-gemini-3-flash` becomes `["antigravity", "gemini", "3", "flash"]`) and scores each quota by how many tokens match its ID or name. The highest-scoring quotas are displayed.
103
+
104
+ **Before filtering (all quotas):**
105
+ ```text
106
+ ST QUOTA NAME USED UTILIZATION RESET ETTL
107
+ --- ------------------- ---- -------------------- ------ -----
108
+ OK Antigravity Flash 20% ████░░░░░░░░░░░░░░░░ 28m 13m
109
+ OK Antigravity Premium 40% ████████░░░░░░░░░░░░ 56m 1h 0m
110
+ ERR Codex Usage 100% ████████████████████ 13h 9m -
111
+ ```
112
+
113
+ **After filtering (model: `google/antigravity-gemini-3-flash`):**
114
+ ```text
115
+ ST QUOTA NAME USED UTILIZATION RESET ETTL
116
+ --- ----------------- ---- -------------------- ----- ----
117
+ OK Antigravity Flash 20% ████░░░░░░░░░░░░░░░░ 28m 13m
118
+ ```
119
+
120
+ ### Explicit Model Mapping
121
+
122
+ For precise control, map model IDs directly to quota IDs:
123
+
124
+ ```json
125
+ {
126
+ "modelMapping": {
127
+ "google/antigravity-gemini-3-flash": ["ag-flash"],
128
+ "google/antigravity-gemini-3-pro": ["ag-pro"],
129
+ "github-copilot/gpt-4o": ["codex-smart"]
130
+ }
131
+ }
132
+ ```
133
+
134
+ > **Note**: Model IDs must match the format from `opencode models` (e.g., `provider/model-name`).
135
+
136
+ ### Hide Specific Quotas
137
+
138
+ Permanently hide quotas you don't care about:
139
+
140
+ ```json
141
+ {
142
+ "disabled": ["ag-pro", "codex-smart"]
143
+ }
144
+ ```
145
+
146
+ ### Smart Aggregation
147
+
148
+ Combine multiple quotas into a single display row using explicit sources or pattern matching.
149
+
150
+ **Pattern-based aggregation** (matches raw quota IDs/names):
151
+ ```json
152
+ {
153
+ "aggregatedGroups": [
154
+ {
155
+ "id": "ag-flash",
156
+ "name": "Antigravity Flash",
157
+ "patterns": ["flash"],
158
+ "providerId": "antigravity",
159
+ "strategy": "most_critical"
160
+ }
161
+ ]
162
+ }
163
+ ```
164
+
165
+ **Explicit source aggregation** (specify exact quota IDs):
166
+ ```json
167
+ {
168
+ "aggregatedGroups": [
169
+ {
170
+ "id": "codex-unified",
171
+ "name": "Codex Usage",
172
+ "sources": ["codex-primary", "codex-secondary"],
173
+ "strategy": "most_critical"
174
+ }
175
+ ]
176
+ }
177
+ ```
178
+
179
+ **Aggregation options:**
180
+ | Option | Type | Description |
181
+ | :--- | :--- | :--- |
182
+ | `id` | string | Unique identifier for the aggregated quota |
183
+ | `name` | string | Display name |
184
+ | `sources` | string[] | Explicit quota IDs to include |
185
+ | `patterns` | string[] | Patterns to match against raw quota IDs/names |
186
+ | `providerId` | string | Limit pattern matching to a specific provider |
187
+ | `strategy` | string | Aggregation strategy (see below) |
188
+
189
+ **Aggregation strategies:**
190
+ | Strategy | Description |
191
+ | :--- | :--- |
192
+ | `most_critical` | Shows the quota predicted to hit its limit soonest (requires usage history) |
193
+ | `max` | Shows the quota with highest current usage percentage |
194
+ | `min` | Shows the quota with lowest current usage percentage |
195
+ | `mean` | Displays average usage across all sources |
196
+ | `median` | Displays median usage across all sources |
197
+
198
+ ## Output Customization
199
+
200
+ All options below work in both CLI and plugin output. ANSI colors only render in terminal environments.
201
+
202
+ ### Select Columns
203
+
204
+ ```json
205
+ {
206
+ "table": {
207
+ "columns": ["name", "bar", "percent"]
208
+ }
209
+ }
210
+ ```
211
+
212
+ ```text
213
+ QUOTA NAME UTILIZATION USED
214
+ ------------------- -------------------- ----
215
+ Antigravity Flash ████░░░░░░░░░░░░░░░░ 20%
216
+ Antigravity Premium ████████░░░░░░░░░░░░ 40%
217
+ Codex Usage ████████████████████ 100%
218
+ ```
219
+
220
+ ### Progress Bar Style
221
+
222
+ ```json
223
+ {
224
+ "progressBar": {
225
+ "filledChar": "=",
226
+ "emptyChar": "-",
227
+ "width": 10
228
+ }
229
+ }
230
+ ```
231
+
232
+ ```text
233
+ ST QUOTA NAME USED UTILIZATION RESET
234
+ --- ------------------- ---- ----------- ------
235
+ OK Antigravity Flash 20% ==-------- 23m
236
+ OK Antigravity Premium 40% ====------ 51m
237
+ ERR Codex Usage 100% ========== 13h 4m
238
+ ```
239
+
240
+ ### Show Remaining Capacity
241
+
242
+ Switch from "used" (default) to "available" mode. This inverts the display—useful if you prefer seeing how much is left:
243
+
244
+ ```json
245
+ {
246
+ "progressBar": {
247
+ "show": "available"
248
+ }
249
+ }
250
+ ```
251
+
252
+ ```text
253
+ ST QUOTA NAME USED UTILIZATION RESET
254
+ --- ------------------- ---- -------------------- ------
255
+ WRN Antigravity Flash 80% ████████████████░░░░ 23m
256
+ OK Codex Usage 0% ░░░░░░░░░░░░░░░░░░░░ 13h 4m
257
+ ```
258
+
259
+ > **Note**: In "available" mode, the percentage shows remaining capacity, and status thresholds are inverted.
260
+
261
+ ### Hide Table Header
262
+
263
+ ```json
264
+ {
265
+ "table": {
266
+ "header": false
267
+ }
268
+ }
269
+ ```
270
+
271
+ ```text
272
+ OK Antigravity Flash 20% ████░░░░░░░░░░░░░░░░ 23m 5h 52m
273
+ OK Antigravity Premium 40% ████████░░░░░░░░░░░░ 51m 1h 2m
274
+ ERR Codex Usage 100% ████████████████████ 13h 4m -
275
+ ```
276
+
277
+ ### Disable Colors
278
+
279
+ For plain text output (logging, CI, or non-TTY environments):
280
+
281
+ ```json
282
+ {
283
+ "progressBar": {
284
+ "color": false
285
+ }
286
+ }
287
+ ```
288
+
289
+ ### Custom Color Thresholds
290
+
291
+ Define when colors change based on usage percentage:
292
+
293
+ ```json
294
+ {
295
+ "progressBar": {
296
+ "color": true,
297
+ "gradients": [
298
+ { "threshold": 0.5, "color": "green" },
299
+ { "threshold": 0.8, "color": "yellow" },
300
+ { "threshold": 1.0, "color": "red" }
301
+ ]
302
+ }
303
+ }
304
+ ```
305
+
306
+ Available colors: `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `gray`
307
+
308
+ ## Full Configuration Reference
309
+
310
+ See [schemas/quotas.schema.json](schemas/quotas.schema.json) for the complete JSON Schema.
311
+
312
+ | Option | Type | Default | Description |
313
+ | :--- | :--- | :--- | :--- |
314
+ | `footer` | boolean | `true` | Show quotas in chat footer |
315
+ | `filterByCurrentModel` | boolean | `true` | Filter quotas by active model |
316
+ | `modelMapping` | object | (see defaults) | Explicit model-to-quota mappings |
317
+ | `disabled` | string[] | `[]` | Quota IDs to hide |
318
+ | `progressBar.color` | boolean | `true` | Enable ANSI colors |
319
+ | `progressBar.width` | number | `20` | Progress bar character width |
320
+ | `progressBar.show` | string | `"used"` | `"used"` or `"available"` |
321
+ | `table.columns` | string[] | (auto) | Columns to display |
322
+ | `table.header` | boolean | `true` | Show column headers |
323
+ | `aggregatedGroups` | array | (see defaults) | Quota aggregation with patterns or sources |
324
+ | `pollingInterval` | number | `60000` | Refresh interval in ms |
325
+ | `debug` | boolean | `false` | Enable debug logging |
326
+
327
+ ## Security
328
+
329
+ Your credentials remain safe. This plugin uses standard local OAuth flows and stores tokens securely on your machine (`~/.config/opencode/`). No data is sent to third-party servers other than the quota providers themselves.
330
+
331
+ ## Development
332
+
333
+ Built with **Bun** for speed.
334
+
335
+ ```bash
336
+ bun install # Install dependencies
337
+ bun test # Run tests
338
+ npm run build # Build for production
339
+ bun run opencode-quotas # Run CLI in dev mode
340
+ ```
341
+
342
+ ## License
343
+
344
+ MIT
@@ -0,0 +1,3 @@
1
+ import { QuotaHubPlugin } from "./src/index";
2
+ export default QuotaHubPlugin;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,eAAe,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { QuotaHubPlugin } from "./src/index";
2
+ export default QuotaHubPlugin;
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,eAAe,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bun
2
+ import { QuotaService } from "./services/quota-service";
3
+ import { HistoryService } from "./services/history-service";
4
+ import { renderQuotaTable } from "./ui/quota-table";
5
+ async function main() {
6
+ if (process.argv.includes("--no-color")) {
7
+ process.env.OPENCODE_QUOTAS_NO_COLOR = "1";
8
+ }
9
+ const historyService = new HistoryService();
10
+ await historyService.init();
11
+ const quotaService = new QuotaService();
12
+ await quotaService.init(process.cwd(), historyService);
13
+ const config = quotaService.getConfig();
14
+ // Parse arguments for provider and model filtering
15
+ let providerId;
16
+ let modelId;
17
+ const providerIdx = process.argv.indexOf("--provider");
18
+ if (providerIdx !== -1 && providerIdx + 1 < process.argv.length) {
19
+ providerId = process.argv[providerIdx + 1];
20
+ }
21
+ const modelIdx = process.argv.indexOf("--model");
22
+ if (modelIdx !== -1 && modelIdx + 1 < process.argv.length) {
23
+ modelId = process.argv[modelIdx + 1];
24
+ }
25
+ const filteredResults = await quotaService.getQuotas({ providerId, modelId });
26
+ if (filteredResults.length === 0) {
27
+ console.log("No active quotas found.");
28
+ return;
29
+ }
30
+ console.log(""); // Empty line
31
+ console.log("📊 OpenCode Quotas");
32
+ console.log("------------------");
33
+ renderQuotaTable(filteredResults, {
34
+ progressBarConfig: config.progressBar,
35
+ tableConfig: config.table,
36
+ }).forEach((row) => {
37
+ console.log(row.line);
38
+ });
39
+ console.log(""); // Empty line
40
+ }
41
+ main().catch(console.error);
42
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,KAAK,UAAU,IAAI;IACf,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,GAAG,CAAC;IAC/C,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;IAC5C,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;IAE5B,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACxC,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC;IAExC,mDAAmD;IACnD,IAAI,UAA8B,CAAC;IACnC,IAAI,OAA2B,CAAC;IAEhC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACvD,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9D,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACxD,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAE9E,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;IAC9B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAElC,gBAAgB,CAAC,eAAe,EAAE;QAC9B,iBAAiB,EAAE,MAAM,CAAC,WAAW;QACrC,WAAW,EAAE,MAAM,CAAC,KAAK;KAC5B,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const PLUGIN_FOOTER_SIGNATURE = "_Opencode Quotas";
2
+ export declare const REASONING_PATTERNS: RegExp[];
3
+ export declare const DEBUG_LOG_FILENAME = "quotas-debug.log";
4
+ export declare const SKIP_REASONS: {
5
+ REASONING: string;
6
+ SUBAGENT: string;
7
+ FOOTER_PRESENT: string;
8
+ };
9
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAG1D,eAAO,MAAM,kBAAkB,UAI9B,CAAC;AAGF,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAErD,eAAO,MAAM,YAAY;;;;CAIxB,CAAC"}
@@ -0,0 +1,15 @@
1
+ export const PLUGIN_FOOTER_SIGNATURE = "_Opencode Quotas";
2
+ // Heuristic patterns for detecting reasoning/thinking blocks
3
+ export const REASONING_PATTERNS = [
4
+ /^<thinking>/i,
5
+ /^<antThinking>/i,
6
+ /^(Thinking|Reasoning|Analysis):\s*(\n|$)/i
7
+ ];
8
+ // File paths
9
+ export const DEBUG_LOG_FILENAME = "quotas-debug.log";
10
+ export const SKIP_REASONS = {
11
+ REASONING: "skip:reasoning",
12
+ SUBAGENT: "skip:subagent",
13
+ FOOTER_PRESENT: "skip:footer_present",
14
+ };
15
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,kBAAkB,CAAC;AAE1D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAC9B,cAAc;IACd,iBAAiB;IACjB,2CAA2C;CAC9C,CAAC;AAEF,aAAa;AACb,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAErD,MAAM,CAAC,MAAM,YAAY,GAAG;IACxB,SAAS,EAAE,gBAAgB;IAC3B,QAAQ,EAAE,eAAe;IACzB,cAAc,EAAE,qBAAqB;CACxC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type QuotaConfig } from "./interfaces";
2
+ export declare const DEFAULT_CONFIG: QuotaConfig;
3
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,eAAO,MAAM,cAAc,EAAE,WAiD5B,CAAC"}
@@ -0,0 +1,52 @@
1
+ // Default configuration for quota rendering and grouping
2
+ export const DEFAULT_CONFIG = {
3
+ displayMode: "simple",
4
+ footer: true,
5
+ showFooterTitle: true,
6
+ debug: false,
7
+ progressBar: {
8
+ color: false,
9
+ gradients: [
10
+ { threshold: 0.5, color: "green" },
11
+ { threshold: 0.8, color: "yellow" },
12
+ { threshold: 1.0, color: "red" },
13
+ ],
14
+ },
15
+ table: {
16
+ header: true,
17
+ },
18
+ filterByCurrentModel: false,
19
+ showUnaggregated: false,
20
+ aggregatedGroups: [
21
+ {
22
+ id: "ag-flash",
23
+ name: "Antigravity Flash",
24
+ patterns: ["flash"],
25
+ providerId: "antigravity",
26
+ strategy: "most_critical",
27
+ },
28
+ {
29
+ id: "ag-pro",
30
+ name: "Antigravity Pro",
31
+ patterns: ["pro", "gemini"],
32
+ providerId: "antigravity",
33
+ strategy: "most_critical",
34
+ },
35
+ {
36
+ id: "ag-premium",
37
+ name: "Antigravity Premium",
38
+ patterns: ["claude", "gpt", "o1"],
39
+ providerId: "antigravity",
40
+ strategy: "most_critical",
41
+ },
42
+ {
43
+ id: "codex-smart",
44
+ name: "Codex Usage",
45
+ sources: ["codex-primary", "codex-secondary"],
46
+ strategy: "most_critical",
47
+ },
48
+ ],
49
+ historyMaxAgeHours: 24,
50
+ pollingInterval: 60_000,
51
+ };
52
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAEA,yDAAyD;AACzD,MAAM,CAAC,MAAM,cAAc,GAAgB;IACvC,WAAW,EAAE,QAAQ;IACrB,MAAM,EAAE,IAAI;IACZ,eAAe,EAAE,IAAI;IACrB,KAAK,EAAE,KAAK;IACZ,WAAW,EAAE;QACT,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE;YACP,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;YAClC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;YACnC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;SACnC;KACJ;IACD,KAAK,EAAE;QACH,MAAM,EAAE,IAAI;KACf;IACD,oBAAoB,EAAE,KAAK;IAC3B,gBAAgB,EAAE,KAAK;IACvB,gBAAgB,EAAE;QACd;YACI,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,eAAe;SAC5B;QACD;YACI,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC;YAC3B,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,eAAe;SAC5B;QACD;YACI,EAAE,EAAE,YAAY;YAChB,IAAI,EAAE,qBAAqB;YAC3B,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC;YACjC,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,eAAe;SAC5B;QACD;YACI,EAAE,EAAE,aAAa;YACjB,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,CAAC,eAAe,EAAE,iBAAiB,CAAC;YAC7C,QAAQ,EAAE,eAAe;SAC5B;KACJ;IACD,kBAAkB,EAAE,EAAE;IACtB,eAAe,EAAE,MAAM;CAC1B,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type Plugin } from "@opencode-ai/plugin";
2
+ /**
3
+ * QuotaHub Plugin for OpenCode.ai
4
+ */
5
+ export declare const QuotaHubPlugin: Plugin;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,qBAAqB,CAAC;AAkC9D;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MA4S5B,CAAC"}