minimax-status 1.1.2 → 1.1.4

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,21 +126,49 @@ npm run package
126
126
  集成成功后,底部状态栏将显示:
127
127
 
128
128
  ```
129
- 📁 my-app | 🤖 MiniMax-M2 | ⚡ 85% | 200K | ↻ 6%·4227/4500 | ⌛ 1h20m | 到期: 5天
129
+ 📁 my-app | 🤖 MiniMax-M2 | ⚡ 85%·150.0k tokens | ↻ 6%·4227/4500 | ⌛ 1h20m | 1 CLAUDE.md | 8 rules | 6 MCPs | 到期: 5天
130
130
  ```
131
131
 
132
- 显示格式:`📁 目录 | 🤖 模型 | 上下文窗口 | ↻ 使用率·剩余次数/总数 | ⌛ 重置时间 | 到期时间`
132
+ 显示格式:`📁 目录 | 🌿 分支 | 🤖 模型 | 上下文 | ↻ 使用量 | ⌛ 重置 | 配置项 | 到期时间`
133
133
 
134
134
  **颜色说明**:
135
135
 
136
+ - **上下文使用量**: ≥85%红色 | 60-85%黄色 | <60%绿色
136
137
  - **到期时间**: ≤3天红色 | ≤7天黄色 | >7天绿色
137
138
 
139
+ ### Git 分支显示说明
140
+
141
+ 状态栏会显示当前 Git 分支信息:
142
+
143
+ ```
144
+ 📁 my-app | ✦ main ↓2 • | 🤖 MiniMax-M2 | ...
145
+ ```
146
+
147
+ **符号说明**:
148
+
149
+ | 符号 | 含义 |
150
+ |------|------|
151
+ | 🌿 | Git 分支图标(emoji) |
152
+ | ⬆n | 有 n 个 commit 未推送到远程 |
153
+ | ⬇n | 有 n 个 commit 未从远程拉取(优先显示) |
154
+ | • | 有未提交的更改 |
155
+
156
+ **颜色规则**:
157
+
158
+ | 元素 | 颜色 | 说明 |
159
+ |------|------|------|
160
+ | 主分支 (main/master) | 绿色 | 默认/主分支 |
161
+ | 其他分支 | 白色 | 普通功能分支 |
162
+ | ⬆ 未推送 | 黄色 | 有待推送的 commit |
163
+ | ⬇ 未拉取 | 青色 | 有待拉取的 commit |
164
+ | • 未提交 | 红色 | 工作区有未提交的更改 |
165
+
138
166
  ### 上下文窗口显示说明
139
167
 
140
168
  状态栏会智能显示当前会话的上下文窗口使用情况:
141
169
 
142
- - **有转录数据时**: 显示 `⚡ 百分比 · 已用tokens/总容量`
143
- - 例如: `⚡ 85% | 200K` 表示已使用 200K tokens,占容量的 85%
170
+ - **有转录数据时**: 显示 `⚡ 百分比·已用 tokens`
171
+ - 例如: `⚡ 85%·150.0k tokens` 表示已使用 150K tokens,占容量的 85%
144
172
 
145
173
  - **无转录数据时**: 仅显示上下文窗口总容量
146
174
  - 例如: `200K` 表示当前模型的上下文窗口大小
@@ -164,11 +192,17 @@ npm run package
164
192
  │ MiniMax Claude Code 使用状态 │
165
193
  │ │
166
194
  │ 当前模型: MiniMax-M2 │
167
- │ 时间窗口: 10:00-15:00(UTC+8) │
168
- │ 剩余时间: 1 小时 26 分钟后重置 │
195
+ │ 时间窗口: 20:00-00:00(UTC+8) │
196
+ │ 剩余时间: 1 小时 42 分钟后重置 │
197
+ │ │
198
+ │ 已用额度: █████░░░░░░░░░░░░░░░░░░░░░░░ 6% │
199
+ │ 剩余: 4234/4500 次调用 │
200
+ │ 套餐到期: 02/26/2026(还剩 6 天) │
169
201
  │ │
170
- 已用额度: █████████████████████░░░░░░░░░ 27%
171
- 剩余: 3307/4500 次调用
202
+ Token 消耗统计:
203
+ 昨日消耗: 4996.4万
204
+ │ 近7天消耗: 2.8亿 │
205
+ │ 套餐总消耗: 14.7亿 │
172
206
  │ │
173
207
  │ 状态: ✓ 正常使用 │
174
208
  └─────────────────────────────────────────────────────────────┘
@@ -186,7 +220,7 @@ npm run package
186
220
  ✓ MiniMax 状态栏已启动
187
221
  按 Ctrl+C 退出
188
222
 
