Statusline install
Skill dox187/usage-aware-claude-statusline/.claude/skills/statusline-install
Usage-aware status line for Claude Code: session & weekly rate-limit gauges with reset countdowns and a precise context-window meter, plus tokens, git & weather. Template-driven and extensible — set it up by chatting with Claude or via a TUI. Pure-stdlib Python, no pip install. macOS, Linux & Windows.
npx -y skills add dox187/usage-aware-claude-statusline --skill statusline-installAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Deploy the usage-aware Claude Code statusline and wire it into Claude Code on macOS, Linux, or Windows. Invoke when the user says things like "install the statusline", "set up the statusline", "deploy statusline.py", "wire the statusline into Claude Code", "add the statusLine to my settings.json", "make the statusline work in every project", "the statusline isn't showing up", or "fix my statusline command / path on Windows". Handles runtime detection (uv / python), copying the files, merging the statusLine block into settings.json, the Windows forward-slash path rule + PowerShell wrapper fallback, OAuth token setup per OS, and a final verification render.
SKILL.md
15.2 KB, as published. Nobody here has run it
statusline-install — deploy & wire the statusline into Claude Code
Goal: get statusline.py running and wired into Claude Code's settings.json
on whatever OS the user is on, without clobbering their existing config, and
verify it actually renders. Work through the steps below in order. Never run an
installer or write settings.json without explicit user confirmation.
The repo lives at the root that contains statusline.py, claude_usage.py,
claude_status.py, statusline_config.json, and this skill under
.claude/skills/statusline-install/.
Refer to that root as REPO. This skill bundles:
merge_settings.py— stdlib helper that merges astatusLineblock into asettings.json, preserving every other key (and carrying forward an existingpadding); it backs up to<file>.bakfirst.assets/settings_snippet.json— the examplestatusLineblock.assets/statusline.ps1.template— a Windows PowerShell wrapper, used only when Git Bash is absent on Windows.assets/sample_input.json— canonical session JSON for the verify render.
Step 1 — Detect the OS
Determine the platform first; every later command branches on it.
- PowerShell:
$IsWindows,$IsMacOS,$IsLinux(or[System.Environment]::OSVersion.Platform). - bash:
uname -s(Darwin= macOS,Linux= Linux; Windows users are usually in Git Bash here).
Map to one of: win32, darwin, linux. Tell the user which you detected.
Step 2 — Detect runtimes (uv, python) and report versions
Check what is available and report versions back to the user:
- uv:
uv --version - python: try
python3 --versionfirst (macOS/Linux), thenpython --version(common on Windows). The floor is Python 3.7 (the renderer usesdatetime.fromisoformat). If only an older Python is found, say so.
Decision:
-
If uv is present → the launcher will be
uv run <path>. -
Else if python3/python ≥ 3.7 is present → launcher
python3 <path>(macOS/Linux) orpython <path>(Windows). This is perfectly fine — the project is stdlib-only, so nopip installis ever needed. -
If neither: offer to install uv (do not run without confirmation):
- macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh - Windows:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
uv is OPTIONAL — installing a plain Python 3.7+ is an equally valid path. Let the user choose. Only run an installer after explicit confirmation.
- macOS / Linux:
Remember the launcher you settled on here — call it LAUNCHER (one of
uv run, python3, or python). The command strings in Steps 5, 6, and 8 use it.
Step 3 — Ask the run location
Use AskUserQuestion. Offer:
~/.claude(recommended) — global, the statusline shows in every project. On Windows that isC:/Users/<you>/.claude.- A specific project — copy into that project's
.claude/folder; the statusline applies only there (projectsettings.jsonoverrides the user one). - A custom path — free-text.
Also ask (separately, yes/no): copy the skills into ~/.claude/skills so the
/statusline-* commands work in every project, not just this repo. If yes, copy
the whole REPO/.claude/skills/ tree to ~/.claude/skills/.
Call the chosen directory DEST.
Step 4 — Copy files to DEST (never clobber an existing config)
Copy from REPO to DEST:
statusline.py— required.claude_usage.py— required. It MUST sit in the same folder asstatusline.py; the renderer imports it as a sibling module. Do not split them.claude_status.py— required. It MUST sit in the same folder asstatusline.py; the renderer imports it as a sibling module when any status placeholder ({status},{status:N},{status_icon},{status_header}) is used. Do not split them. At runtime it creates~/.claude/status_cache.jsonto cache the Claude status RSS feed (conditional GET, TTL 120 s); that file is auto-created and gitignored — nothing to configure.statusline_config.json— copy only ifDEST/statusline_config.jsondoes NOT already exist. If one is there, leave it untouched and tell the user you preserved their existing config.- Optional extras (offer, default no):
statusline_editor.py,README*,examples/.
Create DEST if needed (mkdir -p / New-Item -ItemType Directory -Force).
Per-OS copy examples (adjust DEST):
- bash (macOS/Linux/Git Bash):
mkdir -p ~/.claude cp "$REPO/statusline.py" "$REPO/claude_usage.py" "$REPO/claude_status.py" ~/.claude/ [ -f ~/.claude/statusline_config.json ] || cp "$REPO/statusline_config.json" ~/.claude/ - PowerShell (Windows):
$dest = "$env:USERPROFILE\.claude" New-Item -ItemType Directory -Force $dest | Out-Null Copy-Item "$REPO\statusline.py","$REPO\claude_usage.py","$REPO\claude_status.py" $dest if (-not (Test-Path "$dest\statusline_config.json")) { Copy-Item "$REPO\statusline_config.json" $dest }
Step 5 — Wire settings.json (use the bundled merge_settings.py)
Pick the target settings.json:
- Default /
~/.claudeinstall →~/.claude/settings.json(Windows:C:/Users/<you>/.claude/settings.json). - Project install → that project's
.claude/settings.json.
Build the command string from LAUNCHER (Step 2) and the statusline.py
path in DEST. Prefer ~ or /c/... over absolute backslash paths:
| OS | uv present | uv absent |
|---|---|---|
| macOS / Linux | uv run ~/.claude/statusline.py | python3 ~/.claude/statusline.py |
| Windows (Git Bash present) | uv run ~/.claude/statusline.py | python ~/.claude/statusline.py |
| Windows (no Git Bash) | see PowerShell-wrapper rule below | same |
WINDOWS PATH RULE — STATE THIS LOUDLY TO THE USER
On Windows, Claude Code runs the
statusLine.commandthrough Git Bash when it is installed, otherwise through PowerShell. Git Bash treats\as an escape character, so a path likeC:\Users\you\.claude\statusline.pyis mangled and fails silently. Always use forward slashes or~:~/.claude/statusline.pyor/c/Users/you/.claude/statusline.py— never backslashes.If Git Bash is NOT installed on Windows, the bare
uv run .../python ...command will not run. Instead install the bundled wrapper:
- Copy
assets/statusline.ps1.templateto~/.claude/statusline.ps1(C:/Users/<you>/.claude/statusline.ps1).- Edit its
$Scriptline to point at the deployedstatusline.py, and pickuvvspythonto match what is installed (the template already prefersuvand falls back topython).- Set the command to:
powershell -NoProfile -File C:/Users/<you>/.claude/statusline.ps1To check for Git Bash:
where.exe bash/Get-Command bash(a path underGit\...means Git Bash is present).
Now run the merge helper. It preserves every other key in settings.json,
creates the file/parent dir if missing, backs up to <file>.bak, and — if a
previous statusLine block already had a custom padding (or other extra
keys) — carries those forward while updating only type and command.
In the examples below, substitute the LAUNCHER you chose in Step 2
(uv run, python3, or python) for <LAUNCHER> in the command string — do
NOT leave it pinned to uv run if uv is not installed, or the statusline will
render empty:
# macOS / Linux / Git Bash (replace <LAUNCHER> with uv run / python3 / python)
python3 "$REPO/.claude/skills/statusline-install/merge_settings.py" \
~/.claude/settings.json "<LAUNCHER> ~/.claude/statusline.py"
# Windows (replace <LAUNCHER> with uv run / python)
python "$REPO\.claude\skills\statusline-install\merge_settings.py" `
"$env:USERPROFILE\.claude\settings.json" "<LAUNCHER> ~/.claude/statusline.py"
Before running it: show the user the exact, fully-substituted command string
and the target settings.json path, and get explicit confirmation.
assets/settings_snippet.json shows the resulting block if they prefer to paste
it by hand (edit its command to your launcher).
Step 6 — Record the deployment (save the active-statusline pointer)
Now that settings.json is wired and the files are in DEST, record which
statusline is the active one so the other skills (/statusline-config,
/statusline-theme, /statusline-preview, /statusline-doctor) can target this
live install instantly instead of re-parsing settings.json or guessing the repo
copy every time.
Use the shared helper that lives in the statusline-config skill
(statusline_io.py). From this repo it is at
REPO/.claude/skills/statusline-config/statusline_io.py; if you copied the skills
into ~/.claude/skills, the deployed copy at
~/.claude/skills/statusline-config/statusline_io.py works the same — the helper
computes the pointer location from its own path, so either copy writes the
right pointer. Run save-pointer with the paths you just resolved:
# macOS / Linux / Git Bash (use the same LAUNCHER + paths you wired in Step 5)
python3 "$REPO/.claude/skills/statusline-config/statusline_io.py" save-pointer \
--statusline-py ~/.claude/statusline.py \
--config ~/.claude/statusline_config.json \
--settings ~/.claude/settings.json \
--launcher "<LAUNCHER>"
# Windows (forward slashes / ~ in paths, same as Step 5)
python "$REPO\.claude\skills\statusline-config\statusline_io.py" save-pointer `
--statusline-py ~/.claude/statusline.py `
--config ~/.claude/statusline_config.json `
--settings ~/.claude/settings.json `
--launcher "<LAUNCHER>"
Substitute the actual resolved paths for your DEST (e.g. a project
.claude/... install) and the LAUNCHER from Step 2.
.ps1-wrapper case: always pass the real deployedstatusline.py(the renderer the wrapper launches) as--statusline-py, and record the wrapper + PowerShell launcher in--launcher— e.g.--statusline-py ~/.claude/statusline.py --launcher "powershell -NoProfile -File ~/.claude/statusline.ps1". Do not put the.ps1path in--statusline-py:save-pointerstores that value verbatim, so a later pointer-basedlocatewould report the wrapper as the renderer. Recording the realstatusline.pykeeps the pointer consistent with how settings-based resolution unwraps a.ps1to its sibling renderer.
The helper prints the pointer path it wrote — a .statusline-active.json written
inside the resolved .claude directory (i.e.
<...>/.claude/.statusline-active.json). Tell the user where it landed.
These are machine-specific — gitignored, do not commit.
.claude/.statusline-active.json(the pointer) and.statusline-config-history/(the history-aware config snapshots + change log the writer skills create next to the active config) are per-machine deployment state. The repo.gitignorealready excludes them; never add them to a commit.
Step 7 — OAuth token (so usage segments populate)
Usage segments ({usage_bars}, {usage_micro}, {compact_usage_micro},
{usage_resets}) need an OAuth token. claude_usage.py resolves it, never
writing it to disk, in this order:
CLAUDE_CODE_OAUTH_TOKENenv var (any OS).- macOS login Keychain (
Claude Code-credentials) — read automatically via/usr/bin/security, macOS only. Nothing to configure. ~/.claude/.credentials.jsonwithclaudeAiOauth.accessToken— Linux / Windows / headless. Windows path:C:/Users/<you>/.claude/.credentials.json.
Per OS:
- macOS — usually automatic via Keychain once the user has signed into Claude Code. Nothing to do.
- Linux / Windows — verify
~/.claude/.credentials.jsonexists and containsclaudeAiOauth.accessToken. If it is missing, suggest either:- run
claude setup-token, or - set
CLAUDE_CODE_OAUTH_TOKENin the environment.
- run
If there is no token, that is fine — the usage segments simply render empty and the rest of the bar still works. Do not block the install on this.
Step 8 — VERIFY (test-render with the sample input)
Render the real statusline.py against the bundled
assets/sample_input.json. Point STATUSLINE_CONFIG at the deployed config so
the test is faithful (or omit it to use the one beside the script). Use the same
LAUNCHER you wired into settings.json:
- PowerShell:
$env:STATUSLINE_CONFIG="$env:USERPROFILE\.claude\statusline_config.json" Get-Content "$REPO\.claude\skills\statusline-install\assets\sample_input.json" | uv run ~/.claude/statusline.py # fallback: ... | python ~/.claude/statusline.py - bash:
STATUSLINE_CONFIG=~/.claude/statusline_config.json \ uv run ~/.claude/statusline.py < "$REPO/.claude/skills/statusline-install/assets/sample_input.json" # fallback: python3 instead of uv run
A non-empty, colored multi-line output = success. If a token is present,
confirm at least one usage segment populated (look for s 43%… / w 67%…,
or the full {usage_bars} line). If the output is empty:
- empty / nothing prints → the launcher or path is wrong (re-check the Windows
path rule; try the fallback launcher; on Windows with no Git Bash use the
.ps1wrapper). - bar renders but usage is blank → no token; revisit Step 7.
Finally, tell the user to restart Claude Code (or open a new session) so it
picks up the new settings.json.
Quick checklist
- Detect OS.
- Detect uv / python (≥3.7); pick
LAUNCHER; offer to install uv only on confirmation. - Ask DEST (
~/.clauderecommended) + whether to copy skills globally. - Copy
statusline.py+claude_usage.py+claude_status.py(same folder); copystatusline_config.jsononly if absent. - Merge
statusLineintosettings.jsonviamerge_settings.pyusing your chosenLAUNCHER(not hardcodeduv run) — forward slashes /~only on Windows;.ps1wrapper if no Git Bash. Confirm the exact command first. - Record the deployment:
statusline-config/statusline_io.py save-pointer(--statusline-py / --config / --settings / --launcher) so the other skills target this live install. The pointer +.statusline-config-history/are gitignored — don't commit them. - Check the OAuth token per OS (optional — empty usage is OK).
- Verify render with
assets/sample_input.json; restart Claude Code.
English only. Never offer {peak_label} as a current option. Never recolor the
semantic ctx_bar* band keys.