@ereinha/opencode-enhanced-quotas 1.0.1 → 1.0.3

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 (49) hide show
  1. package/dist/cli.d.ts +0 -1
  2. package/dist/cli.js +0 -1
  3. package/dist/constants.d.ts +0 -1
  4. package/dist/constants.js +0 -1
  5. package/dist/defaults.d.ts +0 -1
  6. package/dist/defaults.js +0 -1
  7. package/dist/index.d.ts +5 -1
  8. package/dist/index.js +141 -147
  9. package/dist/interfaces.d.ts +0 -1
  10. package/dist/interfaces.js +0 -1
  11. package/dist/logger.d.ts +0 -1
  12. package/dist/logger.js +0 -1
  13. package/dist/plugin-state.d.ts +0 -1
  14. package/dist/plugin-state.js +0 -1
  15. package/dist/providers/antigravity/auth.d.ts +0 -1
  16. package/dist/providers/antigravity/auth.js +0 -1
  17. package/dist/providers/antigravity/index.d.ts +0 -1
  18. package/dist/providers/antigravity/index.js +0 -1
  19. package/dist/providers/antigravity/provider.d.ts +0 -1
  20. package/dist/providers/antigravity/provider.js +0 -1
  21. package/dist/providers/codex.d.ts +0 -1
  22. package/dist/providers/codex.js +0 -1
  23. package/dist/providers/github.d.ts +0 -1
  24. package/dist/providers/github.js +0 -1
  25. package/dist/quota-cache.d.ts +0 -1
  26. package/dist/quota-cache.js +0 -1
  27. package/dist/registry.d.ts +0 -1
  28. package/dist/registry.js +0 -1
  29. package/dist/services/aggregation-service.d.ts +0 -1
  30. package/dist/services/aggregation-service.js +0 -1
  31. package/dist/services/config-loader.d.ts +0 -1
  32. package/dist/services/config-loader.js +0 -1
  33. package/dist/services/history-service.d.ts +0 -1
  34. package/dist/services/history-service.js +0 -1
  35. package/dist/services/prediction-engine.d.ts +0 -1
  36. package/dist/services/prediction-engine.js +0 -1
  37. package/dist/services/quota-service.d.ts +0 -1
  38. package/dist/services/quota-service.js +0 -1
  39. package/dist/ui/progress-bar.d.ts +0 -1
  40. package/dist/ui/progress-bar.js +0 -1
  41. package/dist/ui/quota-table.d.ts +0 -1
  42. package/dist/ui/quota-table.js +0 -1
  43. package/dist/utils/paths.d.ts +0 -1
  44. package/dist/utils/paths.js +0 -1
  45. package/dist/utils/time.d.ts +0 -1
  46. package/dist/utils/time.js +0 -1
  47. package/dist/utils/validation.d.ts +0 -1
  48. package/dist/utils/validation.js +0 -1
  49. package/package.json +1 -1
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env bun
2
2
  export {};
3
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js CHANGED
@@ -39,4 +39,3 @@ async function main() {
39
39
  console.log(""); // Empty line
40
40
  }
41
41
  main().catch(console.error);
42
- //# sourceMappingURL=cli.js.map
@@ -10,4 +10,3 @@ export declare const SKIP_REASONS: {
10
10
  STOPPED: string;
11
11
  NOT_COMPLETE: string;
12
12
  };
13
- //# sourceMappingURL=constants.d.ts.map
package/dist/constants.js CHANGED
@@ -16,4 +16,3 @@ export const SKIP_REASONS = {
16
16
  STOPPED: "skip:stopped",
17
17
  NOT_COMPLETE: "skip:not_complete",
18
18
  };
19
- //# sourceMappingURL=constants.js.map
@@ -1,3 +1,2 @@
1
1
  import { type QuotaConfig } from "./interfaces";
2
2
  export declare const DEFAULT_CONFIG: QuotaConfig;
