claude-pace 0.8.0 → 0.8.2

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 +31 -9
  2. package/claude-pace.sh +42 -1
  3. package/package.json +10 -3
package/README.md CHANGED
@@ -1,17 +1,39 @@
1
1
  # Claude Pace
2
2
 
3
- A lightweight status line for Claude Code that tracks your 5-hour and 7-day rate limit usage in real time. Pure Bash + jq, single file, zero npm.
3
+ A lightweight Claude Code status line and rate limit tracker that shows your 5-hour and 7-day quota usage in real time. Pure Bash + jq, single file, zero npm.
4
4
 
5
- Most statuslines show "you used 60%." That number means nothing without context. 60% with 30 minutes left? Fine, the window resets soon. 60% with 4 hours left? You're about to hit the wall. claude-pace compares your burn rate to the time remaining and shows the delta: are you ahead of pace or behind?
5
+ If you are searching for a Claude Code statusline, a Claude Code quota monitor, or a Claude Code usage tracker, claude-pace is built for that narrow job. It shows not only how much quota you have used, but whether your current burn rate is sustainable before the window resets.
6
6
 
7
7
  ![claude-pace statusline demo](.github/claude-pace-demo.gif)
8
8
 
9
+ ## TL;DR
10
+
11
+ - Claude Code status line with `5h` and `7d` quota usage, reset countdowns, and pace delta
12
+ - Pace-aware rate limit tracking, `⇡15%` means overspending, `⇣15%` means headroom
13
+ - Pure Bash + jq, single file, no Node.js runtime and no lockfile churn
14
+ - Install as a Claude Code plugin, with `npx`, or as a single script
15
+
16
+ Most statuslines show "you used 60%." That number means nothing without context. 60% with 30 minutes left? Fine, the window resets soon. 60% with 4 hours left? You are about to hit the wall. claude-pace compares your burn rate to the time remaining and shows the delta.
17
+
9
18
  - **⇣15%** green = you've used 15% less than expected. Headroom. Keep going.
10
19
  - **⇡15%** red = you're burning 15% faster than sustainable. Slow down.
11
20
  - **15%** / **20%** = used in the 5h and 7d windows. **3h** = resets in 3 hours.
12
21
  - Top line: model, effort, project `(branch)`, `3f +24 -7` = git diff stats
13
22
 
