minimax-status 1.1.3 → 1.1.5

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 CHANGED
@@ -126,10 +126,10 @@ npm run package
126
126
  集成成功后,底部状态栏将显示:
127
127
 
128
128
  ```
129
- 📁 my-app | 🤖 MiniMax-M2 | 85%·150.0k tokens | 6%·4227/4500 | 1h20m | 1 CLAUDE.md | 8 rules | 6 MCPs | 到期: 5天
129
+ my-app main * │ MiniMax-M2 205K Usage ██████░░░░ 60% (2700/4500) 1h20m 到期 5天
130
130
  ```
131
131
 
132
- 显示格式:`📁 目录 | 🌿 分支 | 🤖 模型 | 上下文 | 使用量 | 重置 | 配置项 | 到期时间`
132
+ 显示格式:`目录 分支 模型 上下文 Usage 进度条 百分比(剩余/总数) 倒计时 到期 天数`
133
133
 
134
134
  **颜色说明**:
135
135
 
@@ -141,17 +141,14 @@ npm run package
141
141
  状态栏会显示当前 Git 分支信息:
142
142
 
143
143
  ```
144
- 📁 my-app | main ↓2 | 🤖 MiniMax-M2 | ...
144
+ my-app main * ...
145
145
  ```
146
146
 
147
147
  **符号说明**:
148
148
 
149
149
  | 符号 | 含义 |
150
150
  |------|------|
151
- | 🌿 | Git 分支图标(emoji) |
152
- | ⬆n | 有 n 个 commit 未推送到远程 |
153
- | ⬇n | 有 n 个 commit 未从远程拉取(优先显示) |
154
- | • | 有未提交的更改 |
151
+ | * | 有未提交的更改 |
155
152
 
156
153
  **颜色规则**:
157
154
 
@@ -183,6 +180,55 @@ npm run package
183
180
 
184
181
  **注意**: MiniMax 的配置独立存储在 `~/.minimax-config.json`,与 Claude Code 的配置分离。
185
182
 
183
+ ## Droid 集成
184
+
185
+ 将 MiniMax 使用状态显示在 Droid 底部状态栏。
186
+
187
+ ### 配置步骤
188
+
189
+ 1. **安装和配置工具**:
190
+
191
+ ```bash
192
+ npm install -g minimax-status
193
+ minimax auth <token> <groupId>
194
+ ```
195
+
196
+ 2. **配置 Droid**:
197
+
198
+ 编辑 `~/.factory/settings.json`:
199
+
200
+ ```json
201
+ {
202
+ "statusLine": {
203
+ "type": "command",
204
+ "command": "minimax droid-statusline"
205
+ }
206
+ }
207
+ ```
208
+
209
+ 3. **重启 Droid**
210
+
211
+ 集成成功后,底部状态栏将显示:
212
+
213
+ ```
214
+ minimax-status │ main * │ Usage █░░░░░░░░ 10% (4047/4500) │ ⏱ 12m │ 到期 21天
215
+ ```
216
+
217
+ 显示格式:`目录 │ 分支 │ Usage 进度条 百分比(剩余/总数) │ ⏱ 倒计时 │ 到期 天数`
218
+
219
+ ### 进度条风格
220
+
221
+ 使用 `█` 和 `░` 字符显示进度条:
222
+
223
+ - `█░░░░░░░░` - 10% 使用量
224
+ - `█████░░░░` - 50% 使用量
225
+ - `██████████` - 100% 使用量
226
+
227
+ **颜色说明**:
228
+
229
+ - **使用量**: ≥85%红色 | 60-85%黄色 | <60%绿色
230
+ - **到期时间**: ≤3天红色 | ≤7天黄色 | >7天绿色
231
+
186
232
  ## 显示示例
187
233
 
188
234
  ### 详细模式
@@ -225,26 +271,35 @@ npm run package
225
271
 
226
272
  ## 命令说明
227
273
 