3
- //# sourceMappingURL=defaults.d.ts.map
package/dist/defaults.js CHANGED
@@ -53,4 +53,3 @@ export const DEFAULT_CONFIG = {
53
53
  historyResetThreshold: 20,
54
54
  pollingInterval: 60_000,
55
55
  };
56
- //# sourceMappingURL=defaults.js.map
package/dist/index.d.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import { type Plugin } from "@opencode-ai/plugin";
2
2
  /**
3
3
  * QuotaHub Plugin for OpenCode.ai
4
+ *
5
+ * Provides:
6
+ * - /usage command: deterministic local quota display (no AI)
7
+ * - /mymodels command: deterministic local model availability display (no AI)
8
+ * - Footer injection on assistant messages showing quota status
4
9
  */
5
10
  export declare const QuotaHubPlugin: Plugin;
6
11
  export default QuotaHubPlugin;
7
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import { tool } from "@opencode-ai/plugin";
2
1
  import { QuotaService } from "./services/quota-service";
3
2
  import { HistoryService } from "./services/history-service";
4
3
  import { renderQuotaTable } from "./ui/quota-table";
@@ -6,9 +5,13 @@ import { QuotaCache } from "./quota-cache";
6
5
  import { PLUGIN_FOOTER_SIGNATURE, SKIP_REASONS, } from "./constants";
7
6
  import { logger } from "./logger";
8
7
  import { getPluginState } from "./plugin-state";
9
- const z = tool.schema;
10
8
  /**
11
9
  * QuotaHub Plugin for OpenCode.ai
10
+ *
11
+ * Provides:
12
+ * - /usage command: deterministic local quota display (no AI)
13
+ * - /mymodels command: deterministic local model availability display (no AI)
14
+ * - Footer injection on assistant messages showing quota status
12
15
  */
13
16
  export const QuotaHubPlugin = async ({ client, $, directory, serverUrl, }) => {
14
17
  const state = getPluginState();
@@ -60,7 +63,6 @@ export const QuotaHubPlugin = async ({ client, $, directory, serverUrl, }) => {
60
63
  attempt,
61
64
  error: errorMsg,
62
65
  });
63
- // Log a user-visible warning
64
66
  console.warn(`[QuotaHub] Failed to initialize after ${MAX_INIT_RETRIES} attempts. Quota information will be unavailable. Error: ${errorMsg}`);
65
67
  }
66
68
  }
@@ -126,159 +128,153 @@ export const QuotaHubPlugin = async ({ client, $, directory, serverUrl, }) => {
126
128
  lineCount: lines.length,
127
129
  };
128
130
  };
