Brandedflow statusline
install
source · Clone the upstream repo
git clone https://github.com/JenCW/brandedflow
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/JenCW/brandedflow "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.cursor/skills-cursor/statusline" ~/.claude/skills/jencw-brandedflow-statusline && rm -rf "$T"
manifest:
.cursor/skills-cursor/statusline/SKILL.mdsource content
CLI Status Line
The CLI supports a user-configurable status line rendered above the prompt. A command is spawned on each conversation update, receives a JSON payload on stdin describing the session, and its stdout is displayed as the status line. The spec is aligned with Claude Code's status line.
Configuration
Add a
statusLine entry to ~/.cursor/cli-config.json:
{ "statusLine": { "type": "command", "command": "~/.cursor/statusline.sh", "padding": 2 } }
The
command field supports full paths, ~ expansion, and shell-style argument splitting. You can point it at a script file or use an inline command like jq -r '...'.
| Field | Required | Default | Description |
|---|---|---|---|
| yes | — | Must be |
| yes | — | Path to an executable or inline command. is expanded. |
| no | | Horizontal inset (in characters) for the status line container. |
| no | | Minimum interval between invocations. Clamped to >= 300ms. |
| no | | Maximum time the command may run before it is killed. |
Stdin payload
The command receives a JSON object on stdin. The TypeScript interface is
StatusLinePayload in packages/agent-cli/src/hooks/use-status-line.ts.
Full JSON schema
{ "session_id": "abc123", "session_name": "my session", "transcript_path": "/path/to/transcript.jsonl", "render_width_chars": 120, "cwd": "/Users/me/project", "model": { "id": "claude-4-opus", "display_name": "Claude 4 Opus", "param_summary": "(Thinking)", "max_mode": true }, "workspace": { "current_dir": "/Users/me/project", "project_dir": "/Users/me/project/.cursor/transcripts", "added_dirs": [] }, "version": "1.2.3", "output_style": { "name": "default" }, "context_window": { "total_input_tokens": 15234, "total_output_tokens": null, "context_window_size": 200000, "used_percentage": 34.5, "remaining_percentage": 65.5, "current_usage": null }, "vim": { "mode": "NORMAL" }, "worktree": { "name": "my-feature", "path": "/Users/me/.cursor/worktrees/repo/my-feature" } }
Available fields
| Field | Description |
|---|---|
| Unique session identifier |
| Custom session name. Absent if no name has been set |
| Path to conversation transcript file |
| Usable terminal columns minus built-in padding |
, | Current working directory (both contain the same value) |
| Directory where transcripts are stored |
| Additional directories (empty array for now) |
, | Current model identifier and display name |
| Formatted parameter summary (e.g. "(Thinking)", "High"). Absent when empty |
| when max mode is enabled. Absent otherwise |
| CLI version string |
| or |
| Estimated input tokens (derived from used_percentage) |
| Cumulative output tokens (null when not tracked) |
| Maximum context window size in tokens |
| Percentage of context window used |
| Percentage of context window remaining |
| Token counts from the last API call (null before first call) |
| or when vim mode is enabled |
| Worktree name when running inside a worktree |
| Absolute path to the worktree directory |
Fields that may be absent
— only present when a custom name has been setsession_name
— only present when model has non-default parametersmodel.param_summary
— only present when max mode is enabledmodel.max_mode
— only present when vim mode is enabledvim
— only present when running in a worktreeworktree
Fields that may be null
— null before the first API callcontext_window.current_usage
,context_window.used_percentage
— may be null early in the sessioncontext_window.remaining_percentage
Stdout / rendering
- Multiple lines are supported: each line of stdout renders as a separate row in the status area.
- ANSI color codes are supported (use chalk, tput,
, etc.).\033[32m - If the command exits non-zero with empty stdout, the status line is not updated (previous text is kept).
- If the command times out or a new update arrives while the script is running, the in-flight process is killed.
- The status line runs locally and does not consume API tokens.
Examples
Basic: model + context usage
#!/usr/bin/env bash payload=$(cat) model=$(echo "$payload" | jq -r '.model.display_name') pct=$(echo "$payload" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1) printf "\033[90m%s ctx %s%%\033[0m" "$model" "$pct"
Context progress bar
#!/usr/bin/env bash input=$(cat) MODEL=$(echo "$input" | jq -r '.model.display_name') PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1) BAR_WIDTH=10 FILLED=$((PCT * BAR_WIDTH / 100)) EMPTY=$((BAR_WIDTH - FILLED)) BAR="" [ "$FILLED" -gt 0 ] && printf -v FILL "%${FILLED}s" && BAR="${FILL// /▓}" [ "$EMPTY" -gt 0 ] && printf -v PAD "%${EMPTY}s" && BAR="${BAR}${PAD// /░}" echo "[$MODEL] $BAR $PCT%"
Multi-line with git info
#!/usr/bin/env bash input=$(cat) MODEL=$(echo "$input" | jq -r '.model.display_name') DIR=$(echo "$input" | jq -r '.workspace.current_dir') PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1) BRANCH="" git rev-parse --git-dir > /dev/null 2>&1 && BRANCH=" | 🌿 $(git branch --show-current 2>/dev/null)" echo -e "\033[36m[$MODEL]\033[0m 📁 ${DIR##*/}$BRANCH" echo -e "ctx $PCT%"
Inline jq command (no script file)
{ "statusLine": { "type": "command", "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'" } }
Testing
Test a script with mock input:
echo '{"model":{"display_name":"Opus"},"context_window":{"used_percentage":25}}' | ./statusline.sh
The command is spawned with
child_process.spawn (no shell on Unix, shell: true on Windows for .cmd/.bat compatibility). Updates are debounced at the configured interval. If a new update triggers while a script is running, the in-flight process is killed via AbortController and the new invocation starts immediately.