YAS! (Yet Another Statusline)
🌈 Check out the official landing page here: YAS! Yet Another Statusline
Most common form is displaying the first few rows, which include the loaded plugins & skills. Extra sections appear below them as needed
Install/Update
Requires Python 3.10+, and a Nerd Font to render the icons.
curl -fsSL https://raw.githubusercontent.com/tmck-code/yet-another-statusline/main/ops/install.sh | bash
YAS also runs a UserPromptSubmit hook (yas-prompt-hook.py) that records
per-session prompt timestamps, enabling accurate turn-scoped subagent display.
A plugin install registers it through the plugin's own hooks/hooks.json, so the
installer keeps it out of settings.json (and removes a copy an older installer
wrote there). For a git-clone install, or with the plugin disabled, the installer
upserts it into settings.json instead: foreign hooks are preserved, stale paths
are rewritten on upgrade, and it is removed on uninstall.
Or install manually:
claude plugin marketplace add tmck-code/yet-another-statusline#main
claude plugin install yas@yet-another-statusline
claude -p "/yas:init"
If you need to install non-interactively (e.g. in CI/docker)
curl -fsSL https://raw.githubusercontent.com/tmck-code/yet-another-statusline/main/ops/install.sh | YAS_NO_TTY=1 bash
# install with specific python version e.g. 3.15
curl -fsSL https://raw.githubusercontent.com/tmck-code/yet-another-statusline/main/ops/install.sh | YAS_NO_TTY=1 YAS_PYTHON=3.15 bash
Upgrading — the yas/ layout move
Everything YAS writes except yas.toml now lives under a single
$CLAUDE_CONFIG_DIR/yas/ subtree (yas/cache/ and yas/state/). The migration
runs automatically — eagerly when you re-run ops/install.sh, lazily on the
first render otherwise — and is a one-off; afterwards the check costs one
stat().
Day-total token counts and the last-prompt handshake are moved and survive
the upgrade. Rate-limit history, render timings, the transcript parse cache and
mon's per-session payloads are regenerated rather than moved, so expect a
brief cold start after the first upgrade: the t/m rate and sparkline, the
render-time figure and mon's session list start out empty and refill within
one render tick to about five minutes, depending on the item.
Reconfigure later — /yas:config
Run /yas:config any time to re-run the wizard against the already-installed
plugin — switch theme/glyph mode, toggle labels, change the soft limit, or move
to Python 3.15. It re-wires settings.json without re-registering the
marketplace or reinstalling the plugin.
Demo
A dummy session to demonstrate the layout:
Widths
The statusline also renders differently according to available width
| mode | width | screenshot |
|---|
| "medium" | <=80 pixels |  |
| "narrow" | <=55 pixels |  |
Configuration
Every configurable knob resolves through one fixed precedence chain (highest wins):
CLI flag → canonical YAS_* env var → legacy-alias env var → yas.toml → built-in default
The first source in that chain that is present and valid wins; an absent or
invalid source falls through to the next (an empty-string env var counts as
absent). Canonical YAS_* env vars always win over their deprecated legacy
aliases when both are set — the aliases keep working but are deprecated.
Knobs
| Knob | Env var | Legacy alias | yas.toml key | Default |
|---|
max_width | YAS_MAX_WIDTH | — | [layout].max_width | 140 |
full_width | YAS_FULL_WIDTH | — | [layout].full_width | false |
soft_limit | YAS_SOFT_LIMIT | — | [tokens].soft_limit | 150000 |
token_window | YAS_TOKEN_WINDOW | STATUSLINE_TOKEN_WINDOW | [tokens].token_window | 60 |
theme | YAS_THEME (also --theme CLI) | CLAUDE_STATUSLINE_THEME | [appearance].theme | claude-dark |
bg_shift | YAS_BG_SHIFT (also --bg-shift CLI) | — | [appearance].bg_shift | warm |
glyph_mode | YAS_GLYPH_MODE (also --glyph-mode CLI) | — | [appearance.glyphs].mode | nerdfont |
single_width | YAS_GLYPH_SINGLE_WIDTH (also --glyph-single-width CLI) | — | [appearance.glyphs].single_width | false |
show_icons | YAS_SHOW_ICONS | — | [appearance.glyphs].show_icons | true |
context_state | YAS_CONTEXT_STATE | — | [context].state | false |
context_labels | YAS_CONTEXT_LABELS | — | [context].labels | Smart,Coasting,Foggy,Cooked,Dumb |
context_thresholds | YAS_CONTEXT_THRESHOLDS | — | [context].thresholds | 25,50,70,90 |
show_render_time | YAS_SHOW_RENDER_TIME | — | [layout].show_render_time | false |
show_git_status | YAS_SHOW_GIT_STATUS | — | [layout].show_git_status | true |
show_tool_uses | YAS_SHOW_TOOL_USES | — | [layout].show_tool_uses | false |
show_tokens_over_time | YAS_SHOW_TOKENS_OVER_TIME | — | [layout].show_tokens_over_time | false |
labels | YAS_LABELS | — | [layout].labels | false |
justify | YAS_JUSTIFY | — | [layout].justify | false |
show_day_stats | YAS_SHOW_DAY_STATS | — | [tokens].show_day_stats | true |
openspec_scan_depth | YAS_OPENSPEC_SCAN_DEPTH | — | [openspec].scan_depth | 1 |
Valid values
theme — 15 built-in themes; unknown or unset falls back to claude-dark:
- Dark:
claude-dark, catppuccin-mocha, dracula, gruvbox-dark, nord, one-dark, solarized-dark, tokyo-night, palenight
- Light:
claude-light, catppuccin-latte, dracula-light, gruvbox-light, one-light, solarized-light
bg_shift — warm or cool.
glyph_mode — all four modes preserve column geometry; an unknown value falls back to nerdfont:
nerdfont — default; full fidelity, needs a Nerd Font.
ascii — every non-ASCII glyph → width-1 ASCII; maximum compatibility.
unicode — only Nerd Font PUA icons → non-PUA Unicode; keeps box/block/arrow glyphs.
github — GitHub-paste-safe: folds every glyph a browser renders double-wide (the box-drawing frame, block/sparkline ramp, and EAW-ambiguous punctuation/icons) to a width-1, EAW-narrow/ASCII stand-in, so a render stays column-aligned when pasted into a GitHub markdown code block.
Behaviour notes
-
single_width — orthogonal boolean that folds double-width dynamic content (wide emoji, CJK in branch names/paths) to width-1; combinable with any glyph_mode. The statusline's own glyphs are already width-1, so column geometry is preserved.
-
show_icons — when false, drops essentially every icon/glyph the statusline draws, including the top-left home/folder glyph. The exceptions — glyphs that still render — are the task-plan checkboxes, the subagent status markers, and the box/border and workflow structural glyphs (frame, sparkline blocks, separators, row markers). Text and numbers still render; only the glyph beside each is omitted, and column/border alignment is preserved. true by default, preserving current behaviour.
-
full_width — when true, makes the box fill the terminal and ignore max_width.
-
show_render_time — when true, annotates the bottom-right border with the previous run's wall-clock render time (e.g. …47.2ms──╯). Off by default; each run shows the prior run's timing, so it is blank on a session's first render.
-
show_git_status — when false, skips git status entirely and shows no modified/untracked/deleted/renamed counts next to the branch (the branch name still shows). On by default. When on, counts are cached for 5 s per repo, shared across sessions, and invalidated early when .git/index, HEAD or the branch ref changes.
-
show_tool_uses — when true, adds a row (wide layout only) under the tokens/cost band, listing per-tool tool_use counts.
-
show_tokens_over_time — when true, adds a full-width "tokens over time" row (wide layout only) under the tokens/cost band, showing the t/m rate and live sparkline. The trailing column of the tokens/cost row always shows skills + plugins; the sparkline is opt-in via this row.
-
labels — when true, paints small superscript field captions into the border/separator rows (wide layout only). Note: this is a different knob from [context].labels, which is the five-word state list — see Context state word. The two share a key name but live in different sections and take different types.
-
justify — when true, aligns fields into columns instead of packing them left (wide layout only).
-
show_day_stats — when true (the default), shows today's cumulative token and cost totals alongside the session's, as session/day pairs. Note: this key lives under [tokens], not [layout], unlike the other display toggles.
-
openspec_scan_depth — how many repo-levels below cwd the OpenSpec downward scan descends looking for nested openspec/ roots (monorepo-of-repos layout). 1 (the default) finds a repo directly below cwd; 2 also finds one nested a level deeper; 0 disables the downward scan entirely (only an openspec/ found by walking upward from cwd is used). Unlike the other numeric knobs, 0 is a legal value here.
-
CLI flags — --theme NAME / --bg-shift DIR also accept the --theme=NAME / --bg-shift=DIR form. Pass them in the statusLine.command of your ~/.claude/settings.json.
-
Legacy theme file — ~/.claude/statusline-theme is no longer read. If you re-run the installer while the file is non-empty and yas.toml does not already set a theme, the installer folds its value into yas.toml once, and the migration then deletes the file. Otherwise set the theme by hand:
[appearance]
theme = "claude-dark"
Context state word
context_state adds a morphing word to the context line that names how full the
context window is — Smart → Coasting → Foggy → Cooked → Dumb — so you can read
the state at a glance instead of doing percentage math. It is off by default;
enable it with YAS_CONTEXT_STATE=1 or [context].state = true.
The word is tinted with the same threshold colour as the context bar and sits
just before it; in a narrow box it sheds first (the bar and percentage stay).
context_labels — exactly 5 comma-separated words (Smart,Coasting,Foggy,Cooked,Dumb by default).
context_thresholds — exactly 4 strictly-ascending integers in 1..99 (25,50,70,90 by default), the start percentage of bands 2–5.
The percentage driving the word is YAS's soft-limit fill ratio (the same
basis as the context bar), so the word and the bar always agree — the word turns
Dumb exactly as the bar fills toward the compaction soft_limit.
Credit: the state-word idea and its default labels/thresholds are ported from
Dumbometer by Maximo Correa
Rosas (MIT). See NOTICE. Dumbometer maps the word to the full
context window; YAS maps it to the soft-limit fill ratio for bar consistency.
yas.toml
yas.toml lives in CLAUDE_CONFIG_DIR (defaults to ~/.claude/). It is not
auto-created — its absence simply means all-defaults — and /yas:init never