131
+ // ─── Hooks ────────────────────────────────────────────────────────────
129
132
  const hooks = {
130
133
  /**
131
- * Tool definitions for slash commands
134
+ * Intercept /usage and /mymodels commands to execute them deterministically
135
+ * without any AI involvement. Reads from the quota cache directly.
136
+ *
137
+ * By setting output.parts, we replace whatever would normally be sent to the
138
+ * AI with our own pre-computed text. The AI never sees these commands.
132
139
  */
133
- tool: {
134
- /**
135
- * /usage - Display comprehensive quota usage information
136
- * Similar to Claude Code's usage display
137
- */
138
- usage: tool({
139
- description: "Display comprehensive quota usage information for all configured providers. Shows current usage, limits, reset times, and status for each quota.",
140
- args: {
141
- provider: z.string().optional().describe("Filter by specific provider ID (e.g., 'claude', 'openrouter', 'cursor')"),
142
- format: z.enum(["table", "json", "compact"]).optional().describe("Output format: table (default), json, or compact"),
143
- },
144
- async execute(args, context) {
145
- // Ensure initialization is complete
146
- await ensureInit().catch((e) => {
147
- logger.error("usage:init_error", { error: e });
148
- });
149
- if (!quotaCache) {
150
- return "Quota service is not initialized. Please wait a moment and try again.";
151
- }
152
- const snapshot = quotaCache.getSnapshot();
153
- const rawResults = snapshot.data;
154
- if (rawResults.length === 0) {
155
- return "No quota data available. This could mean:\n- No quota providers are configured\n- Providers haven't been initialized yet\n- There was an error fetching quota data";
156
- }
157
- // Helper to calculate percentage
158
- const calcPercent = (q) => q.limit ? (q.used / q.limit) * 100 : 0;
159
- // Filter by provider if specified
160
- let filteredResults = rawResults;
161
- if (args.provider) {
162
- filteredResults = rawResults.filter(q => q.providerName?.toLowerCase().includes(args.provider.toLowerCase()) ||
163
- q.id?.toLowerCase().includes(args.provider.toLowerCase()));
164
- if (filteredResults.length === 0) {
165
- return `No quotas found for provider: ${args.provider}\n\nAvailable providers: ${[...new Set(rawResults.map(q => q.providerName || 'unknown'))].join(', ')}`;
166
- }
167
- }
140
+ "command.execute.before": async (input, output) => {
141
+ const command = input.command;
142
+ const args = input.arguments;
143
+ // Only handle our custom commands
144
+ if (command !== "usage" && command !== "mymodels") {
145
+ return;
146
+ }
147
+ await ensureInit().catch(() => { });
148
+ const snapshot = quotaCache?.getSnapshot();
149
+ const quotas = snapshot?.data || [];
150
+ // ── /usage ────────────────────────────────────────────────
151
+ if (command === "usage") {
152
+ if (quotas.length === 0) {
153
+ output.parts = [{
154
+ type: "text",
155
+ text: "No quota data available. Quota providers may not be configured or initialized yet.",
156
+ }];
157
+ return;
158
+ }
159
+ // Parse arguments: format=table|json|compact provider=<name>
160
+ const argParts = args.split(" ").filter(Boolean);
161
+ const formatArg = argParts.find((a) => a.startsWith("format="));
162
+ const providerArg = argParts.find((a) => a.startsWith("provider="));
163
+ const format = formatArg?.split("=")[1] || "table";
164
+ const providerFilter = providerArg?.split("=")[1];
165
+ let filtered = quotas;
166
+ if (providerFilter) {
167
+ filtered = quotas.filter((q) => q.providerName.toLowerCase().includes(providerFilter.toLowerCase()));
168
+ }
169
+ let result = "";
170
+ if (format === "json") {
171
+ result = JSON.stringify(filtered.map((q) => ({
172
+ id: q.id,
173
+ provider: q.providerName,
174
+ used: q.used,
175
+ limit: q.limit,
176
+ percentUsed: q.limit ? Math.round((q.used / q.limit) * 100) : 0,
177
+ reset: q.reset || q.predictedReset || null,
178
+ unit: q.unit,
179
+ })), null, 2);
180
+ }
181
+ else if (format === "compact") {
182
+ result = filtered
183
+ .map((q) => {
184
+ const pct = q.limit ? Math.round((q.used / q.limit) * 100) : 0;
185
+ return `${q.providerName}: ${q.used}/${q.limit || "unlimited"} (${pct}%)`;
186
+ })
187
+ .join(" | ");
188
+ }
189
+ else {
190
+ // Default: table format using the existing renderQuotaTable
168
191
  const config = quotaService.getConfig();
169
- const format = args.format || "table";
170
- if (format === "json") {
171
- return JSON.stringify(filteredResults.map(q => ({
172
- id: q.id,
173
- provider: q.providerName,
174
- used: q.used,
175
- limit: q.limit,
176
- remaining: q.limit ? q.limit - q.used : null,
177
- percentUsed: calcPercent(q),
178
- reset: q.reset,
179
- unit: q.unit,
180
- })), null, 2);
181
- }
182
- if (format === "compact") {
183
- return filteredResults.map(q => {
184
- const pct = calcPercent(q);
185
- const status = pct >= 90 ? "[!]" : pct >= 70 ? "[~]" : "[OK]";
186
- return `${status} ${q.id}: ${pct.toFixed(0)}% used`;
187
- }).join("\n");
188
- }
189
- // Default: table format
190
- const lines = renderQuotaTable(filteredResults, {
192
+ const lines = renderQuotaTable(filtered, {
191
193
  progressBarConfig: config.progressBar,
192
194
  tableConfig: config.table,
193
195
  }).map((l) => l.line);
194
196
  const showMode = config.progressBar?.show ?? "used";
195
197
  const modeLabel = showMode === "available" ? "(Remaining)" : "(Used)";
196
- const header = `Quota Usage ${modeLabel}\n${"─".repeat(60)}\n`;
197
- const footer = `\n${"─".repeat(60)}\nLast updated: ${snapshot.fetchedAt?.toLocaleTimeString() || 'Unknown'}`;
198
- return header + lines.join("\n") + footer;
199
- },
200
- }),
201
- /**
202
- * /mymodels - Display available models filtered by quota status
203
- */
204
- mymodels: tool({
205
- description: "Display available models filtered by current quota status. Shows which models are available, rate-limited, or exhausted based on real-time quota data.",
206
- args: {
207
- status: z.enum(["available", "limited", "exhausted", "all"]).optional().describe("Filter by availability status (default: all)"),
208
- provider: z.string().optional().describe("Filter by provider ID"),
209
- },
210
- async execute(args, context) {
211
- // Ensure initialization is complete
212
- await ensureInit().catch((e) => {
213
- logger.error("mymodels:init_error", { error: e });
214
- });
215
- if (!quotaCache) {
216
- return "Quota service is not initialized. Please wait a moment and try again.";
217
- }
218
- const snapshot = quotaCache.getSnapshot();
219
- const rawResults = snapshot.data;
220
- if (rawResults.length === 0) {
221
- return "No quota data available to determine model availability.";
222
- }
223
- // Helper to calculate percentage
224
- const calcPercent = (q) => q.limit ? (q.used / q.limit) * 100 : 0;
225
- // Categorize quotas by status
226
- const available = [];
227
- const limited = [];
228
- const exhausted = [];
229
- for (const quota of rawResults) {
230
- // Filter by provider if specified
231
- if (args.provider && !quota.providerName?.toLowerCase().includes(args.provider.toLowerCase())) {
232
- continue;
233
- }
234
- const pct = calcPercent(quota);
235
- if (pct >= 100) {
236
- exhausted.push(quota);
237
- }
238
- else if (pct >= 80) {
239
- limited.push(quota);
240
- }
241
- else {
242
- available.push(quota);
243
- }
244
- }
245
- const statusFilter = args.status || "all";
246
- let output = [];
247
- const formatQuota = (q, marker) => {
248
- const pct = calcPercent(q);
249
- const reset = q.reset ? ` (resets: ${q.reset})` : "";
250
- return `${marker} ${q.id}: ${pct.toFixed(0)}% used${reset}`;
251
- };
252
- if (statusFilter === "all" || statusFilter === "available") {
253
- if (available.length > 0) {
254
- output.push("[OK] Available Models:");
255
- output.push(...available.map(q => formatQuota(q, " +")));
256
- output.push("");
198
+ const header = `_Opencode Quotas ${modeLabel}_`;
199
+ const updatedAt = snapshot?.fetchedAt
200
+ ? `Last updated: ${snapshot.fetchedAt.toLocaleTimeString()}`
201
+ : "";
202
+ result = [header, ...lines, updatedAt].filter(Boolean).join("\n");
203
+ }
204
+ output.parts = [{ type: "text", text: result }];
205
+ return;
206
+ }
207
+ // ── /mymodels ─────────────────────────────────────────────
208
+ if (command === "mymodels") {
209
+ if (quotas.length === 0) {
210
+ output.parts = [{
211
+ type: "text",
212
+ text: "No quota data available to determine model availability.",
213
+ }];
214
+ return;
215
+ }
216
+ // Parse arguments: status=all|available|limited|exhausted provider=<name>
217
+ const argParts = args.split(" ").filter(Boolean);
218
+ const statusArg = argParts.find((a) => a.startsWith("status="));
219
+ const providerArg = argParts.find((a) => a.startsWith("provider="));
220
+ const statusFilter = statusArg?.split("=")[1] || "all";
221
+ const providerFilter = providerArg?.split("=")[1];
222
+ let filtered = quotas;
223
+ if (providerFilter) {
224
+ filtered = quotas.filter((q) => q.providerName.toLowerCase().includes(providerFilter.toLowerCase()));
225
+ }
226
+ const available = [];
227
+ const limited = [];
228
+ const exhausted = [];
229
+ for (const q of filtered) {
230
+ const pct = q.limit ? (q.used / q.limit) * 100 : 0;
231
+ if (pct >= 100)
232
+ exhausted.push(q);
233
+ else if (pct >= 80)
234
+ limited.push(q);
235
+ else
236
+ available.push(q);
237
+ }
238
+ const lines = ["Model Availability by Quota Status:"];
239
+ if (statusFilter === "all" || statusFilter === "available") {
240
+ if (available.length > 0) {
241
+ lines.push("\n[OK] Available:");
242
+ for (const q of available) {
243
+ const pct = q.limit ? Math.round((q.used / q.limit) * 100) : 0;
244
+ const reset = q.reset ? ` (resets: ${q.reset})` : "";
245
+ lines.push(` + ${q.providerName} - ${q.id}: ${pct}% used${reset}`);
257
246
  }
258
247
  }
259
- if (statusFilter === "all" || statusFilter === "limited") {
260
- if (limited.length > 0) {
261
- output.push("[~] Rate-Limited (use with caution):");
262
- output.push(...limited.map(q => formatQuota(q, " ~")));
263
- output.push("");
248
+ }
249
+ if (statusFilter === "all" || statusFilter === "limited") {
250
+ if (limited.length > 0) {
251
+ lines.push("\n[~] Limited (approaching limit):");
252
+ for (const q of limited) {
253
+ const pct = q.limit ? Math.round((q.used / q.limit) * 100) : 0;
254
+ const reset = q.reset ? ` (resets: ${q.reset})` : "";
255
+ lines.push(` ~ ${q.providerName} - ${q.id}: ${pct}% used${reset}`);
264
256
  }
265
257
  }
266
- if (statusFilter === "all" || statusFilter === "exhausted") {
267
- if (exhausted.length > 0) {
268
- output.push("[!] Exhausted (unavailable):");
269
- output.push(...exhausted.map(q => formatQuota(q, " x")));
270
- output.push("");
258
+ }
259
+ if (statusFilter === "all" || statusFilter === "exhausted") {
260
+ if (exhausted.length > 0) {
261
+ lines.push("\n[!] Exhausted (unavailable):");
262
+ for (const q of exhausted) {
263
+ const reset = q.reset ? ` (resets: ${q.reset})` : "";
264
+ lines.push(` x ${q.providerName} - ${q.id}: 100%+ used${reset}`);
271
265
  }
272
266
  }
273
- if (output.length === 0) {
274
- return `No models found with status: ${statusFilter}`;
275
- }
276
- // Add summary
277
- output.push("-".repeat(40));
278
- output.push(`Summary: ${available.length} available, ${limited.length} limited, ${exhausted.length} exhausted`);
279
- return output.join("\n");
280
- },
281
- }),
267
+ }
268
+ if (lines.length === 1) {
269
+ lines.push(`\nNo models found with status: ${statusFilter}`);
270
+ }
271
+ else {
272
+ lines.push(`\n${"-".repeat(40)}`);
273
+ lines.push(`Summary: ${available.length} available, ${limited.length} limited, ${exhausted.length} exhausted`);
274
+ }
275
+ output.parts = [{ type: "text", text: lines.join("\n") }];
276
+ return;
277
+ }
282
278
  },
283
279
  /**
284
280
  * The platform calls this hook after a text generation is complete.
@@ -387,7 +383,7 @@ export const QuotaHubPlugin = async ({ client, $, directory, serverUrl, }) => {
387
383
  partID: input.partID,
388
384
  partType: currentPart?.type,
389
385
  isLastPart,
390
- totalParts: parts.length
386
+ totalParts: parts.length,
391
387
  });
392
388
  const isSubagentMessage = assistantMsg.mode === "subagent";
393
389
  const isReasoningPart = currentPart?.type === "reasoning";
@@ -398,18 +394,17 @@ export const QuotaHubPlugin = async ({ client, $, directory, serverUrl, }) => {
398
394
  debugLog(SKIP_REASONS.THINKING, {
399
395
  messageID: input.messageID,
400
396
  partID: input.partID,
401
- type: currentPart?.type
397
+ type: currentPart?.type,
402
398
  });
403
399
  return;
404
400
  }
405
401
  // Only inject on the last part of the message to avoid double injection
406
- // and to ensure we are at the very end.
407
402
  if (!isLastPart) {
408
403
  debugLog("skip:not_last_part", {
409
404
  messageID: input.messageID,
410
405
  partID: input.partID,
411
406
  index: currentPartIndex,
412
- total: parts.length
407
+ total: parts.length,
413
408
  });
414
409
  return;
415
410
  }
@@ -418,7 +413,7 @@ export const QuotaHubPlugin = async ({ client, $, directory, serverUrl, }) => {
418
413
  debugLog("skip:not_text_part", {
419
414
  messageID: input.messageID,
420
415
  partID: input.partID,
421
- type: currentPart?.type
416
+ type: currentPart?.type,
422
417
  });
423
418
  state.markProcessed(input.messageID);
424
419
  return;
@@ -446,4 +441,3 @@ export const QuotaHubPlugin = async ({ client, $, directory, serverUrl, }) => {
446
441
  return hooks;
447
442
  };
448
443
  export default QuotaHubPlugin;
449
- //# sourceMappingURL=index.js.map
@@ -207,4 +207,3 @@ export interface ProgressBarConfig {
207
207
  color?: boolean;
208
208
  gradients?: GradientLevel[];
209
209
  }
210
- //# sourceMappingURL=interfaces.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=interfaces.js.map
package/dist/logger.d.ts CHANGED
@@ -12,4 +12,3 @@ export declare class Logger {
12
12
  private log;
13
13
  }
14
14
  export declare const logger: Logger;
15
- //# sourceMappingURL=logger.d.ts.map
package/dist/logger.js CHANGED
@@ -44,4 +44,3 @@ export class Logger {
44
44
  }
45
45
  }
46
46
  export const logger = Logger.getInstance();
47
- //# sourceMappingURL=logger.js.map
@@ -29,4 +29,3 @@ export declare class PluginState {
29
29
  */
30
30
  export declare function getPluginState(): PluginState;
31
31
  export {};
32
- //# sourceMappingURL=plugin-state.d.ts.map
@@ -78,4 +78,3 @@ export function getPluginState() {
78
78
  }
79
79
  return globalRef[PLUGIN_STATE_KEY];
80
80
  }
81
- //# sourceMappingURL=plugin-state.js.map
@@ -9,4 +9,3 @@ export declare function getCloudCredentials(): Promise<CloudAuthCredentials>;
9
9
  * Reset the credential cache. Internal use only (primarily for tests).
10
10
  */
11
11
  export declare function resetCredentialCache(): void;
12
- //# sourceMappingURL=auth.d.ts.map
@@ -106,4 +106,3 @@ export async function getCloudCredentials() {
106
106
  export function resetCredentialCache() {
107
107
  cachedCredential = null;
108
108
  }
109
- //# sourceMappingURL=auth.js.map
@@ -1,2 +1 @@
1
1
  export * from "./provider";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1 @@
1
1
  export * from "./provider";
2
- //# sourceMappingURL=index.js.map
@@ -31,4 +31,3 @@ export declare function fetchCloudQuota(accessToken: string, projectId?: string,
31
31
  * Grouping and aggregation is handled by the service layer via AggregatedGroups.
32
32
  */
33
33
  export declare function createAntigravityProvider(config?: AntigravityConfig): IQuotaProvider;
34
- //# sourceMappingURL=provider.d.ts.map
@@ -218,4 +218,3 @@ export function createAntigravityProvider(config = {}) {
218
218
  },
219
219
  };
220
220
  }
221
- //# sourceMappingURL=provider.js.map
@@ -1,4 +1,3 @@
1
1
  import { type IQuotaProvider, type QuotaData } from "../interfaces";
2
2
  export declare function extractCodexQuota(payload: unknown): QuotaData[];
3
3
  export declare function createCodexProvider(): IQuotaProvider;
4
- //# sourceMappingURL=codex.d.ts.map
@@ -230,4 +230,3 @@ export function createCodexProvider() {
230
230
  },
231
231
  };
232
232
  }
233
- //# sourceMappingURL=codex.js.map
@@ -1,4 +1,3 @@
1
1
  import { type IQuotaProvider, type QuotaData } from "../interfaces";
2
2
  export declare function parseGithubUsage(data: unknown, sku: string | null, apiWarning?: string | null): QuotaData[];
3
3
  export declare function createGithubProvider(): IQuotaProvider;
4
- //# sourceMappingURL=github.d.ts.map
@@ -136,4 +136,3 @@ export function createGithubProvider() {
136
136
  },
137
137
  };
138
138
  }
139
- //# sourceMappingURL=github.js.map
@@ -23,4 +23,3 @@ export declare class QuotaCache {
23
23
  private doRefresh;
24
24
  }
25
25
  export {};
26
- //# sourceMappingURL=quota-cache.d.ts.map
@@ -104,4 +104,3 @@ export class QuotaCache {
104
104
  }
105
105
  }
106
106
  }
107
- //# sourceMappingURL=quota-cache.js.map
@@ -1,3 +1,2 @@
1
1
  import { type IQuotaRegistry } from "./interfaces";
2
2
  export declare function getQuotaRegistry(): IQuotaRegistry;
3
- //# sourceMappingURL=registry.d.ts.map
package/dist/registry.js CHANGED
@@ -20,4 +20,3 @@ export function getQuotaRegistry() {
20
20
  }
21
21
  return globalRef[REGISTRY_KEY];
22
22
  }
23
- //# sourceMappingURL=registry.js.map
@@ -31,4 +31,3 @@ export declare class AggregationService implements IAggregationService {
31
31
  */
32
32
  aggregateAverage(quotas: QuotaData[], name: string, id: string, strategy: "mean" | "median"): QuotaData;
33
33
  }
34
- //# sourceMappingURL=aggregation-service.d.ts.map
@@ -86,4 +86,3 @@ export class AggregationService {
86
86
  };
87
87
  }
88
88
  }
