agentsclimarketplace

Statusline config

Skill dox187/usage-aware-claude-statusline/.claude/skills/statusline-config

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.

Install
npx -y skills add dox187/usage-aware-claude-statusline --skill statusline-config

Assembled 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

Guided LAYOUT setup for the usage-aware Claude Code statusline — decides WHAT the bar shows (which lines/elements, usage display style, context gauge form, weather, incident status indicator, emoji width) by chatting, complementing the TUI editor. Invoke when the user says things like "set up the statusline", "configure my statusline", "change which lines/elements show", "add weather to the bar", "show usage in the statusline", "switch to a compact usage display", "hide the git line", "configure the context gauge", "show Claude status in the bar", or "add an incident indicator". This skill does NOT change colors — colors are owned by /statusline-theme; route any color/theme request there instead.

SKILL.md

19.9 KB, as published. Nobody here has run it

statusline-config — guided layout setup

You configure what the statusline shows by editing statusline_config.json. You set layout only: which lines exist, which element blocks appear, the usage display style, the context-gauge form, weather, and emoji_width.

You do NOT touch colors. The colors block is owned entirely by /statusline-theme. Leave colors exactly as you found it (preserve it byte-for-byte). If the user asks about colors/themes/palettes, tell them to run /statusline-theme and do not edit colors here.

Never present {peak_label} as an option — Anthropic removed peak-hour limits; it exists only for back-compat. Only emit placeholders from the list below. English only.


Step 1 — Locate the ACTIVE statusline and read its config

You edit the ACTIVE statusline — the one Claude Code is really running. That is usually the DEPLOYED copy (e.g. ~/.claude/statusline.py and ~/.claude/statusline_config.json), NOT the repo copy. Do not assume the repo. Resolve the active target with the shared helper that lives beside this file, statusline_io.py:

python statusline_io.py locate

