# Fix Fable usage anxiety by adding a daily target to your status bar

Published: 2026-08-17T00:00:00.000Z
Canonical: https://wow.pjh.is/journal/status-bar-daily-usage-target

I've been underusing Fable for fear of hitting the weekly quota on day 5, and then facing some "this *really* needs Fable" tasks on day 6 or 7.

Soon I'll just get another Max plan. Meantime, I've fixed this with a status-line upgrade. It shows a daily target: the % of my weekly quota I can spend, assuming an even seven-day burn.

![A Claude Code status line reading "Opus 5 | Projects/ai-wow | 5h 2% | 7d 45% Fable 70% (t: 82%)", with the usage figures in green because both sit under the 82% daily target](https://wow.pjh.is/static/images/blog/claude-status-line.jpeg)

Using 15% per day—and more if previous days undershot—now becomes a target. So I'm using Fable a bunch more.

The code:

`~/.claude/settings.json`:

```json
"statusLine": {
  "type": "command",
  "command": "bash ~/.claude/scripts/statusline-command.sh"
}
```

`~/.claude/scripts/statusline-command.sh`:

```bash
#!/usr/bin/env bash
# Status line command for Claude Code
# Displays: model | cwd | 5h usage | 7d usage+pace | Fable usage+pace

input=$(cat)

# Model name
model=$(echo "$input" | jq -r '.model.display_name // empty')

# Working directory (strip /Users/ prefix and ph/Documents/ for brevity)
full_cwd=$(echo "$input" | jq -r '.workspace.current_dir')
cwd=$(echo "$full_cwd" | sed -e 's|^/Users/||' -e 's|ph/Documents/||' -e 's|www/_try/|_try/|')

# Pace helper: given %-used and window-reset epoch, print "pace N% <delta>"
# Weekly budget target: cumulative % of quota you'd have used by now at an
# even 1/7-per-day burn. Shared by the all-models and model-scoped windows
# (same 7-day window). Usage figures are coloured green/red against it.
target_pct() {
  awk -v now="$(date +%s)" -v reset="$1" 'BEGIN {
    elapsed = (now - (reset - 604800)) / 86400
    if (elapsed < 0) elapsed = 0
    if (elapsed > 7) elapsed = 7
    printf "%.0f", elapsed * 100 / 7
  }'
}

# colour_pct USED TARGET -> USED% coloured green (at/under target) or red (over)
colour_pct() {
  awk -v used="$1" -v target="$2" 'BEGIN {
    colour = (used > target + 0.5) ? 31 : 32
    printf "\033[%dm%.0f%%\033[0m", colour, used
  }'
}

# Usage limits (server-side, piped in via stdin JSON)
# 5-hour session window: show % used + reset time (HH:MM local)
five_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
five_reset=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
five_seg=""
if [ -n "$five_pct" ]; then
  five_seg="5h $(printf '%.0f' "$five_pct")%"
  if [ -n "$five_reset" ]; then
    five_seg="$five_seg (r: $(date -r "$five_reset" '+%H:%M' 2>/dev/null))"
  fi
fi

# 7-day window (all models): % used, coloured against the shared target.
# The target itself is printed once, on the last segment that has one.
week_pct=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
week_reset=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')
week_target=""
[ -n "$week_reset" ] && week_target=$(target_pct "$week_reset")
week_seg=""
if [ -n "$week_pct" ]; then
  if [ -n "$week_target" ]; then
    week_seg="7d $(colour_pct "$week_pct" "$week_target")"
  else
    week_seg="7d $(printf '%.0f' "$week_pct")%"
  fi
fi

# Model-scoped weekly limit (e.g. Fable): not in the stdin JSON, so fetch from
# the OAuth usage endpoint (same data as /usage), cached for 5 minutes.
usage_cache="$HOME/.cache/claude-statusline/usage.json"
now_epoch=$(date +%s)
cache_mtime=$(stat -f %m "$usage_cache" 2>/dev/null || echo 0)
if [ $((now_epoch - cache_mtime)) -gt 300 ]; then
  mkdir -p "${usage_cache%/*}"
  tok=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null | jq -r '.claudeAiOauth.accessToken // empty')
  fetched=0
  if [ -n "$tok" ]; then
    if curl -s --max-time 3 https://api.anthropic.com/api/oauth/usage \
        -H "Authorization: Bearer $tok" -H "anthropic-beta: oauth-2025-04-20" \
        -o "$usage_cache.tmp" 2>/dev/null \
      && jq -e '.limits' "$usage_cache.tmp" >/dev/null 2>&1; then
      mv "$usage_cache.tmp" "$usage_cache"
      fetched=1
    fi
    rm -f "$usage_cache.tmp"
  fi
  # On failure, bump mtime so the TTL still gates retries (keeps stale data).
  [ "$fetched" = 0 ] && touch "$usage_cache" 2>/dev/null
fi

fable_seg=""
if [ -s "$usage_cache" ]; then
  scoped=$(jq -r '[.limits[]? | select(.kind == "weekly_scoped" and .scope.model.display_name != null)][0] | if . == null then empty else "\(.scope.model.display_name)\t\(.percent)\t\(.resets_at)" end' "$usage_cache" 2>/dev/null)
  if [ -n "$scoped" ]; then
    scoped_name=$(printf '%s' "$scoped" | cut -f1)
    scoped_pct=$(printf '%s' "$scoped" | cut -f2)
    scoped_iso=$(printf '%s' "$scoped" | cut -f3)
    scoped_reset=$(date -j -u -f "%Y-%m-%dT%H:%M:%S" "${scoped_iso%%.*}" +%s 2>/dev/null)
    scoped_target="$week_target"
    [ -z "$scoped_target" ] && [ -n "$scoped_reset" ] && scoped_target=$(target_pct "$scoped_reset")
    if [ -n "$scoped_target" ]; then
      fable_seg="$scoped_name $(colour_pct "$scoped_pct" "$scoped_target") (t: ${scoped_target}%)"
    else
      fable_seg="$scoped_name $(printf '%.0f' "$scoped_pct")%"
    fi
  fi
fi

# Combine: "7d X% Fable X% (t: X%) (r: Tue)"
weekly_seg=""
if [ -n "$week_seg" ] && [ -n "$fable_seg" ]; then
  weekly_seg="$week_seg $fable_seg"
else
  weekly_seg="$week_seg$fable_seg"
fi
# No scoped segment carried the target, so put it back on the 7d one.
if [ -n "$weekly_seg" ] && [ -n "$week_target" ] && [ -z "$scoped_target" ]; then
  weekly_seg="$weekly_seg (t: ${week_target}%)"
fi
if [ -n "$weekly_seg" ] && [ -n "$week_reset" ]; then
  reset_fmt='+%a'
  seconds_until_reset=$((week_reset - now_epoch))
  if [ "$seconds_until_reset" -ge 0 ] && [ "$seconds_until_reset" -lt 172800 ]; then
    reset_fmt='+%a %H:%M'
  fi
  reset_at=$(date -r "$week_reset" "$reset_fmt" 2>/dev/null)
  [ -n "$reset_at" ] && weekly_seg="$weekly_seg (r: $reset_at)"
fi

# Build status line
parts=()
[ -n "$model" ] && parts+=("$model")
parts+=("$cwd")
[ -n "$five_seg" ] && parts+=("$five_seg")
[ -n "$weekly_seg" ] && parts+=("$weekly_seg")

# Join with " | "
result=""
for part in "${parts[@]}"; do
  [ -n "$result" ] && result="$result | "
  result="$result$part"
done

printf "%s" "$result"
```
