In this post I’ll cover the following topics:
- Status line — the script I use to customize the Claude status bar.
settings.json— model, permissions, and safety tweaks.- Plugins — which ones I use day to day and what each is for.
- RTK — a proxy that compresses command output before it reaches the context.
1 The Status Line
The bar I use looks like this:
It shows, from left to right:
| Segment | Example | What it is |
|---|---|---|
| Directory | ~/Workspace/my-app | Current folder, with $HOME shortened to ~ |
| Git branch | master | Current branch of the repository |
| Model | Opus 4.8 | Active Claude model |
| Context | ctx:5% of 1000k | % of the context window used and its total size |
Claude Code supports a command-type status line: it runs a script on every update and sends a JSON payload via stdin with the session state (directory, model, context usage, etc.). The script prints the already-formatted line (with ANSI colors).
1.1 Step by step from scratch
Follow in order:
Step 1 — Install jq (the script depends on it to read the JSON):
brew install jq # macOS
# sudo apt install jq # Ubuntu/Debian
# sudo pacman -S jq # Arch
Step 2 — Create the script at ~/.claude/statusline-command.sh. Open the file in your editor of choice:
nano ~/.claude/statusline-command.sh # or vim, code, etc.
And paste the content below (save and exit):
#!/usr/bin/env bash
input=$(cat)
raw_dir=$(echo "$input" | jq -r '.workspace.current_dir // .cwd')
model=$(echo "$input" | jq -r '.model.display_name // "Claude"')
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
window_size=$(echo "$input" | jq -r '.context_window.context_window_size // empty')
# Shorten the home directory to ~
dir="${raw_dir/#$HOME/\~}"
# Git branch (skip optional locks for safety with agents)
git_branch=""
if git -C "$raw_dir" rev-parse --is-inside-work-tree --no-optional-locks 2>/dev/null | grep -q true; then
branch=$(git -C "$raw_dir" symbolic-ref --short HEAD 2>/dev/null || git -C "$raw_dir" rev-parse --short HEAD 2>/dev/null)
if [ -n "$branch" ]; then
git_branch=$(printf " \033[35m|\033[0m \033[35m%s\033[0m" "$branch")
fi
fi
# Context usage indicator
ctx_info=""
if [ -n "$used_pct" ]; then
used_int=$(printf "%.0f" "$used_pct")
if [ -n "$window_size" ]; then
total_k=$(echo "$window_size" | awk '{printf "%dk", $1/1000}')
ctx_info=$(printf " \033[35m|\033[0m \033[36mctx:%s%% of %s\033[0m" "$used_int" "$total_k")
else
ctx_info=$(printf " \033[35m|\033[0m \033[36mctx:%s%%\033[0m" "$used_int")
fi
fi
printf "\033[34m%s\033[0m%s \033[35m|\033[0m \033[32m%s\033[0m%s" \
"$dir" "$git_branch" "$model" "$ctx_info"
Step 3 — Make it executable:
chmod +x ~/.claude/statusline-command.sh
Step 4 — Test the script manually (simulating the JSON Claude sends):
echo '{"workspace":{"current_dir":"'"$HOME"'/Workspace/my-app"},"model":{"display_name":"Opus 4.8"},"context_window":{"used_percentage":5,"context_window_size":1000000}}' | bash ~/.claude/statusline-command.sh
It should print something like youruser | ~/Workspace/my-app | git:(main) | Opus 4.8 | ctx:5% of 1000k.
Step 5 — Register it in settings.json. In ~/.claude/settings.json, use the absolute path to the script with your real username:
{
"statusLine": {
"type": "command",
"command": "bash /Users/YOUR_USER/.claude/statusline-command.sh"
}
}
Shortcut: inside Claude Code you can also use the
/statuslinecommand to help set this up.
2 Other useful settings.json options
Beyond the status line, a few tweaks from my settings.json are worth highlighting:
{
"model": "opus",
"effortLevel": "xhigh",
"env": {
"DISABLE_TELEMETRY": "1",
"DISABLE_ERROR_REPORTING": "1"
},
"permissions": {
"defaultMode": "auto",
"ask": [
"Bash(git merge *)",
"Bash(git rebase *)",
"Bash(git reset --hard *)",
"Bash(rtk git merge *)",
"Bash(rtk git rebase *)",
"Bash(rtk git reset --hard *)"
],
"deny": [
"Bash(curl *)",
"Bash(rm -rf:*)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(**/secrets/**)"
]
}
}
model— default model (opus).effortLevel— reasoning effort level.DISABLE_TELEMETRY— turns off anonymous usage analytics (which commands you run, how often, feature metrics).DISABLE_ERROR_REPORTING— turns off automatic crash/error reports; stack traces stay on your machine.permissions.defaultMode(auto): a classifier decides per action. Reversible things (reads, ordinary edits, most commands) run without a prompt; destructive ones get soft-blocked until I confirm.permissions.ask: commands that always stop and wait for a yes. I keep the git operations that can rewrite history or throw away work here:merge,rebase, andreset --hard. A wrongreset --hardwipes uncommitted changes, so I never want an agent firing it on autopilot.permissions.deny— safety blocks: never read.env/secrets, never runcurl, neverrm -rf.
Each git rule shows up twice in ask: once as git ... and once as rtk git .... The RTK hook (section 4) rewrites git into rtk git before the command runs, so the pattern has to match the rewritten form too, otherwise the confirmation never fires.
Claude Code reads
settings.jsonat startup, so a running session keeps the old rules — it will still read your.env. Quit Claude Code and reopen it for the newdenylist to take effect.
3 Plugins I use
Plugins are enabled in enabledPlugins inside settings.json and installed from marketplaces. I use 4:
| Plugin | Marketplace | What it’s for |
|---|---|---|
| context7 | claude-plugins-official | Fetches up-to-date docs for libraries/frameworks (React, Next.js, Laravel, etc.) straight from the source, avoiding stale answers. |
| code-review | claude-plugins-official | Reviews pull requests / diffs with a dedicated code review command. |
| code-simplifier | claude-plugins-official | Simplifies and refines code for clarity and maintainability, without changing behavior. |
| caveman | caveman (GitHub: JuliusBrussee/caveman) | Ultra-compressed (“caveman”) communication mode that cuts token usage while keeping the technical content. Has levels: lite, full, ultra. |
3.1 Plugin configuration in settings.json
{
"enabledPlugins": {
"context7@claude-plugins-official": true,
"code-review@claude-plugins-official": true,
"code-simplifier@claude-plugins-official": true,
"caveman@caveman": true
},
"extraKnownMarketplaces": {
"caveman": {
"source": {
"source": "github",
"repo": "JuliusBrussee/caveman"
}
}
}
}
enabledPlugins— turns on each plugin via thename@marketplaceformat.extraKnownMarketplaces— registers extra marketplaces beyond the official one. Herecavemancomes straight from a GitHub repository.
3.2 Installing plugins in practice
Plugins can be managed through the Claude Code interface (the plugins command) or show up in ~/.claude/plugins/config.json once installed. For an external marketplace like caveman, you just need it registered in extraKnownMarketplaces and the plugin marked true in enabledPlugins.
4 RTK — token-optimized CLI proxy
On top of the plugins, I use RTK (rtk-ai/rtk): a command-line proxy that filters and compresses command output before it reaches the LLM context, cutting token usage by 60–90%.
4.1 What it does
- Processes the output of 100+ commands (git, cargo, npm, docker, AWS, etc.).
- Applies 4 strategies: smart filtering, grouping, truncation, and deduplication.
- Single Rust binary, no external dependencies, ~10ms overhead per command.
4.2 Main commands
| Category | Examples |
|---|---|
| Files | rtk ls, rtk read, rtk grep |
| Git | rtk git status, rtk git diff, rtk git push |
| Tests | rtk cargo test, rtk pytest, rtk jest |
| Build | rtk lint, rtk tsc, rtk docker ps |
| Metrics | rtk gain (tracks token savings) |
4.3 Installation
brew install rtk
# or
cargo install --git https://github.com/rtk-ai/rtk
4.4 Setup in Claude Code
rtk init -g
This installs the auto-rewrite hook, which transparently converts bash commands into their RTK equivalents, so you don’t need to change how you work. Paired with the caveman plugin, it forms a context-saving duo: caveman compresses the communication, RTK compresses the tool output.
5 Conclusion
This is the setup I’ve been using day to day. It has added a lot to my development workflow.