189
- [?25l● MiniMax-M2 27% • 3307/4500 • 1h26m ⚡
223
+ [● MiniMax-M2 27% • 3307/4500 • 1h26m ⚡
190
224
  ```
191
225
 
192
226
  ## 命令说明
@@ -202,22 +236,23 @@ npm run package
202
236
 
203
237
  ### 状态图标
204
238
 
205
- | 元素 | 图标 | 说明 |
206
- | ------ | ---- | ---------------------------- |
207
- | 目录 | 📁 | 当前工作目录 |
208
- | 模型 | 🤖 | MiniMax 模型名称 |
209
- | 上下文 | ⚡ | 上下文窗口使用率 |
210
- | 使用量 | ↻ | 使用率·剩余次数/总数 |
211
- | 重置 | ⌛ | 额度重置倒计时 |
212
- | 到期 | - | 订阅到期时间(颜色动态变化) |
239
+ | 元素 | 图标 | 说明 |
240
+ | ------ | ---- | ---------------------------------- |
241
+ | 目录 | 📁 | 当前工作目录 |
242
+ | 模型 | 🤖 | MiniMax 模型名称 |
243
+ | 上下文 | ⚡ | 上下文窗口使用率(百分比·已用tokens)|
244
+ | 使用量 | ↻ | 使用率·剩余次数/总数 |
245
+ | 重置 | ⌛ | 额度重置倒计时 |
246
+ | 配置项 | - | CLAUDE.md、rules、MCPs 数量 |
247
+ | 到期 | - | 订阅到期时间(颜色动态变化) |
213
248
 
214
249
  ### 颜色规则
215
250
 
216
251
  | 场景 | 颜色 | 说明 |
217
252
  | ------------- | ---- | -------- |
218
- | 使用率 < 60% | 绿色 | 正常使用 |
219
- | 使用率 60-85% | 黄色 | 注意使用 |
220
- | 使用率 ≥ 85% | 红色 | 危险状态 |
253
+ | 上下文 ≥85% | 红色 | 危险状态 |
254
+ | 上下文 60-85% | 黄色 | 注意使用 |
255
+ | 上下文 <60% | 绿色 | 正常使用 |
221
256
  | 到期 ≤ 3天 | 红色 | 即将到期 |
222
257
  | 到期 ≤ 7天 | 黄色 | 即将到期 |
223
258
  | 到期 > 7天 | 绿色 | 订阅正常 |
package/cli/index.js CHANGED
@@ -204,16 +204,30 @@ program
204
204
  .action(async () => {
205
205
  let stdinData = null;
206
206
  if (!process.stdin.isTTY) {
207
- const chunks = [];
208
- for await (const chunk of process.stdin) {
209
- chunks.push(chunk);
210
- }
211
- const stdinString = Buffer.concat(chunks).toString();
212
- if (stdinString.trim()) {
213
- try {
214
- stdinData = JSON.parse(stdinString);
215
- } catch (e) {
207
+ // 使用 Promise.race 添加超时,避免 Claude Code 场景下挂起
208
+ const readStdin = async () => {
209
+ const chunks = [];
210
+ for await (const chunk of process.stdin) {
211
+ chunks.push(chunk);
216
212
  }
213
+ return Buffer.concat(chunks).toString();
214
+ };
215
+
216
+ try {
217
+ const stdinString = await Promise.race([
218
+ readStdin(),
219
+ new Promise((_, reject) => setTimeout(() => reject(new Error('stdin timeout')), 1000))
220
+ ]);
221
+
222
+ if (stdinString.trim()) {
223
+ try {
224
+ stdinData = JSON.parse(stdinString);
225
+ } catch (e) {
226
+ // 静默忽略解析错误
227
+ }
228
+ }
229
+ } catch (e) {
230
+ // 超时或其他错误,静默继续
217
231
  }
218
232
  }
219
233
 
@@ -268,9 +282,85 @@ program
268
282
  const displayDir = currentDir || cliCurrentDir || "";
269
283
 
270
284
  let configCounts = { claudeMdCount: 0, rulesCount: 0, mcpCount: 0, hooksCount: 0 };
271
- const workspacePath = stdinData?.workspace?.current_directory;
272
- if (workspacePath && typeof workspacePath === 'string') {
273
- configCounts = await configCounter.count(workspacePath);
285
+ // 优先使用 stdin 传入的 workspacePath,否则 fallback 到 process.cwd()
286
+ const workspacePath = stdinData?.workspace?.current_directory || process.cwd();
287
+ if (workspacePath) {
288
+ try {
289
+ // 添加超时防止挂起
290
+ configCounts = await Promise.race([
291
+ configCounter.count(workspacePath),
292
+ new Promise((_, reject) => setTimeout(() => reject(new Error('config timeout')), 2000))
293
+ ]);
294
+ } catch (e) {
295
+ // 超时或失败,保持默认值
296
+ }
297
+ }
298
+
299
+ // 获取 git 分支信息
300
+ // 优先使用 stdin 传入的 workspacePath,否则 fallback 到 process.cwd()
301
+ const gitSearchPath = workspacePath || process.cwd();
302
+ let gitBranch = null;
303
+ if (gitSearchPath) {
304
+ try {
305
+ const branch = require('child_process').execSync(
306
+ 'git symbolic-ref --short HEAD',
307
+ { cwd: gitSearchPath, encoding: 'utf8', timeout: 3000 }
308
+ ).trim();
309
+ if (branch) {
310
+ gitBranch = { name: branch };
311
+
312
+ // 获取 ahead/behind
313
+ let hasUpstream = false;
314
+ try {
315
+ const revList = require('child_process').execSync(
316
+ 'git rev-list --left-right --count HEAD...@{upstream}',
317
+ { cwd: gitSearchPath, encoding: 'utf8', timeout: 3000 }
318
+ ).trim();
319
+ if (revList) {
320
+ hasUpstream = true;
321
+ const [behind, ahead] = revList.split(/\s+/).map(n => parseInt(n) || 0);
322
+ if (ahead > 0 || behind > 0) {
323
+ gitBranch.ahead = ahead;
324
+ gitBranch.behind = behind;
325
+ }
326
+ }
327
+ } catch (e) {
328
+ // 无 upstream 或获取失败,静默跳过
329
+ }
330
+
331
+ // 如果没有 upstream,尝试获取本地 commit 数作为提示
332
+ if (!hasUpstream) {
333
+ try {
334
+ const localCommits = require('child_process').execSync(
335
+ 'git rev-list --count HEAD',
336
+ { cwd: gitSearchPath, encoding: 'utf8', timeout: 3000 }
337
+ ).trim();
338
+ const commitCount = parseInt(localCommits) || 0;
339
+ // 如果有本地 commits(大于1,因为初始commit算1个),标记有待推送
340
+ if (commitCount > 1) {
341
+ gitBranch.ahead = -1; // -1 表示有未知数量的待推送
342
+ }
343
+ } catch (e) {
344
+ // 获取失败,静默跳过
345
+ }
346
+ }
347
+
348
+ // 检查未提交的更改
349
+ try {
350
+ const status = require('child_process').execSync(
351
+ 'git status --porcelain',
352
+ { cwd: gitSearchPath, encoding: 'utf8', timeout: 3000 }
353
+ ).trim();
354
+ if (status) {
355
+ gitBranch.hasChanges = true;
356
+ }
357
+ } catch (e) {
358
+ // 获取失败,静默跳过
359
+ }
360
+ }
361
+ } catch (e) {
362
+ // 非 git 目录或获取失败,静默跳过
363
+ }
274
364
  }
275
365
 
276
366
  // 使用 Claude Code 提供的 context_window(最准确)
@@ -292,6 +382,7 @@ program
292
382
  contextUsage: contextUsageValue,
293
383
  contextSize: contextSizeValue,
294
384
  configCounts,
385
+ gitBranch,
295
386
  tools: [],
296
387
  agents: [],
297
388
  todos: [],
package/cli/renderer.js CHANGED
@@ -78,6 +78,35 @@ class Renderer {
78
78
  parts.push(`${chalk.blue('📁')} ${chalk.cyan(currentDir)}`);
79
79
  }
80
80
 
81
+ // Git 分支显示
82
+ if (data.gitBranch && data.gitBranch.name) {
83
+ const { name, ahead, behind, hasChanges } = data.gitBranch;
84
+
85
+ // 主分支(main/master)用绿色,其他分支用白色
86
+ const isMainBranch = name === 'main' || name === 'master';
87
+ const branchColor = isMainBranch ? chalk.green : chalk.white;
88
+
89
+ // 构建分支显示字符串(使用 emoji 图标)
90
+ let branchStr = branchColor('🌿 ' + name);
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
+ } else if (ahead === -1) {
98
+ // 没有 upstream 但有本地 commits
99
+ branchStr += chalk.yellow(' ⬆');
100
+ }
101
+
102
+ // 未提交更改用红色点
103
+ if (hasChanges) {
104
+ branchStr += chalk.red(' •');
105
+ }
106
+
107
+ parts.push(branchStr);
108
+ }
109
+
81
110
  parts.push(`${chalk.magenta('🤖')} ${chalk.magenta(modelName)}`);
82
111
 
83
112
  // 上下文窗口在前
@@ -100,16 +129,6 @@ class Renderer {
100
129
  : `${remaining.minutes}m`;
101
130
  parts.push(`${chalk.yellow('⌛')} ${chalk.white(remainingText)}`);
102
131
 
103
- if (configCounts.claudeMdCount > 0) {
104
- parts.push(`${chalk.white(configCounts.claudeMdCount + ' CLAUDE.md')}`);
105
- }
106
- if (configCounts.rulesCount > 0) {
107
- parts.push(`${chalk.cyan(configCounts.rulesCount + ' rules')}`);
108
- }
109
- if (configCounts.mcpCount > 0) {
110
- parts.push(`${chalk.yellow(configCounts.mcpCount + ' MCPs')}`);
111
- }
112
-
113
132
  if (expiry) {
114
133
  const expiryColor = expiry.daysRemaining <= 3 ? chalk.red : expiry.daysRemaining <= 7 ? chalk.yellow : chalk.green;
115
134
  parts.push(`${expiryColor('到期: ' + expiry.daysRemaining + '天')}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minimax-status",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "MiniMax Claude Code 使用状态监控工具",
5
5
  "bin": {
6
6
  "minimax-status": "cli/index.js",