Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## v0.22.0 — 2026-07-28 — the agent surface

**New: `skills/usage-insight` — teach Claude Code to read its own
usage.** Three layers, one source of truth: line 1 shows the numbers,
the advisor row says the one sentence that matters, and the skill
carries the full conversation — "should I start a heavy task now?",
"which account has headroom?", "what did I waste this week?". Install
with `cp -r skills/usage-insight ~/.claude/skills/` and ask.

The skill encodes the state-dir contract, the learned-forecast
semantics, and the advisor's judgment rules — feasibility before
advice, facts only while the ratio is unlearned, staleness said out
loud, fresh siblings only. It runs the same `report`/`check`
subcommands instead of re-mining, so all three layers always agree.
Docs-only release: no script changes, test count unchanged.

## v0.21.0 — 2026-07-28 — the advisor, wired into your world

**New: `statusline.sh check` — the advisor as an exit code.** The
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,25 @@ Run it bare and it summarizes the last session in the log. Window
deltas are positive-delta sums, so a session that straddles a 5h reset
still reports what it actually consumed.

## The agent surface

Three layers, one source of truth: line 1 shows the numbers, line 2
says the one sentence that matters, and for the full conversation —
"should I start a heavy task now?", "which account has headroom?",
"what did I waste this week?" — there's a skill that teaches Claude
Code itself to read the state dir:

```bash
cp -r skills/usage-insight ~/.claude/skills/
```

Then just ask. The skill knows the state-dir contract
(`docs/api/state-dir.md`), the learned-forecast semantics
(`pct_per_window`, weekday profile, prediction calibration), and the
advisor's judgment rules — including the important one: never advise
what the data can't back. It reads the same files and runs the same
`report`/`check` subcommands, so all three layers always agree.

<details><summary>OAuth and API behavior</summary>

Quota, profile, and extra-usage requests use Claude Code's OAuth credentials
Expand Down
2 changes: 1 addition & 1 deletion docs/api/state-dir.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ is the ONLY writer; everything here is safe to read concurrently.

- Contract version: **1** (bump on any breaking layout/field change; this
file is the changelog)
- Synced with: statusline.sh v0.21.0
- Synced with: statusline.sh v0.22.0
- Permissions: the script runs under `umask 077` — files are owner-only.
Caches hold account PII (email, uuid, org names).

Expand Down
1 change: 1 addition & 0 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ Key facts for agents:
## Optional

- [Site](https://thevibeworks.github.io/claude-code-statusline/): animated demo of the line
- [usage-insight skill](https://github.com/thevibeworks/claude-code-statusline/blob/main/skills/usage-insight/SKILL.md): teaches an agent to read the state dir and answer usage questions (install: `cp -r skills/usage-insight ~/.claude/skills/`)
85 changes: 85 additions & 0 deletions skills/usage-insight/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
name: usage-insight
description: >
Answer Claude Code usage and quota questions from the statusline state
dir (~/.claude/statusline/): why the statusline is yellow/red, whether
to start a heavy task now, which account has headroom, what expired
unused this week, when a capped model comes back. Triggers on quota,
5h/7d windows, rate limits, capacity planning, statusline questions,
"should I run this now", "which account", "what did I waste".
---

# Usage insight from the statusline state dir

claude-code-statusline maintains a read-only-for-you state dir and
documents it as a contract (docs/api/state-dir.md in
https://github.com/thevibeworks/claude-code-statusline). This skill
teaches you to read it and answer usage questions conversationally —
the deep-dive version of what the advisor row says in one sentence.

## Ground rules

1. READ-ONLY. Never write, touch, or delete anything under
`~/.claude/statusline/`. The statusline is the only writer.
2. Account scoping: state for tagged accounts lives under
`~/.claude/statusline/accounts/<tag>/`; the top level is the default
account. If `STATUSLINE_ACCOUNT` or `DEVA_AUTH_TAG` is set in the
environment, that names the current account.
3. Staleness: trust `fetched_at` (epoch seconds) in usage.cache.
Older than ~1h means no active session feeds that account — say the
numbers are stale instead of presenting them as now.
4. These files hold account PII (email, uuid, org). Quote numbers and
reset times to the user; do not echo emails/uuids unless asked.

## What to read for which question

| Question | Source |
|----------|--------|
| "Why is the line yellow/red?" / "what's my quota now?" | `usage.cache`: `five_hour.{utilization,resets_at}`, `seven_day.*`, `limits[]` (per-model weekly caps, `kind=weekly_scoped`) |
| "Should I start a heavy task now?" | `usage.cache` now + `forecast.cache` patterns (below) |
| "Which account has headroom?" | every `accounts/*/usage.cache`, compare `five_hour.utilization` and `fetched_at` freshness |
| "What did I waste?" / weekly retrospective | run `~/.claude/statusline.sh report [--days N]` — the reference consumer; don't re-mine by hand |
| "Anything I should know right now?" | run `~/.claude/statusline.sh check` — exit 0 calm / 1 opportunity / 2 pressure / 3 unknown |
| "What did that session cost me?" | `~/.claude/statusline.sh session-summary` (last session), or pipe `{"session_id":"..."}` |

## Semantics crib (forecast.cache)

```json
{"days_history": 21, "recent_24h": 14.2,
"pct_per_window": 11.83,
"weekday_profile": {"0": 5.1, "1": 27.3, "6": -1}}
```

- `weekday_profile`: learned percent-of-7d-quota burned per weekday
(0=Sun..6=Sat), EWMA half-life 14 days; `-1` = never observed.
Cold start below 14 `days_history` — say projections are unlearned.
- `pct_per_window`: the exchange rate — 7d percentage points one fully
burned 5h window costs THIS account. `-1` = unlearned. A week holds
roughly `100 / pct_per_window` full windows.
- usage.jsonl lines carry `predicted_end` (the projection made at
sample time): compare old predictions against what actually happened
before presenting the forecast as reliable.

## Judgment rules (mirror the advisor; never advise what data can't back)

- Feasibility before advice: with S% of the 7d window unused and T
hours to its reset, the burnable maximum is roughly
`pct_per_window x (T / 5h)` (capped by the current 5h window's own
headroom). If that is less than S, do NOT say "use it up" — say how
much expires no matter what.
- With `pct_per_window = -1`, state facts, not advice.
- A scoped limit (`limits[]`) at 100% means that model is unavailable:
the useful fact is its `resets_at`, not the percentage.
- 5h pressure with a reset < 30min away is self-healing — say "resets
in N minutes" instead of alarming.
- Recommending another account: only name siblings whose cache is
fresh (< 1h); an idle-looking stale account is unknown, not free.

## Answer style

Lead with the verdict ("yes, start it — 5h at 22% with 4h of window
left"), then the two or three numbers that justify it. Convert
percentages into work-terms using the exchange rate ("~49% expires
even at full burn — about 4.7 windows' worth"). Say when data is
stale, unlearned, or invisible (usage from other devices between
renders never reaches the log).
Loading