89
- //# sourceMappingURL=aggregation-service.js.map
@@ -29,4 +29,3 @@ export declare class ConfigLoader {
29
29
  */
30
30
  private static validateConfig;
31
31
  }
32
- //# sourceMappingURL=config-loader.d.ts.map
@@ -165,4 +165,3 @@ export class ConfigLoader {
165
165
  }
166
166
  }
167
167
  }
168
- //# sourceMappingURL=config-loader.js.map
@@ -36,4 +36,3 @@ export declare class HistoryService implements IHistoryService {
36
36
  */
37
37
  private flushSave;
38
38
  }
39
- //# sourceMappingURL=history-service.d.ts.map
@@ -204,4 +204,3 @@ export class HistoryService {
204
204
  }
205
205
  }
206
206
  }
207
- //# sourceMappingURL=history-service.js.map
@@ -48,4 +48,3 @@ export declare class NullPredictionEngine implements IPredictionEngine {
48
48
  windowInfo?: string;
49
49
  }): number;
50
50
  }
51
- //# sourceMappingURL=prediction-engine.d.ts.map
@@ -105,4 +105,3 @@ export class NullPredictionEngine {
105
105
  return Infinity;
106
106
  }
107
107
  }
108
- //# sourceMappingURL=prediction-engine.js.map
@@ -39,4 +39,3 @@ export declare class QuotaService {
39
39
  private filterByModel;
40
40
  private sortQuotas;
41
41
  }
