opencode-glm-quota 1.4.0 → 1.4.2
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 +6 -6
- package/dist/index.js +55 -37
- package/dist/utils/progress-bar.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ OpenCode plugin to query Z.ai GLM Coding Plan usage statistics with real-time qu
|
|
|
19
19
|
- 🔧 View MCP tool usage (web_search, web_reader, etc.)
|
|
20
20
|
- 🌍 Supports both Global (api.z.ai) and CN (open.bigmodel.cn) platforms
|
|
21
21
|
- 🔐 Automatic credential discovery from OpenCode auth.json
|
|
22
|
-
- 📈 Visual progress bars for quota percentages
|
|
22
|
+
- 📈 Visual progress bars for quota percentages (ASCII for terminal alignment)
|
|
23
23
|
- ⚡ Fail-fast error handling (no retry logic - user controls when to retry)
|
|
24
24
|
|
|
25
25
|
## Installation
|
|
@@ -134,19 +134,19 @@ After authentication, simply run:
|
|
|
134
134
|
║ Platform: ZAI ║
|
|
135
135
|
║ Period: 2026-01-17 21:00:00 → 2026-01-18 20:59:59 ║
|
|
136
136
|
╠══════════════════════════════════════════════════════════════════╣
|
|
137
|
-
║
|
|
137
|
+
║ QUOTA LIMITS ║
|
|
138
138
|
╟──────────────────────────────────────────────────────────────────╢
|
|
139
|
-
║ Token usage(5 Hour) [
|
|
140
|
-
║ MCP usage(1 Month) [
|
|
139
|
+
║ Token usage(5 Hour) [###################--------] 40.5% ║
|
|
140
|
+
║ MCP usage(1 Month) [####-----------------------] 12.3% ║
|
|
141
141
|
║ Used: 123/1,000 ║
|
|
142
142
|
╠══════════════════════════════════════════════════════════════════╣
|
|
143
|
-
║
|
|
143
|
+
║ MODEL USAGE (24h) ║
|
|
144
144
|
╟──────────────────────────────────────────────────────────────────╢
|
|
145
145
|
║ Total Tokens (24h): 12,500,000 (31% of 5h limit) ║
|
|
146
146
|
║ 5h Window Usage: 40.5% of 40,000,000 ║
|
|
147
147
|
║ Total Calls: 1,234 ║
|
|
148
148
|
╠══════════════════════════════════════════════════════════════════╣
|
|
149
|
-
║
|
|
149
|
+
║ TOOL/MCP USAGE (24h) ║
|
|
150
150
|
╟──────────────────────────────────────────────────────────────────╢
|
|
151
151
|
║ Network Searches: 5,678 ║
|
|
152
152
|
║ Web Reads: 2,345 ║
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,17 @@ const CANDIDATE_PROVIDER_IDS = [
|
|
|
25
25
|
'zhipu',
|
|
26
26
|
'zhipuai'
|
|
27
27
|
];
|
|
28
|
+
/**
|
|
29
|
+
* Box drawing layout constants
|
|
30
|
+
* Total line width: LEFT_BORDER (1) + LEFT_PAD (2) + CONTENT (56) + RIGHT_PAD (0) + RIGHT_BORDER (1) = 60
|
|
31
|
+
* Border lines: ╔ + 58 chars + ╗ = 60 total
|
|
32
|
+
* Content lines: ║ + 2 spaces + 56 content + 2 spaces + ║ = 60 total (formatted by formatBoxLine)
|
|
33
|
+
*/
|
|
34
|
+
const BOX_WIDTH = {
|
|
35
|
+
CONTENT: 56, // Available content width
|
|
36
|
+
BORDER_CHARS: 58, // Character count between borders (╔══...══╗)
|
|
37
|
+
TOTAL: 60 // Total line width including borders
|
|
38
|
+
};
|
|
28
39
|
// ============================================================================
|
|
29
40
|
// CREDENTIAL DISCOVERY
|
|
30
41
|
// ============================================================================
|
|
@@ -97,20 +108,33 @@ async function getCredentials() {
|
|
|
97
108
|
}
|
|
98
109
|
/**
|
|
99
110
|
* Create error message for missing credentials
|
|
100
|
-
* @returns Error message with setup instructions
|
|
111
|
+
* @returns Error message with setup instructions (box formatted)
|
|
101
112
|
*/
|
|
102
113
|
function createCredentialError() {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
const header = '❌ Z.ai Credentials Not Found';
|
|
115
|
+
const instructions = [
|
|
116
|
+
'',
|
|
117
|
+
'Please authenticate first:',
|
|
118
|
+
'',
|
|
119
|
+
'1. Run /connect command in OpenCode TUI',
|
|
120
|
+
'2. Select "Z.AI Coding Plan" or "Z.AI"',
|
|
121
|
+
'3. Or "Zhipu" (for China region)',
|
|
122
|
+
'',
|
|
123
|
+
'For dev/testing, set environment:',
|
|
124
|
+
'- ZAI_API_KEY (global)',
|
|
125
|
+
'- ZHIPU_API_KEY (China)',
|
|
126
|
+
''
|
|
127
|
+
];
|
|
128
|
+
const lines = [];
|
|
129
|
+
lines.push('╔' + '═'.repeat(BOX_WIDTH.BORDER_CHARS) + '╗');
|
|
130
|
+
lines.push('║' + ' '.repeat(BOX_WIDTH.BORDER_CHARS) + '║');
|
|
131
|
+
lines.push(formatBoxLine(header, BOX_WIDTH.CONTENT));
|
|
132
|
+
lines.push('║' + ' '.repeat(BOX_WIDTH.BORDER_CHARS) + '║');
|
|
133
|
+
for (const instruction of instructions) {
|
|
134
|
+
lines.push(formatBoxLine(instruction, BOX_WIDTH.CONTENT));
|
|
135
|
+
}
|
|
136
|
+
lines.push('╚' + '═'.repeat(BOX_WIDTH.BORDER_CHARS) + '╝');
|
|
137
|
+
return lines.join('\n');
|
|
114
138
|
}
|
|
115
139
|
// ============================================================================
|
|
116
140
|
// RESPONSE PROCESSING
|
|
@@ -348,16 +372,14 @@ function isFullWidthCodePoint(codePoint) {
|
|
|
348
372
|
*/
|
|
349
373
|
function formatHeader(platformName, startTime, endTime) {
|
|
350
374
|
const lines = [];
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
lines.push('
|
|
354
|
-
lines.push('║' + ' '.repeat(
|
|
355
|
-
lines.push('
|
|
356
|
-
lines.push(
|
|
357
|
-
lines.push(
|
|
358
|
-
lines.push(
|
|
359
|
-
lines.push(formatBoxLine(`Period: ${startTime} → ${endTime}`, LINE_INDENT));
|
|
360
|
-
lines.push('╠' + '═'.repeat(LINE_CONTENT) + '╣');
|
|
375
|
+
lines.push('╔' + '═'.repeat(BOX_WIDTH.BORDER_CHARS) + '╗');
|
|
376
|
+
lines.push('║' + ' '.repeat(BOX_WIDTH.BORDER_CHARS) + '║');
|
|
377
|
+
lines.push('║' + ' Z.ai GLM Coding Plan Usage Statistics '.padStart(35).padEnd(BOX_WIDTH.BORDER_CHARS) + '║');
|
|
378
|
+
lines.push('║' + ' '.repeat(BOX_WIDTH.BORDER_CHARS) + '║');
|
|
379
|
+
lines.push('╠' + '═'.repeat(BOX_WIDTH.BORDER_CHARS) + '╣');
|
|
380
|
+
lines.push(formatBoxLine(`Platform: ${platformName}`, BOX_WIDTH.CONTENT));
|
|
381
|
+
lines.push(formatBoxLine(`Period: ${startTime} → ${endTime}`, BOX_WIDTH.CONTENT));
|
|
382
|
+
lines.push('╠' + '═'.repeat(BOX_WIDTH.BORDER_CHARS) + '╣');
|
|
361
383
|
return lines;
|
|
362
384
|
}
|
|
363
385
|
/**
|
|
@@ -367,32 +389,30 @@ function formatHeader(platformName, startTime, endTime) {
|
|
|
367
389
|
*/
|
|
368
390
|
function formatQuotaLimits(quotaData) {
|
|
369
391
|
const lines = [];
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
lines.push(formatBoxLine('QUOTA LIMITS', LINE_INDENT));
|
|
373
|
-
lines.push('╟' + '─'.repeat(LINE_CONTENT) + '╢');
|
|
392
|
+
lines.push(formatBoxLine('QUOTA LIMITS', BOX_WIDTH.CONTENT));
|
|
393
|
+
lines.push('╟' + '─'.repeat(BOX_WIDTH.BORDER_CHARS) + '╢');
|
|
374
394
|
const limits = quotaData?.limits;
|
|
375
395
|
if (limits && Array.isArray(limits)) {
|
|
376
396
|
for (const limit of limits) {
|
|
377
397
|
const pct = typeof limit.percentage === 'number' ? limit.percentage : 0;
|
|
378
398
|
const line = formatProgressLine(limit.type || 'Unknown', pct);
|
|
379
|
-
lines.push(formatProgressBoxLine(line,
|
|
399
|
+
lines.push(formatProgressBoxLine(line, BOX_WIDTH.CONTENT));
|
|
380
400
|
if (limit.nextResetTime !== undefined) {
|
|
381
401
|
const resetMsg = formatTimeUntilReset(limit.nextResetTime);
|
|
382
402
|
if (resetMsg) {
|
|
383
|
-
lines.push(formatBoxLine(resetMsg,
|
|
403
|
+
lines.push(formatBoxLine(resetMsg, BOX_WIDTH.CONTENT));
|
|
384
404
|
}
|
|
385
405
|
}
|
|
386
406
|
if (limit.currentValue !== undefined && limit.total !== undefined) {
|
|
387
407
|
const usageStr = ' Used: ' + limit.currentValue + '/' + limit.total;
|
|
388
|
-
lines.push(formatBoxLine(usageStr,
|
|
408
|
+
lines.push(formatBoxLine(usageStr, BOX_WIDTH.CONTENT));
|
|
389
409
|
}
|
|
390
410
|
}
|
|
391
411
|
}
|
|
392
412
|
else {
|
|
393
|
-
lines.push(formatBoxLine('No quota data available',
|
|
413
|
+
lines.push(formatBoxLine('No quota data available', BOX_WIDTH.CONTENT));
|
|
394
414
|
}
|
|
395
|
-
lines.push('╠' + '═'.repeat(
|
|
415
|
+
lines.push('╠' + '═'.repeat(BOX_WIDTH.BORDER_CHARS) + '╣');
|
|
396
416
|
return lines;
|
|
397
417
|
}
|
|
398
418
|
/**
|
|
@@ -406,9 +426,8 @@ function formatQuotaLimits(quotaData) {
|
|
|
406
426
|
*/
|
|
407
427
|
function formatDataSection(title, data, formatter, quotaData, noDataMessage, LINE_INDENT) {
|
|
408
428
|
const lines = [];
|
|
409
|
-
const LINE_CONTENT = 58;
|
|
410
429
|
lines.push(formatBoxLine(title, LINE_INDENT));
|
|
411
|
-
lines.push('╟' + '─'.repeat(
|
|
430
|
+
lines.push('╟' + '─'.repeat(BOX_WIDTH.BORDER_CHARS) + '╢');
|
|
412
431
|
if (data) {
|
|
413
432
|
const formattedLines = formatter(data, quotaData);
|
|
414
433
|
for (const line of formattedLines) {
|
|
@@ -418,7 +437,7 @@ function formatDataSection(title, data, formatter, quotaData, noDataMessage, LIN
|
|
|
418
437
|
else {
|
|
419
438
|
lines.push(formatBoxLine(noDataMessage, LINE_INDENT));
|
|
420
439
|
}
|
|
421
|
-
lines.push('╠' + '═'.repeat(
|
|
440
|
+
lines.push('╠' + '═'.repeat(BOX_WIDTH.BORDER_CHARS) + '╣');
|
|
422
441
|
return lines;
|
|
423
442
|
}
|
|
424
443
|
/**
|
|
@@ -441,11 +460,10 @@ function formatFooter() {
|
|
|
441
460
|
function formatOutput(platform, startTime, endTime, quotaData, modelData, toolData) {
|
|
442
461
|
const lines = [];
|
|
443
462
|
const platformName = getPlatformName(platform);
|
|
444
|
-
const LINE_INDENT = 56;
|
|
445
463
|
lines.push(...formatHeader(platformName, startTime, endTime));
|
|
446
464
|
lines.push(...formatQuotaLimits(quotaData));
|
|
447
|
-
lines.push(...formatDataSection('MODEL USAGE (24h)', modelData, formatModelUsage, quotaData, 'No model usage data available',
|
|
448
|
-
lines.push(...formatDataSection('TOOL/MCP USAGE (24h)', toolData, formatToolUsage, quotaData, 'No tool usage data available',
|
|
465
|
+
lines.push(...formatDataSection('MODEL USAGE (24h)', modelData, formatModelUsage, quotaData, 'No model usage data available', BOX_WIDTH.CONTENT));
|
|
466
|
+
lines.push(...formatDataSection('TOOL/MCP USAGE (24h)', toolData, formatToolUsage, quotaData, 'No tool usage data available', BOX_WIDTH.CONTENT));
|
|
449
467
|
lines.push(...formatFooter());
|
|
450
468
|
return lines.join('\n');
|
|
451
469
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @returns Progress bar string
|
|
10
10
|
*/
|
|
11
11
|
export function createProgressBar(percentage, options = {}) {
|
|
12
|
-
const { width = 30, filledChar = '
|
|
12
|
+
const { width = 30, filledChar = '#', emptyChar = '-' } = options;
|
|
13
13
|
// Clamp percentage to 0-100
|
|
14
14
|
const clampedPercentage = Math.min(100, Math.max(0, percentage));
|
|
15
15
|
// Calculate filled width
|
package/package.json
CHANGED