14
- ## Install
23
+ Claude Code supports custom status lines through its `statusLine` setting and `/statusline` workflow in the official docs:
24
+
25
+ - [Customize your status line](https://code.claude.com/docs/en/statusline)
26
+ - [Claude Code settings](https://docs.anthropic.com/en/docs/claude-code/settings)
27
+
28
+ ## Table of Contents
29
+
30
+ - [Install This Claude Code Statusline](#install-this-claude-code-statusline)
31
+ - [Upgrade](#upgrade)
32
+ - [Claude Code Statusline Comparison](#claude-code-statusline-comparison)
33
+ - [How Claude Pace Tracks Quota](#how-claude-pace-tracks-quota)
34
+ - [Claude Code Statusline FAQ](#claude-code-statusline-faq)
35
+
36
+ ## Install This Claude Code Statusline
15
37
 
16
38
  Requires `jq`.
17
39
 
@@ -65,7 +87,7 @@ To remove: delete the `statusLine` block from `~/.claude/settings.json`.
65
87
 
66
88
  Release notifications: Watch this repo → Custom → Releases.
67
89
 
68
- ## How It Compares
90
+ ## Claude Code Statusline Comparison
69
91
 
70
92
  | | claude-pace | [claude-hud](https://github.com/jarrodwatts/claude-hud) | [CCometixLine](https://github.com/Haleclipse/CCometixLine) | [ccstatusline](https://github.com/sirmalloc/ccstatusline) |
71
93
  |---|---|---|---|---|
@@ -79,21 +101,21 @@ Execution and memory measured on Apple Silicon, 300 runs, same stdin JSON.
79
101
 
80
102
  Need themes, powerline aesthetics, or TUI config? Try [ccstatusline](https://github.com/sirmalloc/ccstatusline). The entire source of claude-pace is [one file](claude-pace.sh). Read it.
81
103
 
82
- ## Under the Hood
104
+ ## How Claude Pace Tracks Quota
83
105
 
84
106
  Claude Code polls the statusline every ~300ms:
85
107
 
86
108
  | Data | Source | Cache |
87
109
  |------|--------|-------|
88
110
  | Model, context, cost | stdin JSON (single `jq` call) | None needed |
89
- | Quota (5h, 7d, pace) | stdin `rate_limits` (CC >= 2.1.80) | None needed (real-time) |
111
+ | Quota (5h, 7d, pace) | stdin `rate_limits`; fallback to last-known private cache when `rate_limits` is absent | Private cache root, accepted only before cached reset |
90
112
  | Git branch + diff | `git` commands | Private cache dir, 5s TTL |
91
113
 
92
- Usage tracking requires Claude Code `2.1.80+`, where `rate_limits` is available in statusline stdin. claude-pace does not call the Anthropic Usage API.
114
+ Best experience is on Claude Code `2.1.80+`, where `rate_limits` is available in statusline stdin. When a later statusline run omits `rate_limits`, claude-pace can reuse the last known stdin quota snapshot from its private cache until either cached reset time expires.
93
115
 
94
116
  Cache files live in a private per-user directory (`$XDG_RUNTIME_DIR/claude-pace` or `~/.cache/claude-pace`, mode 700). All cache reads are validated before use. No files are ever written to shared `/tmp`.
95
117
 
96
- ## FAQ
118
+ ## Claude Code Statusline FAQ
97
119
 
98
120
  **Does it need Node.js?**
99
121
  No. Only `jq` (available via `brew install jq` or your package manager). No npm, no node_modules, no lock files.
@@ -102,7 +124,7 @@ No. Only `jq` (available via `brew install jq` or your package manager). No npm,
102
124
  claude-pace compares your current usage percentage to the fraction of time elapsed in each window (5-hour and 7-day). If you've used 40% of your quota but only 30% of the time has passed, the pace delta shows ⇡10% (red, burning too fast). If you've used 30% with 40% of time elapsed, it shows ⇣10% (green, headroom).
103
125
 
104
126
  **Does it make network calls?**
105
- No. All displayed quota data comes from stdin. If `rate_limits` is missing, claude-pace shows `--` for quota and can still show the local session cost.
127
+ No. Quota data comes from stdin `rate_limits` on Claude Code `2.1.80+`. If a later statusline run omits `rate_limits`, claude-pace can reuse the last known stdin quota snapshot from its private cache as long as that snapshot's reset times are still in the future. Otherwise it falls back to `--` and may still show the local session cost.
106
128
 
107
129
  **Can I inspect the source?**
108
130
  The entire tool is [one Bash file](claude-pace.sh). Read it before you install it.
package/claude-pace.sh CHANGED
@@ -65,6 +65,17 @@ _write_cache_record() {
65
65
  printf '%s\n' "$*"
66
66
  ) >"$tmp" && mv "$tmp" "$path"
67
67
  }
68
+ # Avoids rewriting the quota cache when the live snapshot is unchanged.
69
+ _write_quota_snapshot_if_changed() {
70
+ local path="$1" u5="$2" u7="$3" r5="$4" r7="$5"
71
+ if [ -f "$path" ] && [ ! -L "$path" ] && [ -r "$path" ] && _load_cache_record_file "$path"; then
72
+ [[ "${CACHE_FIELDS[0]:-}" == "$u5" ]] &&
73
+ [[ "${CACHE_FIELDS[1]:-}" == "$u7" ]] &&
74
+ [[ "${CACHE_FIELDS[2]:-}" == "$r5" ]] &&
75
+ [[ "${CACHE_FIELDS[3]:-}" == "$r7" ]] && return 0
76
+ fi
77
+ _write_cache_record "$path" "$u5" "$u7" "$r5" "$r7"
78
+ }
68
79
  # Computes remaining whole minutes until a future epoch. Missing or expired
69
80
  # timestamps return an empty string so callers can skip countdown formatting.
70
81
  _minutes_until() {
@@ -74,6 +85,16 @@ _minutes_until() {
74
85
  ((mins < 0)) && mins=0
75
86
  printf '%s\n' "$mins"
76
87
  }
88
+ # Valid quota snapshots must contain integer usage values and future reset
89
+ # epochs for both windows. Partial or expired snapshots never enter the cache.
90
+ _valid_quota_snapshot() {
91
+ local u5="$1" u7="$2" r5="$3" r7="$4"
92
+ [[ "$u5" =~ ^[0-9]+$ ]] || return 1
93
+ [[ "$u7" =~ ^[0-9]+$ ]] || return 1
94
+ [[ "$r5" =~ ^[0-9]+$ ]] || return 1
95
+ [[ "$r7" =~ ^[0-9]+$ ]] || return 1
96
+ ((r5 > NOW && r7 > NOW))
97
+ }
77
98
  # Collects live Git metadata for DIR. On non-repos, leaves defaults in place
78
99
  # and returns non-zero so callers can decide whether to cache the empty result.
79
100
  _collect_git_info() {
@@ -101,6 +122,8 @@ for _BASE in "${XDG_RUNTIME_DIR:-}" "${HOME}/.cache"; do
101
122
  CACHE_OK=1
102
123
  break
103
124
  done
125
+ QC=""
126
+ [[ "$CACHE_OK" == "1" ]] && QC="${_CD}/claude-sl-quota"
104
127
  # Returns true (exit 0) when file is missing or older than $2 seconds.
105
128
  _stale() { [ ! -f "$1" ] || [ $((NOW - $(stat -f%m "$1" 2>/dev/null || stat -c%Y "$1" 2>/dev/null || echo 0))) -gt "$2" ]; }
106
129
 
@@ -198,12 +221,30 @@ fi
198
221
  SHOW_COST=0
199
222
  if [[ "$HAS_RL" == "1" ]]; then
200
223
  # Stdin path: real-time, no network. U5/U7 already set by jq read above.
201
- # Guard: resets_at=0 means field missing, leave RM empty so _pace/_rc skip it
224
+ # Guard: resets_at=0 means field missing, leave RM empty so _usage skips it.
202
225
  RM5=$(_minutes_until "$R5")
203
226
  RM7=$(_minutes_until "$R7")
227
+ if [[ -n "$QC" ]] && _valid_quota_snapshot "$U5" "$U7" "$R5" "$R7"; then
228
+ _write_quota_snapshot_if_changed "$QC" "$U5" "$U7" "$R5" "$R7" || true
229
+ fi
204
230
  else
205
231
  U5="--" U7="--" RM5="" RM7=""
206
232
  SHOW_COST=1
233
+ if [[ -n "$QC" ]] && _load_cache_record_file "$QC"; then
234
+ _CU5=${CACHE_FIELDS[0]:-}
235
+ _CU7=${CACHE_FIELDS[1]:-}
236
+ _CR5=${CACHE_FIELDS[2]:-}
237
+ _CR7=${CACHE_FIELDS[3]:-}
238
+ if _valid_quota_snapshot "$_CU5" "$_CU7" "$_CR5" "$_CR7"; then
239
+ U5="$_CU5"
240
+ U7="$_CU7"
241
+ R5="$_CR5"
242
+ R7="$_CR7"
243
+ RM5=$(_minutes_until "$R5")
244
+ RM7=$(_minutes_until "$R7")
245
+ SHOW_COST=0
246
+ fi
247
+ fi
207
248
  fi
208
249
 
209
250
  # Combined usage formatter: used% [pace delta] (countdown)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "claude-pace",
3
- "version": "0.8.0",
4
- "description": "A statusline for Claude Code. Pure Bash + jq, single file.",
3
+ "version": "0.8.2",
4
+ "description": "Claude Code statusline and rate limit tracker. Pure Bash + jq, single file.",
5
5
  "bin": {
6
6
  "claude-pace": "cli.js"
7
7
  },
@@ -15,11 +15,18 @@
15
15
  },
16
16
  "keywords": [
17
17
  "claude-code",
18
+ "claude-code-statusline",
19
+ "claude-code-plugin",
18
20
  "statusline",
21
+ "status-line",
22
+ "rate-limit-tracker",
19
23
  "quota",
24
+ "quota-tracker",
20
25
  "usage",
26
+ "usage-monitor",
21
27
  "pace-tracking",
22
- "bash"
28
+ "bash",
29
+ "jq"
23
30
  ],
24
31
  "license": "MIT",
25
32
  "repository": {