@luckvd/glmbar 0.1.0 → 0.2.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.
Files changed (3) hide show
  1. package/README.md +15 -4
  2. package/package.json +1 -1
  3. package/src/glmbar.cjs +26 -10
package/README.md CHANGED
@@ -12,6 +12,20 @@ GLM Coding Plan 按套餐额度计费(5h 窗口 / 月度),而非按量计费—
12
12
  glmbar 围绕这个核心关切组织状态栏:本次会话 token、套餐额度使用率、
13
13
  上下文剩余、Git 状态,让「该不该收着用、何时 /clear」一目了然。
14
14
 
15
+ ## 安装
16
+
17
+ ```bash
18
+ npm install -g @luckvd/glmbar
19
+ ```
20
+
21
+ 然后在 `~/.claude/settings.json` 启用状态栏:
22
+
23
+ ```json
24
+ { "statusLine": { "type": "command", "command": "glmbar", "padding": 0 } }
25
+ ```
26
+
27
+ 两步即可用。可选的子 agent 计数、`--ascii` 降级等见[完整配置](#配置到-claude-code)。
28
+
15
29
  ## 状态栏示例
16
30
 
17
31
  ```
@@ -52,10 +66,7 @@ echo '{"model":{"display_name":"GLM-5.2"},"workspace":{"current_dir":"/opt/proje
52
66
 
53
67
  ### 1. 安装
54
68
 
55
- ```bash
56
- npm install -g @luckvd/glmbar # 从 npm 安装,提供 glmbar 命令
57
- # 或从源码:cd /opt/projects/glmbar && npm link
58
- ```
69
+ 见上方[安装](#安装)。从源码用则 `cd` 到仓库后 `npm link`。
59
70
 
60
71
  ### 2. 启用状态栏
61
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luckvd/glmbar",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Claude Code statusline for GLM Coding Plan (subscription)",
5
5
  "type": "commonjs",
6
6
  "main": "src/glmbar.cjs",
package/src/glmbar.cjs CHANGED
@@ -112,24 +112,40 @@ function parseArgs(argv) {
112
112
 
113
113
  function loadConfig() {
114
114
  try {
115
- return { barAscii: !!JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8')).barAscii };
115
+ const c = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
116
+ return {
117
+ barAscii: !!c.barAscii,
118
+ barWidth: Number.isInteger(c.barWidth) && c.barWidth > 0 ? c.barWidth : 7,
119
+ };
116
120
  }
117
121
  catch {
118
- return { barAscii: false };
122
+ return { barAscii: false, barWidth: 7 };
119
123
  }
120
124
  }
121
125
 
122
- const ASCII = parseArgs(process.argv.slice(2)) || loadConfig().barAscii;
126
+ const _config = loadConfig();
127
+ const ASCII = parseArgs(process.argv.slice(2)) || _config.barAscii;
128
+ const BAR_WIDTH = _config.barWidth;
123
129
 
124
130
  // ---------- 进度条 ----------
131
+ // 用 Unicode block 元素,每个字符分 8 级(█▉▊▋▌▍▎▏),精度 = 宽度 × 8。
132
+ const BLOCKS = ['', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█'];
133
+
125
134
  function fmtBar(pct) {
126
- const segments = 5;
127
- const filled = ASCII ? '#' : '▓';
128
- const empty = ASCII ? '-' : '░';
129
- const on = Math.max(0, Math.min(segments, Math.round(pct / 20)));
130
- const bar = filled.repeat(on) + empty.repeat(segments - on);
135
+ const w = BAR_WIDTH;
131
136
  const color = pct < 50 ? C.green : pct < 80 ? C.yellow : C.red;
132
- return `${color}${bar}${C.reset}`;
137
+ if (ASCII) {
138
+ const on = Math.max(0, Math.min(w, Math.round((pct / 100) * w)));
139
+ return `${color}[${'#'.repeat(on)}${'-'.repeat(w - on)}]${C.reset}`;
140
+ }
141
+ const total = Math.max(0, Math.min(w * 8, Math.round((pct / 100) * w * 8)));
142
+ const full = Math.floor(total / 8);
143
+ const partial = total % 8;
144
+ const filled = full + (partial > 0 ? 1 : 0);
145
+ let bar = '█'.repeat(full);
146
+ if (partial > 0) bar += BLOCKS[partial];
147
+ // 方括号界定总长;括号内 ─ 做线槽(灰 dim)、实心 block 填充(彩色)
148
+ return `${color}[${bar}${C.reset}${C.dim}${'─'.repeat(Math.max(0, w - filled))}${C.reset}${color}]${C.reset}`;
133
149
  }
134
150
 
135
151
  // ---------- Git ----------
@@ -348,7 +364,7 @@ function renderContext(input) {
348
364
  const used = parsed.lastInput;
349
365
  const pct = max ? (used / max) * 100 : 0;
350
366
  const color = pct < 50 ? C.green : pct < 80 ? C.yellow : C.red;
351
- return `${color}${fmtUsed(used)}/${fmtMax(max)} ${fmtBar(pct)} (${pct.toFixed(1)}%)${C.reset}`;
367
+ return `${color}${fmtUsed(used)}/${fmtMax(max)} (${pct.toFixed(1)}%)${C.reset}`;
352
368
  }
353
369
 
354
370
  function renderSessionTokens(input) {