claude-simple-status 1.3.1 → 1.4.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/README.md CHANGED
@@ -21,8 +21,8 @@ A simple, no-frills statusline for [Claude Code](https://docs.anthropic.com/en/d
21
21
  - **Cross-platform** — works on macOS, Linux, and Windows
22
22
  - **Non-blocking** — returns cached data instantly, refreshes quota in the background
23
23
  - **Color-coded** — green/orange/red percentages at a glance
24
- - **Context velocity** — estimates remaining turns until context compaction (`42% →~8t`), with directional arrows showing if burn rate is accelerating (↑), steady (→), or decelerating (↓)
25
- - **Quota pressure** — reset time changes color based on projected burn rate: green (safe), orange (cutting it close), red (will hit the limit before reset). The 7d percentage color is also overridden when the projection says danger
24
+ - **Context velocity** *(opt-in)* — estimates remaining turns until context compaction (`42% →~8t`), with directional arrows showing if burn rate is accelerating (↑), steady (→), or decelerating (↓)
25
+ - **Quota pressure** *(opt-in)* — reset time changes color based on projected burn rate: green (safe), orange (cutting it close), red (will hit the limit before reset). The 7d percentage color is also overridden when the projection says danger
26
26
  - **Project name** — bold uppercase project directory name so you never mix up sessions
27
27
  - **Git-aware** — shows the current branch name in repos (cached 30s to reduce overhead)
28
28
  - **API cost tracking** — pay-as-you-go API users see cumulative session cost instead of quota
@@ -92,6 +92,24 @@ To uninstall, remove `~/.claude/statusline/` and the `"statusLine"` block from s
92
92
 
93
93
  </details>
94
94
 
95
+ ## Configuration
96
+
97
+ Create `~/.config/claude-simple-status.json` to enable optional features:
98
+
99
+ ```json
100
+ {
101
+ "contextVelocity": true,
102
+ "quotaBurnRate": true
103
+ }
104
+ ```
105
+
106
+ | Option | Default | Description |
107
+ |--------|---------|-------------|
108
+ | `contextVelocity` | `false` | Show estimated turns remaining until context compaction (`42% →~8t`) |
109
+ | `quotaBurnRate` | `false` | Color reset time and 7d quota based on projected burn rate |
110
+
111
+ Without this file, you get a clean statusline showing just project, branch, model, context %, reset time, and quota percentages.
112
+
95
113
  ## Requirements
96
114
 
97
115
  - Claude Code CLI
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-simple-status",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "A simple statusline for Claude Code — project name, git branch, model, context usage, quota, and API costs at a glance",
5
5
  "type": "module",
6
6
  "bin": {
package/statusline.mjs CHANGED
@@ -46,7 +46,7 @@ const CACHE_STALE_AGE = 300; // seconds - when to show "--" instead of old value
46
46
  const GIT_BRANCH_CACHE = join(tmpdir(), 'claude-statusline-branches.json');
47
47
  const GIT_BRANCH_MAX_AGE = 30; // seconds
48
48
  const CONTEXT_HISTORY_FILE = join(tmpdir(), 'claude-statusline-context.json');
49
- const CONTEXT_COMPACT_THRESHOLD = 95; // % at which compaction typically fires
49
+ const CONTEXT_COMPACT_THRESHOLD = 83; // % at which autocompact typically fires
50
50
  const CONTEXT_MAX_SAMPLES = 20; // rolling window of turn deltas
51
51
  const QUOTA_HISTORY_FILE = join(tmpdir(), 'claude-statusline-quota-history.json');
52
52
  const QUOTA_MAX_READINGS = 30; // ~1h of data at 120s refresh intervals
@@ -81,6 +81,12 @@ function readJsonFile(filepath) {
81
81
  }
82
82
  }
83
83
 
84
+ // User config — features off by default, opt-in via ~/.config/claude-simple-status.json
85
+ const CONFIG_FILE = join(homedir(), '.config', 'claude-simple-status.json');
86
+ const userConfig = readJsonFile(CONFIG_FILE) || {};
87
+ const SHOW_CONTEXT_VELOCITY = userConfig.contextVelocity === true;
88
+ const SHOW_BURN_RATE = userConfig.quotaBurnRate === true;
89
+
84
90
  // Clean up stale lock (older than 30s)
85
91
  function cleanStaleLock() {
86
92
  if (existsSync(LOCK_DIR) && getFileAge(LOCK_DIR) > 30) {
@@ -233,8 +239,9 @@ function getContextVelocity(projectDir, contextUsed) {
233
239
  history[projectDir] = entry;
234
240
  try { writeFileSync(CONTEXT_HISTORY_FILE, JSON.stringify(history)); } catch {}
235
241
 
236
- // Need at least 2 turn deltas to estimate
237
- if (entry.deltas.length < 2) return null;
242
+ // Need at least 5 turn deltas to estimate — fewer gives noisy results
243
+ // (especially right after compaction when early turns inflate context quickly)
244
+ if (entry.deltas.length < 5) return null;
238
245
 
239
246
  // Weighted average: recent deltas matter more
240
247
  let weightSum = 0;
@@ -399,8 +406,8 @@ async function main() {
399
406
  hasError = errContent.length > 0;
400
407
  } catch {}
401
408
 
402
- // Get context velocity estimate
403
- const velocity = getContextVelocity(projectDir, contextUsed);
409
+ // Get context velocity estimate (opt-in)
410
+ const velocity = SHOW_CONTEXT_VELOCITY ? getContextVelocity(projectDir, contextUsed) : null;
404
411
 
405
412
  // Get rig name (claude-rig sets CLAUDE_CONFIG_DIR to ~/.claude-rig/rigs/<name>)
406
413
  const rigProfile = (() => {
@@ -425,15 +432,15 @@ async function main() {
425
432
  contextDisplay += ` ${turnsColor}${velocity.arrow}${turnsStr}${RESET}`;
426
433
  }
427
434
 
428
- // Color the reset time based on 5h quota burn rate projection
429
- const fiveHourPressure = getQuotaPressure('5h', fiveHourPct, fiveHourResetsAt);
435
+ // Color the reset time based on 5h quota burn rate projection (opt-in)
436
+ const fiveHourPressure = SHOW_BURN_RATE ? getQuotaPressure('5h', fiveHourPct, fiveHourResetsAt) : null;
430
437
  let resetDisplay = resetLocal;
431
438
  if (fiveHourPressure === 'danger') resetDisplay = `${RED}${resetLocal}${RESET}`;
432
439
  else if (fiveHourPressure === 'tight') resetDisplay = `${ORANGE}${resetLocal}${RESET}`;
433
440
  else if (fiveHourPressure === 'safe') resetDisplay = `${GREEN}${resetLocal}${RESET}`;
434
441
 
435
- // Override 7d percentage color when burn rate projects exhaustion before reset
436
- const sevenDayPressure = getQuotaPressure('7d', sevenDayPct, sevenDayResetsAt);
442
+ // Override 7d percentage color when burn rate projects exhaustion before reset (opt-in)
443
+ const sevenDayPressure = SHOW_BURN_RATE ? getQuotaPressure('7d', sevenDayPct, sevenDayResetsAt) : null;
437
444
  let sevenDayDisplay = colorPct(sevenDayPct);
438
445
  if (sevenDayPressure === 'danger') sevenDayDisplay = `${RED}${sevenDayPct}%${RESET}`;
439
446
  else if (sevenDayPressure === 'tight') sevenDayDisplay = `${ORANGE}${sevenDayPct}%${RESET}`;