(Run it with the absolute path to statusline_io.py in this skill's own directory; fall back to python3 if python is unavailable.) It prints a single JSON object:

{"statusline_py": <abs or null>, "config_path": <abs or null>,
 "settings_json": <path or null>, "launcher": <str or null>,
 "source": "pointer"|"settings"|"none",
 "pointer_path": <abs path where the pointer would live>,
 "notes": <short human string>}

Use config_path as the file you will write back to, and statusline_py as the renderer. Handle source as follows:

  • pointer — a saved pointer resolved the target. Use it as-is.
  • settings — resolved by parsing the active settings.json (statusLine.command). Use it, then OFFER to save a pointer so future runs are instant:
    python statusline_io.py save-pointer --statusline-py <statusline_py> --config <config_path> [--settings <settings_json>] [--launcher <launcher>]
    
  • none — nothing resolvable. ASK the user where their statusline is installed (the path to the active statusline.py); the config is statusline_config.json beside it unless they set STATUSLINE_CONFIG. Then OFFER to save-pointer with those values.

Always make clear to the user that you are editing the ACTIVE (often deployed ~/.claude) config, not the repo copy. Never write to a directory the renderer will not read from.

Now read the resolved config_path. If it is missing or invalid JSON, note that you'll start from built-in defaults (the bar always renders even with no config). Then summarize what is currently active:

  • Which templates keys start with line (those are ON, in order) vs _disabled_*/_* (those are OFF).
  • Which element blocks each active line contains (session header / weather / git / usage / status incident indicator).
  • Which usage style is in use, if any ({usage_bars}+{usage_resets} / {usage_micro} / {compact_usage_micro} / none).
  • Which context-gauge form is in use ({ctx_micro} inline / bare {ctx_bar} / {ctx_bar:N} / just {ctx}/{ctx_percent}).
  • emoji_width, and weather name + show_* flags.
  • Whether a status block is present and whether any active line uses a status placeholder ({status}, {status:N}, {status_icon}, {status_header}).

Step 2 — Gather choices (use the AskUserQuestion tool)

Fast path first

Offer the user a choice up front:

  • Start from a preset (recommended) — pick one of the four presets below, then optionally tweak.
  • Customize (ask me everything) — go through the custom rounds.

Presets (mirror the repo's examples/):

PresetLinesWhat it shows
Minimal (1 line)line1model + context label/percent + inline ctx micro. No weather, no usage, no git.
Two-line (weather + compact usage)line1, line2sun + time + model + effort + ctx percent on line1; weather + {compact_usage_micro} on line2.
Three-line (context bar + git)line1, line2, line3header on line1; weather + big auto-aligned {ctx_bar} on line2; path/git/changes on line3.
Four-line (full usage)line1..line4header on line1; path/git on line2; {usage_bars} on line3; {usage_resets} on line4.

The exact preset templates are in the Preset templates section near the end of this file — copy them verbatim when a preset is chosen.

Custom rounds (only if the user picked "customize")

Ask in clear, separate rounds:

  1. Element blocks (multiSelect): session header, weather, git, usage, status (incident indicator — zero-cost when nothing is active; the whole line is suppressed automatically).
  2. Usage style (single select — pick at most ONE, never mix):
    • Full bars (2 lines){usage_bars} on one line, {usage_resets} on the next. Most detail; costs two lines.
    • Micro (1 line){usage_micro}: one line, full-word labels ("session 41%…").
    • Compact micro (1 line){compact_usage_micro}: one line, terse ("s 41%…w 63%…").
    • None — no usage segment.
  3. Context gauge (single select):
    • Inline micro — append {ctx_micro} to line1 (tiny ▕<cell>▏).
    • Big auto-aligned bar — bare {ctx_bar} on its own line (see composition rule).
    • Fixed N-cell{ctx_bar:N} (ask N, e.g. 28); sits anywhere.
    • Percent text only — just {ctx} and/or {ctx_percent}, no gauge.
  4. Weather (only if weather chosen): ask the city (free text), then which parts to show (multiSelect over show_name, show_icon, show_temp, show_humidity, show_wind), then sun glyph on/off ({sun}).
  5. Emoji width (single select): 2 (default; most terminals) or 1 (tip: choose 1 if emoji render single-width and the bar looks shifted).

Step 3 — Geocode the city (only if weather is ON)

Resolve the city name to coordinates via the Open-Meteo geocoding endpoint (this is separate from the forecast call statusline.py makes):

GET https://geocoding-api.open-meteo.com/v1/search?name=<CITY>&count=1&language=en&format=json

Read results[0]: use .latitude, .longitude, and .name (and .country to confirm). Write name/latitude/longitude into the weather block and confirm the resolved city + country with the user before composing. If geocoding returns no results, ask the user to refine the city name.

Do NOT ship a config that uses {weather}/{sun} without a geocoded weather block — if latitude/longitude are missing the renderer falls back to the default placeholder location (Newyork / 56.25 / -5.2833) and shows bogus weather.


Step 4 — Compose the templates

Build the active line1..lineN from the chosen modules using the Fragment recipes below, then enforce the composition rules.

Placeholders (the COMPLETE list — emit nothing else)

Color/format:  {c.NAME}  {r}
Session:       {time} {version} {model} {effort}
Context:       {ctx} {ctx_percent} {ctx_bar} {ctx_bar:N} {ctx_micro} {align_pad}
Tokens:        {total} {input} {output} {cached}
Usage gauges:  {usage_bars} {usage_resets} {usage_micro} {compact_usage_micro}
Path/git:      {path} {branch} {added} {removed}
Weather:       {weather} {sun}
Status:        {status} {status:N} {status_icon} {status_header}

{effort} renders like (high) or empty when unsupported. Do not use {peak_label}.

{status:N} caps the label+title at N characters (0 = unlimited), exactly like {ctx_bar:N}. All four status placeholders render empty (and suppress their whole line) when no incident is active — the RSS feed is fetched only when a rendered line actually uses one of them.

Fragment recipes (module → fragment)

ModuleFragment
session header{sun} {c.time}[{time}]{r} {c.version}{version}{r} {c.model}{model}{r}{c.effort}{effort}{r} Ctx:{ctx} {c.ctx_percent}({ctx_percent}%){r}
inline ctx micro (append to header){ctx_micro}
weather line{c.weather}{weather}{r}
git line{c.path}{path}{r} {c.git_icon}(git)/{r}{c.branch}{branch}{r} ({c.output}+{added}{r},{c.input}-{removed}{r})
usage full (two lines)line A = {usage_bars} ; line B = {usage_resets}
usage micro line{usage_micro}
usage compact line{compact_usage_micro}
weather + compact usage on one line{c.weather}{weather}{r} {compact_usage_micro}
status indicator{status} (or {status:N} to cap width)
status icon only{status_icon}
status header banner{status_header} — on its OWN line, ABOVE the line containing {status}; appears only when an incident is active

If the user chose the inline-micro gauge and no {sun} glyph, drop the leading {sun} from the header. Include {sun} only when the user opted into it.

Usage display styles (pick exactly ONE — never mix)

  • (a) FULL BARS → two lines: {usage_bars} then {usage_resets}.
  • (b) MICRO → one line: {usage_micro}.
  • (c) COMPACT → one line: {compact_usage_micro}.
  • or none.

A config must use at most one of these. Never combine (a)+(b), (b)+(c), etc.

Context-gauge forms (3) + composition rules

  1. INLINE MICRO — append {ctx_micro} to line1.
  2. BIG AUTO-ALIGNED {ctx_bar} — on its OWN line. It auto-sizes to align under the line1 segment that starts at {effort}. THEREFORE line1 MUST contain {effort}, and the bar line MUST include {align_pad} before the opening bracket:
    • without weather: {align_pad}{c.ctx_bracket}▐{r}{ctx_bar}{c.ctx_bracket}▌{r}
    • with weather: {c.weather}{weather}{r}{align_pad}{c.ctx_bracket}▐{r}{ctx_bar}{c.ctx_bracket}▌{r}
  3. FIXED {ctx_bar:N} — fixed N cells, sits anywhere, no {align_pad}, e.g. {c.ctx_bracket}▐{r}{ctx_bar:28}{c.ctx_bracket}▌{r}
  4. Just text{ctx} and/or {ctx_percent}.

Line ordering and disabling

Order lines sensibly: header → weather/usage → git (gauge line usually right after the header). Assign active lines as line1, line2, … in display order.

Status incident lines follow a special rule: {status_header} MUST appear on its OWN line placed ABOVE the line that contains {status}. Both lines vanish together when no incident is active. The shipped config already contains a ready-to-enable pair — enable both by renaming them from _disabled_* to line* keys:

"_disabled_status_header": "{status_header}",
"_disabled_status_line":   "{status}"

Rename _disabled_status_header to line_status_header (or similar) and _disabled_status_line to line_status — or insert them as line2/line3 etc. in the display order. Never place {status_header} on the same line as {status}.

To turn OFF an existing line without deleting it, rename its key to _disabled_<name> (keys not starting with line are ignored). Preserve every existing _comment* key. Do NOT alter the colors block.


Step 5 — Show a unified DIFF

Present a unified diff of the old statusline_config.json vs the new one so the user sees exactly what changes (templates, weather, emoji_width). Confirm colors is unchanged.


Step 6 — Validate

Before rendering, check ALL of:

  • JSON parses.
  • Every {placeholder} used appears in the placeholder list above (no {peak_label}).
  • emoji_width is 1 or 2.
  • At least one active line (a key starting with line).
  • Usage style is not mixed (at most one of full/micro/compact).
  • Big-bar rule: if any line uses bare {ctx_bar}, then line1 contains {effort} and that bar line contains {align_pad}.
  • If any active line uses {weather} or {sun}, the weather block has a geocoded name/latitude/longitude (not the default placeholder).
  • If any active line uses {status}, {status:N}, {status_icon}, or {status_header}: no special config is required (the status block has sensible defaults and is optional); the RSS fetch happens only when these placeholders appear in a rendered line. If {status_header} is used, confirm it is on a separate line placed ABOVE the line containing {status}.
  • colors block is byte-for-byte unchanged; _comment* keys preserved.

Fix any failure before proceeding.


Step 7 — Test-render with the sample input

Render the new config against assets/sample_input.json (bundled with this skill). Point STATUSLINE_CONFIG at a temp copy of the new config so the user's live file is untouched until they confirm — the live config is never written until Step 8's commit.

Use the statusline_py path you resolved in Step 1 (from the helper's locate JSON) wherever <statusline.py> appears below — the absolute path to the active renderer (the deployed copy, e.g. ~/.claude/statusline.py, or wherever locate reported). Do not hardcode any particular machine's path. Write the candidate config to a temp path (e.g. the OS temp dir), then:

PowerShell:

$env:STATUSLINE_CONFIG="<temp-config>"; Get-Content <skill>/assets/sample_input.json | uv run <statusline.py>

(fallback: replace uv run with python)

bash:

STATUSLINE_CONFIG=<temp-config> uv run <statusline.py> < <skill>/assets/sample_input.json

(fallback: python3 instead of uv run)

A non-empty colored line = success. Show the rendered bar to the user.


Step 8 — Confirm, then commit (history-aware)

Only on explicit user confirmation (after the Step 5 diff, Step 6 validate, and Step 7 test-render), install the new config. Otherwise iterate from Step 2. Never write the live config without confirmation.

Never write the live config directly. Instead, write the fully-built new config object (comments / _disabled_* / colors preserved exactly as required above) to a temp file, then hand that file to the shared helper, which snapshots the about-to-be-replaced config and records a human changelog entry next to the active config:

python statusline_io.py commit --config <config_path> --new <temp-new-config> \
    --skill statusline-config \
    --summary "<what changed, e.g. switched to three-line preset; added weather + big ctx bar>" \
    --why "<the user's intent in their words>" \
    --diff "<the key changes, e.g. the unified diff from Step 5>"
  • <config_path> is the ACTIVE config resolved in Step 1.
  • <temp-new-config> is the temp file holding your fully-formed new config (the same content you test-rendered in Step 7 — reuse that temp file).
  • The helper validates the temp file parses as JSON before touching anything, snapshots the current config into .statusline-config-history/YYYYMMDD-hhmm.json next to the active config, writes the new bytes to the active config, and appends to .statusline-config-history/YYYYMMDD.md.

It prints {"snapshot": <path or null>, "changelog": <path>, "config_path": <abs>}. Report the snapshot and changelog paths to the user so they know where the previous version and the change note were saved.


Preset templates (copy verbatim when a preset is chosen)

Set the listed templates, weather, and emoji_width fields; keep the existing colors block and all _comment* keys untouched. (The presets below show emoji_width: 1 to match examples/; if the user's emoji render 2-wide, use 2.)

For any preset that uses {weather}/{sun} you MUST first run Step 3 geocoding and fill the weather block's name/latitude/longitude with the resolved values before writing — do not ship the placeholders shown below.

Minimal (1 line): (no weather)

"emoji_width": 1,
"templates": {
  "line1": "{c.model}{model}{r}  {c.ctx_label}Ctx{r} {c.ctx_value}{ctx}{r} {c.ctx_percent}({ctx_percent}%){r} {ctx_micro}"
}

Two-line (weather + compact usage): (replace the weather placeholders with the Step 3 geocoded city)

"emoji_width": 1,
"weather": {
  "name": "<geocoded name>", "latitude": <lat>, "longitude": <lon>,
  "show_name": true, "show_icon": true, "show_temp": true,
  "show_humidity": true, "show_wind": true
},
"templates": {
  "line1": "{sun} {c.time}[{time}]{r} {c.model}{model}{r}{c.effort}{effort}{r}  {c.ctx_label}Ctx{r} {c.ctx_percent}({ctx_percent}%){r}",
  "line2": "{c.weather}{weather}{r}   {compact_usage_micro}"
}

Three-line (context bar + git): (replace the weather placeholders with the Step 3 geocoded city)

"emoji_width": 1,
"weather": {
  "name": "<geocoded name>", "latitude": <lat>, "longitude": <lon>,
  "show_name": false, "show_icon": true, "show_temp": true,
  "show_humidity": false, "show_wind": false
},
"templates": {
  "line1": "{c.time}[{time}]{r} {c.version}{version}{r} {c.model}{model}{r}{c.effort}{effort}{r} Ctx:{ctx} {c.ctx_percent}({ctx_percent}%){r}",
  "line2": "{c.weather}{weather}{r}{align_pad}{c.ctx_bracket}▐{r}{ctx_bar}{c.ctx_bracket}▌{r}",
  "line3": "{c.path}{path}{r} {c.git_icon}(git)/{r}{c.branch}{branch}{r} ({c.output}+{added}{r},{c.input}-{removed}{r})"
}

Four-line (full usage): (no weather)

"emoji_width": 1,
"templates": {
  "line1": "{c.time}[{time}]{r} {c.model}{model}{r}{c.effort}{effort}{r} Ctx:{ctx} {c.ctx_percent}({ctx_percent}%){r}",
  "line2": "{c.path}{path}{r} {c.git_icon}(git)/{r}{c.branch}{branch}{r} ({c.output}+{added}{r},{c.input}-{removed}{r})",
  "line3": "{usage_bars}",
  "line4": "{usage_resets}"
}

Status config block

The status block is optional — if absent, all status placeholders use these defaults. Add or edit the block to override specific keys; the rest remain at their defaults.

"status": {
  "show_icon":             true,   // show the incident emoji in {status}
  "show_label":            true,   // show the status label (Investigating / Identified / Monitoring …)
  "show_title":            true,   // show the incident title text
  "show_count":            true,   // show "(+N)" hint when multiple incidents are active
  "show_header":           true,   // allow {status_header} to render
  "include_maintenance":   false,  // also surface scheduled / in-progress maintenance events
  "max_len":               48,     // global char cap for {status} (0 = unlimited)
  "max_age_hours":         48,     // only incidents updated within this many hours count (0 = no limit)
  "title": "⚠️ Claude have some issues"  // banner text shown by {status_header}
}

Key notes:

  • max_len is the global cap for {status}; {status:N} overrides it per-line (0 = unlimited for that line).
  • include_maintenance: false (default) hides scheduled/in-progress maintenance events; set to true to surface them alongside incidents.
  • max_age_hours: 0 disables the age filter — every parsed incident counts regardless of when it was last updated.
  • A leading emoji in title is auto-spaced from the words; no manual spacing needed.
  • The status block does not live inside colors — it is a sibling of templates, weather, and emoji_width.
  • Color keys for the status indicator (status_investigating, status_identified, status_monitoring, status_maintenance, status_default, status_title, status_count, status_header) live in the colors block and are owned by /statusline-theme; do not touch them here.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.