cc-context-stats 1.10.0 → 1.11.1

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.
@@ -0,0 +1,324 @@
1
+ <div align="center">
2
+ <img src="assets/logo/logo-full.svg" alt="cc-context-stats" width="320"/>
3
+
4
+ <h1>Stop Shipping from a Half-Blind Model</h1>
5
+
6
+ <p><strong>Real-time model intelligence monitoring for Claude Code.</strong><br/>Know exactly when your model is at peak quality — and when it's time for a fresh session.</p>
7
+
8
+ [![PyPI version](https://img.shields.io/pypi/v/cc-context-stats)](https://pypi.org/project/cc-context-stats/)
9
+ [![npm version](https://img.shields.io/npm/v/cc-context-stats)](https://www.npmjs.com/package/cc-context-stats)
10
+ [![PyPI Downloads](https://img.shields.io/pypi/dm/cc-context-stats)](https://pypi.org/project/cc-context-stats/)
11
+ [![npm Downloads](https://img.shields.io/npm/dm/cc-context-stats)](https://www.npmjs.com/package/cc-context-stats)
12
+ [![GitHub stars](https://img.shields.io/github/stars/luongnv89/cc-context-stats)](https://github.com/luongnv89/cc-context-stats)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
+
15
+ [**Get Started in 60 Seconds →**](#installation)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ![Context Stats - Model Intelligence](images/1.10/1.10.0-model-intelligence.png)
22
+
23
+ ## The Problem
24
+
25
+ You're deep into a Claude Code session — refactoring, debugging, shipping. Everything feels fine. But behind the scenes:
26
+
27
+ - **Your model is getting dumber and you can't see it.** Research shows LLM retrieval accuracy drops as the context window fills. Claude starts missing details, hallucinating references, and losing track of your codebase — silently.
28
+ - **You don't know when to start fresh.** Is 50% context usage safe? 70%? It depends on the model. Opus holds quality longer than Sonnet, which degrades faster than Haiku. Without data, you're guessing.
29
+ - **Wasted sessions cost real money.** Pushing through a degraded context means more back-and-forth, more corrections, more tokens burned on worse output. You pay more for less.
30
+
31
+ You can't fix what you can't measure.
32
+
33
+ ## How cc-context-stats Fixes This
34
+
35
+ cc-context-stats gives you a **Model Intelligence (MI) score** — a single number from 1.000 to 0.000 that tells you how sharp your model is right now, calibrated from Anthropic's [MRCR v2 8-needle](https://docs.anthropic.com/) retrieval benchmark.
36
+
37
+ - **One glance, full picture** — MI score lives in your Claude Code status bar. Green means sharp. Yellow means degrading. Red means stop and start fresh.
38
+ - **Per-model awareness** — Opus (beta=1.8) retains quality longest. Sonnet (beta=1.5) is moderate. Haiku (beta=1.2) degrades earliest. MI reflects your actual model automatically.
39
+ - **Live dashboard** — ASCII graphs track context growth, MI degradation, and token I/O over time. Watch quality erode in real-time so you can make informed decisions.
40
+ - **Zero config, zero dependencies** — Install in one command. Works with pip, npm, or a shell script. No API keys, no network calls. All data stays local.
41
+ - **Context zones** — Five-state indicators tell you where you stand:
42
+
43
+ | Zone | Indicator | Color | What It Means |
44
+ | --- | --- | --- | --- |
45
+ | **Planning** | Plan | Green | Safe to plan and code |
46
+ | **Code-only** | Code | Yellow | Avoid starting new plans |
47
+ | **Dump zone** | Dump | Orange | Quality declining — finish up |
48
+ | **Hard limit** | ExDump | Dark red | Start a new session now |
49
+ | **Dead zone** | Dead | Gray | Nothing productive here |
50
+
51
+ [**Install and See Your MI Score →**](#installation)
52
+
53
+ ## How It Works
54
+
55
+ 1. **Install** — One command: `pip install cc-context-stats` or `npm install -g cc-context-stats`
56
+ 2. **Configure** — Add the statusline command to `~/.claude/settings.json` (two lines of JSON)
57
+ 3. **Restart Claude Code** — MI score and context stats appear in your status bar immediately
58
+ 4. **Monitor** — Run `context-stats <session_id>` for a live dashboard with graphs, zone status, and session summary
59
+
60
+ | Status Bar (green — model is sharp) | Status Bar (yellow — quality degrading) |
61
+ |:---:|:---:|
62
+ | ![Green](images/1.10/statusline-green.png) | ![Yellow](images/1.10/1.10-statusline.png) |
63
+
64
+ | Delta Graph | Cumulative Graph |
65
+ |:---:|:---:|
66
+ | ![Delta](images/1.10/1.10-delta.png) | ![Cumulative](images/1.10/1.10-cumulative.png) |
67
+
68
+ [**See Full CLI Options →**](#context-stats-cli)
69
+
70
+ ## Model Intelligence — The Science
71
+
72
+ MI isn't a guess. It's derived from `MI(u) = max(0, 1 - u^beta)` where `u` is context utilization and `beta` is a model-specific degradation rate calibrated against Anthropic's MRCR v2 8-needle long-context retrieval benchmark.
73
+
74
+ | Model | Beta | MI at 50% Context | MI at 75% Context | When to Worry |
75
+ |-------|------|-----------|-----------|---------------|
76
+ | Opus | 1.8 | 0.713 | 0.404 | ~60% used |
77
+ | Sonnet| 1.5 | 0.646 | 0.350 | ~50% used |
78
+ | Haiku | 1.2 | 0.565 | 0.292 | ~45% used |
79
+
80
+ The model is auto-detected from your session. See [Model Intelligence docs](docs/MODEL_INTELLIGENCE.md) for the full formula and benchmark data.
81
+
82
+ ## Installation
83
+
84
+ ### Shell Script (quickest)
85
+
86
+ ```bash
87
+ curl -fsSL https://raw.githubusercontent.com/luongnv89/cc-context-stats/main/install.sh | bash
88
+ ```
89
+
90
+ ### npm
91
+
92
+ ```bash
93
+ npm install -g cc-context-stats
94
+ ```
95
+
96
+ ### Python
97
+
98
+ ```bash
99
+ pip install cc-context-stats
100
+ ```
101
+
102
+ Or with uv:
103
+
104
+ ```bash
105
+ uv pip install cc-context-stats
106
+ ```
107
+
108
+ ### Verify Installation
109
+
110
+ ```bash
111
+ curl -fsSL https://raw.githubusercontent.com/luongnv89/cc-context-stats/main/scripts/check-install.sh | bash
112
+ ```
113
+
114
+ ### Quick Start
115
+
116
+ Add to `~/.claude/settings.json`:
117
+
118
+ **pip or npm install:**
119
+ ```json
120
+ {
121
+ "statusLine": {
122
+ "type": "command",
123
+ "command": "claude-statusline"
124
+ }
125
+ }
126
+ ```
127
+
128
+ **Shell script install (`install.sh`):**
129
+ ```json
130
+ {
131
+ "statusLine": {
132
+ "type": "command",
133
+ "command": "~/.claude/statusline.sh"
134
+ }
135
+ }
136
+ ```
137
+
138
+ Restart Claude Code. MI score and context stats appear in your status bar immediately.
139
+
140
+ ### Real-Time Dashboard
141
+
142
+ Get your session ID from the status line (the last part after the pipe `|`), then:
143
+
144
+ ```bash
145
+ context-stats <session_id>
146
+ ```
147
+
148
+ ```
149
+ Context Stats (my-project • abc123def)
150
+
151
+ Context Growth Per Interaction
152
+ Max: 4,787 Min: 0 Points: 254
153
+ ...graph...
154
+
155
+ Session Summary
156
+ ----------------------------------------------------------------------------
157
+ Context Remaining: 43,038/200,000 (21%)
158
+ >>> DUMB ZONE <<< (You are in the dumb zone - Dex Horthy says so)
159
+ Model Intelligence: 0.646 (Context pressure building, consider wrapping up)
160
+ Context: 79% used
161
+
162
+ Last Growth: +2,500
163
+ Input Tokens: 1,234
164
+ Output Tokens: 567
165
+ Lines Changed: +45 / -12
166
+ Total Cost: $0.1234
167
+ Model: claude-sonnet-4-6
168
+ Session Duration: 2h 29m
169
+ ```
170
+
171
+ [**See All Graph Types and Options →**](#context-stats-cli)
172
+
173
+ ## Context Stats CLI
174
+
175
+ ```bash
176
+ context-stats # Live monitoring (default)
177
+ context-stats -w 5 # Custom refresh interval (5 seconds)
178
+ context-stats --no-watch # Show once and exit
179
+ context-stats --type cumulative # Show cumulative context usage
180
+ context-stats --type both # Show both graphs
181
+ context-stats --type mi # Model Intelligence over time
182
+ context-stats --type all # Show all graphs including I/O and MI
183
+ context-stats <session_id> # View specific session
184
+ context-stats explain # Diagnostic dump (pipe JSON to stdin)
185
+ context-stats --version # Show version
186
+ ```
187
+
188
+ ## FAQ
189
+
190
+ **Is it free?**
191
+ Yes. MIT licensed, zero dependencies, free forever. [See the license](LICENSE).
192
+
193
+ **Does it send my data anywhere?**
194
+ No. All data stays local in `~/.claude/statusline/`. No network requests, no telemetry, no API keys required.
195
+
196
+ **Is it actively maintained?**
197
+ Very. 11 releases since January 2025, with MI per-model profiles, configurable colors, state rotation, and cross-implementation parity tests all shipped in the last few months.
198
+
199
+ **How does it compare to just watching the context counter?**
200
+ The raw context counter tells you how full the window is. MI tells you how much quality you've lost — which depends on the model. 50% context on Opus (MI: 0.713) is fine. 50% on Haiku (MI: 0.565) means you should start wrapping up. cc-context-stats gives you the nuance.
201
+
202
+ **Can I use it with Opus, Sonnet, and Haiku?**
203
+ Yes. MI auto-detects your model and applies the correct degradation curve. Each model has a calibrated beta value from benchmark data.
204
+
205
+ **What runtimes does it support?**
206
+ Python (pip), Node.js (npm), or pure Bash. The statusline scripts are implemented in all three languages so you can use whichever runtime you have available.
207
+
208
+ **How do I customize colors?**
209
+ Create `~/.claude/statusline.conf` with named colors or hex codes. See [Configuration docs](docs/configuration.md) for all options.
210
+
211
+ ## Start Shipping with Confidence
212
+
213
+ You wouldn't deploy without monitoring your servers. Don't code without monitoring your model.
214
+
215
+ cc-context-stats is MIT licensed, has zero dependencies, installs in one command, and works with any Claude Code setup. If you don't like it, `pip uninstall cc-context-stats` and it's gone.
216
+
217
+ [**Install cc-context-stats Now →**](#installation)
218
+
219
+ ---
220
+
221
+ <details>
222
+ <summary><strong>Status Line Components</strong></summary>
223
+
224
+ The status line shows at-a-glance metrics in your Claude Code interface:
225
+
226
+ | Component | Description |
227
+ | --------- | ----------------------------------------- |
228
+ | Model | Current Claude model |
229
+ | Context | Tokens used / remaining with color coding |
230
+ | Delta | Token change since last update |
231
+ | MI | Model Intelligence score (per-model) |
232
+ | Git | Branch name and uncommitted changes |
233
+ | Session | Session ID for correlation |
234
+
235
+ Colors change based on MI score and context utilization — green when the model is sharp, yellow as quality degrades.
236
+
237
+ </details>
238
+
239
+ <details>
240
+ <summary><strong>Configuration</strong></summary>
241
+
242
+ Create `~/.claude/statusline.conf`:
243
+
244
+ ```bash
245
+ token_detail=true # Show exact token counts (vs abbreviated like "12.5k")
246
+ show_delta=true # Show token delta in status line
247
+ show_session=true # Show session ID
248
+ autocompact=true # Show autocompact buffer indicator
249
+ reduced_motion=false # Disable animations for accessibility
250
+ show_mi=false # Show Model Intelligence score (disabled by default)
251
+ mi_curve_beta=0 # Use model-specific profile (0=auto, or set custom beta)
252
+
253
+ # Custom colors - named colors or hex (#rrggbb)
254
+ color_green=#7dcfff
255
+ color_red=#f7768e
256
+ color_yellow=bright_yellow
257
+
258
+ # Per-property colors (override individual elements)
259
+ color_context_length=bold_white # Context remaining
260
+ color_project_name=cyan # Project directory
261
+ color_branch_name=green # Git branch
262
+ color_mi_score=yellow # MI score
263
+ color_separator=dim # Model, delta, session
264
+ ```
265
+
266
+ </details>
267
+
268
+ <details>
269
+ <summary><strong>Migration from cc-statusline</strong></summary>
270
+
271
+ If you were using the previous `cc-statusline` package:
272
+
273
+ ```bash
274
+ pip uninstall cc-statusline
275
+ pip install cc-context-stats
276
+ ```
277
+
278
+ The `claude-statusline` command still works. The main change is `token-graph` is now `context-stats`.
279
+
280
+ </details>
281
+
282
+ <details>
283
+ <summary><strong>Documentation</strong></summary>
284
+
285
+ - [Installation Guide](docs/installation.md) - Platform-specific setup (shell, pip, npm)
286
+ - [Context Stats Guide](docs/context-stats.md) - Detailed CLI usage guide
287
+ - [Configuration Options](docs/configuration.md) - All settings explained
288
+ - [Available Scripts](docs/scripts.md) - Script variants and features
289
+ - [Model Intelligence](docs/MODEL_INTELLIGENCE.md) - MI formula, per-model profiles, benchmark data
290
+ - [Architecture](docs/ARCHITECTURE.md) - System design and components
291
+ - [CSV Format](docs/CSV_FORMAT.md) - State file field specification
292
+ - [Development](docs/DEVELOPMENT.md) - Dev setup, testing, and debugging
293
+ - [Deployment](docs/DEPLOYMENT.md) - Publishing and release process
294
+ - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions
295
+ - [Changelog](CHANGELOG.md) - Version history
296
+
297
+ </details>
298
+
299
+ <details>
300
+ <summary><strong>Contributing</strong></summary>
301
+
302
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on the development setup, branching strategy, and PR process.
303
+
304
+ This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md).
305
+
306
+ </details>
307
+
308
+ <details>
309
+ <summary><strong>How It Works (Architecture)</strong></summary>
310
+
311
+ Context Stats hooks into Claude Code's status line feature to track token usage across your sessions. The Python and Node.js statusline scripts write state data to local CSV files, which the context-stats CLI reads to render live graphs. Data is stored locally in `~/.claude/statusline/` and never sent anywhere.
312
+
313
+ The statusline is implemented in three languages (Bash, Python, Node.js) so you can choose whichever runtime you have available. Claude Code invokes the statusline script via stdin JSON pipe — any implementation that reads JSON from stdin and writes formatted text to stdout works.
314
+
315
+ </details>
316
+
317
+ ## Related
318
+
319
+ - [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code)
320
+ - [Blog: Building this project](https://medium.com/@luongnv89/closing-the-gap-between-mvp-and-production-with-feature-dev-an-official-plugin-from-anthropic-444e2f00a0ad)
321
+
322
+ ## License
323
+
324
+ MIT
package/README.md CHANGED
@@ -1,93 +1,306 @@
1
1
  <div align="center">
2
2
  <img src="assets/logo/logo-full.svg" alt="cc-context-stats" width="320"/>
3
3
 
4
- <h3>Know your zone. Ship with confidence.</h3>
4
+ <h1>Stop Shipping from a Half-Blind Model</h1>
5
5
 
6
- <p>Real-time context monitoring for Claude Code so you always know when you're sharp and when to wrap up.</p>
6
+ <p><strong>Real-time model intelligence monitoring for Claude Code.</strong><br/>Know exactly when your model is at peak quality and when it's time for a fresh session.</p>
7
7
 
8
- [![PyPI version](https://badge.fury.io/py/cc-context-stats.svg)](https://pypi.org/project/cc-context-stats/)
9
- [![npm version](https://badge.fury.io/js/cc-context-stats.svg)](https://www.npmjs.com/package/cc-context-stats)
8
+ [![PyPI version](https://img.shields.io/pypi/v/cc-context-stats)](https://pypi.org/project/cc-context-stats/)
9
+ [![npm version](https://img.shields.io/npm/v/cc-context-stats)](https://www.npmjs.com/package/cc-context-stats)
10
10
  [![PyPI Downloads](https://img.shields.io/pypi/dm/cc-context-stats)](https://pypi.org/project/cc-context-stats/)
11
11
  [![npm Downloads](https://img.shields.io/npm/dm/cc-context-stats)](https://www.npmjs.com/package/cc-context-stats)
12
+ [![GitHub stars](https://img.shields.io/github/stars/luongnv89/cc-context-stats)](https://github.com/luongnv89/cc-context-stats)
12
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
13
14
 
15
+ [**Get Started in 60 Seconds →**](#installation)
16
+
14
17
  </div>
15
18
 
16
- **Never run out of context unexpectedly** - monitor your session context in real-time.
19
+ ---
17
20
 
18
- ![Context Stats](images/v1.6.1.png)
21
+ ![Context Stats - Model Intelligence](images/1.10/1.10.0-model-intelligence.png)
19
22
 
20
- ## Why Context Stats?
23
+ ## The Problem
21
24
 
22
- When working with Claude Code on complex tasks, you can easily burn through your context window without realizing it. As your context fills up, Claude's performance degrades - this is what Dex Horthy calls the "dumb zone". Context Stats helps you:
25
+ You're deep into a Claude Code session refactoring, debugging, shipping. Everything feels fine. But behind the scenes:
23
26
 
24
- - **Know your zone** - See if you're in the Smart Zone, Dumb Zone, or Wrap Up Zone
25
- - **Track context usage** - Real-time monitoring with live-updating graphs
26
- - **Get early warnings** - Color-coded status alerts you before performance degrades
27
- - **Make informed decisions** - Know when to start a fresh session
27
+ - **Your model is getting dumber and you can't see it.** Research shows LLM retrieval accuracy drops as the context window fills. Claude starts missing details, hallucinating references, and losing track of your codebase — silently.
28
+ - **You don't know when to start fresh.** Is 50% context usage safe? 70%? It depends on the model. Opus holds quality longer than Sonnet, which degrades faster than Haiku. Without data, you're guessing.
29
+ - **Wasted sessions cost real money.** Pushing through a degraded context means more back-and-forth, more corrections, more tokens burned on worse output. You pay more for less.
28
30
 
29
- ## Context Zones
31
+ You can't fix what you can't measure.
30
32
 
31
- | Zone | Context Used | Status | What It Means |
32
- | ------------------- | ------------ | -------- | --------------------------------------------- |
33
- | 🟢 **Smart Zone** | < 40% | Optimal | Claude is performing at its best |
34
- | 🟡 **Dumb Zone** | 40-80% | Degraded | Context getting full, Claude may miss details |
35
- | 🔴 **Wrap Up Zone** | > 80% | Critical | Better to wrap up and start a new session |
33
+ ## How cc-context-stats Fixes This
36
34
 
37
- ## Installation
35
+ cc-context-stats gives you a **Model Intelligence (MI) score** — a single number from 1.000 to 0.000 that tells you how sharp your model is right now, calibrated from Anthropic's [MRCR v2 8-needle](https://docs.anthropic.com/) retrieval benchmark.
36
+
37
+ - **One glance, full picture** — MI score lives in your Claude Code status bar. Green means sharp. Yellow means degrading. Red means stop and start fresh.
38
+ - **Per-model awareness** — Opus (beta=1.8) retains quality longest. Sonnet (beta=1.5) is moderate. Haiku (beta=1.2) degrades earliest. MI reflects your actual model automatically.
39
+ - **Live dashboard** — ASCII graphs track context growth, MI degradation, and token I/O over time. Watch quality erode in real-time so you can make informed decisions.
40
+ - **Fully customizable** — Control the color of every element, toggle each component on/off, and use named colors or hex codes to match your terminal theme.
41
+ - **Context zones** — Five-state indicators tell you where you stand:
42
+
43
+ | Zone | Indicator | Color | What It Means |
44
+ | --- | --- | --- | --- |
45
+ | **Planning** | Plan | Green | Safe to plan and code |
46
+ | **Code-only** | Code | Yellow | Avoid starting new plans |
47
+ | **Dump zone** | Dump | Orange | Quality declining — finish up |
48
+ | **Hard limit** | ExDump | Dark red | Start a new session now |
49
+ | **Dead zone** | Dead | Gray | Nothing productive here |
50
+
51
+ [**Install and See Your MI Score →**](#installation)
52
+
53
+ ## How It Works
54
+
55
+ ```mermaid
56
+ graph LR
57
+ A["Claude Code<br/>sends JSON via stdin"] --> B["Statusline Script<br/>(Python / Node.js / Bash)"]
58
+ B --> C["Status Bar Output<br/>colored, fitted to terminal width"]
59
+ B --> D["CSV State File<br/>~/.claude/statusline/"]
60
+ D --> E["context-stats CLI<br/>live ASCII dashboard"]
61
+ ```
62
+
63
+ 1. **Install** — One command: `pip install cc-context-stats` or `npm install -g cc-context-stats`
64
+ 2. **Configure** — Add the statusline command to `~/.claude/settings.json` (two lines of JSON)
65
+ 3. **Restart Claude Code** — MI score and context stats appear in your status bar immediately
66
+ 4. **Monitor** — Run `context-stats <session_id>` for a live dashboard with graphs, zone status, and session summary
67
+
68
+ | Status Bar (green — model is sharp) | Status Bar (yellow — quality degrading) |
69
+ |:---:|:---:|
70
+ | ![Green](images/1.10/statusline-green.png) | ![Yellow](images/1.10/1.10-statusline.png) |
71
+
72
+ | Delta Graph | Cumulative Graph |
73
+ |:---:|:---:|
74
+ | ![Delta](images/1.10/1.10-delta.png) | ![Cumulative](images/1.10/1.10-cumulative.png) |
75
+
76
+ [**See Full CLI Options →**](#context-stats-cli)
77
+
78
+ ## Customization
79
+
80
+ Every element in the status line can be individually colored and toggled. Configuration lives in `~/.claude/statusline.conf` (created automatically on first run).
81
+
82
+ ### Status Line Anatomy
83
+
84
+ The status line is assembled left-to-right in **priority order** — when the terminal is too narrow, lower-priority elements on the right are dropped first:
85
+
86
+ ```
87
+ project-dir | main [3] | 64,000 free (32.0%) | Plan | MI:0.918 | +2,500 | Opus 4.6 (1M context) | session_id
88
+ ─────┬──── ───┬──── ────────┬────────── ──┬── ───┬──── ──┬─── ──────────┬────────── ────┬──────
89
+ │ │ │ │ │ │ │ │
90
+ project_name branch_name context_length zone mi_score separator separator separator
91
+ (cyan) (green) (bold_white) (auto) (yellow) (dim) (dim) (dim)
92
+ ```
93
+
94
+ | Position | Element | Config Key | Default Color | What It Shows |
95
+ |:---:|---|---|---|---|
96
+ | 1 | Project directory | `color_project_name` | cyan | Current working directory |
97
+ | 2 | Git branch + changes | `color_branch_name` | green | Branch name and `[N]` uncommitted changes |
98
+ | 3 | Context remaining | `color_context_length` | bold_white | Tokens free + usage percentage |
99
+ | 4 | Zone indicator | `color_zone` | auto (zone color) | Plan / Code / Dump / ExDump / Dead |
100
+ | 5 | MI score | `color_mi_score` | yellow | Model Intelligence: `MI:0.918` |
101
+ | 6 | Token delta | `color_separator` | dim | Change since last refresh: `+2,500` |
102
+ | 7 | Model name | `color_separator` | dim | `Opus 4.6 (1M context)` |
103
+ | 8 | Session ID | `color_separator` | dim | Session identifier |
104
+
105
+ Elements 6-8 share `color_separator` because they are structural/secondary information. The most critical data (project, branch, context, zone, MI) each have their own dedicated color key.
38
106
 
39
- ### Shell Script
107
+ ### Per-Element Color Control
40
108
 
41
- For the quickest setup:
109
+ Override any element's color independently. Per-property keys take precedence over base color slots.
42
110
 
43
111
  ```bash
44
- curl -fsSL https://raw.githubusercontent.com/luongnv89/cc-context-stats/main/install.sh | bash
112
+ # ~/.claude/statusline.conf
113
+
114
+ # Each element has its own color key
115
+ color_context_length=bold_white # The most critical info — tokens remaining
116
+ color_project_name=cyan # Which project you're working in
117
+ color_branch_name=green # Git branch at a glance
118
+ color_mi_score=yellow # Model Intelligence score
119
+ color_zone=default # Zone indicator (uses zone's own color by default)
120
+ color_separator=dim # Model name, delta, session ID
45
121
  ```
46
122
 
47
- ### NPM
123
+ ### Base Color Slots (MI-Aware)
124
+
125
+ These control the automatic MI-based coloring of context tokens and act as fallbacks for per-property keys:
48
126
 
49
127
  ```bash
50
- npm install -g cc-context-stats
128
+ # Base MI color thresholds
129
+ color_green=#7dcfff # Used when MI > 0.70 (model is sharp)
130
+ color_yellow=bright_yellow # Used when MI 0.40–0.70 (quality degrading)
131
+ color_red=#f7768e # Used when MI < 0.40 (start a new session)
132
+
133
+ # Legacy element fallbacks (used if per-property key is not set)
134
+ color_blue=bright_blue # Fallback for color_project_name
135
+ color_magenta=#bb9af7 # Fallback for color_branch_name
136
+ color_cyan=bright_cyan # Git change count [N]
137
+ ```
138
+
139
+ ### Color Resolution Order
140
+
141
+ When rendering each element, the system checks colors in this order:
142
+
143
+ ```mermaid
144
+ graph TD
145
+ A["Per-property key set?<br/>(e.g. color_project_name)"] -->|Yes| B["Use per-property color"]
146
+ A -->|No| C["Base color key set?<br/>(e.g. color_blue)"]
147
+ C -->|Yes| D["Use base color"]
148
+ C -->|No| E["Use built-in default"]
51
149
  ```
52
150
 
53
- Or with yarn:
151
+ For example, `color_project_name` falls back to `color_blue`, which falls back to the built-in cyan.
152
+
153
+ ### Supported Color Values
154
+
155
+ | Format | Examples | Notes |
156
+ |---|---|---|
157
+ | Named colors | `red`, `green`, `cyan`, `white` | Standard 16-color terminal palette |
158
+ | Bright variants | `bright_red`, `bright_green`, `bright_cyan` | High-intensity versions |
159
+ | Special | `bold_white`, `dim` | Weight/opacity modifiers |
160
+ | Hex codes | `#7dcfff`, `#f7768e`, `#bb9af7` | 24-bit truecolor (requires terminal support) |
161
+
162
+ Full named color list: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `bright_black`, `bright_red`, `bright_green`, `bright_yellow`, `bright_blue`, `bright_magenta`, `bright_cyan`, `bright_white`, `bold_white`, `dim`
163
+
164
+ Unrecognized values are ignored with a warning to stderr. Omitted keys use defaults.
165
+
166
+ ### Toggle Elements On/Off
167
+
168
+ Control which elements appear in the status line:
54
169
 
55
170
  ```bash
56
- yarn global add cc-context-stats
171
+ # ~/.claude/statusline.conf
172
+
173
+ show_delta=true # Show token delta [+2,500] (default: true)
174
+ show_session=true # Show session ID (default: true)
175
+ show_mi=false # Show MI score (default: false — enable it!)
176
+ token_detail=true # Exact counts "64,000" vs abbreviated "64.0k" (default: true)
177
+ autocompact=true # Factor in autocompact buffer (default: true)
178
+ reduced_motion=false # Disable text animations (default: false)
57
179
  ```
58
180
 
59
- ### Python
181
+ ### Example Configurations
182
+
183
+ **Tokyo Night theme** — dark purple/blue palette:
60
184
 
61
185
  ```bash
62
- pip install cc-context-stats
186
+ # ~/.claude/statusline.conf
187
+ color_green=#7dcfff
188
+ color_yellow=#e0af68
189
+ color_red=#f7768e
190
+ color_project_name=#7aa2f7
191
+ color_branch_name=#bb9af7
192
+ color_context_length=bold_white
193
+ color_mi_score=#e0af68
194
+ color_separator=dim
195
+ show_mi=true
63
196
  ```
64
197
 
65
- Or with uv:
198
+ **High contrast** — maximum readability:
66
199
 
67
200
  ```bash
68
- uv pip install cc-context-stats
201
+ # ~/.claude/statusline.conf
202
+ color_project_name=bright_white
203
+ color_branch_name=bright_green
204
+ color_context_length=bold_white
205
+ color_mi_score=bright_yellow
206
+ color_separator=bright_black
207
+ color_green=bright_green
208
+ color_yellow=bright_yellow
209
+ color_red=bright_red
210
+ show_mi=true
69
211
  ```
70
212
 
71
- ### Verify Installation
213
+ **Minimal** context and MI only, muted colors:
72
214
 
73
- After installing via any method, verify that both the statusline and context-stats CLI are working:
215
+ ```bash
216
+ # ~/.claude/statusline.conf
217
+ show_delta=false
218
+ show_session=false
219
+ show_mi=true
220
+ color_project_name=dim
221
+ color_branch_name=dim
222
+ color_context_length=bold_white
223
+ color_mi_score=yellow
224
+ color_separator=dim
225
+ ```
226
+
227
+ **Monochrome** — no color, just structure:
74
228
 
75
229
  ```bash
76
- curl -fsSL https://raw.githubusercontent.com/luongnv89/cc-context-stats/main/scripts/check-install.sh | bash
230
+ # ~/.claude/statusline.conf
231
+ color_project_name=white
232
+ color_branch_name=white
233
+ color_context_length=bold_white
234
+ color_mi_score=white
235
+ color_separator=dim
236
+ color_green=white
237
+ color_yellow=white
238
+ color_red=white
77
239
  ```
78
240
 
79
- Or if you cloned the repo:
241
+ ### MI Curve Customization
242
+
243
+ The MI degradation curve is model-specific by default. Override it for all models with `mi_curve_beta`:
80
244
 
81
245
  ```bash
82
- ./scripts/check-install.sh
246
+ # ~/.claude/statusline.conf
247
+ mi_curve_beta=0 # Auto-detect (default): Opus=1.8, Sonnet=1.5, Haiku=1.2
248
+ mi_curve_beta=1.5 # Force Sonnet-like curve for all models
249
+ mi_curve_beta=2.0 # More optimistic — quality retained longer
250
+ mi_curve_beta=1.0 # More pessimistic — warns earlier
83
251
  ```
84
252
 
85
- ## Quick Start
253
+ Higher beta = the model retains quality longer before degrading. Lower beta = earlier warnings.
254
+
255
+ ## Model Intelligence — The Science
256
+
257
+ MI is derived from `MI(u) = max(0, 1 - u^beta)` where `u` is context utilization and `beta` is a model-specific degradation rate calibrated against Anthropic's MRCR v2 8-needle long-context retrieval benchmark.
86
258
 
87
- ### Status Line Integration
259
+ | Model | Beta | MI at 50% Context | MI at 75% Context | When to Worry |
260
+ |-------|------|-----------|-----------|---------------|
261
+ | Opus | 1.8 | 0.713 | 0.404 | ~60% used |
262
+ | Sonnet| 1.5 | 0.646 | 0.350 | ~50% used |
263
+ | Haiku | 1.2 | 0.565 | 0.292 | ~45% used |
264
+
265
+ The model is auto-detected from your session. See [Model Intelligence docs](docs/MODEL_INTELLIGENCE.md) for the full formula and benchmark data.
266
+
267
+ ## Installation
268
+
269
+ ### Shell Script (quickest)
270
+
271
+ ```bash
272
+ curl -fsSL https://raw.githubusercontent.com/luongnv89/cc-context-stats/main/install.sh | bash
273
+ ```
274
+
275
+ ### npm
276
+
277
+ ```bash
278
+ npm install -g cc-context-stats
279
+ ```
280
+
281
+ ### Python
282
+
283
+ ```bash
284
+ pip install cc-context-stats
285
+ ```
286
+
287
+ Or with uv:
288
+
289
+ ```bash
290
+ uv pip install cc-context-stats
291
+ ```
292
+
293
+ ### Verify Installation
294
+
295
+ ```bash
296
+ curl -fsSL https://raw.githubusercontent.com/luongnv89/cc-context-stats/main/scripts/check-install.sh | bash
297
+ ```
298
+
299
+ ### Quick Start
88
300
 
89
301
  Add to `~/.claude/settings.json`:
90
302
 
303
+ **pip or npm install:**
91
304
  ```json
92
305
  {
93
306
  "statusLine": {
@@ -97,30 +310,50 @@ Add to `~/.claude/settings.json`:
97
310
  }
98
311
  ```
99
312
 
100
- Restart Claude Code to see real-time token stats in your status bar.
313
+ **Shell script install (`install.sh`):**
314
+ ```json
315
+ {
316
+ "statusLine": {
317
+ "type": "command",
318
+ "command": "~/.claude/statusline.sh"
319
+ }
320
+ }
321
+ ```
101
322
 
102
- ### Real-Time Monitoring
323
+ Restart Claude Code. MI score and context stats appear in your status bar immediately.
103
324
 
104
- Get your session ID from the status line (the last part after the pipe `|`), then run:
325
+ ### Real-Time Dashboard
326
+
327
+ Get your session ID from the status line (the last part after the pipe `|`), then:
105
328
 
106
329
  ```bash
107
330
  context-stats <session_id>
108
331
  ```
109
332
 
110
- For example:
111
-
112
- ```bash
113
- context-stats abc123def-456-789
114
333
  ```
334
+ Context Stats (my-project • abc123def)
115
335
 
116
- This opens a live dashboard that refreshes every 2 seconds, showing:
336
+ Context Growth Per Interaction
337
+ Max: 4,787 Min: 0 Points: 254
338
+ ...graph...
117
339
 
118
- - Your current project and session
119
- - Context growth per interaction graph
120
- - Your current zone status
121
- - Remaining context percentage
340
+ Session Summary
341
+ ----------------------------------------------------------------------------
342
+ Context Remaining: 43,038/200,000 (21%)
343
+ >>> DUMB ZONE <<< (You are in the dumb zone - Dex Horthy says so)
344
+ Model Intelligence: 0.646 (Context pressure building, consider wrapping up)
345
+ Context: 79% used
346
+
347
+ Last Growth: +2,500
348
+ Input Tokens: 1,234
349
+ Output Tokens: 567
350
+ Lines Changed: +45 / -12
351
+ Total Cost: $0.1234
352
+ Model: claude-sonnet-4-6
353
+ Session Duration: 2h 29m
354
+ ```
122
355
 
123
- Press `Ctrl+C` to exit.
356
+ [**See All Graph Types and Options →**](#context-stats-cli)
124
357
 
125
358
  ## Context Stats CLI
126
359
 
@@ -130,76 +363,71 @@ context-stats -w 5 # Custom refresh interval (5 seconds)
130
363
  context-stats --no-watch # Show once and exit
131
364
  context-stats --type cumulative # Show cumulative context usage
132
365
  context-stats --type both # Show both graphs
133
- context-stats --type all # Show all graphs including I/O
366
+ context-stats --type mi # Model Intelligence over time
367
+ context-stats --type all # Show all graphs including I/O and MI
134
368
  context-stats <session_id> # View specific session
135
369
  context-stats explain # Diagnostic dump (pipe JSON to stdin)
136
370
  context-stats --version # Show version
137
371
  ```
138
372
 
139
- ### Output Example
373
+ ## FAQ
140
374
 
141
- ```
142
- Context Stats (my-project abc123def)
375
+ **Is it free?**
376
+ Yes. MIT licensed, zero dependencies, free forever. [See the license](LICENSE).
143
377
 
144
- Context Growth Per Interaction
145
- Max: 4,787 Min: 0 Points: 254
146
- ...graph...
378
+ **Does it send my data anywhere?**
379
+ No. All data stays local in `~/.claude/statusline/`. No network requests, no telemetry, no API keys required.
147
380
 
148
- Session Summary
149
- ----------------------------------------------------------------------------
150
- Context Remaining: 43,038/200,000 (21%)
151
- >>> DUMB ZONE <<< (You are in the dumb zone - Dex Horthy says so)
381
+ **Is it actively maintained?**
382
+ Very. 11 releases since January 2025, with MI per-model profiles, configurable colors, state rotation, and cross-implementation parity tests all shipped in the last few months.
152
383
 
153
- Last Growth: +2,500
154
- Input Tokens: 1,234
155
- Output Tokens: 567
156
- Lines Changed: +45 / -12
157
- Total Cost: $0.1234
158
- Model: claude-sonnet-4-20250514
159
- Session Duration: 2h 29m
160
- ```
384
+ **How does it compare to just watching the context counter?**
385
+ The raw context counter tells you how full the window is. MI tells you how much quality you've lost — which depends on the model. 50% context on Opus (MI: 0.713) is fine. 50% on Haiku (MI: 0.565) means you should start wrapping up. cc-context-stats gives you the nuance.
386
+
387
+ **Can I use it with Opus, Sonnet, and Haiku?**
388
+ Yes. MI auto-detects your model and applies the correct degradation curve. Each model has a calibrated beta value from benchmark data.
389
+
390
+ **What runtimes does it support?**
391
+ Python (pip), Node.js (npm), or pure Bash. The statusline scripts are implemented in all three languages so you can use whichever runtime you have available.
161
392
 
162
- ## Status Line
393
+ **How do I customize colors?**
394
+ Create `~/.claude/statusline.conf` with named colors or hex codes. See the [Customization section](#customization) above or the [full configuration docs](docs/configuration.md).
163
395
 
164
- ![Status Line](images/statusline-detail.png)
396
+ ## Start Shipping with Confidence
165
397
 
166
- The status line shows at-a-glance metrics in your Claude Code interface:
398
+ You wouldn't deploy without monitoring your servers. Don't code without monitoring your model.
167
399
 
168
- | Component | Description |
169
- | --------- | ----------------------------------------- |
170
- | Model | Current Claude model |
171
- | Context | Tokens used / remaining with color coding |
172
- | Delta | Token change since last update |
173
- | Git | Branch name and uncommitted changes |
174
- | Session | Session ID for correlation |
400
+ cc-context-stats is MIT licensed, has zero dependencies, installs in one command, and works with any Claude Code setup. If you don't like it, `pip uninstall cc-context-stats` and it's gone.
175
401
 
176
- ## Configuration
402
+ [**Install cc-context-stats Now →**](#installation)
177
403
 
178
- Create `~/.claude/statusline.conf`:
404
+ ---
405
+
406
+ <details>
407
+ <summary><strong>Migration from cc-statusline</strong></summary>
408
+
409
+ If you were using the previous `cc-statusline` package:
179
410
 
180
411
  ```bash
181
- token_detail=true # Show exact token counts (vs abbreviated like "12.5k")
182
- show_delta=true # Show token delta in status line
183
- show_session=true # Show session ID
184
- autocompact=true # Show autocompact buffer indicator
185
- reduced_motion=false # Disable animations for accessibility
412
+ pip uninstall cc-statusline
413
+ ```
186
414
 
187
- # Custom colors - named colors or hex (#rrggbb)
188
- color_green=#7dcfff
189
- color_red=#f7768e
190
- color_yellow=bright_yellow
415
+ ```bash
416
+ pip install cc-context-stats
191
417
  ```
192
418
 
193
- ## How It Works
419
+ The `claude-statusline` command still works. The main change is `token-graph` is now `context-stats`.
194
420
 
195
- Context Stats hooks into Claude Code's status line feature to track token usage across your sessions. The Python and Node.js statusline scripts write state data to local CSV files, which the context-stats CLI reads to render live graphs. Data is stored locally in `~/.claude/statusline/` and never sent anywhere.
421
+ </details>
196
422
 
197
- ## Documentation
423
+ <details>
424
+ <summary><strong>Documentation</strong></summary>
198
425
 
199
426
  - [Installation Guide](docs/installation.md) - Platform-specific setup (shell, pip, npm)
200
427
  - [Context Stats Guide](docs/context-stats.md) - Detailed CLI usage guide
201
428
  - [Configuration Options](docs/configuration.md) - All settings explained
202
429
  - [Available Scripts](docs/scripts.md) - Script variants and features
430
+ - [Model Intelligence](docs/MODEL_INTELLIGENCE.md) - MI formula, per-model profiles, benchmark data
203
431
  - [Architecture](docs/ARCHITECTURE.md) - System design and components
204
432
  - [CSV Format](docs/CSV_FORMAT.md) - State file field specification
205
433
  - [Development](docs/DEVELOPMENT.md) - Dev setup, testing, and debugging
@@ -207,22 +435,25 @@ Context Stats hooks into Claude Code's status line feature to track token usage
207
435
  - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions
208
436
  - [Changelog](CHANGELOG.md) - Version history
209
437
 
210
- ## Contributing
438
+ </details>
439
+
440
+ <details>
441
+ <summary><strong>Contributing</strong></summary>
211
442
 
212
443
  Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on the development setup, branching strategy, and PR process.
213
444
 
214
445
  This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md).
215
446
 
216
- ## Migration from cc-statusline
447
+ </details>
217
448
 
218
- If you were using the previous `cc-statusline` package:
449
+ <details>
450
+ <summary><strong>How It Works (Architecture)</strong></summary>
219
451
 
220
- ```bash
221
- pip uninstall cc-statusline
222
- pip install cc-context-stats
223
- ```
452
+ Context Stats hooks into Claude Code's status line feature to track token usage across your sessions. The Python and Node.js statusline scripts write state data to local CSV files, which the context-stats CLI reads to render live graphs. Data is stored locally in `~/.claude/statusline/` and never sent anywhere.
224
453
 
225
- The `claude-statusline` command still works. The main change is `token-graph` is now `context-stats`.
454
+ The statusline is implemented in three languages (Bash, Python, Node.js) so you can choose whichever runtime you have available. Claude Code invokes the statusline script via stdin JSON pipe — any implementation that reads JSON from stdin and writes formatted text to stdout works.
455
+
456
+ </details>
226
457
 
227
458
  ## Related
228
459
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-context-stats",
3
- "version": "1.10.0",
3
+ "version": "1.11.1",
4
4
  "description": "Monitor your Claude Code session context in real-time - track token usage and never run out of context",
5
5
  "main": "scripts/statusline.js",
6
6
  "bin": {
@@ -22,7 +22,7 @@
22
22
 
23
23
  # === CONFIGURATION ===
24
24
  # shellcheck disable=SC2034
25
- VERSION="1.10.0"
25
+ VERSION="1.11.1"
26
26
  COMMIT_HASH="dev" # Will be replaced during installation
27
27
  STATE_DIR=~/.claude/statusline
28
28
  CONFIG_FILE=~/.claude/statusline.conf
@@ -82,6 +82,7 @@ OPTIONS:
82
82
  -w [interval] Set refresh interval in seconds (default: 2)
83
83
  --no-watch Show graphs once and exit (disable live monitoring)
84
84
  --no-color Disable color output
85
+ --version, -V Show version and exit
85
86
  --help Show this help message
86
87
 
87
88
  NOTE:
@@ -886,6 +887,10 @@ parse_args() {
886
887
  show_help
887
888
  exit 0
888
889
  ;;
890
+ --version | -V)
891
+ echo "cc-context-stats v${VERSION} (${COMMIT_HASH})"
892
+ exit 0
893
+ ;;
889
894
  --no-color)
890
895
  COLOR_ENABLED=false
891
896
  shift
@@ -36,26 +36,41 @@ const os = require('os');
36
36
  const ROTATION_THRESHOLD = 10000;
37
37
  const ROTATION_KEEP = 5000;
38
38
 
39
- // Model Intelligence constants (hardcoded, not configurable)
40
- const MI_GREEN_THRESHOLD = 0.70;
41
- const MI_YELLOW_THRESHOLD = 0.40;
39
+ // Model Intelligence color thresholds
40
+ const MI_GREEN_THRESHOLD = 0.9;
41
+ const MI_YELLOW_THRESHOLD = 0.8;
42
+ const MI_CONTEXT_YELLOW = 0.4; // 40% context used
43
+ const MI_CONTEXT_RED = 0.8; // 80% context used
42
44
 
43
45
  // Per-model degradation profiles: beta controls curve shape
44
46
  // Higher beta = quality retained longer (degradation happens later)
45
47
  const MODEL_PROFILES = {
46
- opus: 1.8,
47
- sonnet: 1.5,
48
- haiku: 1.2,
48
+ opus: 1.8,
49
+ sonnet: 1.5,
50
+ haiku: 1.2,
49
51
  default: 1.5,
50
52
  };
51
53
 
54
+ // Zone indicator thresholds
55
+ const LARGE_MODEL_THRESHOLD = 500000; // >= 500k context = 1M-class model
56
+ const ZONE_1M_P_MAX = 70000; // P zone: < 70k used
57
+ const ZONE_1M_C_MAX = 100000; // C zone: 70k–100k used
58
+ const ZONE_1M_D_MAX = 250000; // D zone: 100k–250k used
59
+ const ZONE_1M_X_MAX = 275000; // X zone: 250k–275k used; Z zone: >= 275k
60
+ const ZONE_STD_DUMP_ZONE = 0.4;
61
+ const ZONE_STD_WARN_BUFFER = 30000;
62
+ const ZONE_STD_HARD_LIMIT = 0.7;
63
+ const ZONE_STD_DEAD_ZONE = 0.75;
64
+
52
65
  /**
53
66
  * Match model_id to degradation beta.
54
67
  */
55
68
  function getModelProfile(modelId) {
56
69
  const lower = (modelId || '').toLowerCase();
57
70
  for (const family of ['opus', 'sonnet', 'haiku']) {
58
- if (lower.includes(family)) return MODEL_PROFILES[family];
71
+ if (lower.includes(family)) {
72
+ return MODEL_PROFILES[family];
73
+ }
59
74
  }
60
75
  return MODEL_PROFILES.default;
61
76
  }
@@ -72,22 +87,98 @@ function computeMI(usedTokens, contextWindowSize, modelId, betaOverride) {
72
87
  }
73
88
 
74
89
  const betaFromProfile = getModelProfile(modelId || '');
75
- const beta = (betaOverride && betaOverride > 0) ? betaOverride : betaFromProfile;
90
+ const beta = betaOverride && betaOverride > 0 ? betaOverride : betaFromProfile;
76
91
 
77
92
  const u = usedTokens / contextWindowSize;
78
- if (u <= 0) return { mi: 1.0 };
93
+ if (u <= 0) {
94
+ return { mi: 1.0 };
95
+ }
79
96
 
80
97
  const mi = Math.max(0, 1 - Math.pow(u, beta));
81
98
  return { mi };
82
99
  }
83
100
 
84
101
  /**
85
- * Return ANSI color code for MI score.
102
+ * Return ANSI color code for MI score considering both MI and context utilization.
103
+ */
104
+ function getMIColor(mi, utilization, greenColor, yellowColor, redColor) {
105
+ if (mi <= MI_YELLOW_THRESHOLD || utilization >= MI_CONTEXT_RED) {
106
+ return redColor || RED;
107
+ }
108
+ if (mi < MI_GREEN_THRESHOLD || utilization >= MI_CONTEXT_YELLOW) {
109
+ return yellowColor || YELLOW;
110
+ }
111
+ return greenColor || GREEN;
112
+ }
113
+
114
+ /**
115
+ * Determine context zone indicator (P/C/D/X/Z) based on token usage.
116
+ * Returns { zone, colorName }.
117
+ */
118
+ function getContextZone(usedTokens, contextWindowSize) {
119
+ if (contextWindowSize === 0) {
120
+ return { zone: 'Plan', colorName: 'green' };
121
+ }
122
+
123
+ const isLarge = contextWindowSize >= LARGE_MODEL_THRESHOLD;
124
+
125
+ if (isLarge) {
126
+ if (usedTokens < ZONE_1M_P_MAX) {
127
+ return { zone: 'Plan', colorName: 'green' };
128
+ }
129
+ if (usedTokens < ZONE_1M_C_MAX) {
130
+ return { zone: 'Code', colorName: 'yellow' };
131
+ }
132
+ if (usedTokens < ZONE_1M_D_MAX) {
133
+ return { zone: 'Dump', colorName: 'orange' };
134
+ }
135
+ if (usedTokens < ZONE_1M_X_MAX) {
136
+ return { zone: 'ExDump', colorName: 'dark_red' };
137
+ }
138
+ return { zone: 'Dead', colorName: 'gray' };
139
+ }
140
+
141
+ // Standard models (< 500k context)
142
+ const dumpZoneTokens = Math.floor(contextWindowSize * ZONE_STD_DUMP_ZONE);
143
+ const warnStart = Math.max(0, dumpZoneTokens - ZONE_STD_WARN_BUFFER);
144
+ const hardLimitTokens = Math.floor(contextWindowSize * ZONE_STD_HARD_LIMIT);
145
+ const deadZoneTokens = Math.floor(contextWindowSize * ZONE_STD_DEAD_ZONE);
146
+
147
+ if (usedTokens < warnStart) {
148
+ return { zone: 'Plan', colorName: 'green' };
149
+ }
150
+ if (usedTokens < dumpZoneTokens) {
151
+ return { zone: 'Code', colorName: 'yellow' };
152
+ }
153
+ if (usedTokens < hardLimitTokens) {
154
+ return { zone: 'Dump', colorName: 'orange' };
155
+ }
156
+ if (usedTokens < deadZoneTokens) {
157
+ return { zone: 'ExDump', colorName: 'dark_red' };
158
+ }
159
+ return { zone: 'Dead', colorName: 'gray' };
160
+ }
161
+
162
+ /**
163
+ * Map zone color name to ANSI escape code.
86
164
  */
87
- function getMIColor(mi, greenColor, yellowColor, redColor) {
88
- if (mi > MI_GREEN_THRESHOLD) return greenColor || GREEN;
89
- if (mi > MI_YELLOW_THRESHOLD) return yellowColor || YELLOW;
90
- return redColor || RED;
165
+ function zoneAnsiColor(colorName) {
166
+ if (colorName === 'green') {
167
+ return GREEN;
168
+ }
169
+ if (colorName === 'yellow') {
170
+ return YELLOW;
171
+ }
172
+ if (colorName === 'orange') {
173
+ return '\x1b[38;2;255;165;0m';
174
+ }
175
+ if (colorName === 'dark_red') {
176
+ return '\x1b[38;2;139;0;0m';
177
+ }
178
+ if (colorName === 'gray') {
179
+ return '\x1b[0;90m';
180
+ }
181
+ return RESET;
91
182
  }
92
183
 
93
184
  /**
@@ -154,6 +245,8 @@ const COLOR_NAMES = {
154
245
  bright_magenta: '\x1b[0;95m',
155
246
  bright_cyan: '\x1b[0;96m',
156
247
  bright_white: '\x1b[0;97m',
248
+ bold_white: '\x1b[1;97m',
249
+ dim: '\x1b[2m',
157
250
  };
158
251
 
159
252
  /**
@@ -182,6 +275,13 @@ const COLOR_CONFIG_KEYS = {
182
275
  color_blue: 'blue',
183
276
  color_magenta: 'magenta',
184
277
  color_cyan: 'cyan',
278
+ // Per-property color keys
279
+ color_context_length: 'context_length',
280
+ color_project_name: 'project_name',
281
+ color_branch_name: 'branch_name',
282
+ color_mi_score: 'mi_score',
283
+ color_zone: 'zone',
284
+ color_separator: 'separator',
185
285
  };
186
286
 
187
287
  /**
@@ -290,7 +390,7 @@ function readConfig() {
290
390
  showSession: true,
291
391
  showIoTokens: true,
292
392
  reducedMotion: false,
293
- showMI: true,
393
+ showMI: false,
294
394
  miCurveBeta: 0,
295
395
  colors: {},
296
396
  };
@@ -409,17 +509,23 @@ process.stdin.on('end', () => {
409
509
  const cMagenta = c.magenta || MAGENTA;
410
510
  const cCyan = c.cyan || CYAN;
411
511
 
412
- // Git info (pass configurable colors)
413
- const gitInfo = getGitInfo(projectDir, cMagenta, cCyan);
512
+ // Per-property color defaults (highlighted key info)
513
+ // Falls back to old color keys for backward compatibility, then to new defaults
514
+ const cProjectName = c.project_name || (c.blue ? cBlue : CYAN);
515
+ const cBranchName = c.branch_name || (c.magenta ? cMagenta : GREEN);
516
+ const cSeparator = c.separator || DIM;
517
+
518
+ // Git info (use per-property branch color, fallback to green)
519
+ const gitInfo = getGitInfo(projectDir, cBranchName, cCyan);
414
520
 
415
521
  // Extract session_id once for reuse
416
522
  const sessionId = data.session_id;
417
523
 
418
524
  // Context window calculation
419
525
  let contextInfo = '';
420
- let acInfo = '';
421
526
  let deltaInfo = '';
422
527
  let miInfo = '';
528
+ let zoneInfo = '';
423
529
  let sessionInfo = '';
424
530
  const showMI = config.showMI;
425
531
  const miCurveBeta = config.miCurveBeta;
@@ -448,14 +554,9 @@ process.stdin.on('end', () => {
448
554
  // Free tokens calculation depends on autocompact setting
449
555
  let freeTokens;
450
556
  if (autocompactEnabled) {
451
- // When AC enabled: subtract buffer to show actual usable space
452
557
  freeTokens = totalSize - usedTokens - autocompactBuffer;
453
- const bufferK = Math.floor(autocompactBuffer / 1000);
454
- acInfo = ` ${DIM}[AC:${bufferK}k]${RESET}`;
455
558
  } else {
456
- // When AC disabled: show full free space
457
559
  freeTokens = totalSize - usedTokens;
458
- acInfo = ` ${DIM}[AC:off]${RESET}`;
459
560
  }
460
561
 
461
562
  if (freeTokens < 0) {
@@ -464,24 +565,27 @@ process.stdin.on('end', () => {
464
565
 
465
566
  // Calculate percentage with one decimal (relative to total size)
466
567
  const freePct = (freeTokens * 100.0) / totalSize;
467
- const freePctInt = Math.floor(freePct);
468
568
 
469
569
  // Format tokens based on token_detail setting
470
570
  const freeDisplay = tokenDetail
471
571
  ? freeTokens.toLocaleString('en-US')
472
572
  : `${(freeTokens / 1000).toFixed(1)}k`;
473
573
 
474
- // Color based on free percentage
475
- let ctxColor;
476
- if (freePctInt > 50) {
477
- ctxColor = cGreen;
478
- } else if (freePctInt > 25) {
479
- ctxColor = cYellow;
480
- } else {
481
- ctxColor = cRed;
482
- }
574
+ // Color based on MI thresholds (consistent with MI display)
575
+ const ctxUtil = totalSize > 0 ? usedTokens / totalSize : 0;
576
+ const ctxMI = computeMI(usedTokens, totalSize, modelId, miCurveBeta);
577
+ const ctxColor = getMIColor(ctxMI.mi, ctxUtil, cGreen, cYellow, cRed);
578
+
579
+ // Use per-property context_length color if configured, else MI-based color
580
+ const effectiveCtxColor = c.context_length || ctxColor;
483
581
 
484
- contextInfo = ` | ${ctxColor}${freeDisplay} (${freePct.toFixed(1)}%)${RESET}`;
582
+ contextInfo = ` | ${effectiveCtxColor}${freeDisplay} (${freePct.toFixed(1)}%)${RESET}`;
583
+
584
+ // Always show zone indicator
585
+ const zoneResult = getContextZone(usedTokens, totalSize);
586
+ // Use per-property zone color if configured, else dynamic zone color
587
+ const zoneAnsi = c.zone || zoneAnsiColor(zoneResult.colorName);
588
+ zoneInfo = ` | ${zoneAnsi}${zoneResult.zone}${RESET}`;
485
589
 
486
590
  // Read previous entry if needed for delta OR MI
487
591
  if (showDelta || showMI) {
@@ -550,15 +654,18 @@ process.stdin.on('end', () => {
550
654
  const deltaDisplay = tokenDetail
551
655
  ? delta.toLocaleString('en-US')
552
656
  : `${(delta / 1000).toFixed(1)}k`;
553
- deltaInfo = ` ${DIM}[+${deltaDisplay}]${RESET}`;
657
+ deltaInfo = ` | ${cSeparator}+${deltaDisplay}${RESET}`;
554
658
  }
555
659
  }
556
660
 
557
661
  // Calculate and display MI score if enabled
558
662
  if (showMI) {
559
663
  const miResult = computeMI(usedTokens, totalSize, modelId, miCurveBeta);
560
- const miColor = getMIColor(miResult.mi, cGreen, cYellow, cRed);
561
- miInfo = ` ${miColor}MI:${miResult.mi.toFixed(3)}${RESET}`;
664
+ const miUtil = totalSize > 0 ? usedTokens / totalSize : 0;
665
+ const miColor = getMIColor(miResult.mi, miUtil, cGreen, cYellow, cRed);
666
+ // Use per-property mi_score color if configured, else MI-based color
667
+ const effectiveMIColor = c.mi_score || miColor;
668
+ miInfo = ` | ${effectiveMIColor}MI:${miResult.mi.toFixed(3)}${RESET}`;
562
669
  }
563
670
 
564
671
  // Only append if context usage changed (avoid duplicates from multiple refreshes)
@@ -596,17 +703,25 @@ process.stdin.on('end', () => {
596
703
 
597
704
  // Display session_id if enabled
598
705
  if (showSession && sessionId) {
599
- sessionInfo = ` ${DIM}${sessionId}${RESET}`;
706
+ sessionInfo = ` | ${cSeparator}${sessionId}${RESET}`;
600
707
  }
601
708
 
602
- // Output: [Model] dir | branch [n] | free (%) [+delta] [AC] session
603
- const base = `${DIM}[${model}]${RESET} ${cBlue}${dirName}${RESET}`;
709
+ // Output: dir | branch [n] | free (%) | zone | MI | +delta | [Model] session
710
+ // Model name is lowest priority — truncated first when terminal is narrow
711
+ const base = `${cProjectName}${dirName}${RESET}`;
712
+ const modelInfo = ` | ${cSeparator}${model}${RESET}`;
604
713
  const maxWidth = getTerminalWidth();
605
- const parts = [base, gitInfo, contextInfo, deltaInfo, miInfo, acInfo, sessionInfo];
714
+ const parts = [base, gitInfo, contextInfo, zoneInfo, miInfo, deltaInfo, modelInfo, sessionInfo];
606
715
  console.log(fitToWidth(parts, maxWidth));
607
716
  });
608
717
 
609
718
  // Export for testing
610
719
  if (typeof module !== 'undefined' && module.exports) {
611
- module.exports = { maybeRotateStateFile, ROTATION_THRESHOLD, ROTATION_KEEP, computeMI };
720
+ module.exports = {
721
+ maybeRotateStateFile,
722
+ ROTATION_THRESHOLD,
723
+ ROTATION_KEEP,
724
+ computeMI,
725
+ getContextZone,
726
+ };
612
727
  }