minimax-status 1.0.0

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 ADDED
@@ -0,0 +1,239 @@
1
+ # MiniMax StatusBar
2
+
3
+ [![npm version](https://img.shields.io/npm/v/minimax-status.svg)](https://www.npmjs.com/package/minimax-status)
4
+ [![npm downloads](https://img.shields.io/npm/dm/minimax-status.svg)](https://www.npmjs.com/package/minimax-status)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ MiniMax Claude Code 使用状态监控工具,支持 CLI 命令和 Claude Code 状态栏集成。
8
+
9
+ ![MiniMax StatusBar](https://img.shields.io/badge/StatusBar-MiniMax-blue?style=flat-square)
10
+
11
+ ## 特性
12
+
13
+ - ✅ **实时状态监控**: 显示 MiniMax Claude Code 使用额度、剩余次数、重置时间
14
+ - ✅ **多种显示模式**: 详细模式、紧凑模式、持续状态栏
15
+ - ✅ **Claude Code 集成**: 可在 Claude Code 底部状态栏显示
16
+ - ✅ **智能颜色编码**: 根据使用率自动切换颜色和图标
17
+ - ✅ **简洁命令**: `minimax status` 查看状态
18
+ - ✅ **安全存储**: 凭据存储在独立的配置文件中
19
+
20
+ ## 快速开始
21
+
22
+ ### 1. 安装
23
+
24
+ ```bash
25
+ npm install -g minimax-status
26
+ ```
27
+
28
+ ### 2. 配置认证
29
+
30
+ ```bash
31
+ minimax auth <token> <groupId>
32
+ ```
33
+
34
+ 配置信息将保存在 `~/.minimax-config.json` 文件中。
35
+
36
+ 获取令牌和组 ID:
37
+
38
+ 1. 访问 [MiniMax 开放平台](https://platform.minimaxi.com/user-center/payment/coding-plan)
39
+ 2. 登录并进入控制台
40
+ 3. 账户信息中复制 groupID
41
+ 4. Coding Plan 中创建或获取 API Key
42
+
43
+ ### 3. 查看状态
44
+
45
+ ```bash
46
+ # 详细模式
47
+ minimax status
48
+
49
+ # 紧凑模式
50
+ minimax status --compact
51
+
52
+ # 持续监控模式
53
+ minimax status --watch
54
+ ```
55
+
56
+ ## Claude Code 集成
57
+
58
+ 将 MiniMax 使用状态显示在 Claude Code 底部状态栏。
59
+
60
+ ### 配置步骤
61
+
62
+ 1. **安装和配置工具**:
63
+
64
+ ```bash
65
+ npm install -g minimax-status
66
+ minimax auth <token> <groupId>
67
+ ```
68
+
69
+ 2. **配置 Claude Code**:
70
+
71
+ 编辑 `~/.claude/settings.json`:
72
+
73
+ ```json
74
+ {
75
+ "statusLine": {
76
+ "command": "minimax statusline"
77
+ }
78
+ }
79
+ ```
80
+
81
+ 3. **重启 Claude Code**
82
+
83
+ 集成成功后,底部状态栏将显示:
84
+
85
+ ```
86
+ 📁 my-app | 🤖 MiniMax-M2 | 40% | ↻ 2690/4500 | 200K | ⏱️ 35m ✓
87
+ ```
88
+
89
+ 显示格式:`📁 目录 | 🤖 模型 | 使用率 | ↻ 剩余次数/总数 | 上下文窗口 | ⏱️ 剩余时间 状态图标`
90
+
91
+ **注意**: MiniMax 的配置独立存储在 `~/.minimax-config.json`,与 Claude Code 的配置分离。
92
+
93
+ ## 显示示例
94
+
95
+ ### 详细模式
96
+
97
+ ```
98
+ ┌─────────────────────────────────────────────────────────────┐
99
+ │ MiniMax Claude Code 使用状态 │
100
+ │ │
101
+ │ 当前模型: MiniMax-M2 │
102
+ │ 时间窗口: 10:00-15:00(UTC+8) │
103
+ │ 剩余时间: 1 小时 26 分钟后重置 │
104
+ │ │
105
+ │ 已用额度: █████████████████████░░░░░░░░░ 27% │
106
+ │ 剩余: 3307/4500 次调用 │
107
+ │ │
108
+ │ 状态: ✓ 正常使用 │
109
+ └─────────────────────────────────────────────────────────────┘
110
+ ```
111
+
112
+ ### 紧凑模式
113
+
114
+ ```
115
+ ● MiniMax-M2 27% • 1 小时 26 分钟后重置 • ✓ 正常使用
116
+ ```
117
+
118
+ ### 持续状态栏模式
119
+
120
+ ```
121
+ ✓ MiniMax 状态栏已启动
122
+ 按 Ctrl+C 退出
123
+
124
+ [?25l● MiniMax-M2 27% • 3307/4500 • 1h26m ⚡
125
+ ```
126
+
127
+ ## 命令说明
128
+
129
+ | 命令 | 描述 | 示例 |
130
+ | ---------------- | ---------------------------------- | -------------------------------- |
131
+ | `minimax auth` | 设置认证凭据 | `minimax auth <token> <groupId>` |
132
+ | `minimax status` | 显示当前使用状态(支持 --compact、--watch) | `minimax status` |
133
+ | `minimax bar` | 终端底部持续状态栏 | `minimax bar` |
134
+ | `minimax statusline` | Claude Code 状态栏集成 | 用于 Claude Code 配置 |
135
+
136
+ ## 状态说明
137
+
138
+ ### 状态图标
139
+
140
+ | 使用率 | 图标 | 含义 |
141
+ | ------ | ---- | ---------- |
142
+ | < 60% | ✓ | 正常使用 |
143
+ | 60-85% | ⚡ | 注意使用 |
144
+ | ≥ 85% | ⚠ | 危险状态 |
145
+
146
+ ## 配置文件
147
+
148
+ ### 默认位置
149
+
150
+ - 独立配置文件: `~/.minimax-config.json`
151
+
152
+ ### 配置示例
153
+
154
+ ```json
155
+ {
156
+ "token": "your_access_token_here",
157
+ "groupId": "your_group_id_here"
158
+ }
159
+ ```
160
+
161
+ ### Claude Code 配置
162
+
163
+ Claude Code 只需要配置状态栏命令,不包含 MiniMax 配置:
164
+
165
+ ```json
166
+ // ~/.claude/settings.json
167
+ {
168
+ "statusLine": {
169
+ "command": "minimax statusline"
170
+ }
171
+ }
172
+ ```
173
+
174
+ ### 安全说明
175
+
176
+ 凭据仅存储在本地,不会上传到任何服务器。
177
+
178
+ ## 故障排除
179
+
180
+ ### 命令未找到
181
+
182
+ ```bash
183
+ # 确保已全局安装
184
+ npm install -g minimax-status
185
+
186
+ # 重新打开终端
187
+ ```
188
+
189
+ ### 认证失败
190
+
191
+ ```bash
192
+ # 检查令牌和组 ID
193
+ minimax status
194
+
195
+ # 重新设置认证
196
+ minimax auth <new_token> <new_groupId>
197
+ ```
198
+
199
+ ### 状态栏不显示
200
+
201
+ 1. 检查 Claude Code 配置
202
+ 2. 重启 Claude Code
203
+ 3. 手动测试: `minimax statusline`
204
+
205
+ ## 开发
206
+
207
+ ### 构建项目
208
+
209
+ ```bash
210
+ git clone <repository>
211
+ cd minimax-status
212
+ npm install
213
+ ```
214
+
215
+ ### 测试
216
+
217
+ ```bash
218
+ # 运行示例
219
+ node cli/example.js
220
+
221
+ # 测试 CLI 命令
222
+ node cli/index.js status
223
+ ```
224
+
225
+ ## 许可证
226
+
227
+ MIT License - 详见 [LICENSE](LICENSE) 文件
228
+
229
+ ## 贡献
230
+
231
+ 欢迎提交 Issue 和 Pull Request!
232
+
233
+ ## 相关链接
234
+
235
+ - [MiniMax 开放平台](https://platform.minimaxi.com/)
236
+
237
+ ---
238
+
239
+ **注意**: 本工具仅用于监控 MiniMax Claude Code 使用状态,不存储或传输任何用户数据。
package/cli/index.js ADDED
@@ -0,0 +1,352 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require("commander");
4
+ const chalk = require("chalk").default;
5
+ const ora = require("ora").default;
6
+ const MinimaxAPI = require("./api");
7
+ const StatusBar = require("./status");
8
+
9
+ const program = new Command();
10
+ const api = new MinimaxAPI();
11
+
12
+ program
13
+ .name("minimax-status")
14
+ .description("MiniMax Claude Code 使用状态监控工具")
15
+ .version("1.0.0");
16
+
17
+ // Auth command
18
+ program
19
+ .command("auth")
20
+ .description("设置认证凭据")
21
+ .argument("<token>", "MiniMax 访问令牌")
22
+ .argument("<groupId>", "MiniMax 组 ID")
23
+ .action((token, groupId) => {
24
+ api.setCredentials(token, groupId);
25
+ console.log(chalk.green("✓ 认证信息已保存"));
26
+ });
27
+
28
+ // Status command
29
+ program
30
+ .command("status")
31
+ .description("显示当前使用状态")
32
+ .option("-c, --compact", "紧凑模式显示")
33
+ .option("-w, --watch", "实时监控模式")
34
+ .action(async (options) => {
35
+ const spinner = ora("获取使用状态中...").start();
36
+
37
+ try {
38
+ const apiData = await api.getUsageStatus();
39
+ const usageData = api.parseUsageData(apiData);
40
+ const statusBar = new StatusBar(usageData);
41
+
42
+ spinner.succeed("状态获取成功");
43
+
44
+ if (options.compact) {
45
+ console.log(statusBar.renderCompact());
46
+ } else {
47
+ console.log("\n" + statusBar.render() + "\n");
48
+ }
49
+
50
+ if (options.watch) {
51
+ console.log(chalk.gray("监控中... 按 Ctrl+C 退出"));
52
+ startWatching(api, statusBar);
53
+ }
54
+ } catch (error) {
55
+ spinner.fail(chalk.red("获取状态失败"));
56
+ console.error(chalk.red(`错误: ${error.message}`));
57
+ process.exit(1);
58
+ }
59
+ });
60
+
61
+ // List command
62
+ program
63
+ .command("list")
64
+ .description("显示所有模型的使用状态")
65
+ .action(async () => {
66
+ const spinner = ora("获取使用状态中...").start();
67
+
68
+ try {
69
+ const apiData = await api.getUsageStatus();
70
+ const usageData = api.parseUsageData(apiData);
71
+ const statusBar = new StatusBar(usageData);
72
+
73
+ spinner.succeed("状态获取成功");
74
+ console.log("\n" + statusBar.render() + "\n");
75
+ } catch (error) {
76
+ spinner.fail(chalk.red("获取状态失败"));
77
+ console.error(chalk.red(`错误: ${error.message}`));
78
+ process.exit(1);
79
+ }
80
+ });
81
+
82
+ // StatusBar command - 持续显示在终端底部
83
+ program
84
+ .command("bar")
85
+ .description("在终端底部持续显示状态栏(类似 ccline)")
86
+ .action(async () => {
87
+ const TerminalStatusBar = require("./statusbar");
88
+ const statusBar = new TerminalStatusBar();
89
+ await statusBar.start();
90
+ });
91
+
92
+ // 上下文窗口大小映射表(仅MiniMax模型)
93
+ const MODEL_CONTEXT_SIZES = {
94
+ "minimax-m2": 200000,
95
+ "minimax-m2-stable": 200000,
96
+ "minimax-m1": 200000,
97
+ "minimax-m1-stable": 200000,
98
+ };
99
+
100
+ // 解析转录文件,借鉴ccline的实现
101
+ async function parseTranscriptUsage(transcriptPath) {
102
+ const fs = require('fs').promises;
103
+ const path = require('path');
104
+
105
+ try {
106
+ const fileContent = await fs.readFile(transcriptPath, 'utf8');
107
+ const lines = fileContent.trim().split('\n');
108
+
109
+ if (lines.length === 0) {
110
+ return null;
111
+ }
112
+
113
+ // 解析最后一行JSON
114
+ const lastLine = lines[lines.length - 1].trim();
115
+ const lastEntry = JSON.parse(lastLine);
116
+
117
+ // 如果是summary类型,查找usage
118
+ if (lastEntry.type === 'summary' && lastEntry.leafUuid) {
119
+ // 在所有行中查找对应的leafUuid
120
+ for (let i = lines.length - 2; i >= 0; i--) {
121
+ const entry = JSON.parse(lines[i].trim());
122
+ if (entry.leafUuid === lastEntry.leafUuid) {
123
+ if (entry.message && entry.message.usage) {
124
+ return calculateUsageTokens(entry.message.usage);
125
+ }
126
+ break;
127
+ }
128
+ }
129
+ }
130
+
131
+ // 查找最新的assistant消息
132
+ for (let i = lines.length - 1; i >= 0; i--) {
133
+ const line = lines[i].trim();
134
+ if (!line) continue;
135
+
136
+ const entry = JSON.parse(line);
137
+ if (entry.type === 'assistant' && entry.message) {
138
+ if (entry.message.usage) {
139
+ return calculateUsageTokens(entry.message.usage);
140
+ }
141
+ }
142
+ }
143
+
144
+ return null;
145
+ } catch (error) {
146
+ return null;
147
+ }
148
+ }
149
+
150
+ // 计算token使用量(参考ccline的normalize逻辑)
151
+ function calculateUsageTokens(usage) {
152
+ // 根据不同格式计算display tokens
153
+ if (usage.total_tokens) {
154
+ return usage.total_tokens;
155
+ } else if (usage.input_tokens && usage.output_tokens) {
156
+ return usage.input_tokens + usage.output_tokens;
157
+ } else if (usage.context_tokens) {
158
+ return usage.context_tokens;
159
+ } else if (usage.cache_creation_input_tokens && usage.cache_read_input_tokens) {
160
+ return usage.input_tokens + usage.cache_creation_input_tokens + usage.cache_read_input_tokens;
161
+ }
162
+ return 0;
163
+ }
164
+
165
+ // Statusline command
166
+ program
167
+ .command("statusline")
168
+ .description("Claude Code状态栏集成(从stdin读取数据,输出单行状态)")
169
+ .action(async () => {
170
+ try {
171
+ // 读取stdin数据(如果可用)
172
+ let stdinData = null;
173
+ if (!process.stdin.isTTY) {
174
+ const chunks = [];
175
+ for await (const chunk of process.stdin) {
176
+ chunks.push(chunk);
177
+ }
178
+ const stdinString = Buffer.concat(chunks).toString();
179
+ if (stdinString.trim()) {
180
+ try {
181
+ stdinData = JSON.parse(stdinString);
182
+ } catch (e) {
183
+ // 忽略JSON解析错误
184
+ }
185
+ }
186
+ }
187
+
188
+ // 获取使用状态
189
+ const apiData = await api.getUsageStatus();
190
+ const usageData = api.parseUsageData(apiData);
191
+
192
+ // 构建状态信息
193
+ const { usage, modelName, remaining } = usageData;
194
+ const percentage = usage.percentage;
195
+
196
+ // 从stdin数据获取Claude Code信息
197
+ let displayModel = modelName;
198
+ let currentDir = null;
199
+ let modelId = null;
200
+ let contextSize = 200000; // 默认值
201
+
202
+ // 获取CLI当前目录
203
+ const cliCurrentDir = process.cwd().split(/[\\/]/).pop();
204
+
205
+ if (stdinData) {
206
+ // Claude Code传递的模型信息
207
+ if (stdinData.model && stdinData.model.display_name) {
208
+ displayModel = stdinData.model.display_name;
209
+ modelId = stdinData.model.id;
210
+ } else if (stdinData.model && stdinData.model.id) {
211
+ displayModel = stdinData.model.id;
212
+ modelId = stdinData.model.id;
213
+ }
214
+
215
+ // 当前工作目录(从stdin获取)
216
+ if (stdinData.workspace && stdinData.workspace.current_directory) {
217
+ currentDir = stdinData.workspace.current_directory.split('/').pop();
218
+ }
219
+ } else {
220
+ // 如果没有stdin,使用API返回的模型名作为ID
221
+ modelId = modelName.toLowerCase().replace(/\s+/g, '-');
222
+ }
223
+
224
+ // 查找上下文窗口大小
225
+ if (modelId) {
226
+ const modelKey = modelId.toLowerCase();
227
+ for (const [key, value] of Object.entries(MODEL_CONTEXT_SIZES)) {
228
+ if (modelKey.includes(key.toLowerCase())) {
229
+ contextSize = value;
230
+ break;
231
+ }
232
+ }
233
+ }
234
+
235
+ // 尝试从转录文件获取真实token使用量(类似ccline)
236
+ let contextUsageTokens = null;
237
+ let contextUsagePercentage = null;
238
+ if (stdinData && stdinData.transcript_path) {
239
+ contextUsageTokens = await parseTranscriptUsage(stdinData.transcript_path);
240
+ if (contextUsageTokens) {
241
+ contextUsagePercentage = Math.round((contextUsageTokens / contextSize) * 100);
242
+ }
243
+ }
244
+
245
+ const formatContextSize = (size) => {
246
+ if (size >= 1000000) {
247
+ return `${Math.round(size / 100000) / 10}M`;
248
+ } else if (size >= 1000) {
249
+ return `${Math.round(size / 1000)}K`;
250
+ }
251
+ return `${size}`;
252
+ };
253
+
254
+ const formatTokens = (tokens) => {
255
+ if (tokens >= 1000000) {
256
+ return `${Math.round(tokens / 100000) / 10}M`;
257
+ } else if (tokens >= 1000) {
258
+ return `${Math.round(tokens / 100) / 10}k`;
259
+ }
260
+ return `${tokens}`;
261
+ };
262
+
263
+ const contextSizeText = formatContextSize(contextSize);
264
+
265
+ // 状态图标(基于真实上下文使用情况,否则基于额度)
266
+ const displayPercentage = contextUsagePercentage || percentage;
267
+ const statusIcon = displayPercentage >= 85 ? "⚠" : displayPercentage >= 60 ? "⚡" : "✓";
268
+
269
+ // 剩余时间文本
270
+ const remainingText =
271
+ remaining.hours > 0
272
+ ? `${remaining.hours}h${remaining.minutes}m`
273
+ : `${remaining.minutes}m`;
274
+
275
+ // 构建带图标的状态行
276
+ let statusLine = '';
277
+
278
+ // 显示目录(优先使用Claude Code的目录,否则显示CLI当前目录)
279
+ const displayDir = currentDir || cliCurrentDir || '';
280
+ if (displayDir) {
281
+ statusLine += `📁 ${displayDir} | `;
282
+ }
283
+
284
+ // 模型信息
285
+ statusLine += `🤖 ${displayModel} | `;
286
+
287
+ // 账户使用额度百分比
288
+ statusLine += `${percentage}% | `;
289
+
290
+ // 剩余次数 - 使用更简洁的图标
291
+ statusLine += `↻ ${usage.used}/${usage.total} | `;
292
+
293
+ // 上下文使用情况(参考ccline:⚡ 百分比 · token数/总大小)
294
+ if (contextUsageTokens) {
295
+ statusLine += `⚡ ${displayPercentage}% · ${formatTokens(contextUsageTokens)}/${contextSizeText} | `;
296
+ } else {
297
+ // 没有转录数据时,显示上下文窗口大小
298
+ statusLine += `${contextSizeText} | `;
299
+ }
300
+
301
+ // 剩余时间和状态图标
302
+ statusLine += `⏱ ${remainingText} ${statusIcon}`;
303
+
304
+ // 输出单行状态(纯文本,无颜色)
305
+ console.log(statusLine);
306
+ } catch (error) {
307
+ // 输出错误状态(纯文本)
308
+ console.log(`❌ MiniMax 错误: ${error.message}`);
309
+ process.exit(1);
310
+ }
311
+ });
312
+
313
+ function startWatching(api, statusBar) {
314
+ let intervalId;
315
+
316
+ const update = async () => {
317
+ try {
318
+ const apiData = await api.getUsageStatus();
319
+ const usageData = api.parseUsageData(apiData);
320
+ const newStatusBar = new StatusBar(usageData);
321
+
322
+ // Clear previous output
323
+ process.stdout.write("\x1Bc");
324
+
325
+ console.log("\n" + newStatusBar.render() + "\n");
326
+ console.log(chalk.gray(`最后更新: ${new Date().toLocaleTimeString()}`));
327
+ } catch (error) {
328
+ console.error(chalk.red(`更新失败: ${error.message}`));
329
+ }
330
+ };
331
+
332
+ // Initial update
333
+ update();
334
+
335
+ // Update every 30 seconds
336
+ intervalId = setInterval(update, 30000);
337
+
338
+ // Handle Ctrl+C
339
+ process.on("SIGINT", () => {
340
+ clearInterval(intervalId);
341
+ console.log(chalk.yellow("\n监控已停止"));
342
+ process.exit(0);
343
+ });
344
+ }
345
+
346
+ // Show help if no command provided
347
+ if (!process.argv.slice(2).length) {
348
+ program.outputHelp();
349
+ process.exit(1);
350
+ }
351
+
352
+ program.parse();
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+
3
+ const chalk = require('chalk').default;
4
+ const readline = require('readline');
5
+ const MinimaxAPI = require('./api');
6
+
7
+ class StatusBar {
8
+ constructor(data) {
9
+ this.data = data;
10
+ }
11
+
12
+ render() {
13
+ const { usage, remaining, modelName } = this.data;
14
+ const percentage = usage.percentage;
15
+
16
+ // 基于已使用百分比:使用越多越危险
17
+ let color = chalk.green;
18
+ if (percentage >= 85) {
19
+ color = chalk.red;
20
+ } else if (percentage >= 60) {
21
+ color = chalk.yellow;
22
+ }
23
+
24
+ const statusIcon = percentage >= 85 ? '⚠' : percentage >= 60 ? '⚡' : '✓';
25
+ const remainingText = remaining.hours > 0
26
+ ? `${remaining.hours}h${remaining.minutes}m`
27
+ : `${remaining.minutes}m`;
28
+
29
+ return `${color('●')} ${modelName} ${color(percentage + '%')} (${usage.used}/${usage.total}) ${remainingText} ${statusIcon}`;
30
+ }
31
+ }
32
+
33
+ class TerminalStatusBar {
34
+ constructor() {
35
+ this.api = new MinimaxAPI();
36
+ this.currentLine = '';
37
+ this.isActive = false;
38
+ }
39
+
40
+ async start() {
41
+ const configPath = require('path').join(
42
+ process.env.HOME || process.env.USERPROFILE,
43
+ '.minimax-config.json'
44
+ );
45
+
46
+ if (!require('fs').existsSync(configPath)) {
47
+ console.log(chalk.red('错误:未找到配置文件'));
48
+ console.log(chalk.yellow('请先运行: minimax-status auth <token> <groupId>'));
49
+ process.exit(1);
50
+ }
51
+
52
+ this.isActive = true;
53
+ console.log(chalk.green('✓ MiniMax 状态栏已启动'));
54
+ console.log(chalk.gray('按 Ctrl+C 退出\n'));
55
+
56
+ // 隐藏光标
57
+ process.stdout.write('\x1B[?25l');
58
+ this.startUpdating();
59
+ }
60
+
61
+ async startUpdating() {
62
+ const update = async () => {
63
+ if (!this.isActive) return;
64
+
65
+ try {
66
+ const apiData = await this.api.getUsageStatus();
67
+ const usageData = this.api.parseUsageData(apiData);
68
+ const statusBar = new StatusBar(usageData);
69
+ const newLine = statusBar.render();
70
+
71
+ // 清除上一行并显示新状态
72
+ if (this.currentLine) {
73
+ readline.clearLine(process.stdout, 0);
74
+ readline.cursorTo(process.stdout, 0);
75
+ }
76
+
77
+ process.stdout.write(newLine);
78
+ this.currentLine = newLine;
79
+
80
+ // 移动光标到底部下一行
81
+ process.stdout.write('\n');
82
+ readline.cursorTo(process.stdout, 0);
83
+
84
+ } catch (error) {
85
+ // 显示错误但不退出
86
+ readline.clearLine(process.stdout, 0);
87
+ readline.cursorTo(process.stdout, 0);
88
+ process.stdout.write(chalk.red(`错误: ${error.message}`));
89
+ process.stdout.write('\n');
90
+ readline.cursorTo(process.stdout, 0);
91
+ }
92
+ };
93
+
94
+ // 立即更新一次
95
+ await update();
96
+
97
+ // 每 30 秒更新
98
+ setInterval(update, 30000);
99
+
100
+ // 处理 Ctrl+C
101
+ process.on('SIGINT', () => {
102
+ this.stop();
103
+ });
104
+
105
+ // 处理进程退出
106
+ process.on('exit', () => {
107
+ this.cleanup();
108
+ });
109
+ }
110
+
111
+ stop() {
112
+ this.isActive = false;
113
+ console.log(chalk.yellow('\n\n状态栏已停止'));
114
+ this.cleanup();
115
+ process.exit(0);
116
+ }
117
+
118
+ cleanup() {
119
+ // 显示光标
120
+ process.stdout.write('\x1B[?25h');
121
+
122
+ // 清除状态行
123
+ readline.clearLine(process.stdout, 0);
124
+ readline.cursorTo(process.stdout, 0);
125
+ }
126
+ }
127
+
128
+ // 如果直接运行此文件
129
+ if (require.main === module) {
130
+ const statusBar = new TerminalStatusBar();
131
+ statusBar.start().catch(error => {
132
+ console.error(chalk.red('启动失败:'), error.message);
133
+ process.exit(1);
134
+ });
135
+ }
136
+
137
+ module.exports = TerminalStatusBar;
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "minimax-status",
3
+ "version": "1.0.0",
4
+ "description": "MiniMax Claude Code 使用状态监控工具",
5
+ "bin": {
6
+ "minimax-status": "./cli/index.js",
7
+ "minimax": "./cli/index.js"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "keywords": [
13
+ "minimax",
14
+ "claude",
15
+ "status",
16
+ "monitor"
17
+ ],
18
+ "author": "Jochen Yang",
19
+ "license": "MIT",
20
+ "dependencies": {
21
+ "axios": "^1.13.2",
22
+ "boxen": "^8.0.1",
23
+ "chalk": "^5.6.2",
24
+ "commander": "^14.0.2",
25
+ "dayjs": "^1.11.19",
26
+ "ora": "^9.0.0"
27
+ }
28
+ }
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "minimax-status-vscode",
3
+ "displayName": "MiniMax Status",
4
+ "description": "在 VS Code 状态栏显示 MiniMax Claude Code 使用状态",
5
+ "version": "1.0.0",
6
+ "publisher": "your-name",
7
+ "engines": {
8
+ "vscode": "^1.74.0"
9
+ },
10
+ "categories": [
11
+ "Other"
12
+ ],
13
+ "activationEvents": [
14
+ "onStartupFinished"
15
+ ],
16
+ "main": "./extension.js",
17
+ "contributes": {
18
+ "configuration": {
19
+ "title": "MiniMax Status",
20
+ "properties": {
21
+ "minimaxStatus.token": {
22
+ "type": "string",
23
+ "default": "",
24
+ "description": "MiniMax 访问令牌",
25
+ "order": 1
26
+ },
27
+ "minimaxStatus.groupId": {
28
+ "type": "string",
29
+ "default": "",
30
+ "description": "MiniMax 组 ID",
31
+ "order": 2
32
+ },
33
+ "minimaxStatus.refreshInterval": {
34
+ "type": "number",
35
+ "default": 30,
36
+ "description": "刷新间隔(秒)",
37
+ "order": 3
38
+ },
39
+ "minimaxStatus.showTooltip": {
40
+ "type": "boolean",
41
+ "default": true,
42
+ "description": "显示详细提示信息",
43
+ "order": 4
44
+ }
45
+ }
46
+ }
47
+ },
48
+ "scripts": {
49
+ "lint": "eslint .",
50
+ "pretest": "npm run lint",
51
+ "test": "node ./test/runTest.js",
52
+ "package": "vsce package"
53
+ },
54
+ "devDependencies": {
55
+ "@types/vscode": "^1.74.0",
56
+ "eslint": "^8.56.0",
57
+ "@vscode/vsce": "^2.22.0"
58
+ },
59
+ "dependencies": {
60
+ "axios": "^1.6.2"
61
+ },
62
+ "keywords": [
63
+ "minimax",
64
+ "status",
65
+ "claude"
66
+ ],
67
+ "author": "",
68
+ "license": "ISC"
69
+ }