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.
- package/README.md +344 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +42 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/constants.d.ts +9 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +15 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/defaults.d.ts +3 -0
- package/dist/src/defaults.d.ts.map +1 -0
- package/dist/src/defaults.js +52 -0
- package/dist/src/defaults.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +265 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces.d.ts +197 -0
- package/dist/src/interfaces.d.ts.map +1 -0
- package/dist/src/interfaces.js +2 -0
- package/dist/src/interfaces.js.map +1 -0
- package/dist/src/logger.d.ts +14 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +44 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/plugin-state.d.ts +20 -0
- package/dist/src/plugin-state.d.ts.map +1 -0
- package/dist/src/plugin-state.js +53 -0
- package/dist/src/plugin-state.js.map +1 -0
- package/dist/src/providers/antigravity/auth.d.ts +12 -0
- package/dist/src/providers/antigravity/auth.d.ts.map +1 -0
- package/dist/src/providers/antigravity/auth.js +109 -0
- package/dist/src/providers/antigravity/auth.js.map +1 -0
- package/dist/src/providers/antigravity/index.d.ts +2 -0
- package/dist/src/providers/antigravity/index.d.ts.map +1 -0
- package/dist/src/providers/antigravity/index.js +2 -0
- package/dist/src/providers/antigravity/index.js.map +1 -0
- package/dist/src/providers/antigravity/provider.d.ts +34 -0
- package/dist/src/providers/antigravity/provider.d.ts.map +1 -0
- package/dist/src/providers/antigravity/provider.js +216 -0
- package/dist/src/providers/antigravity/provider.js.map +1 -0
- package/dist/src/providers/codex.d.ts +4 -0
- package/dist/src/providers/codex.d.ts.map +1 -0
- package/dist/src/providers/codex.js +242 -0
- package/dist/src/providers/codex.js.map +1 -0
- package/dist/src/providers/github.d.ts +4 -0
- package/dist/src/providers/github.d.ts.map +1 -0
- package/dist/src/providers/github.js +139 -0
- package/dist/src/providers/github.js.map +1 -0
- package/dist/src/quota-cache.d.ts +26 -0
- package/dist/src/quota-cache.d.ts.map +1 -0
- package/dist/src/quota-cache.js +107 -0
- package/dist/src/quota-cache.js.map +1 -0
- package/dist/src/registry.d.ts +3 -0
- package/dist/src/registry.d.ts.map +1 -0
- package/dist/src/registry.js +23 -0
- package/dist/src/registry.js.map +1 -0
- package/dist/src/services/aggregation-service.d.ts +34 -0
- package/dist/src/services/aggregation-service.d.ts.map +1 -0
- package/dist/src/services/aggregation-service.js +89 -0
- package/dist/src/services/aggregation-service.js.map +1 -0
- package/dist/src/services/config-loader.d.ts +25 -0
- package/dist/src/services/config-loader.d.ts.map +1 -0
- package/dist/src/services/config-loader.js +105 -0
- package/dist/src/services/config-loader.js.map +1 -0
- package/dist/src/services/history-service.d.ts +15 -0
- package/dist/src/services/history-service.d.ts.map +1 -0
- package/dist/src/services/history-service.js +99 -0
- package/dist/src/services/history-service.js.map +1 -0
- package/dist/src/services/prediction-engine.d.ts +47 -0
- package/dist/src/services/prediction-engine.d.ts.map +1 -0
- package/dist/src/services/prediction-engine.js +94 -0
- package/dist/src/services/prediction-engine.js.map +1 -0
- package/dist/src/services/quota-service.d.ts +41 -0
- package/dist/src/services/quota-service.d.ts.map +1 -0
- package/dist/src/services/quota-service.js +257 -0
- package/dist/src/services/quota-service.js.map +1 -0
- package/dist/src/tools/quotas.d.ts +11 -0
- package/dist/src/tools/quotas.d.ts.map +1 -0
- package/dist/src/tools/quotas.js +62 -0
- package/dist/src/tools/quotas.js.map +1 -0
- package/dist/src/ui/progress-bar.d.ts +20 -0
- package/dist/src/ui/progress-bar.d.ts.map +1 -0
- package/dist/src/ui/progress-bar.js +150 -0
- package/dist/src/ui/progress-bar.js.map +1 -0
- package/dist/src/ui/quota-table.d.ts +15 -0
- package/dist/src/ui/quota-table.d.ts.map +1 -0
- package/dist/src/ui/quota-table.js +136 -0
- package/dist/src/ui/quota-table.js.map +1 -0
- package/dist/src/utils/debug.d.ts +1 -0
- package/dist/src/utils/debug.d.ts.map +1 -0
- package/dist/src/utils/debug.js +3 -0
- package/dist/src/utils/debug.js.map +1 -0
- package/dist/src/utils/paths.d.ts +7 -0
- package/dist/src/utils/paths.d.ts.map +1 -0
- package/dist/src/utils/paths.js +37 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/src/utils/time.d.ts +3 -0
- package/dist/src/utils/time.d.ts.map +1 -0
- package/dist/src/utils/time.js +38 -0
- package/dist/src/utils/time.js.map +1 -0
- package/dist/src/utils/validation.d.ts +6 -0
- package/dist/src/utils/validation.d.ts.map +1 -0
- package/dist/src/utils/validation.js +66 -0
- package/dist/src/utils/validation.js.map +1 -0
- package/package.json +42 -0
- package/src/cli.ts +53 -0
- package/src/constants.ts +17 -0
- package/src/defaults.ts +53 -0
- package/src/index.ts +338 -0
- package/src/interfaces.ts +258 -0
- package/src/logger.ts +55 -0
- package/src/plugin-state.ts +65 -0
- package/src/providers/antigravity/auth.ts +163 -0
- package/src/providers/antigravity/index.ts +1 -0
- package/src/providers/antigravity/provider.ts +337 -0
- package/src/providers/codex.ts +327 -0
- package/src/providers/github.ts +161 -0
- package/src/quota-cache.ts +157 -0
- package/src/registry.ts +30 -0
- package/src/services/aggregation-service.ts +116 -0
- package/src/services/config-loader.ts +124 -0
- package/src/services/history-service.ts +116 -0
- package/src/services/prediction-engine.ts +133 -0
- package/src/services/quota-service.ts +343 -0
- package/src/tools/quotas.ts +78 -0
- package/src/ui/progress-bar.ts +204 -0
- package/src/ui/quota-table.ts +173 -0
- package/src/utils/debug.ts +1 -0
- package/src/utils/paths.ts +41 -0
- package/src/utils/time.ts +40 -0
- package/src/utils/validation.ts +63 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import { renderQuotaTable } from "../ui/quota-table";
|
|
3
|
+
import { logger } from "../logger";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a tool definition for fetching and displaying quota information.
|
|
6
|
+
* This tool always performs a fresh fetch of quotas from all providers.
|
|
7
|
+
*
|
|
8
|
+
* @returns A ToolDefinition that can be registered under Hooks.tool
|
|
9
|
+
*/
|
|
10
|
+
export function createQuotaTool(quotaService, getConfig) {
|
|
11
|
+
return tool({
|
|
12
|
+
description: "Fetch and display the current API quota usage across all configured providers (Antigravity, Codex, etc.). " +
|
|
13
|
+
"Always returns fresh, up-to-date quota information. " +
|
|
14
|
+
"Use this tool when you need to check remaining API capacity, quota limits, or usage statistics.",
|
|
15
|
+
args: {
|
|
16
|
+
providerId: tool.schema
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Optional: Filter results to show only quotas from a specific provider (e.g., 'antigravity', 'codex')"),
|
|
20
|
+
modelId: tool.schema
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Optional: Filter results to show only quotas relevant to a specific model"),
|
|
24
|
+
},
|
|
25
|
+
async execute(args) {
|
|
26
|
+
const config = getConfig();
|
|
27
|
+
logger.debug("tool:quotas:execute", {
|
|
28
|
+
providerId: args.providerId,
|
|
29
|
+
modelId: args.modelId,
|
|
30
|
+
});
|
|
31
|
+
try {
|
|
32
|
+
// Always fetch fresh quotas
|
|
33
|
+
const quotas = await quotaService.getQuotas({
|
|
34
|
+
providerId: args.providerId,
|
|
35
|
+
modelId: args.modelId,
|
|
36
|
+
});
|
|
37
|
+
logger.debug("tool:quotas:fetched", {
|
|
38
|
+
count: quotas.length,
|
|
39
|
+
});
|
|
40
|
+
if (quotas.length === 0) {
|
|
41
|
+
return "No quota information available. This could mean:\n" +
|
|
42
|
+
"- No quota providers are configured\n" +
|
|
43
|
+
"- The filter criteria matched no quotas\n" +
|
|
44
|
+
"- There was an error fetching quota data";
|
|
45
|
+
}
|
|
46
|
+
// Render the quota table
|
|
47
|
+
const lines = renderQuotaTable(quotas, {
|
|
48
|
+
progressBarConfig: config.progressBar,
|
|
49
|
+
tableConfig: config.table,
|
|
50
|
+
}).map((l) => l.line);
|
|
51
|
+
const showMode = config.progressBar?.show ?? "used";
|
|
52
|
+
const modeLabel = showMode === "available" ? "(Remaining)" : "(Used)";
|
|
53
|
+
return `**Quota Status ${modeLabel}**\n\n` + lines.join("\n");
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
logger.error("tool:quotas:error", { error });
|
|
57
|
+
return `Error fetching quotas: ${error instanceof Error ? error.message : String(error)}`;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=quotas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quotas.js","sourceRoot":"","sources":["../../../src/tools/quotas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAuB,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC3B,YAA0B,EAC1B,SAA4B;IAE5B,OAAO,IAAI,CAAC;QACR,WAAW,EACP,4GAA4G;YAC5G,sDAAsD;YACtD,iGAAiG;QACrG,IAAI,EAAE;YACF,UAAU,EAAE,IAAI,CAAC,MAAM;iBAClB,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACL,sGAAsG,CACzG;YACL,OAAO,EAAE,IAAI,CAAC,MAAM;iBACf,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACL,2EAA2E,CAC9E;SACR;QACD,KAAK,CAAC,OAAO,CAAC,IAAI;YACd,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAE3B,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE;gBAChC,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;aACxB,CAAC,CAAC;YAEH,IAAI,CAAC;gBACD,4BAA4B;gBAC5B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC;oBACxC,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;iBACxB,CAAC,CAAC;gBAEH,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE;oBAChC,KAAK,EAAE,MAAM,CAAC,MAAM;iBACvB,CAAC,CAAC;gBAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACtB,OAAO,oDAAoD;wBACvD,uCAAuC;wBACvC,2CAA2C;wBAC3C,0CAA0C,CAAC;gBACnD,CAAC;gBAED,yBAAyB;gBACzB,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE;oBACnC,iBAAiB,EAAE,MAAM,CAAC,WAAW;oBACrC,WAAW,EAAE,MAAM,CAAC,KAAK;iBAC5B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,MAAM,CAAC;gBACpD,MAAM,SAAS,GAAG,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAEtE,OAAO,kBAAkB,SAAS,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC7C,OAAO,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9F,CAAC;QACL,CAAC;KACJ,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type AnsiColor, type ProgressBarConfig } from "../interfaces";
|
|
2
|
+
export declare function colorize(text: string, color: AnsiColor | undefined, useColor: boolean): string;
|
|
3
|
+
export type RenderQuotaBarParts = {
|
|
4
|
+
labelPart: string;
|
|
5
|
+
bar: string;
|
|
6
|
+
percent: string;
|
|
7
|
+
valuePart: string;
|
|
8
|
+
detailsPart: string;
|
|
9
|
+
statusEmoji: string;
|
|
10
|
+
statusText: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function getQuotaStatusEmoji(ratio: number, config?: ProgressBarConfig): string;
|
|
13
|
+
export declare function getQuotaStatusText(ratio: number, config?: ProgressBarConfig): string;
|
|
14
|
+
export declare function renderQuotaBarParts(used: number, limit: number, options: {
|
|
15
|
+
label: string;
|
|
16
|
+
unit: string;
|
|
17
|
+
details?: string;
|
|
18
|
+
config?: ProgressBarConfig;
|
|
19
|
+
}): RenderQuotaBarParts;
|
|
20
|
+
//# sourceMappingURL=progress-bar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-bar.d.ts","sourceRoot":"","sources":["../../../src/ui/progress-bar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAsB,MAAM,eAAe,CAAC;AA4C3F,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAI9F;AAaD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,iBAAsB,GAC7B,MAAM,CAgBR;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,iBAAsB,GAC7B,MAAM,CAgBR;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B,GACA,mBAAmB,CAgFrB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { isValidNumber } from "../utils/validation";
|
|
2
|
+
const DEFAULT_BAR_WIDTH = 20;
|
|
3
|
+
const DEFAULT_FILLED_CHAR = "█";
|
|
4
|
+
const DEFAULT_EMPTY_CHAR = "░";
|
|
5
|
+
const DEFAULT_GRADIENTS = [
|
|
6
|
+
{ threshold: 0.5, color: "green" },
|
|
7
|
+
{ threshold: 0.8, color: "yellow" },
|
|
8
|
+
{ threshold: 1.0, color: "red" },
|
|
9
|
+
];
|
|
10
|
+
const ANSI_CODES = {
|
|
11
|
+
red: "\x1b[31m",
|
|
12
|
+
green: "\x1b[32m",
|
|
13
|
+
yellow: "\x1b[33m",
|
|
14
|
+
blue: "\x1b[34m",
|
|
15
|
+
magenta: "\x1b[35m",
|
|
16
|
+
cyan: "\x1b[36m",
|
|
17
|
+
white: "\x1b[37m",
|
|
18
|
+
gray: "\x1b[90m",
|
|
19
|
+
bold: "\x1b[1m",
|
|
20
|
+
dim: "\x1b[2m",
|
|
21
|
+
reset: "\x1b[0m",
|
|
22
|
+
};
|
|
23
|
+
function shouldUseColor(config) {
|
|
24
|
+
// FORCE_COLOR should take precedence when explicitly set
|
|
25
|
+
if (process.env.FORCE_COLOR !== undefined)
|
|
26
|
+
return true;
|
|
27
|
+
// Respect explicit no-color flags
|
|
28
|
+
if (process.env.NO_COLOR !== undefined)
|
|
29
|
+
return false;
|
|
30
|
+
if (process.env.OPENCODE_QUOTAS_NO_COLOR !== undefined)
|
|
31
|
+
return false;
|
|
32
|
+
// Respect explicit config request (useful for tests/environments)
|
|
33
|
+
if (config?.color === true)
|
|
34
|
+
return true;
|
|
35
|
+
// If not a TTY, generally disable color
|
|
36
|
+
if (!process.stdout.isTTY)
|
|
37
|
+
return false;
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
export function colorize(text, color, useColor) {
|
|
41
|
+
if (!useColor)
|
|
42
|
+
return text;
|
|
43
|
+
if (!color || color === "reset")
|
|
44
|
+
return text;
|
|
45
|
+
return `${ANSI_CODES[color]}${text}${ANSI_CODES.reset}`;
|
|
46
|
+
}
|
|
47
|
+
function formatNumber(value) {
|
|
48
|
+
if (!Number.isFinite(value))
|
|
49
|
+
return "0";
|
|
50
|
+
if (Number.isInteger(value)) {
|
|
51
|
+
return `${value}`;
|
|
52
|
+
}
|
|
53
|
+
if (Math.abs(value) >= 100) {
|
|
54
|
+
return value.toFixed(1);
|
|
55
|
+
}
|
|
56
|
+
return value.toFixed(1);
|
|
57
|
+
}
|
|
58
|
+
export function getQuotaStatusEmoji(ratio, config = {}) {
|
|
59
|
+
// Default thresholds if not provided
|
|
60
|
+
const gradients = config.gradients || DEFAULT_GRADIENTS;
|
|
61
|
+
const sorted = [...gradients].sort((a, b) => a.threshold - b.threshold);
|
|
62
|
+
// Find the matching level
|
|
63
|
+
const match = sorted.find((g) => ratio <= g.threshold);
|
|
64
|
+
const color = match ? match.color : sorted[sorted.length - 1]?.color || "red";
|
|
65
|
+
switch (color) {
|
|
66
|
+
case "green": return "🟢";
|
|
67
|
+
case "yellow": return "🟡";
|
|
68
|
+
case "red": return "🔴";
|
|
69
|
+
default: return "⚪"; // Grey/Unknown
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function getQuotaStatusText(ratio, config = {}) {
|
|
73
|
+
// Default thresholds if not provided
|
|
74
|
+
const gradients = config.gradients || DEFAULT_GRADIENTS;
|
|
75
|
+
const sorted = [...gradients].sort((a, b) => a.threshold - b.threshold);
|
|
76
|
+
// Find the matching level
|
|
77
|
+
const match = sorted.find((g) => ratio <= g.threshold);
|
|
78
|
+
const color = match ? match.color : sorted[sorted.length - 1]?.color || "red";
|
|
79
|
+
switch (color) {
|
|
80
|
+
case "green": return "OK "; // Space for alignment
|
|
81
|
+
case "yellow": return "WRN";
|
|
82
|
+
case "red": return "ERR";
|
|
83
|
+
default: return "UNK";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function renderQuotaBarParts(used, limit, options) {
|
|
87
|
+
const config = options.config || {};
|
|
88
|
+
const width = config.width ?? DEFAULT_BAR_WIDTH;
|
|
89
|
+
const filledChar = config.filledChar ?? DEFAULT_FILLED_CHAR;
|
|
90
|
+
const emptyChar = config.emptyChar ?? DEFAULT_EMPTY_CHAR;
|
|
91
|
+
const showMode = config.show ?? "used";
|
|
92
|
+
const useColor = shouldUseColor(config);
|
|
93
|
+
// Defensive guards: normalize inputs
|
|
94
|
+
const usedVal = isValidNumber(used) ? Math.max(0, used) : 0;
|
|
95
|
+
const limitVal = isValidNumber(limit) && limit > 0 ? limit : 0;
|
|
96
|
+
// Calculate value and ratio based on mode
|
|
97
|
+
let displayValue = usedVal;
|
|
98
|
+
let ratio = 0;
|
|
99
|
+
if (limitVal > 0) {
|
|
100
|
+
if (showMode === "available") {
|
|
101
|
+
displayValue = Math.max(0, limitVal - usedVal);
|
|
102
|
+
}
|
|
103
|
+
ratio = displayValue / limitVal;
|
|
104
|
+
}
|
|
105
|
+
// Cap visual ratio at 1.0 for the bar filling, but keep actual ratio for color calculation if needed
|
|
106
|
+
const visualRatio = Math.min(Math.max(ratio, 0), 1);
|
|
107
|
+
const filledLen = Math.round(width * visualRatio);
|
|
108
|
+
const emptyLen = Math.max(0, width - filledLen);
|
|
109
|
+
// Determine Color
|
|
110
|
+
let barColor = "reset";
|
|
111
|
+
let statusColor = "reset";
|
|
112
|
+
if (config.gradients && config.gradients.length > 0) {
|
|
113
|
+
// Sort gradients by threshold to ensure correct evaluation
|
|
114
|
+
const sorted = [...config.gradients].sort((a, b) => a.threshold - b.threshold);
|
|
115
|
+
// Find the matching level
|
|
116
|
+
const match = sorted.find((g) => ratio <= g.threshold);
|
|
117
|
+
if (match) {
|
|
118
|
+
barColor = match.color;
|
|
119
|
+
statusColor = match.color;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// If ratio exceeds all thresholds (e.g. > 100%), use the last defined color (highest severity)
|
|
123
|
+
barColor = sorted[sorted.length - 1].color;
|
|
124
|
+
statusColor = sorted[sorted.length - 1].color;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const filledStr = filledChar.repeat(filledLen);
|
|
128
|
+
const emptyStr = emptyChar.repeat(emptyLen);
|
|
129
|
+
const bar = `${colorize(filledStr, barColor, useColor)}${emptyStr}`; // Only color filled part? Or empty too? usually just filled.
|
|
130
|
+
const percentRaw = limitVal > 0 ? `${Math.round(ratio * 100)}%` : "n/a";
|
|
131
|
+
const percentText = percentRaw === "n/a" ? percentRaw : percentRaw.padStart(4);
|
|
132
|
+
const percent = colorize(percentText, barColor, useColor);
|
|
133
|
+
const valueText = `${formatNumber(displayValue)}/${formatNumber(limitVal)} ${options.unit}`;
|
|
134
|
+
// Only append colon if label is present and not empty
|
|
135
|
+
const labelPart = options.label ? `${options.label}: ` : "";
|
|
136
|
+
// Determine Emoji
|
|
137
|
+
const statusEmoji = getQuotaStatusEmoji(ratio, config);
|
|
138
|
+
const statusTextRaw = getQuotaStatusText(ratio, config);
|
|
139
|
+
const statusText = colorize(statusTextRaw, statusColor, useColor);
|
|
140
|
+
return {
|
|
141
|
+
labelPart,
|
|
142
|
+
bar,
|
|
143
|
+
percent,
|
|
144
|
+
valuePart: `(${valueText})`,
|
|
145
|
+
detailsPart: options.details ? ` | ${options.details}` : "",
|
|
146
|
+
statusEmoji,
|
|
147
|
+
statusText,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=progress-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-bar.js","sourceRoot":"","sources":["../../../src/ui/progress-bar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAS,MAAM,qBAAqB,CAAC;AAE3D,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,MAAM,iBAAiB,GAAoB;IACvC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IAClC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACnC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;CACnC,CAAC;AAEF,MAAM,UAAU,GAA8B;IAC5C,GAAG,EAAE,UAAU;IACf,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,SAAS,cAAc,CAAC,MAA0B;IAChD,yDAAyD;IACzD,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvD,kCAAkC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAErE,kEAAkE;IAClE,IAAI,MAAM,EAAE,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAExC,wCAAwC;IACxC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAExC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAA4B,EAAE,QAAiB;IACpF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC7C,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;AAC1D,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAG,KAAK,EAAE,CAAC;IACpB,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1B,CAAC;AAYD,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,SAA4B,EAAE;IAE9B,qCAAqC;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,iBAAiB,CAAC;IAExD,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAExE,0BAA0B;IAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC;IAE9E,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC;QAC1B,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC;QAC3B,KAAK,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC;QACxB,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,eAAe;IACtC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,SAA4B,EAAE;IAE9B,qCAAqC;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,iBAAiB,CAAC;IAExD,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAExE,0BAA0B;IAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC;IAE9E,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,sBAAsB;QAClD,KAAK,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC;QAC5B,KAAK,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC;QACzB,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,KAAa,EACb,OAKC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,iBAAiB,CAAC;IAChD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,kBAAkB,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC;IACvC,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAExC,qCAAqC;IACrC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/D,0CAA0C;IAC1C,IAAI,YAAY,GAAG,OAAO,CAAC;IAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC7B,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;QACjD,CAAC;QACD,KAAK,GAAG,YAAY,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED,qGAAqG;IACrG,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEpD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC;IAEhD,kBAAkB;IAClB,IAAI,QAAQ,GAAc,OAAO,CAAC;IAClC,IAAI,WAAW,GAAc,OAAO,CAAC;IAErC,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,2DAA2D;QAC3D,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CACpC,CAAC;QAEF,0BAA0B;QAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;QAEvD,IAAI,KAAK,EAAE,CAAC;YACV,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;YACvB,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,+FAA+F;YAC/F,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YAC3C,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QAChD,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE5C,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC,6DAA6D;IAElI,MAAM,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IACxE,MAAM,WAAW,GAAG,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAE1D,MAAM,SAAS,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAE5F,sDAAsD;IACtD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5D,kBAAkB;IAClB,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAElE,OAAO;QACL,SAAS;QACT,GAAG;QACH,OAAO;QACP,SAAS,EAAE,IAAI,SAAS,GAAG;QAC3B,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;QAC3D,WAAW;QACX,UAAU;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ProgressBarConfig, type QuotaData, type QuotaColumn } from "../interfaces";
|
|
2
|
+
type RenderedQuotaLine = {
|
|
3
|
+
id: string;
|
|
4
|
+
providerName: string;
|
|
5
|
+
line: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function renderQuotaTable(quotas: QuotaData[], options: {
|
|
8
|
+
progressBarConfig?: ProgressBarConfig;
|
|
9
|
+
tableConfig?: {
|
|
10
|
+
columns?: QuotaColumn[];
|
|
11
|
+
header?: boolean;
|
|
12
|
+
};
|
|
13
|
+
}): RenderedQuotaLine[];
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=quota-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-table.d.ts","sourceRoot":"","sources":["../../../src/ui/quota-table.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAGzF,KAAK,iBAAiB,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAeF,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,SAAS,EAAE,EACnB,OAAO,EAAE;IACL,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC/D,GACF,iBAAiB,EAAE,CA+IrB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { renderQuotaBarParts, colorize } from "./progress-bar";
|
|
2
|
+
import { validateQuotaData } from "../utils/validation";
|
|
3
|
+
const DEFAULT_COLUMNS = ["status", "name", "percent", "bar", "reset", "ettl"];
|
|
4
|
+
const HEADERS = {
|
|
5
|
+
name: "QUOTA NAME",
|
|
6
|
+
bar: "UTILIZATION",
|
|
7
|
+
percent: "USED",
|
|
8
|
+
value: "VALUE",
|
|
9
|
+
reset: "RESET",
|
|
10
|
+
ettl: "ETTL",
|
|
11
|
+
window: "WINDOW",
|
|
12
|
+
info: "INFO",
|
|
13
|
+
status: "ST"
|
|
14
|
+
};
|
|
15
|
+
export function renderQuotaTable(quotas, options) {
|
|
16
|
+
if (quotas.length === 0)
|
|
17
|
+
return [];
|
|
18
|
+
const columns = options.tableConfig?.columns || DEFAULT_COLUMNS;
|
|
19
|
+
const useColor = options.progressBarConfig?.color ?? false;
|
|
20
|
+
// 1. Pre-calculate cell data for every row
|
|
21
|
+
const rows = quotas.map((quota) => {
|
|
22
|
+
const validated = validateQuotaData(quota) || quota;
|
|
23
|
+
const isUnlimited = validated.limit === null || validated.limit <= 0;
|
|
24
|
+
// Render bar parts if limited
|
|
25
|
+
let barParts = null;
|
|
26
|
+
if (!isUnlimited) {
|
|
27
|
+
barParts = renderQuotaBarParts(validated.used, validated.limit, {
|
|
28
|
+
label: "",
|
|
29
|
+
unit: validated.unit,
|
|
30
|
+
config: options.progressBarConfig,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const name = colorize(validated.providerName, "cyan", useColor);
|
|
34
|
+
const status = barParts
|
|
35
|
+
? barParts.statusText
|
|
36
|
+
: (validated.info === "unlimited" ? colorize("OK ", "green", useColor) : colorize("UNK", "gray", useColor));
|
|
37
|
+
// Strip "resets in " or "resets at " prefix for cleaner table display
|
|
38
|
+
const resetRaw = validated.reset?.replace(/^resets (in|at) /, "") || "";
|
|
39
|
+
const reset = colorize(resetRaw, "gray", useColor);
|
|
40
|
+
// Remove leading 'in ' if present and strip '(predicted)'
|
|
41
|
+
const ettlRaw = validated.predictedReset?.replace(/^in\s+/i, "").replace(/\(predicted\)/, "").trim() || "-";
|
|
42
|
+
const ettl = colorize(ettlRaw, "gray", useColor);
|
|
43
|
+
return {
|
|
44
|
+
quota: validated,
|
|
45
|
+
barParts,
|
|
46
|
+
cells: {
|
|
47
|
+
name,
|
|
48
|
+
bar: barParts ? barParts.bar : (isUnlimited ? colorize("Unlimited", "green", useColor) : ""),
|
|
49
|
+
percent: barParts ? barParts.percent : "",
|
|
50
|
+
value: barParts ? barParts.valuePart : `${validated.used} ${validated.unit}`,
|
|
51
|
+
reset,
|
|
52
|
+
ettl,
|
|
53
|
+
window: validated.window || "",
|
|
54
|
+
info: validated.info || "",
|
|
55
|
+
status,
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
// 2. Measure widths
|
|
60
|
+
const widths = {
|
|
61
|
+
name: 0, bar: 0, percent: 0, value: 0, reset: 0, window: 0, info: 0, status: 0, ettl: 0
|
|
62
|
+
};
|
|
63
|
+
// Calculate max widths including headers
|
|
64
|
+
for (const col of columns) {
|
|
65
|
+
widths[col] = Math.max(widths[col], HEADERS[col].length);
|
|
66
|
+
}
|
|
67
|
+
for (const row of rows) {
|
|
68
|
+
for (const col of columns) {
|
|
69
|
+
const content = row.cells[col];
|
|
70
|
+
const visibleLength = content.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
71
|
+
if (visibleLength > widths[col]) {
|
|
72
|
+
widths[col] = visibleLength;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const outputRows = [];
|
|
77
|
+
// 3. Render Header (optional)
|
|
78
|
+
if (options.tableConfig?.header !== false) {
|
|
79
|
+
const headerSegments = [];
|
|
80
|
+
const separatorSegments = [];
|
|
81
|
+
for (const col of columns) {
|
|
82
|
+
const width = widths[col];
|
|
83
|
+
const headerTitle = HEADERS[col];
|
|
84
|
+
// Alignments: same as content
|
|
85
|
+
// percent: right
|
|
86
|
+
// others: left
|
|
87
|
+
const coloredHeader = colorize(headerTitle, "bold", useColor);
|
|
88
|
+
let segment = "";
|
|
89
|
+
let sep = "";
|
|
90
|
+
// When padding, we need to consider visible length of the colored string vs stripped
|
|
91
|
+
// But here `headerTitle` is uncolored when calculating padding, so standard pad works
|
|
92
|
+
// provided we apply color AFTER padding, OR pad properly.
|
|
93
|
+
// Actually, padStart/padEnd on the uncolored string, THEN colorize.
|
|
94
|
+
let paddedTitle = "";
|
|
95
|
+
if (col === "percent") {
|
|
96
|
+
paddedTitle = headerTitle.padStart(width);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
paddedTitle = headerTitle.padEnd(width);
|
|
100
|
+
}
|
|
101
|
+
segment = colorize(paddedTitle, "bold", useColor);
|
|
102
|
+
// Create separator line using hyphens
|
|
103
|
+
sep = colorize("-".repeat(width), "dim", useColor);
|
|
104
|
+
headerSegments.push(segment);
|
|
105
|
+
separatorSegments.push(sep);
|
|
106
|
+
}
|
|
107
|
+
outputRows.push({ id: "header", providerName: "header", line: headerSegments.join(" ") });
|
|
108
|
+
outputRows.push({ id: "sep", providerName: "sep", line: separatorSegments.join(" ") });
|
|
109
|
+
}
|
|
110
|
+
// 4. Render lines
|
|
111
|
+
rows.forEach((row) => {
|
|
112
|
+
const segments = [];
|
|
113
|
+
for (let i = 0; i < columns.length; i++) {
|
|
114
|
+
const col = columns[i];
|
|
115
|
+
const content = row.cells[col];
|
|
116
|
+
const width = widths[col];
|
|
117
|
+
let segment = "";
|
|
118
|
+
const visibleLength = content.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
119
|
+
const padding = Math.max(0, width - visibleLength);
|
|
120
|
+
if (col === "percent") {
|
|
121
|
+
segment = " ".repeat(padding) + content;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
segment = content + " ".repeat(padding);
|
|
125
|
+
}
|
|
126
|
+
segments.push(segment);
|
|
127
|
+
}
|
|
128
|
+
outputRows.push({
|
|
129
|
+
id: row.quota.id,
|
|
130
|
+
providerName: row.quota.providerName,
|
|
131
|
+
line: segments.join(" "), // Use 3 spaces separator as in example
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
return outputRows;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=quota-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-table.js","sourceRoot":"","sources":["../../../src/ui/quota-table.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/utils/debug.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../../src/utils/debug.ts"],"names":[],"mappings":";AAAA,oDAAoD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function getDataDirectory(): string;
|
|
2
|
+
export declare function getConfigDirectory(): string;
|
|
3
|
+
export declare const AUTH_FILE: () => string;
|
|
4
|
+
export declare const HISTORY_FILE: () => string;
|
|
5
|
+
export declare const DEBUG_LOG_FILE: () => string;
|
|
6
|
+
export declare const ANTIGRAVITY_ACCOUNTS_FILE: () => string;
|
|
7
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/utils/paths.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,IAAI,MAAM,CAezC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAe3C;AAED,eAAO,MAAM,SAAS,QAAO,MAA+C,CAAC;AAC7E,eAAO,MAAM,YAAY,QAAO,MAAwD,CAAC;AACzF,eAAO,MAAM,cAAc,QAAO,MAAsD,CAAC;AACzF,eAAO,MAAM,yBAAyB,QAAO,MAAiE,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { homedir, platform } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
export function getDataDirectory() {
|
|
4
|
+
const home = homedir();
|
|
5
|
+
switch (platform()) {
|
|
6
|
+
case "win32":
|
|
7
|
+
return process.env.APPDATA
|
|
8
|
+
? join(process.env.APPDATA, "opencode")
|
|
9
|
+
: join(home, "AppData", "Roaming", "opencode");
|
|
10
|
+
case "darwin":
|
|
11
|
+
return join(home, "Library", "Application Support", "opencode");
|
|
12
|
+
default:
|
|
13
|
+
return process.env.XDG_DATA_HOME
|
|
14
|
+
? join(process.env.XDG_DATA_HOME, "opencode")
|
|
15
|
+
: join(home, ".local", "share", "opencode");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function getConfigDirectory() {
|
|
19
|
+
const home = homedir();
|
|
20
|
+
switch (platform()) {
|
|
21
|
+
case "win32":
|
|
22
|
+
return process.env.APPDATA
|
|
23
|
+
? join(process.env.APPDATA, "opencode")
|
|
24
|
+
: join(home, "AppData", "Roaming", "opencode");
|
|
25
|
+
case "darwin":
|
|
26
|
+
return join(home, "Library", "Application Support", "opencode");
|
|
27
|
+
default:
|
|
28
|
+
return process.env.XDG_CONFIG_HOME
|
|
29
|
+
? join(process.env.XDG_CONFIG_HOME, "opencode")
|
|
30
|
+
: join(home, ".config", "opencode");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export const AUTH_FILE = () => join(getDataDirectory(), "auth.json");
|
|
34
|
+
export const HISTORY_FILE = () => join(getDataDirectory(), "quota-history.json");
|
|
35
|
+
export const DEBUG_LOG_FILE = () => join(getDataDirectory(), "quotas-debug.log");
|
|
36
|
+
export const ANTIGRAVITY_ACCOUNTS_FILE = () => join(getConfigDirectory(), "antigravity-accounts.json");
|
|
37
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,gBAAgB;IAC5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACjB,KAAK,OAAO;YACR,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO;gBACtB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC;gBACvC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACvD,KAAK,QAAQ;YACT,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAC;QACpE;YACI,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa;gBAC5B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC;gBAC7C,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB;IAC9B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACjB,KAAK,OAAO;YACR,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO;gBACtB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC;gBACvC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACvD,KAAK,QAAQ;YACT,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAC;QACpE;YACI,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe;gBAC9B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC;gBAC/C,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAChD,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,WAAW,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,oBAAoB,CAAC,CAAC;AACzF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACzF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,2BAA2B,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/utils/time.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,CAkB3D;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAmBnD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export function formatRelativeTime(targetDate) {
|
|
2
|
+
const now = new Date();
|
|
3
|
+
const diffMs = targetDate.getTime() - now.getTime();
|
|
4
|
+
if (diffMs <= 0)
|
|
5
|
+
return "now";
|
|
6
|
+
const diffMins = Math.floor(diffMs / (1000 * 60));
|
|
7
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
8
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
9
|
+
const remainingHours = diffHours % 24;
|
|
10
|
+
const remainingMins = diffMins % 60;
|
|
11
|
+
if (diffDays > 0) {
|
|
12
|
+
return `${diffDays}d ${remainingHours}h`;
|
|
13
|
+
}
|
|
14
|
+
if (diffHours > 0) {
|
|
15
|
+
return `${diffHours}h ${remainingMins}m`;
|
|
16
|
+
}
|
|
17
|
+
return `${diffMins}m`;
|
|
18
|
+
}
|
|
19
|
+
export function formatDurationMs(ms) {
|
|
20
|
+
if (ms <= 0)
|
|
21
|
+
return "now";
|
|
22
|
+
const diffMins = Math.floor(ms / (1000 * 60));
|
|
23
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
24
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
25
|
+
const remainingHours = diffHours % 24;
|
|
26
|
+
const remainingMins = diffMins % 60;
|
|
27
|
+
if (diffDays > 0) {
|
|
28
|
+
return `${diffDays}d ${remainingHours}h`;
|
|
29
|
+
}
|
|
30
|
+
if (diffHours > 0) {
|
|
31
|
+
return `${diffHours}h ${remainingMins}m`;
|
|
32
|
+
}
|
|
33
|
+
if (diffMins > 0) {
|
|
34
|
+
return `${diffMins}m`;
|
|
35
|
+
}
|
|
36
|
+
return "less than 1m";
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/utils/time.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,UAAgB;IACjD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;IACpD,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,SAAS,GAAG,EAAE,CAAC;IACtC,MAAM,aAAa,GAAG,QAAQ,GAAG,EAAE,CAAC;IAEpC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,OAAO,GAAG,QAAQ,KAAK,cAAc,GAAG,CAAC;IAC3C,CAAC;IACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO,GAAG,SAAS,KAAK,aAAa,GAAG,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACvC,IAAI,EAAE,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,SAAS,GAAG,EAAE,CAAC;IACtC,MAAM,aAAa,GAAG,QAAQ,GAAG,EAAE,CAAC;IAEpC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,GAAG,QAAQ,KAAK,cAAc,GAAG,CAAC;IAC7C,CAAC;IACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,GAAG,SAAS,KAAK,aAAa,GAAG,CAAC;IAC7C,CAAC;IACD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,GAAG,QAAQ,GAAG,CAAC;IAC1B,CAAC;IACD,OAAO,cAAc,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type QuotaData } from "../interfaces";
|
|
2
|
+
export declare function isValidNumber(v: unknown): v is number;
|
|
3
|
+
export declare function clamp(value: number, min: number, max?: number): number;
|
|
4
|
+
export declare function validatePollingInterval(v: unknown): number | null;
|
|
5
|
+
export declare function validateQuotaData(input: unknown): QuotaData | null;
|
|
6
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAErD;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAKtE;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKjE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CA0ClE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export function isValidNumber(v) {
|
|
2
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
3
|
+
}
|
|
4
|
+
export function clamp(value, min, max) {
|
|
5
|
+
if (!Number.isFinite(value))
|
|
6
|
+
return min;
|
|
7
|
+
if (value < min)
|
|
8
|
+
return min;
|
|
9
|
+
if (max !== undefined && value > max)
|
|
10
|
+
return max;
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
export function validatePollingInterval(v) {
|
|
14
|
+
if (v === null || v === undefined)
|
|
15
|
+
return null;
|
|
16
|
+
const n = typeof v === "string" ? Number(v.trim()) : Number(v);
|
|
17
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
18
|
+
return null;
|
|
19
|
+
return n;
|
|
20
|
+
}
|
|
21
|
+
export function validateQuotaData(input) {
|
|
22
|
+
if (typeof input !== "object" || input === null)
|
|
23
|
+
return null;
|
|
24
|
+
const q = input;
|
|
25
|
+
if (!q.id || typeof q.id !== "string")
|
|
26
|
+
return null;
|
|
27
|
+
if (!q.providerName || typeof q.providerName !== "string")
|
|
28
|
+
return null;
|
|
29
|
+
let used = Number(q.used ?? 0);
|
|
30
|
+
if (!Number.isFinite(used))
|
|
31
|
+
used = 0;
|
|
32
|
+
if (used < 0)
|
|
33
|
+
used = 0;
|
|
34
|
+
let limit = null;
|
|
35
|
+
if (q.limit === null) {
|
|
36
|
+
limit = null;
|
|
37
|
+
}
|
|
38
|
+
else if (q.limit !== undefined) {
|
|
39
|
+
const n = Number(q.limit);
|
|
40
|
+
if (Number.isFinite(n) && n > 0) {
|
|
41
|
+
limit = n;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
limit = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const unit = typeof q.unit === "string" ? q.unit : "";
|
|
48
|
+
const reset = typeof q.reset === "string" ? q.reset : undefined;
|
|
49
|
+
const predictedReset = typeof q.predictedReset === "string" ? q.predictedReset : undefined;
|
|
50
|
+
const window = typeof q.window === "string" ? q.window : undefined;
|
|
51
|
+
const info = typeof q.info === "string" ? q.info : undefined;
|
|
52
|
+
const details = typeof q.details === "string" ? q.details : undefined;
|
|
53
|
+
return {
|
|
54
|
+
id: q.id,
|
|
55
|
+
providerName: q.providerName,
|
|
56
|
+
used,
|
|
57
|
+
limit,
|
|
58
|
+
unit,
|
|
59
|
+
reset,
|
|
60
|
+
predictedReset,
|
|
61
|
+
window,
|
|
62
|
+
info,
|
|
63
|
+
details,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/utils/validation.ts"],"names":[],"mappings":"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"}
|