minimax-status 1.1.11 → 1.1.13
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/cli/api.js +37 -1
- package/cli/index.js +14 -6
- package/cli/renderer.js +7 -3
- package/cli/status.js +108 -10
- package/cli/statusbar.js +12 -2
- package/package.json +1 -1
package/cli/api.js
CHANGED
|
@@ -312,7 +312,7 @@ class MinimaxAPI {
|
|
|
312
312
|
// Calculate weekly usage data
|
|
313
313
|
const weeklyUsed = modelData.current_weekly_total_count - modelData.current_weekly_usage_count;
|
|
314
314
|
const weeklyTotal = modelData.current_weekly_total_count;
|
|
315
|
-
const weeklyPercentage = Math.floor((weeklyUsed / weeklyTotal) * 100);
|
|
315
|
+
const weeklyPercentage = weeklyTotal > 0 ? Math.floor((weeklyUsed / weeklyTotal) * 100) : 0;
|
|
316
316
|
const weeklyRemainingMs = modelData.weekly_remains_time;
|
|
317
317
|
const weeklyDays = Math.floor(weeklyRemainingMs / (1000 * 60 * 60 * 24));
|
|
318
318
|
const weeklyHours = Math.floor((weeklyRemainingMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
@@ -393,6 +393,7 @@ class MinimaxAPI {
|
|
|
393
393
|
percentage: weeklyPercentage,
|
|
394
394
|
days: weeklyDays,
|
|
395
395
|
hours: weeklyHours,
|
|
396
|
+
unlimited: weeklyTotal === 0,
|
|
396
397
|
text: weeklyDays > 0
|
|
397
398
|
? `${weeklyDays} 天 ${weeklyHours} 小时后重置`
|
|
398
399
|
: `${weeklyHours} 小时后重置`,
|
|
@@ -401,6 +402,41 @@ class MinimaxAPI {
|
|
|
401
402
|
expiry: expiryInfo,
|
|
402
403
|
};
|
|
403
404
|
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Parse all models from API data
|
|
408
|
+
* @param {Object} apiData - Raw API response
|
|
409
|
+
* @returns {Array} Array of model usage data
|
|
410
|
+
*/
|
|
411
|
+
parseAllModels(apiData) {
|
|
412
|
+
if (!apiData.model_remains || apiData.model_remains.length === 0) {
|
|
413
|
+
return [];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return apiData.model_remains.map(modelData => {
|
|
417
|
+
const totalCount = modelData.current_interval_total_count;
|
|
418
|
+
const remainingCount = modelData.current_interval_usage_count;
|
|
419
|
+
const usedCount = totalCount - remainingCount;
|
|
420
|
+
const usedPercentage = totalCount > 0 ? Math.round((usedCount / totalCount) * 100) : 0;
|
|
421
|
+
|
|
422
|
+
// Weekly data
|
|
423
|
+
const weeklyTotal = modelData.current_weekly_total_count || 0;
|
|
424
|
+
const weeklyUsed = weeklyTotal > 0 ? (modelData.current_weekly_total_count - modelData.current_weekly_usage_count) : 0;
|
|
425
|
+
const weeklyPercentage = weeklyTotal > 0 ? Math.floor((weeklyUsed / weeklyTotal) * 100) : 0;
|
|
426
|
+
|
|
427
|
+
return {
|
|
428
|
+
name: modelData.model_name,
|
|
429
|
+
used: usedCount,
|
|
430
|
+
remaining: remainingCount,
|
|
431
|
+
total: totalCount,
|
|
432
|
+
percentage: usedPercentage,
|
|
433
|
+
unlimited: weeklyTotal === 0,
|
|
434
|
+
weeklyPercentage,
|
|
435
|
+
weeklyTotal,
|
|
436
|
+
weeklyRemainingCount: modelData.current_weekly_usage_count || 0,
|
|
437
|
+
};
|
|
438
|
+
});
|
|
439
|
+
}
|
|
404
440
|
}
|
|
405
441
|
|
|
406
442
|
module.exports = MinimaxAPI;
|
package/cli/index.js
CHANGED
|
@@ -131,13 +131,16 @@ program
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
const statusBar = new StatusBar(usageData, usageStats, api);
|
|
134
|
+
const allModels = api.parseAllModels(apiData);
|
|
134
135
|
|
|
135
136
|
spinner.succeed("状态获取成功");
|
|
136
137
|
|
|
137
138
|
if (options.compact) {
|
|
138
139
|
console.log(statusBar.renderCompact());
|
|
139
140
|
} else {
|
|
140
|
-
|
|
141
|
+
// 将 allModels 传入 StatusBar 内部渲染
|
|
142
|
+
const statusBarWithModels = new StatusBar(usageData, usageStats, api, allModels);
|
|
143
|
+
console.log("\n" + statusBarWithModels.render() + "\n");
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
if (options.watch) {
|
|
@@ -164,10 +167,11 @@ program
|
|
|
164
167
|
api.getSubscriptionDetails(),
|
|
165
168
|
]);
|
|
166
169
|
const usageData = api.parseUsageData(apiData, subscriptionData);
|
|
167
|
-
const
|
|
170
|
+
const allModels = api.parseAllModels(apiData);
|
|
168
171
|
|
|
169
172
|
spinner.succeed("状态获取成功");
|
|
170
|
-
|
|
173
|
+
const statusBarWithModels = new StatusBar(usageData, null, null, allModels);
|
|
174
|
+
console.log("\n" + statusBarWithModels.render() + "\n");
|
|
171
175
|
} catch (error) {
|
|
172
176
|
spinner.fail(chalk.red("获取状态失败"));
|
|
173
177
|
console.error(chalk.red(`错误: ${error.message}`));
|
|
@@ -665,11 +669,15 @@ program
|
|
|
665
669
|
// 使用量 - 进度条风格 (显示次数)
|
|
666
670
|
const usageBar = coloredBar(usage.percentage);
|
|
667
671
|
const usageColor = usage.percentage >= 85 ? chalk.red : usage.percentage >= 60 ? chalk.yellow : chalk.green;
|
|
668
|
-
let usageLine = `${
|
|
672
|
+
let usageLine = `${usageBar} ${usageColor(usage.percentage + '%')} (${usage.remaining}/${usage.total})`;
|
|
669
673
|
// 周用量紧跟在 usage 后面
|
|
670
674
|
if (weekly) {
|
|
671
|
-
|
|
672
|
-
|
|
675
|
+
if (weekly.unlimited) {
|
|
676
|
+
usageLine += ` ${chalk.gray('·')} ${chalk.blue('W')} ♾️`;
|
|
677
|
+
} else {
|
|
678
|
+
const weeklyColor = weekly.percentage >= 85 ? chalk.red : weekly.percentage >= 60 ? chalk.yellow : chalk.green;
|
|
679
|
+
usageLine += ` ${chalk.gray('·')} ${chalk.blue('W')} ${weeklyColor(weekly.percentage + '%')}`;
|
|
680
|
+
}
|
|
673
681
|
}
|
|
674
682
|
parts.push(usageLine);
|
|
675
683
|
|
package/cli/renderer.js
CHANGED
|
@@ -123,11 +123,15 @@ class Renderer {
|
|
|
123
123
|
const filled = Math.round((usagePercentage / 100) * 10);
|
|
124
124
|
const empty = 10 - filled;
|
|
125
125
|
const usageBar = usageColor('█'.repeat(filled) + '\x1b[2m' + '░'.repeat(empty) + '\x1b[0m');
|
|
126
|
-
let usageLine = `${
|
|
126
|
+
let usageLine = `${usageBar} ${usageColor(usagePercentage + '%')} (${usage.remaining}/${usage.total})`;
|
|
127
127
|
// 周用量紧跟在 usage 后面
|
|
128
128
|
if (weekly) {
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
if (weekly.unlimited) {
|
|
130
|
+
usageLine += ` ${chalk.gray('·')} ${chalk.blue('W')} ♾️`;
|
|
131
|
+
} else {
|
|
132
|
+
const weeklyColor = this.getStatusColor(weekly.percentage);
|
|
133
|
+
usageLine += ` ${chalk.gray('·')} ${chalk.blue('W')} ${weeklyColor(weekly.percentage + '%')}`;
|
|
134
|
+
}
|
|
131
135
|
}
|
|
132
136
|
parts.push(usageLine);
|
|
133
137
|
|
package/cli/status.js
CHANGED
|
@@ -4,10 +4,11 @@ const { default: boxen } = require('boxen');
|
|
|
4
4
|
const { default: stringWidth } = require('string-width');
|
|
5
5
|
|
|
6
6
|
class StatusBar {
|
|
7
|
-
constructor(data, usageStats = null, api = null) {
|
|
7
|
+
constructor(data, usageStats = null, api = null, allModels = []) {
|
|
8
8
|
this.data = data;
|
|
9
9
|
this.usageStats = usageStats;
|
|
10
10
|
this.api = api;
|
|
11
|
+
this.allModels = allModels;
|
|
11
12
|
this.totalWidth = 63; // 总宽度包括边框
|
|
12
13
|
this.borderWidth = 4; // '│ ' (2) + ' │' (2) = 4
|
|
13
14
|
}
|
|
@@ -54,6 +55,56 @@ class StatusBar {
|
|
|
54
55
|
return lines.join('\n');
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
// 渲染所有模型额度区块
|
|
59
|
+
renderAllModelsSection() {
|
|
60
|
+
if (!this.allModels || this.allModels.length === 0) {
|
|
61
|
+
return '';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const lines = [];
|
|
65
|
+
lines.push('');
|
|
66
|
+
lines.push(chalk.bold('📋 所有模型额度'));
|
|
67
|
+
|
|
68
|
+
// 简化模型名称映射
|
|
69
|
+
const shortName = (name) => {
|
|
70
|
+
if (name.includes('MiniMax-M')) return 'MiniMax-M*';
|
|
71
|
+
if (name.includes('speech')) return 'speech-hd';
|
|
72
|
+
if (name.includes('Hailuo-2.3-Fast')) return 'Hailuo';
|
|
73
|
+
if (name.includes('Hailuo-2.3')) return 'Hailuo-2.3';
|
|
74
|
+
if (name.includes('Hailuo')) return 'Hailuo';
|
|
75
|
+
if (name.includes('music')) return 'music';
|
|
76
|
+
if (name.includes('image')) return 'image';
|
|
77
|
+
return name.length > 15 ? name.substring(0, 12) + '...' : name;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// 获取状态颜色
|
|
81
|
+
const getStatusColor = (percentage) => {
|
|
82
|
+
if (percentage >= 85) return chalk.red;
|
|
83
|
+
if (percentage >= 60) return chalk.yellow;
|
|
84
|
+
return chalk.green;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// 显示状态
|
|
88
|
+
const getStatusText = (percentage) => {
|
|
89
|
+
if (percentage >= 85) return '⚠';
|
|
90
|
+
if (percentage >= 60) return '⚡';
|
|
91
|
+
return '✓';
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// 每行显示一个模型
|
|
95
|
+
for (const model of this.allModels) {
|
|
96
|
+
const short = shortName(model.name);
|
|
97
|
+
const color = getStatusColor(model.percentage);
|
|
98
|
+
const status = getStatusText(model.percentage);
|
|
99
|
+
const pct = `${model.percentage}%`;
|
|
100
|
+
const usedTotal = `${model.used}/${model.total}`;
|
|
101
|
+
|
|
102
|
+
lines.push(` ${color(short.padEnd(15))} ${color(pct.padEnd(5))} ${color(usedTotal.padEnd(12))} ${color(status)}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return lines.join('\n');
|
|
106
|
+
}
|
|
107
|
+
|
|
57
108
|
// 辅助函数:填充内容到正确长度,处理 chalk 代码和中文字符
|
|
58
109
|
padLine(leftContent, rightContent) {
|
|
59
110
|
// 移除 chalk 代码以便计算
|
|
@@ -113,15 +164,21 @@ class StatusBar {
|
|
|
113
164
|
// 周用量(如果有数据)
|
|
114
165
|
if (weekly) {
|
|
115
166
|
contentLines.push('');
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
weeklyPercent
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
167
|
+
if (weekly.unlimited) {
|
|
168
|
+
// 不受限制
|
|
169
|
+
contentLines.push(`${chalk.cyan('周限额:')} ${chalk.green('不受限制')}`);
|
|
170
|
+
} else {
|
|
171
|
+
// 有限制,显示具体数据
|
|
172
|
+
const weeklyPercent = weekly.percentage;
|
|
173
|
+
const weeklyColor = weeklyPercent >= 85 ? chalk.red : weeklyPercent >= 60 ? chalk.yellow : chalk.green;
|
|
174
|
+
const weeklyProgress = this.createProgressBar(
|
|
175
|
+
Math.floor((weeklyPercent / 100) * 15),
|
|
176
|
+
15 - Math.floor((weeklyPercent / 100) * 15),
|
|
177
|
+
weeklyPercent
|
|
178
|
+
);
|
|
179
|
+
contentLines.push(`${chalk.cyan('周限额:')} ${weeklyColor(weeklyProgress)} ${weeklyColor(weekly.percentage + '%')} (${weekly.used}/${weekly.total})`);
|
|
180
|
+
contentLines.push(`${chalk.dim(' 重置:')} ${weekly.text}`);
|
|
181
|
+
}
|
|
125
182
|
}
|
|
126
183
|
|
|
127
184
|
// 添加到期行(如果可用)
|
|
@@ -135,6 +192,11 @@ class StatusBar {
|
|
|
135
192
|
contentLines.push(this.renderConsumptionStats());
|
|
136
193
|
}
|
|
137
194
|
|
|
195
|
+
// 添加所有模型额度(如果有数据)
|
|
196
|
+
if (this.allModels && this.allModels.length > 0) {
|
|
197
|
+
contentLines.push(this.renderAllModelsSection());
|
|
198
|
+
}
|
|
199
|
+
|
|
138
200
|
contentLines.push('');
|
|
139
201
|
|
|
140
202
|
// 状态行
|
|
@@ -216,6 +278,42 @@ class StatusBar {
|
|
|
216
278
|
|
|
217
279
|
return `${color('●')} ${modelName} ${usage.percentage}% ${chalk.dim(`(${usage.remaining}/${usage.total})`)} ${chalk.gray('•')} ${remaining.text} ${chalk.gray('•')} ${status}${expiryInfo}`;
|
|
218
280
|
}
|
|
281
|
+
|
|
282
|
+
// 渲染所有模型的额度
|
|
283
|
+
static renderAllModels(models) {
|
|
284
|
+
if (!models || models.length === 0) {
|
|
285
|
+
return '';
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const lines = [];
|
|
289
|
+
lines.push('');
|
|
290
|
+
lines.push(chalk.bold('📋 所有模型额度'));
|
|
291
|
+
|
|
292
|
+
// 表头
|
|
293
|
+
lines.push(chalk.gray('─'.repeat(55)));
|
|
294
|
+
lines.push(`│ ${chalk.cyan('模型').padEnd(30)} ${chalk.cyan('已用/总额').padEnd(15)} ${chalk.cyan('状态')}`);
|
|
295
|
+
lines.push(chalk.gray('─'.repeat(55)));
|
|
296
|
+
|
|
297
|
+
for (const model of models) {
|
|
298
|
+
// 颜色基于百分比
|
|
299
|
+
let color;
|
|
300
|
+
if (model.percentage >= 85) {
|
|
301
|
+
color = chalk.red;
|
|
302
|
+
} else if (model.percentage >= 60) {
|
|
303
|
+
color = chalk.yellow;
|
|
304
|
+
} else {
|
|
305
|
+
color = chalk.green;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const status = model.percentage >= 85 ? '⚠ 即将用完' : model.percentage >= 60 ? '⚡ 注意' : '✓ 正常';
|
|
309
|
+
const name = model.name.length > 28 ? model.name.substring(0, 25) + '...' : model.name;
|
|
310
|
+
|
|
311
|
+
lines.push(`│ ${name.padEnd(30)} ${color(`${model.used}/${model.total} (${model.percentage}%)`).padEnd(15)} ${color(status)}`);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
lines.push(chalk.gray('─'.repeat(55)));
|
|
315
|
+
return lines.join('\n');
|
|
316
|
+
}
|
|
219
317
|
}
|
|
220
318
|
|
|
221
319
|
module.exports = StatusBar;
|
package/cli/statusbar.js
CHANGED
|
@@ -10,7 +10,7 @@ class StatusBar {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
render() {
|
|
13
|
-
const { usage, remaining, modelName } = this.data;
|
|
13
|
+
const { usage, remaining, modelName, weekly } = this.data;
|
|
14
14
|
const percentage = usage.percentage;
|
|
15
15
|
|
|
16
16
|
// 基于已使用百分比:使用越多越危险
|
|
@@ -26,7 +26,17 @@ class StatusBar {
|
|
|
26
26
|
? `${remaining.hours}h${remaining.minutes}m`
|
|
27
27
|
: `${remaining.minutes}m`;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
let weeklyStr = '';
|
|
30
|
+
if (weekly) {
|
|
31
|
+
if (weekly.unlimited) {
|
|
32
|
+
weeklyStr = ` ${chalk.blue('W')} ♾️`;
|
|
33
|
+
} else {
|
|
34
|
+
const weeklyColor = weekly.percentage >= 85 ? chalk.red : weekly.percentage >= 60 ? chalk.yellow : chalk.green;
|
|
35
|
+
weeklyStr = ` ${chalk.blue('W')} ${weeklyColor(weekly.percentage + '%')}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return `${color('●')} ${modelName} ${color(percentage + '%')} (${usage.used}/${usage.total}) ${remainingText}${weeklyStr} ${statusIcon}`;
|
|
30
40
|
}
|
|
31
41
|
}
|
|
32
42
|
|