claude-pace 0.7.1 → 0.7.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.
package/README.md CHANGED
@@ -80,11 +80,17 @@ Claude Code polls the statusline every ~300ms:
80
80
  |------|--------|-------|
81
81
  | Model, context, cost | stdin JSON (single `jq` call) | None needed |
82
82
  | Quota (5h, 7d, pace) | stdin `rate_limits` (CC >= 2.1.80) | None needed (real-time) |
83
- | Quota fallback | Anthropic Usage API (CC < 2.1.80) | `/tmp`, 300s TTL, async background refresh |
84
- | Git branch + diff | `git` commands | `/tmp`, 5s TTL |
83
+ | Quota fallback | Anthropic Usage API (CC < 2.1.80) | Private cache dir, 300s TTL, async background refresh |
84
+ | Git branch + diff | `git` commands | Private cache dir, 5s TTL |
85
85
 
86
86
  On Claude Code >= 2.1.80, usage data comes directly from stdin. No network calls. On older versions, it falls back to the Usage API in a background subshell so the statusline never blocks.
87
87
 
88
+ 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`.
89
+
90
+ ## Also by the Author
91
+
92
+ [**diffpane**](https://github.com/Astro-Han/diffpane) - Real-time TUI diff viewer for AI coding agents. See what Claude Code changes as it happens.
93
+
88
94
  ## License
89
95
 
90
96
  MIT
package/claude-pace.sh CHANGED
@@ -213,7 +213,7 @@ else
213
213
  # Check in order: env var → macOS Keychain → credentials file → secret-tool (Linux).
214
214
  _get_token() {
215
215
  [ -n "$CLAUDE_CODE_OAUTH_TOKEN" ] && {
216
- echo "$CLAUDE_CODE_OAUTH_TOKEN"
216
+ printf '%s' "$CLAUDE_CODE_OAUTH_TOKEN"
217
217
  return
218
218
  }
219
219
  local b=""
@@ -222,18 +222,28 @@ else
222
222
  [ -z "$b" ] && [ -f ~/.claude/.credentials.json ] && b=$(<~/.claude/.credentials.json)
223
223
  [ -z "$b" ] && command -v secret-tool >/dev/null &&
224
224
  b=$(timeout 2 secret-tool lookup service "Claude Code-credentials" 2>/dev/null)
225
- [ -n "$b" ] && jq -r '.claudeAiOauth.accessToken//empty' <<<"$b" 2>/dev/null
225
+ [ -n "$b" ] && jq -j '.claudeAiOauth.accessToken//empty' <<<"$b" 2>/dev/null
226
226
  }
227
227
 
228
228
  # ── _fetch_usage_api: direct API read into usage globals ──
229
229
  # Used by both the cached background refresh path and the no-cache fallback.
230
230
  _fetch_usage_api() {
231
231
  local tk resp
232
- tk=$(_get_token)
232
+ # Command substitution strips trailing newlines. Append a sentinel byte only
233
+ # on success so malformed tokens with a trailing LF remain detectable here.
234
+ tk=$(_get_token && printf '\001') || return 1
235
+ [[ "$tk" == *$'\001' ]] || return 1
236
+ tk=${tk%$'\001'}
233
237
  [ -n "$tk" ] || return 1
238
+ # OAuth bearer tokens must remain a single header line. Reject malformed
239
+ # credentials up front instead of letting curl parse injected CR/LF bytes.
240
+ case "$tk" in *$'\n'* | *$'\r'*) return 1 ;; esac
241
+ # Feed headers through process substitution so the bearer token stays out
242
+ # of curl argv while preserving literal bytes like quotes and backslashes.
234
243
  resp=$(curl -s --max-time 3 \
235
- -H "Authorization: Bearer $tk" -H "anthropic-beta: oauth-2025-04-20" \
236
- -H "Content-Type: application/json" \
244
+ -H @<(printf 'Authorization: Bearer %s\n' "$tk"
245
+ printf '%s\n' 'anthropic-beta: oauth-2025-04-20'
246
+ printf '%s\n' 'Content-Type: application/json') \
237
247
  "https://api.anthropic.com/api/oauth/usage" 2>/dev/null)
238
248
  IFS=$'\t' read -r U5 U7 XO XU XL RM5 RM7 < <(jq -r '
239
249
  def rmins: if . and . != "" then (sub("\\.[0-9]+"; "") | sub("\\+00:00$"; "Z") | fromdateiso8601) - (now|floor) | ./60|floor | if .<0 then 0 else . end else null end;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-pace",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "A statusline for Claude Code. Pure Bash + jq, single file.",
5
5
  "bin": {
6
6
  "claude-pace": "cli.js"