228
- | 命令 | 描述 | 示例 |
229
- | -------------------- | ------------------------------------------- | -------------------------------- |
230
- | `minimax auth` | 设置认证凭据 | `minimax auth <token> <groupId>` |
231
- | `minimax status` | 显示当前使用状态(支持 --compact、--watch) | `minimax status` |
232
- | `minimax bar` | 终端底部持续状态栏 | `minimax bar` |
233
- | `minimax statusline` | Claude Code 状态栏集成 | 用于 Claude Code 配置 |
274
+ | 命令 | 描述 | 示例 |
275
+ | --------------------- | ------------------------------------------- | -------------------------------- |
276
+ | `minimax auth` | 设置认证凭据 | `minimax auth <token> <groupId>` |
277
+ | `minimax status` | 显示当前使用状态(支持 --compact、--watch) | `minimax status` |
278
+ | `minimax bar` | 终端底部持续状态栏 | `minimax bar` |
279
+ | `minimax statusline` | Claude Code 状态栏集成 | 用于 Claude Code 配置 |
280
+ | `minimax droid-statusline` | Droid 状态栏集成 | 用于 Droid 配置 |
234
281
 
235
282
  ## 状态说明
236
283
 
237
- ### 状态图标
238
-
239
- | 元素 | 图标 | 说明 |
240
- | ------ | ---- | ---------------------------------- |
241
- | 目录 | 📁 | 当前工作目录 |
242
- | 模型 | 🤖 | MiniMax 模型名称 |
243
- | 上下文 | | 上下文窗口使用率(百分比·已用tokens)|
244
- | 使用量 | | 使用率·剩余次数/总数 |
245
- | 重置 | | 额度重置倒计时 |
246
- | 配置项 | - | CLAUDE.md、rules、MCPs 数量 |
247
- | 到期 | - | 订阅到期时间(颜色动态变化) |
284
+ ### 显示元素
285
+
286
+ | 元素 | 说明 |
287
+ | ------ | ---------------------------------- |
288
+ | 目录 | 当前工作目录 |
289
+ | 分支 | Git 分支名称 |
290
+ | 模型 | MiniMax 模型名称 |
291
+ | 上下文 | 上下文窗口使用率 |
292
+ | Usage | 使用量进度条和百分比(剩余/总数) |
293
+ | | 额度重置倒计时 |
294
+ | 到期 | 订阅到期时间(颜色动态变化) |
295
+
296
+ ### 进度条
297
+
298
+ 使用 `█` 和 `░` 字符显示进度条:
299
+
300
+ - `█░░░░░░░░` - 10% 使用量
301
+ - `█████░░░░░` - 50% 使用量
302
+ - `██████████` - 100% 使用量
248
303
 
249
304
  ### 颜色规则
250
305
 
package/cli/index.js CHANGED
@@ -246,7 +246,7 @@ program
246
246
  let displayModel = modelName;
247
247
  let currentDir = null;
248
248
  let modelId = null;
249
- let contextSize = 200000;
249
+ let contextSize = 204800;
250
250
 