42
- //# sourceMappingURL=quota-service.d.ts.map
@@ -336,4 +336,3 @@ export class QuotaService {
336
336
  return quotas.sort((a, b) => a.providerName.localeCompare(b.providerName));
337
337
  }
338
338
  }
339
- //# sourceMappingURL=quota-service.js.map
@@ -17,4 +17,3 @@ export declare function renderQuotaBarParts(used: number, limit: number, options
17
17
  details?: string;
18
18
  config?: ProgressBarConfig;
19
19
  }): RenderQuotaBarParts;
20
- //# sourceMappingURL=progress-bar.d.ts.map
@@ -147,4 +147,3 @@ export function renderQuotaBarParts(used, limit, options) {
147
147
  statusText,
148
148
  };
149
149
  }
150
- //# sourceMappingURL=progress-bar.js.map
@@ -12,4 +12,3 @@ export declare function renderQuotaTable(quotas: QuotaData[], options: {
12
12
  };
13
13
  }): RenderedQuotaLine[];
14
14
  export {};
15
- //# sourceMappingURL=quota-table.d.ts.map
@@ -134,4 +134,3 @@ export function renderQuotaTable(quotas, options) {
134
134
  });
135
135
  return outputRows;
136
136
  }
137
- //# sourceMappingURL=quota-table.js.map
@@ -4,4 +4,3 @@ export declare const AUTH_FILE: () => string;
4
4
  export declare const HISTORY_FILE: () => string;
