ccglance 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CxMYu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,384 @@
1
+ # ccglance
2
+
3
+ > A fast, zero-dependency, multi-line status line for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) — model, effort, context, cache, git and session, all at a glance.
4
+
5
+ [![Node.js >= 22](https://img.shields.io/badge/node-%3E%3D22-3c873a)](https://nodejs.org/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
7
+
8
+ English | [简体中文](./README.zh-CN.md)
9
+
10
+ Repository: [github.com/CxMYu/CcGlanceLine](https://github.com/CxMYu/CcGlanceLine)
11
+
12
+ `ccglance` uses the JSON that Claude Code pipes to its status-line command
13
+ on stdin as its primary data source; the session `status` segment reads only
14
+ the transcript tail when enabled. It's written in
15
+ **TypeScript** and ships as compiled JavaScript with **zero runtime
16
+ dependencies** (Node standard library only).
17
+
18
+ ## Preview
19
+
20
+ ![ccglance preview](./docs/assets/preview.png)
21
+
22
+ Generated from `ccglance preview`.
23
+
24
+ ## Features
25
+
26
+ - **Compact multi-line layout** — runtime, quota and project/session state are
27
+ separate logical rows; empty rows disappear.
28
+ - **Zero runtime dependencies** — Node standard library only; TypeScript is a
29
+ build-time tool, never shipped in the published package.
30
+ - **stdin-first** — core segments consume the JSON Claude Code provides; status
31
+ reads a bounded transcript tail only when used.
32
+ - **Rich context block** — usage %, this-turn input/output tokens, tokens left.
33
+ - **Prompt-cache block** — cache hit rate, read/write tokens.
34
+ - **Git segment** — branch, clean/dirty/conflict glyph, ahead/behind counts,
35
+ using one bounded `git status` call plus a short local cache.
36
+ - **Session segment** — elapsed time plus lines added/removed.
37
+ - **Claude Code version + update hint** — shows the `version` field from
38
+ Claude Code stdin and appends `↑latest` when the 4h local cache reports a
39
+ newer Claude Code release. Refresh runs after stdout and never blocks.
40
+ - **Additional session context** — 5h/7d rate-limit quota, USD cost and
41
+ worktree name next to the git branch when Claude Code provides it.
42
+ - **Responsive multi-line layout** — probes the terminal width
43
+ (`CCGLANCE_WIDTH` → `COLUMNS` → TTY → `tput`/`stty`) and wraps each row into
44
+ as many lines as fit, down to a minimum of **one segment per line** so
45
+ nothing gets hidden; display-width aware (CJK/emoji safe).
46
+ - **Fixed built-in style** — no user config file and no external style file;
47
+ the status line uses ccglance's own emoji-first style.
48
+
49
+ ## Requirements
50
+
51
+ - Node.js **>= 22**
52
+ - `git` on `PATH` (optional — only for the git segment)
53
+
54
+ Claude Code compatibility:
55
+
56
+ | Claude Code CLI | ccglance behavior |
57
+ |---|---|
58
+ | >= 1.0.71 | Basic status-line stdin support |
59
+ | >= 2.1.80 | Subscription quota row when official `rate_limits.five_hour` / `rate_limits.seven_day` fields are present |
60
+ | >= 2.1.153 | Preferred terminal-width sizing through `COLUMNS` / `LINES`; older versions fall back to TTY width or 80 columns |
61
+
62
+ The quota row is subscription-only. Claude.ai Pro/Max-style sessions can expose
63
+ `rate_limits`; API-key, Bedrock, Vertex, and other usage-based sessions usually
64
+ do not, so ccglance hides the quota row instead of inferring one.
65
+
66
+ ## Install
67
+
68
+ ### Option A — npm (global, recommended)
69
+
70
+ ```bash
71
+ npm install -g ccglance # npm
72
+ yarn global add ccglance # or yarn
73
+ pnpm add -g ccglance # or pnpm
74
+ ```
75
+
76
+ Behind a slow registry? Use a mirror:
77
+
78
+ ```bash
79
+ npm install -g ccglance --registry https://registry.npmmirror.com
80
+ ```
81
+
82
+ npm downloads the prebuilt `dist/` — no compiler runs on your machine — and puts
83
+ a `ccglance` command on your `PATH`. Requires Node.js **>= 22**.
84
+
85
+ After installation:
86
+
87
+ - ✅ The `ccglance` command is available everywhere.
88
+ - ⚙️ **Installing alone does not activate the status line** — add the `statusLine`
89
+ block to `~/.claude/settings.json` (see [Configure](#configure)), then restart
90
+ Claude Code.
91
+ - 🔎 Verify with `ccglance preview` (sample render) or `ccglance --help` (usage +
92
+ the exact `settings.json` setup). Running `ccglance` in a plain terminal just
93
+ prints this help.
94
+
95
+ Update or remove later with `npm update -g ccglance` / `npm uninstall -g ccglance`.
96
+
97
+ ### Option B — build from source
98
+
99
+ ```bash
100
+ git clone https://github.com/CxMYu/CcGlanceLine.git
101
+ cd CcGlanceLine
102
+ npm install # installs devDeps; the `prepare` script then compiles src/ → dist/
103
+ npm link # optional: expose `ccglance` on your PATH
104
+ ```
105
+
106
+ `npm install` already builds `dist/` for you via the `prepare` lifecycle script —
107
+ there is no separate build step to run. The compiled entry point is
108
+ `dist/cli.js`; the `ccglance` bin command and `node dist/cli.js` are the same
109
+ file. Verify:
110
+
111
+ ```bash
112
+ node dist/cli.js preview
113
+ ```
114
+
115
+ ## Configure
116
+
117
+ Add a `statusLine` block to `~/.claude/settings.json`:
118
+
119
+ ```json
120
+ {
121
+ "statusLine": {
122
+ "type": "command",
123
+ "command": "ccglance",
124
+ "padding": 0
125
+ }
126
+ }
127
+ ```
128
+
129
+ If you didn't install globally, point Node at the compiled file directly:
130
+
131
+ ```json
132
+ {
133
+ "statusLine": {
134
+ "type": "command",
135
+ "command": "node /absolute/path/to/ccglance/dist/cli.js"
136
+ }
137
+ }
138
+ ```
139
+
140
+ On Windows use a full path, e.g. `node D:\\path\\to\\ccglance\\dist\\cli.js`.
141
+
142
+ > **Cross-platform paths:** Claude Code v2.1.47+ expands a leading `~` in the
143
+ > command on every platform, so `node ~/path/to/dist/cli.js` works too. Prefer
144
+ > `~` over `%USERPROFILE%` (unreliable in recent versions); the global `ccglance`
145
+ > command needs no path at all. `"padding": 0` drops Claude Code's default leading
146
+ > indent so the row starts at the left edge.
147
+
148
+ ## Line reference
149
+
150
+ **Line 1 — runtime**
151
+
152
+ | Label | Segment | Source | Shows |
153
+ |---|---|---|---|
154
+ | 🤖 | model | `model.display_name`, fallback to `model.id` | stdin display name with minimal compacting (`Opus 4.8 1M`); readable id fallback when missing |
155
+ | 🧠 | effort | `effort.level` | reasoning effort |
156
+ | ✅/⏸️/💭/⚙️/🔧 | status | transcript tail | icon-only state; tool name while a tool is running |
157
+ | 🚀 | fast | `fast_mode` | shown only when fast mode is on |
158
+ | ⚡️ | context | `context_window` | usage % · input · output · tokens left |
159
+ | 💾 | cache | `context_window.current_usage` | hit % · cache read · cache write |
160
+ | 🎯 | style | `output_style.name` | active output style |
161
+
162
+ **Line 2 — quota**
163
+
164
+ | Label | Segment | Source | Shows |
165
+ |---|---|---|---|
166
+ | 📊 | rate limits | `rate_limits.five_hour` / `rate_limits.seven_day` | Compact Hour / Week moon-phase meters with percentage and reset time; Claude Code does not provide a monthly quota window |
167
+
168
+ **Line 3 — project / session**
169
+
170
+ | Icon | Segment | Source | Shows |
171
+ |---|---|---|---|
172
+ | 📁 | dir | `workspace.current_dir` | current directory name |
173
+ | 🌿 / 🌲 | git + worktree | stdin + local `git` | branch + status glyph: `✓` clean, `●` dirty, `⚠` conflicts; plus `↑ahead` `↓behind`; `worktree.name` is appended after the branch state |
174
+ | 🏷️ | session name | `session_name` | set via `--name` or `/rename` |
175
+ | ⏱️ | session | `cost` | elapsed time + `+added` `-removed` lines |
176
+ | 💰 | cost | `cost.total_cost_usd` | USD cost, shown only when greater than 0 |
177
+ | 💩 | version | `version` | Claude Code version; appends `↑latest` when the 4h cache finds a newer release |
178
+
179
+ Rate-limit moon phases:
180
+
181
+ | Usage | Icon |
182
+ |---|---|
183
+ | 0% <= usage < 10% | 🌑 |
184
+ | 10% <= usage < 30% | 🌒 |
185
+ | 30% <= usage < 60% | 🌓 |
186
+ | 60% <= usage < 90% | 🌔 |
187
+ | 90% <= usage <= 100% | 🌕 |
188
+
189
+ ## Icon Reference
190
+
191
+ | Icon | Meaning |
192
+ |---|---|
193
+ | 🤖 | model name; `model.display_name` is the source of truth, with readable `model.id` fallback |
194
+ | 🧠 | reasoning effort |
195
+ | ✅ | idle; the last assistant turn appears complete |
196
+ | ⏸️ | paused; a running action was interrupted or cancelled |
197
+ | 💭 | thinking; waiting for or receiving model output |
198
+ | ⚙️ | working; a tool result returned and Claude is processing it |
199
+ | 🔧 | tool call in progress; the tool name is shown when available |
200
+ | 🚀 | fast mode |
201
+ | ⚡️ | context-window usage |
202
+ | 💾 | prompt cache usage |
203
+ | 🎯 | output style |
204
+ | 📊 | Hour / Week rate-limit quota |
205
+ | 🌑 🌒 🌓 🌔 🌕 | rate-limit usage level |
206
+ | ⏳ | time until the quota window resets |
207
+ | 📁 | current directory |
208
+ | 🌿 | git branch |
209
+ | ✓ ● ⚠ | git clean / dirty / conflict |
210
+ | 🌲 | worktree name, shown inside the git segment |
211
+ | 🏷️ | session name |
212
+ | ⏱️ | session duration |
213
+ | 💰 | session cost |
214
+ | 💩 | Claude Code version |
215
+ | ↑latest | newer Claude Code version is available |
216
+
217
+ ## Color Semantics
218
+
219
+ | Color | Meaning |
220
+ |---|---|
221
+ | Bright green | idle/healthy state, fast mode, cache, additions, clean git marker, git ahead/outgoing/push count |
222
+ | Yellow | attention state: paused status, effort, quota reset time, cost, warning thresholds |
223
+ | Bright red | risk or negative state: danger thresholds, conflicts, deletions, update hint |
224
+ | Blue | Git modified/dirty status and behind/incoming/pull count |
225
+ | Cyan / white | neutral runtime/project identity: model, style, session duration, git branch |
226
+ | Magenta | active context/session identity: context window, session name |
227
+
228
+ The status icons are inferred from the transcript tail when Claude Code redraws
229
+ the status line. They are a redraw-time approximation, not a live event stream.
230
+ If a running action is cancelled with Esc, ccglance updates on the next Claude
231
+ Code redraw; transcript interrupt markers are shown as paused.
232
+
233
+ ## How it works
234
+
235
+ On every redraw Claude Code runs your status-line `command` and pipes a JSON
236
+ object to its **stdin** (model, effort, context window, cost, workspace,
237
+ version, …). `ccglance` reads that once via `fs.readFileSync(0)`, formats its
238
+ fixed rows, and **prints them first**. The `status` segment reads only a
239
+ bounded transcript tail. The version segment synchronously
240
+ reads only a tiny local cache; after stdout is written, ccglance refreshes the
241
+ Claude Code latest-version cache in a detached background process when it is
242
+ older than 4 hours. If the JSON can't be parsed it exits silently so it can never
243
+ break the CLI. Text from stdin, transcript, and git is sanitized before being
244
+ printed so terminal control sequences cannot escape the status line. The main
245
+ external calls are local `git` (single bounded status call with a short cache),
246
+ bounded transcript-tail reads, and the post-render detached npm registry check.
247
+
248
+ ## Development
249
+
250
+ ### Source Build
251
+
252
+ ```bash
253
+ git clone https://github.com/CxMYu/CcGlanceLine.git
254
+ cd CcGlanceLine
255
+ npm install # installs devDeps and runs prepare -> build
256
+
257
+ npm run build # compile src/ → dist/
258
+ npm run typecheck # tsc --noEmit (strict)
259
+ npm test # build + node:test fixtures/snapshots/smoke
260
+ npm run benchmark # build + latency benchmark
261
+ ccglance preview # preview the linked/global command
262
+
263
+ # smoke-test with a sample stdin payload:
264
+ printf '%s' '{"model":{"display_name":"Claude Opus 4.8 (1M context)","id":"claude-opus-4-8[1m]"}}' | node dist/cli.js
265
+ ```
266
+
267
+ For local dogfooding, use `npm link` after building and configure Claude Code
268
+ with `"command": "ccglance"`. Without a global link, point Claude Code directly
269
+ at `node /absolute/path/to/ccglance/dist/cli.js`.
270
+
271
+ ### Validation
272
+
273
+ - `test/fixtures/` contains stdin payloads for subscription, API-style,
274
+ missing-field, and high-context scenarios.
275
+ - `test/snapshots/` locks the ANSI-colored rendered output so icon, spacing,
276
+ color, and row changes are intentional.
277
+ - `test/*.test.js` uses Node's built-in `node:test`; no test runner dependency
278
+ is added to the runtime package.
279
+ - `bench/latency.js` measures cold process startup against an empty Node
280
+ baseline, plus no-git, subscription+transcript, git warm-cache, and git
281
+ cold-fallback paths. On Windows, the empty Node baseline is usually the
282
+ dominant part of the number; compare ccglance cases to that baseline.
283
+
284
+ ### Agent Build Practices
285
+
286
+ - Treat `src/` as the source of truth. Do not hand-edit `dist/`; regenerate it
287
+ with `npm run build`.
288
+ - Keep the status line fixed-style: no user config loader, no external style
289
+ file, and no runtime style discovery.
290
+ - Keep runtime dependencies at zero. New dependencies must be development-only
291
+ and justified by the build pipeline.
292
+ - After code changes, run `npm run typecheck`, `npm run build`, and
293
+ `ccglance preview`.
294
+ - When changing icon or spacing behavior, test the plain ANSI-stripped preview
295
+ and at least one synthetic stdin payload that exercises the edited segment.
296
+
297
+ ### Source layout
298
+
299
+ ```text
300
+ src/
301
+ cli.ts # command entry: preview / statusLine stdin
302
+ defaults/ # fixed built-in style and segment order
303
+ readers/ # stdin, transcript tail reads, terminal width
304
+ render/ # colors, icons, layout, final rendering
305
+ segments/ # per-segment rendering logic
306
+ runtime/ # git and Claude Code version-cache helpers
307
+ types/ # Claude Code stdin and renderer types
308
+ utils/ # formatting and display-width helpers
309
+ test/
310
+ fixtures/ # representative Claude Code stdin and transcript data
311
+ snapshots/ # fixed rendered-output baselines
312
+ bench/
313
+ latency.js # startup and cache-path benchmark
314
+ ```
315
+
316
+ Only the compiled `dist/` is published to npm. `npm run build` cleans `dist`
317
+ before compiling so old flat artifacts cannot leak into the package.
318
+
319
+ ## Session status and preview
320
+
321
+ - Session status: an icon indicator inferred from the transcript tail; `✅` idle, `⏸️` paused/interrupted, `💭` thinking, `⚙️` processing a tool result, `🔧 <tool>` running a tool.
322
+ - ccglance preview: render a built-in sample with the fixed renderer.
323
+
324
+ ## Cache Files
325
+
326
+ ccglance stores only disposable runtime caches: git status, transcript-derived
327
+ status, and the Claude Code latest-version check. Files are grouped under
328
+ `git/`, `transcript/`, and `version/`.
329
+
330
+ Caches live under Claude Code's own config directory on every platform, so they
331
+ travel with your Claude setup and are trivial to clear:
332
+
333
+ ```text
334
+ ~/.claude/ccglance/
335
+ ├── git/ # git status snapshots (one per repo)
336
+ ├── transcript/ # transcript-derived session status
337
+ └── version/ # Claude Code latest-version check
338
+ ```
339
+
340
+ If you set `CLAUDE_CONFIG_DIR` to relocate Claude Code's config, ccglance places
341
+ its caches under that directory instead. Deleting the whole `ccglance/` folder is
342
+ safe — every file is regenerated on the next render.
343
+
344
+ Git cache behavior:
345
+
346
+ - Cache key is the Git worktree root, so multiple Claude Code terminals in the
347
+ same repo share one git cache.
348
+ - The branch name prefers Claude Code stdin when `worktree.branch` is present;
349
+ otherwise ccglance checks `.git/HEAD` on every render, so normal branch
350
+ switches still show up immediately.
351
+ - Dirty/conflict and ahead/behind details use a cache. A cache newer than 20
352
+ minutes is returned when it still belongs to the current branch.
353
+ - Local state (`✓` / `●` / `⚠`) and upstream state (`↑ahead` / `↓behind`) come
354
+ from the same cached `git status --porcelain=v2 --branch` snapshot, so they
355
+ share the same TTL. If both local and upstream changes exist, ccglance shows
356
+ them together, for example `main ● ↑1 ↓1`.
357
+ - A stale cache, missing cache, or branch change still renders immediately;
358
+ ccglance shows a fast branch-only `HEAD` fallback, then refreshes `git status`
359
+ in a detached process.
360
+ - Refresh uses an exclusive `.refresh` marker and atomic temp-file rename, so
361
+ concurrent terminals do not corrupt the cache.
362
+ - There is no heartbeat or resident watcher. Refresh is lazy: Claude Code
363
+ redraws the status line, ccglance checks the cache age, and only then starts
364
+ the detached refresh process if the cache is stale.
365
+
366
+ ## Related Projects
367
+
368
+ - [CCometixLine](https://github.com/Haleclipse/CCometixLine) — high-performance Rust status line with an interactive TUI config and themes
369
+ - [ccstatusline](https://github.com/sirmalloc/ccstatusline) — configurable status line with powerline styling
370
+ - [claude-powerline](https://github.com/Owloops/claude-powerline) — lightweight powerline-style status line
371
+
372
+ ## Contributing
373
+
374
+ Issues and pull requests are welcome. For code changes, run `npm run typecheck`,
375
+ `npm run build`, and `ccglance preview` before opening a PR; keep the runtime at
376
+ **zero dependencies** and the style fixed (no config loader).
377
+
378
+ ## Star History
379
+
380
+ [![Star History Chart](https://api.star-history.com/svg?repos=CxMYu/CcGlanceLine&type=Date)](https://star-history.com/#CxMYu/CcGlanceLine&Date)
381
+
382
+ ## License
383
+
384
+ [MIT](./LICENSE) © 2026 CxMYu