251
251
  if (stdinData) {
252
252
  if (stdinData.model && stdinData.model.display_name) {
@@ -265,13 +265,8 @@ program
265
265
  }
266
266
 
267
267
  if (modelId) {
268
- const modelKey = modelId.toLowerCase();
269
- for (const [key, value] of Object.entries(MODEL_CONTEXT_SIZES)) {
270
- if (modelKey.includes(key.toLowerCase())) {
271
- contextSize = value;
272
- break;
273
- }
274
- }
268
+ // MiniMax 模型统一使用 208K context window
269
+ contextSize = 204800;
275
270
  }
276
271
 
277
272
  let contextUsageTokens = null;
@@ -282,9 +277,18 @@ program
282
277
  const displayDir = currentDir || cliCurrentDir || "";
283
278
 
284
279
  let configCounts = { claudeMdCount: 0, rulesCount: 0, mcpCount: 0, hooksCount: 0 };
285
- const workspacePath = stdinData?.workspace?.current_directory;
286
- if (workspacePath && typeof workspacePath === 'string') {
287
- configCounts = await configCounter.count(workspacePath);
280
+ // 优先使用 stdin 传入的 workspacePath,否则 fallback 到 process.cwd()
281
+ const workspacePath = stdinData?.workspace?.current_directory || process.cwd();
282
+ if (workspacePath) {
283
+ try {
284
+ // 添加超时防止挂起
285
+ configCounts = await Promise.race([
286
+ configCounter.count(workspacePath),
287
+ new Promise((_, reject) => setTimeout(() => reject(new Error('config timeout')), 2000))
288
+ ]);
289
+ } catch (e) {
290
+ // 超时或失败,保持默认值
291
+ }
288
292
  }
289
293
 
290
294
  // 获取 git 分支信息
@@ -301,12 +305,14 @@ program
301
305
  gitBranch = { name: branch };
302
306
 
303
307
  // 获取 ahead/behind
308
+ let hasUpstream = false;
304
309
  try {
305
310
  const revList = require('child_process').execSync(
306
311
  'git rev-list --left-right --count HEAD...@{upstream}',
307
312
  { cwd: gitSearchPath, encoding: 'utf8', timeout: 3000 }
308
313
  ).trim();
309
314
  if (revList) {
315
+ hasUpstream = true;
310
316
  const [behind, ahead] = revList.split(/\s+/).map(n => parseInt(n) || 0);
311
317
  if (ahead > 0 || behind > 0) {
312
318
  gitBranch.ahead = ahead;
@@ -317,6 +323,23 @@ program
317
323
  // 无 upstream 或获取失败,静默跳过
318
324
  }
319
325
 
326
+ // 如果没有 upstream,尝试获取本地 commit 数作为提示
327
+ if (!hasUpstream) {
328
+ try {
329
+ const localCommits = require('child_process').execSync(
330
+ 'git rev-list --count HEAD',
331
+ { cwd: gitSearchPath, encoding: 'utf8', timeout: 3000 }
332
+ ).trim();
333
+ const commitCount = parseInt(localCommits) || 0;
334
+ // 如果有本地 commits(大于1,因为初始commit算1个),标记有待推送
335
+ if (commitCount > 1) {
336
+ gitBranch.ahead = -1; // -1 表示有未知数量的待推送
337
+ }
338
+ } catch (e) {
339
+ // 获取失败,静默跳过
340
+ }
341
+ }
342
+
320
343
  // 检查未提交的更改
321
344
  try {
322
345
  const status = require('child_process').execSync(
@@ -373,13 +396,303 @@ program
373
396
  }
374
397
  });
375
398
 
376
- // 模型上下文窗口大小映射表(仅MiniMax模型)
377
- const MODEL_CONTEXT_SIZES = {
378
- "minimax-m2": 200000,
379
- "minimax-m2-stable": 200000,
380
- "minimax-m1": 200000,
381
- "minimax-m1-stable": 200000,
382
- };
399
+ // Droid-statusline command - Droid 状态栏集成(从 session 文件读取数据)
400
+ program
401
+ .command("droid-statusline")
402
+ .description("Droid状态栏集成(从 session 文件读取数据,单次输出)")
403
+ .argument("[sessionPath]", "Droid session 目录路径(可选,默认自动查找)")
404
+ .action(async (sessionPath) => {
405
+ const fs = require("fs");
406
+ const path = require("path");
407
+
408
+ // 查找 session 目录
409
+ let targetSessionPath = sessionPath;
410
+ const currentCwd = process.cwd().replace(/\\/g, "/");
411
+
412
+ if (!targetSessionPath) {
413
+ const sessionsDir = path.join(process.env.HOME || process.env.USERPROFILE, ".factory", "sessions");
414
+
415
+ if (!fs.existsSync(sessionsDir)) {
416
+ console.log("❌ 未找到 Droid sessions 目录");
417
+ process.exit(1);
418
+ }
419
+
420
+ // 优先查找与当前工作目录匹配的 session
421
+ const userDirs = fs.readdirSync(sessionsDir);
422
+ let matchedSession = null;
423
+ let latestSession = null;
424
+ let latestStartTime = 0;
425
+
426
+ for (const userDir of userDirs) {
427
+ const userPath = path.join(sessionsDir, userDir);
428
+ if (!fs.statSync(userPath).isDirectory()) continue;
429
+
430
+ const sessions = fs.readdirSync(userPath);
431
+ for (const session of sessions) {
432
+ if (!session.endsWith(".jsonl")) continue;
433
+
434
+ const jsonlPath = path.join(userPath, session);
435
+ try {
436
+ const content = fs.readFileSync(jsonlPath, "utf8");
437
+ const firstLine = content.split("\n")[0];
438
+ const entry = JSON.parse(firstLine);
439
+
440
+ if (entry.cwd) {
441
+ const sessionCwd = entry.cwd.replace(/\\/g, "/");
442
+ // 优先匹配当前工作目录
443
+ if (sessionCwd === currentCwd || currentCwd.includes(sessionCwd) || sessionCwd.includes(currentCwd)) {
444
+ if (!matchedSession) {
445
+ matchedSession = userPath;
446
+ }
447
+ }
448
+ }
449
+
450
+ // 记录最新 session
451
+ if (entry.timestamp) {
452
+ const startTime = new Date(entry.timestamp).getTime();
453
+ if (startTime > latestStartTime) {
454
+ latestStartTime = startTime;
455
+ latestSession = userPath;
456
+ }
457
+ }
458
+ } catch (e) {
459
+ // continue
460
+ }
461
+ }
462
+ }
463
+
464
+ // 优先使用匹配的 session,否则用最新的
465
+ targetSessionPath = matchedSession || latestSession;
466
+
467
+ if (!targetSessionPath) {
468
+ console.log("❌ 未找到 Droid session");
469
+ process.exit(1);
470
+ }
471
+ }
472
+
473
+ // 读取 settings.json
474
+ const settingsFiles = fs.readdirSync(targetSessionPath).filter(f => f.endsWith(".settings.json"));
475
+ let settings = {};
476
+
477
+ for (const sf of settingsFiles) {
478
+ try {
479
+ const content = fs.readFileSync(path.join(targetSessionPath, sf), "utf8");
480
+ const parsed = JSON.parse(content);
481
+ if (parsed.tokenUsage) {
482
+ settings = parsed;
483
+ break;
484
+ }
485
+ } catch (e) {
486
+ // continue
487
+ }
488
+ }
489
+
490
+ // 读取 jsonl 获取 cwd 和模型信息,以及实时 token 使用量
491
+ let cwd = process.cwd();
492
+ let jsonlTokens = null;
493
+ const jsonlFiles = fs.readdirSync(targetSessionPath).filter(f => f.endsWith(".jsonl"));
494
+
495
+ for (const jf of jsonlFiles) {
496
+ try {
497
+ const content = fs.readFileSync(path.join(targetSessionPath, jf), "utf8");
498
+ const lines = content.split('\n').filter(l => l.trim());
499
+
500
+ // 获取第一行获取 cwd
501
+ if (lines.length > 0) {
502
+ try {
503
+ const firstEntry = JSON.parse(lines[0]);
504
+ if (firstEntry.cwd) {
505
+ cwd = firstEntry.cwd;
506
+ }
507
+ } catch (e) {}
508
+ }
509
+
510
+ // 从最后的消息中解析实时 token 使用量
511
+ for (let i = lines.length - 1; i >= 0; i--) {
512
+ try {
513
+ const entry = JSON.parse(lines[i]);
514
+ // 查找 assistant 消息中的 usage
515
+ if (entry.type === 'message' && entry.message?.role === 'assistant' && entry.message?.usage) {
516
+ const u = entry.message.usage;
517
+ jsonlTokens = {
518
+ inputTokens: u.input_tokens || u.prompt_tokens || 0,
519
+ outputTokens: u.output_tokens || u.completion_tokens || 0,
520
+ cacheCreationTokens: u.cache_creation_input_tokens || u.cache_creation_prompt_tokens || 0,
521
+ cacheReadTokens: u.cache_read_input_tokens || u.cache_read_prompt_tokens || 0,
522
+ thinkingTokens: u.thinking_tokens || 0
523
+ };
524
+ break;
525
+ }
526
+ } catch (e) {
527
+ continue;
528
+ }
529
+ }
530
+ } catch (e) {
531
+ // continue
532
+ }
533
+ }
534
+
535
+ const currentDir = cwd.split(/[/\\]/).pop();
536
+
537
+ // 优先使用 jsonl 中的实时 token 使用量,否则用 settings 中的累计值
538
+ const tokenUsage = (jsonlTokens && (jsonlTokens.inputTokens > 0 || jsonlTokens.outputTokens > 0))
539
+ ? jsonlTokens
540
+ : (settings.tokenUsage || {});
541
+
542
+ const inputTokens = tokenUsage.inputTokens || 0;
543
+ const outputTokens = tokenUsage.outputTokens || 0;
544
+ const cacheCreationTokens = tokenUsage.cacheCreationTokens || 0;
545
+ const cacheReadTokens = tokenUsage.cacheReadTokens || 0;
546
+ const thinkingTokens = tokenUsage.thinkingTokens || 0;
547
+
548
+ // 实时上下文使用量(不包括累计的 cacheReadTokens)
549
+ const contextTokens = inputTokens + outputTokens + cacheCreationTokens + thinkingTokens;
550
+ // 累计 token(用于显示)
551
+ const totalTokens = inputTokens + outputTokens + cacheCreationTokens + cacheReadTokens + thinkingTokens;
552
+
553
+ // 获取模型信息
554
+ const modelName = settings.model || "MiniMax-M2.5-highspeed";
555
+ const modelDisplayName = modelName.replace(/^custom:/, "").replace(/-[0-9]+$/, "");
556
+
557
+ // 获取 API 使用量
558
+ let usageData = null;
559
+ try {
560
+ const [apiData, subscriptionData] = await Promise.all([
561
+ api.getUsageStatus(),
562
+ api.getSubscriptionDetails(),
563
+ ]);
564
+ usageData = api.parseUsageData(apiData, subscriptionData);
565
+ } catch (e) {
566
+ usageData = {
567
+ usage: { percentage: 0, input: 0, output: 0, cached: 0, total: 0 },
568
+ remaining: "未知",
569
+ expiry: "未知",
570
+ modelName: modelDisplayName
571
+ };
572
+ }
573
+
574
+ const { usage, remaining, expiry } = usageData;
575
+
576
+ // 获取 git 分支
577
+ let gitBranch = null;
578
+ try {
579
+ const branch = require('child_process').execSync(
580
+ 'git symbolic-ref --short HEAD',
581
+ { cwd: cwd, encoding: 'utf8', timeout: 3000 }
582
+ ).trim();
583
+ if (branch) {
584
+ gitBranch = { name: branch };
585
+
586
+ // 检查未提交的更改
587
+ try {
588
+ const status = require('child_process').execSync(
589
+ 'git status --porcelain',
590
+ { cwd: cwd, encoding: 'utf8', timeout: 3000 }
591
+ ).trim();
592
+ if (status) {
593
+ gitBranch.hasChanges = true;
594
+ }
595
+ } catch (e) {
596
+ // ignore
597
+ }
598
+ }
599
+ } catch (e) {
600
+ // 非 git 目录
601
+ }
602
+
603
+ // 计算上下文使用量(从 session 实时 token)
604
+ // 使用实时 contextTokens 计算百分比
605
+ const contextUsageValue = contextTokens;
606
+ const contextSizeValue = 204800; // MiniMax M2 context window
607
+
608
+ // 获取 Droid 全局配置统计(不是当前工作目录)
609
+ const droidConfigDir = path.join(process.env.HOME || process.env.USERPROFILE, ".factory");
610
+ let configCounts = { claudeMdCount: 0, rulesCount: 0, mcpCount: 0, hooksCount: 0, skillsCount: 0 };
611
+
612
+ try {
613
+ const agentsPath = path.join(droidConfigDir, "agents");
614
+ const rulesPath = path.join(droidConfigDir, "rules");
615
+ const skillsPath = path.join(droidConfigDir, "skills");
616
+ const hooksPath = path.join(droidConfigDir, "hooks");
617
+ const mcpPath = path.join(droidConfigDir, "mcp.json");
618
+
619
+ if (fs.existsSync(agentsPath)) {
620
+ configCounts.claudeMdCount = fs.readdirSync(agentsPath).filter(f => f.endsWith(".md")).length;
621
+ }
622
+ if (fs.existsSync(rulesPath)) {
623
+ configCounts.rulesCount = fs.readdirSync(rulesPath).filter(f => f.endsWith(".md")).length;
624
+ }
625
+ if (fs.existsSync(skillsPath)) {
626
+ configCounts.skillsCount = fs.readdirSync(skillsPath).filter(f => f.endsWith(".md")).length;
627
+ }
628
+ if (fs.existsSync(hooksPath)) {
629
+ configCounts.hooksCount = fs.readdirSync(hooksPath).filter(f => f.endsWith(".ps1") || f.endsWith(".sh")).length;
630
+ }
631
+ if (fs.existsSync(mcpPath)) {
632
+ try {
633
+ const mcpData = JSON.parse(fs.readFileSync(mcpPath, "utf8"));
634
+ if (mcpData.mcpServers) {
635
+ configCounts.mcpCount = Object.keys(mcpData.mcpServers).length;
636
+ }
637
+ } catch (e) {}
638
+ }
639
+ } catch (e) {
640
+ // ignore errors
641
+ }
642
+
643
+ // 进度条渲染函数
644
+ function getBarColor(p) {
645
+ if (p >= 85) return chalk.red;
646
+ if (p >= 60) return chalk.yellow;
647
+ return chalk.green;
648
+ }
649
+ const coloredBar = (percent, width = 10) => {
650
+ const filled = Math.round((percent / 100) * width);
651
+ const empty = width - filled;
652
+ const barColor = getBarColor(percent);
653
+ return barColor('█'.repeat(filled) + '\x1b[2m' + '░'.repeat(empty) + '\x1b[0m');
654
+ };
655
+
656
+ // 简化输出:目录 | git分支 | 使用量(进度条) | 倒计时
657
+ const parts = [];
658
+
659
+ // 目录
660
+ if (currentDir) {
661
+ parts.push(`${chalk.cyan(currentDir)}`);
662
+ }
663
+
664
+ // Git 分支
665
+ if (gitBranch && gitBranch.name) {
666
+ const isMainBranch = gitBranch.name === 'main' || gitBranch.name === 'master';
667
+ const branchColor = isMainBranch ? chalk.green : chalk.white;
668
+ let branchStr = branchColor(gitBranch.name);
669
+ if (gitBranch.hasChanges) {
670
+ branchStr += chalk.red(' *');
671
+ }
672
+ parts.push(branchStr);
673
+ }
674
+
675
+ // 使用量 - 进度条风格 (显示次数)
676
+ const usageBar = coloredBar(usage.percentage);
677
+ const usageColor = usage.percentage >= 85 ? chalk.red : usage.percentage >= 60 ? chalk.yellow : chalk.green;
678
+ parts.push(`${chalk.yellow('Usage')} ${usageBar} ${usageColor(usage.percentage + '%')} (${usage.remaining}/${usage.total})`);
679
+
680
+ // 倒计时
681
+ const remainingText = remaining.hours > 0
682
+ ? `${remaining.hours}h${remaining.minutes}m`
683
+ : `${remaining.minutes}m`;
684
+ parts.push(`${chalk.yellow('⏱')} ${remainingText}`);
685
+
686
+ // 到期
687
+ if (expiry) {
688
+ const expiryColor = expiry.daysRemaining <= 3 ? chalk.red : expiry.daysRemaining <= 7 ? chalk.yellow : chalk.green;
689
+ parts.push(`${expiryColor('到期 ' + expiry.daysRemaining + '天')}`);
690
+ }
691
+
692
+ console.log(parts.join(' │ '));
693
+ });
694
+
695
+ // 模型上下文窗口大小(仅MiniMax模型)
383
696
 
384
697
  function startWatching(api, statusBar) {
385
698
  let intervalId;
package/cli/renderer.js CHANGED
@@ -75,7 +75,7 @@ class Renderer {
75
75
  const parts = [];
76
76
 
77
77
  if (currentDir) {
78
- parts.push(`${chalk.blue('📁')} ${chalk.cyan(currentDir)}`);
78
+ parts.push(`${chalk.cyan(currentDir)}`);
79
79
  }
80
80
 
81
81
  // Git 分支显示
@@ -86,62 +86,49 @@ class Renderer {
86
86
  const isMainBranch = name === 'main' || name === 'master';
87
87
  const branchColor = isMainBranch ? chalk.green : chalk.white;
88
88
 
89
- // 构建分支显示字符串(使用 emoji 图标)
90
- let branchStr = branchColor('🌿 ' + name);
89
+ // 构建分支显示字符串
90
+ let branchStr = branchColor(name);
91
91
 
92
- // 优先显示 behind(未拉取),不同时显示 ahead 和 behind
93
- if (behind > 0) {
94
- branchStr += chalk.cyan(' ⬇' + behind);
95
- } else if (ahead > 0) {
96
- branchStr += chalk.yellow(' ⬆' + ahead);
97
- }
98
-
99
- // 未提交更改用红色点
92
+ // 未提交更改用 * 标记
100
93
  if (hasChanges) {
101
- branchStr += chalk.red(' ');
94
+ branchStr += chalk.red(' *');
102
95
  }
103
96
 
104
97
  parts.push(branchStr);
105
98
  }
106
99
 
107
- parts.push(`${chalk.magenta('🤖')} ${chalk.magenta(modelName)}`);
100
+ // 模型
101
+ parts.push(`${chalk.magenta(modelName)}`);
108
102
 
109
- // 上下文窗口在前
103
+ // 上下文窗口
110
104
  if (contextUsage !== null && contextUsage !== undefined) {
111
105
  const contextPercent = Math.round((contextUsage / contextSize) * 100);
112
106
  const contextColor = this.getStatusColor(contextPercent);
113
- // 合并百分比和实际使用量,用 · 分割,统一颜色
114
- const contextStr = `${contextColor('⚡' + contextPercent + '%')}${contextColor('·')}${contextColor(this.formatTokens(contextUsage) + ' tokens')}`;
115
- parts.push(contextStr);
107
+ parts.push(`${contextColor(contextPercent + '%')} ${chalk.gray(this.formatTokens(contextUsage))}`);
116
108
  } else {
117
- parts.push(`${chalk.cyan(this.formatContextSize(contextSize))}`);
109
+ parts.push(chalk.cyan(this.formatContextSize(contextSize)));
118
110
  }
119
111
 
120
- // 使用量合并
112
+ // 使用量 - 进度条风格
121
113
  const usageColor = this.getStatusColor(usagePercentage);
122
- parts.push(`${chalk.yellow('↻')} ${usageColor(usagePercentage + '%')}${chalk.yellow('·')}${chalk.white(usage.remaining + '/' + usage.total)}`);
114
+ const filled = Math.round((usagePercentage / 100) * 10);
115
+ const empty = 10 - filled;
116
+ const usageBar = usageColor('█'.repeat(filled) + '\x1b[2m' + '░'.repeat(empty) + '\x1b[0m');
117
+ parts.push(`${chalk.yellow('Usage')} ${usageBar} ${usageColor(usagePercentage + '%')} (${usage.remaining}/${usage.total})`);
123
118
 
119
+ // 倒计时 - 保留图标
124
120
  const remainingText = remaining.hours > 0
125
121
  ? `${remaining.hours}h${remaining.minutes}m`
126
122
  : `${remaining.minutes}m`;
127
- parts.push(`${chalk.yellow('')} ${chalk.white(remainingText)}`);
123
+ parts.push(`${chalk.yellow('')} ${remainingText}`);
128
124
 
129
- if (configCounts.claudeMdCount > 0) {
130
- parts.push(`${chalk.white(configCounts.claudeMdCount + ' CLAUDE.md')}`);
131
- }
132
- if (configCounts.rulesCount > 0) {
133
- parts.push(`${chalk.cyan(configCounts.rulesCount + ' rules')}`);
134
- }
135
- if (configCounts.mcpCount > 0) {
136
- parts.push(`${chalk.yellow(configCounts.mcpCount + ' MCPs')}`);
137
- }
138
-
125
+ // 到期 - 保留图标
139
126
  if (expiry) {
140
127
  const expiryColor = expiry.daysRemaining <= 3 ? chalk.red : expiry.daysRemaining <= 7 ? chalk.yellow : chalk.green;
141
- parts.push(`${expiryColor('到期: ' + expiry.daysRemaining + '天')}`);
128
+ parts.push(`${expiryColor('到期 ' + expiry.daysRemaining + '天')}`);
142
129
  }
143
130
 
144
- return parts.join(' | ');
131
+ return parts.join(' ');
145
132
  }
146
133
 
147
134
  renderToolsLine(tools) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minimax-status",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "MiniMax Claude Code 使用状态监控工具",
5
5
  "bin": {
6
6
  "minimax-status": "cli/index.js",