5
5
  export declare const DEBUG_LOG_FILE: () => string;
6
6
  export declare const ANTIGRAVITY_ACCOUNTS_FILE: () => string;
7
- //# sourceMappingURL=paths.d.ts.map
@@ -34,4 +34,3 @@ export const AUTH_FILE = () => join(getDataDirectory(), "auth.json");
34
34
  export const HISTORY_FILE = () => join(getDataDirectory(), "quota-history.json");
35
35
  export const DEBUG_LOG_FILE = () => join(getDataDirectory(), "quotas-debug.log");
36
36
  export const ANTIGRAVITY_ACCOUNTS_FILE = () => join(getConfigDirectory(), "antigravity-accounts.json");
37
- //# sourceMappingURL=paths.js.map
@@ -1,3 +1,2 @@
1
1
  export declare function formatRelativeTime(targetDate: Date): string;
2
2
  export declare function formatDurationMs(ms: number): string;
3
- //# sourceMappingURL=time.d.ts.map
@@ -35,4 +35,3 @@ export function formatDurationMs(ms) {
35
35
  }
36
36
  return "less than 1m";
37
37
  }
38
- //# sourceMappingURL=time.js.map
@@ -3,4 +3,3 @@ export declare function isValidNumber(v: unknown): v is number;
3
3
  export declare function clamp(value: number, min: number, max?: number): number;
4
4
  export declare function validatePollingInterval(v: unknown): number | null;
5
5
  export declare function validateQuotaData(input: unknown): QuotaData | null;
6
- //# sourceMappingURL=validation.d.ts.map
@@ -63,4 +63,3 @@ export function validateQuotaData(input) {
63
63
  details,
64
64
  };
65
65
  }
66
- //# sourceMappingURL=validation.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ereinha/opencode-enhanced-quotas",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {