Smooth, gradient statusline for Claude Code — context window + Pro/Max 5h/7d rate-limit bars
Project description
smoothline
Smooth, gradient statusline for Claude Code — context window + Pro/Max 5h/7d rate-limit bars (Windows / macOS / Linux)
English | 한국어
A drop-in statusline for Claude Code that ships the same look across Windows, macOS, and Linux.
| OS | Installer | How it runs |
|---|---|---|
| Windows | install.cmd (or install.ps1) |
statusline.cmd invokes Python |
| macOS / Linux | install.sh |
statusline.py runs directly via shebang |
The core renderer (statusline.py) is identical on every OS. Only the installer branches per OS, and ~/.claude/settings.json's statusLine.command is wired to the right entry point automatically.
Preview
youja@HOSTNAME ~/workspace │ ⎇ main │ Claude Opus 4.7 │ ctx [████▏ ] 42% │ 5h [██▏ ] 28% ↻3h11m │ 7d [▉ ] 12% ↻4d23h
user@host+ current directory (home shown as~)- git branch (when present)
- model name
ctx— context window usage of the current session (10-cell bar)5h— Claude Pro/Max 5-hour rolling window usage + time until reset↻Xh Ym(8-cell bar)7d— Claude Pro/Max 7-day rolling window usage + time until reset↻Xd(8-cell bar)
All bars use 1/8-cell smooth Unicode glyphs and a green→yellow→red gradient that follows the percentage.
When
5h/7dshow up: only for Claude.ai Pro/Max subscribers. After the first API response, the statusline JSON includesrate_limits.five_hour.*/rate_limits.seven_day.*(per Anthropic's official statusline schema). For API-key users, or before the first message, those two chunks are hidden automatically.
The renderer parses stdin JSON once and reads .git/HEAD directly — no git subprocess per prompt.
0. Prerequisites
- Python 3.x — required to run
statusline.py. Any Python build works.- Windows:
python/python.exemust be reachable on PATH, or set the absolute path insidestatusline.cmd - macOS/Linux:
python3orpythonmust be on PATH (install.shdiscovers this automatically)
- Windows:
- A terminal with truecolor (24-bit) ANSI support so the gradient renders. Windows Terminal / iTerm2 / recent GNOME Terminal / etc. all qualify.
Verify Python:
# Windows (PowerShell)
where.exe python
# macOS / Linux
which python3 || which python
1. The three files
Destination: %USERPROFILE%\.claude\ (e.g. C:\Users\<USERNAME>\.claude\) on Windows, ~/.claude/ elsewhere.
1-A. statusline.cmd (Windows only — generated by the installer)
The installer writes this file at install time, baking in the absolute path to the Python it found on PATH. You normally don't touch it. A typical generated copy:
@echo off
"C:\Users\<USERNAME>\AppData\Local\Programs\Python\Python312\python.exe" "C:\Users\<USERNAME>\.claude\statusline.py"
If python is not on PATH at install time, the installer falls back to the literal python and warns you. Once Python is installed and on PATH, just re-run the installer.
1-B. statusline.py
Use the
statusline.pyshipped in this package as-is. The full source (Pro/Maxrate_limitsrendering included) lives in the file — the installer wires up the canonical copy.
Encoding note:
statusline.pymust be saved as UTF-8 (no BOM). PowerShell's default forSet-Content/Out-Fileis UTF-16 LE, which corrupts it. The "One-shot install" section below handles this safely.
1-C. statusline-command.ps1 (optional)
A pure-PowerShell fallback. No colors, no smooth bars, ASCII only. You don't normally need it — keep it as a backup for machines without Python installed.
2. Registering in settings.json (the installer does this for you)
The installer adds/merges the statusLine key into ~/.claude/settings.json, preserving any other keys.
If you wire it up by hand, here is what the OS-specific entry looks like:
Windows — %USERPROFILE%\.claude\settings.json
{
"statusLine": {
"type": "command",
"command": "C:\\Users\\<USERNAME>\\.claude\\statusline.cmd",
"padding": 0
}
}
macOS / Linux — ~/.claude/settings.json
{
"statusLine": {
"type": "command",
"command": "/Users/<USERNAME>/.claude/statusline.py",
"padding": 0
}
}
Replace
<USERNAME>. On macOS/Linux,statusline.pyischmod +x'd and has a#!/usr/bin/env python3shebang, so it runs directly — no wrapper needed.
3. One-shot install
3-A. One-liner (fastest)
The installer pulls everything it needs straight from GitHub, drops it under ~/.claude/, and patches settings.json.
macOS / Linux
curl -fsSL https://raw.githubusercontent.com/youja2014/smoothline/main/install.sh | bash
Windows (PowerShell)
irm https://raw.githubusercontent.com/youja2014/smoothline/main/install.ps1 | iex
Windows (cmd)
curl -fsSL https://raw.githubusercontent.com/youja2014/smoothline/main/install.cmd -o install.cmd && install.cmd && del install.cmd
3-B. git clone / zip install
Grab the sources and run the installer in local mode. Sibling files are copied verbatim, so this works fully offline.
Windows
install.cmd :: double-click works
or PowerShell:
.\install.ps1
macOS / Linux
bash install.sh
# or
chmod +x install.sh && ./install.sh
Inside Claude Code (macOS/Linux)
On a machine that already has Claude Code, cd into the unpacked folder and just say:
"Run install.sh in this folder to set up the statusline"
What every installer does
- Source the assets — if
statusline.pyis a sibling, copy it (local mode); otherwise download from the GitHub raw URL (one-liner mode) - Auto-detect Python — Windows checks
pythonon PATH, Unix triespython3thenpython - On Windows, regenerate
statusline.cmdwith the detected Python's absolute path (so the one-liner install just works without editing) - Add/replace only the
statusLinekey in~/.claude/settings.json(other keys preserved) - Run the statusline once with a dummy JSON payload and print the output
4. Verifying
The installer prints sample output, so usually you don't need to do anything. To re-run the check:
Windows (PowerShell)
$json = '{"model":{"display_name":"Claude Opus 4.7"},"workspace":{"current_dir":"D:\\workspace"},"context_window":{"used_percentage":42},"rate_limits":{"five_hour":{"used_percentage":28,"resets_at":2000000000},"seven_day":{"used_percentage":12,"resets_at":2000300000}}}'
$tmp = [System.IO.Path]::GetTempFileName()
[System.IO.File]::WriteAllText($tmp, $json, (New-Object System.Text.UTF8Encoding $false))
& cmd /c "type `"$tmp`" | `"$env:USERPROFILE\.claude\statusline.cmd`""
Remove-Item $tmp
Piping
'{...}' | statusline.cmddirectly in PowerShell encodes as UTF-16 LE and breaks Python's JSON parser. Going through a tempfile is the safe path.
macOS / Linux (bash)
NOW=$(date +%s)
echo '{"model":{"display_name":"Claude Opus 4.7"},"workspace":{"current_dir":"'"$HOME"'"},"context_window":{"used_percentage":42},"rate_limits":{"five_hour":{"used_percentage":28,"resets_at":'$((NOW+11600))'},"seven_day":{"used_percentage":12,"resets_at":'$((NOW+424600))'}}}' \
| "$HOME/.claude/statusline.py"
You should see two colored lines. After that, restart Claude Code — the new statusline shows up immediately.
5. Troubleshooting
| Symptom | Cause / Fix |
|---|---|
| Korean / emoji garbled | statusline.py was saved as UTF-16 or CP949. Re-save as UTF-8 (no BOM). |
Raw color codes ([38;2;...m) visible |
Terminal lacks ANSI truecolor. Switch to Windows Terminal / iTerm2 / recent GNOME Terminal. |
'python' is not recognized (Win) / python3: command not found (Unix) |
Python not on PATH. On Windows, hard-code the absolute path inside statusline.cmd. On macOS, brew install python or use python.org. On Linux, use the distro's package manager. |
| Statusline doesn't show at all | Verify the command path in settings.json. Run section 4 manually to debug. On macOS/Linux, check chmod +x ~/.claude/statusline.py. |
| Bar glyphs out of alignment | Font lacks Powerline / Unicode box characters. Switch to Cascadia Mono / JetBrains Mono / Menlo. |
Permission denied on Linux |
chmod +x ~/.claude/statusline.py was skipped. Re-run the installer or fix it manually. |
6. Customization
- Bar width: the 4th argument to each
render_usage(...)call insidemain()(ctxis 10,5h/7dare 8) - Colors:
GRAY / BLUE / PURPLE / ORANGE / SEPRGB tuples - Gradient breakpoints:
green / yellow / redinsidegradient_color() - Display order: reorder how
line1/line2chunks are appended - Hide the 5h / 7d chunks: comment out their
render_usage(...)calls - Drop the reset-time tail: pass
Noneas theresets_atargument torender_usage()
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smoothline-0.1.0.tar.gz.
File metadata
- Download URL: smoothline-0.1.0.tar.gz
- Upload date:
- Size: 8.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1788b72adbc7c117e32d64198c74831d24fdb2d989bac3dfd9bb37cf020f31a8
|
|
| MD5 |
7ce8b2518f947592e375e8519318d297
|
|
| BLAKE2b-256 |
d67997d37ff929148c7dd0d2086cfb28a8fe6b9b955d96012675a298577f379f
|
Provenance
The following attestation bundles were made for smoothline-0.1.0.tar.gz:
Publisher:
publish.yml on youja2014/smoothline
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smoothline-0.1.0.tar.gz -
Subject digest:
1788b72adbc7c117e32d64198c74831d24fdb2d989bac3dfd9bb37cf020f31a8 - Sigstore transparency entry: 1473918681
- Sigstore integration time:
-
Permalink:
youja2014/smoothline@2a27d95677c0e6248e1e837540b4e2ac6ff22f21 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/youja2014
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2a27d95677c0e6248e1e837540b4e2ac6ff22f21 -
Trigger Event:
release
-
Statement type:
File details
Details for the file smoothline-0.1.0-py3-none-any.whl.
File metadata
- Download URL: smoothline-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
817a6c7e61a22815765a6a74785d84762f172b716470ef7269982b99c6c521fe
|
|
| MD5 |
fabf46c0e44c7b08647074c0807675d6
|
|
| BLAKE2b-256 |
46859edb071dbdc3af039d0abce5676e32ca0618f82e5309c1f359bda4afaf91
|
Provenance
The following attestation bundles were made for smoothline-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on youja2014/smoothline
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smoothline-0.1.0-py3-none-any.whl -
Subject digest:
817a6c7e61a22815765a6a74785d84762f172b716470ef7269982b99c6c521fe - Sigstore transparency entry: 1473919036
- Sigstore integration time:
-
Permalink:
youja2014/smoothline@2a27d95677c0e6248e1e837540b4e2ac6ff22f21 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/youja2014
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2a27d95677c0e6248e1e837540b4e2ac6ff22f21 -
Trigger Event:
release
-
Statement type: