-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfetch-usage.sh
More file actions
executable file
·94 lines (82 loc) · 3.67 KB
/
Copy pathfetch-usage.sh
File metadata and controls
executable file
·94 lines (82 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/sh
# Fetches Claude Code usage stats from the Anthropic API and caches them.
#
# Cache format (/tmp/.claude_usage_cache):
# Line 1: five_hour utilization (integer %)
# Line 2: seven_day utilization (integer %)
# Line 3: five_hour resets_at (ISO 8601)
# Line 4: seven_day resets_at (ISO 8601)
# Line 5: model-scoped weekly utilization (integer %, empty if none)
# Line 6: model-scoped weekly resets_at (ISO 8601, empty if none)
# Line 7: model-scoped label, lowercased (e.g. "fable", empty if none)
#
# Designed to run in background via Claude Code hooks.
CACHE_FILE="/tmp/.claude_usage_cache"
# ---------------------------------------------------------------------------
# Platform detection
# ---------------------------------------------------------------------------
if stat -f %m /dev/null > /dev/null 2>&1; then
file_mtime() { stat -f %m "$1"; }
else
file_mtime() { stat -c %Y "$1"; }
fi
# ---------------------------------------------------------------------------
# Throttle: skip if cache is fresh (< 60s)
# ---------------------------------------------------------------------------
if [ -f "$CACHE_FILE" ]; then
cache_age=$(( $(date +%s) - $(file_mtime "$CACHE_FILE") ))
[ "$cache_age" -lt 60 ] && exit 0
fi
# ---------------------------------------------------------------------------
# Extract OAuth token
# ---------------------------------------------------------------------------
# macOS: Keychain
if command -v security > /dev/null 2>&1; then
raw_creds=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null)
fi
# Linux fallback: check common credential file locations
if [ -z "$raw_creds" ]; then
for f in \
"$HOME/.config/claude-code/credentials.json" \
"$HOME/.claude/credentials.json"; do
[ -f "$f" ] && raw_creds=$(cat "$f" 2>/dev/null) && break
done
fi
if [ -z "$raw_creds" ]; then
exit 0
fi
token=$(printf '%s' "$raw_creds" | jq -r '.claudeAiOauth.accessToken // empty' 2>/dev/null)
if [ -z "$token" ]; then
exit 0
fi
# ---------------------------------------------------------------------------
# Fetch usage from API
# ---------------------------------------------------------------------------
usage_json=$(curl -s -m 10 \
-H "accept: application/json" \
-H "anthropic-beta: oauth-2025-04-20" \
-H "authorization: Bearer $token" \
-H "user-agent: claude-code" \
"https://api.anthropic.com/oauth/usage" 2>/dev/null)
if [ -z "$usage_json" ]; then
exit 0
fi
five_h_raw=$(printf '%s' "$usage_json" | jq -r '.five_hour.utilization // empty' 2>/dev/null)
seven_d_raw=$(printf '%s' "$usage_json" | jq -r '.seven_day.utilization // empty' 2>/dev/null)
five_h_reset=$(printf '%s' "$usage_json" | jq -r '.five_hour.resets_at // ""' 2>/dev/null)
seven_d_reset=$(printf '%s' "$usage_json" | jq -r '.seven_day.resets_at // ""' 2>/dev/null)
# Model-scoped weekly limit (e.g. Fable) from the limits[] array
scoped_filter='[.limits[]? | select(.kind == "weekly_scoped" and .scope.model.display_name != null)][0]'
scoped_pct_raw=$(printf '%s' "$usage_json" | jq -r "$scoped_filter.percent // empty" 2>/dev/null)
scoped_reset=$(printf '%s' "$usage_json" | jq -r "$scoped_filter.resets_at // \"\"" 2>/dev/null)
scoped_label=$(printf '%s' "$usage_json" | jq -r "$scoped_filter.scope.model.display_name // \"\"" 2>/dev/null \
| tr '[:upper:]' '[:lower:]')
scoped_pct=""
[ -n "$scoped_pct_raw" ] && scoped_pct=$(printf "%.0f" "$scoped_pct_raw")
if [ -n "$five_h_raw" ] && [ -n "$seven_d_raw" ]; then
five_h=$(printf "%.0f" "$five_h_raw")
seven_d=$(printf "%.0f" "$seven_d_raw")
printf '%s\n%s\n%s\n%s\n%s\n%s\n%s\n' \
"$five_h" "$seven_d" "$five_h_reset" "$seven_d_reset" \
"$scoped_pct" "$scoped_reset" "$scoped_label" > "$CACHE_FILE"
fi