Этот документ — промпт для AI-агента (Claude Code, Cursor, Codex и т.п.). Пользователь передаёт файл агенту со словами «выполни инструкцию» — дальше всё делает агент. Все команды выполняются от имени текущего пользователя, без
sudo, если не указано иное.
В нижней части окна Claude Code появляется одна строка со статусом сессии:
Слева направо: имя проекта, остаток 5-часового лимита со временем до сброса, остаток 7-дневного лимита, заполнение контекста (если показывает), стоимость текущей сессии, уровень effort, модель.
Ты — агент, устанавливающий кастомный статус-бар для Claude Code. Работай идемпотентно: если что-то уже сделано — не переделывай. Не затирай существующий конфиг. После каждого изменяющего шага проверяй результат. В конце отчитайся одним коротким сообщением.
В терминале Claude Code внизу должна появиться строка вида:
• <project> | 5h:NN% Xh Ym | 7d:NN% Xd Yh | ctx:NN% | $X.XX | effort:<level> | <model>
Цвета (ANSI): зелёный/жёлтый/красный для лимитов и контекста по порогам ниже.
Все пункты должны быть true:
~/.claude/statusline-command.sh существует,
исполняемый.~/.claude/settings.json — валидный JSON и содержит:
"statusLine": { "type": "command", "command": "bash ~/.claude/statusline-command.sh" }settings.json, существовавшие до
правки, на месте и неизменны.jq и awk доступны в
PATH.Выполни параллельно и зафиксируй результаты:
claude --version || echo "claude_missing"
command -v jq || echo "jq_missing"
command -v awk || echo "awk_missing"
uname -s
test -f ~/.claude/settings.json && echo "settings_exists" || echo "settings_missing"Реакция:
claude_missing → останови, попроси пользователя
установить Claude Code, выйди.awk_missing → крайне маловероятно; если случилось —
останови, попроси разобраться.jq_missing →
brew install jqsudo apt-get update && sudo apt-get install -y jq
(если есть sudo) или попроси пользователя поставить.rate_limits могут не отображаться до
обновления.if [ -f ~/.claude/settings.json ]; then
cp ~/.claude/settings.json ~/.claude/settings.json.bak.$(date +%s)
fi
mkdir -p ~/.claudeЗапиши дословно содержимое из секции SCRIPT в
~/.claude/statusline-command.sh. Не меняй ничего, не
«улучшай», не добавляй комментарии от себя. После записи:
chmod +x ~/.claude/statusline-command.shПроверка:
test -x ~/.claude/statusline-command.sh && echo OKИспользуй jq для безопасного мерджа. Не парси JSON
руками, не пиши cat > settings.json.
TMP=$(mktemp)
if [ -f ~/.claude/settings.json ]; then
jq '.statusLine = {"type":"command","command":"bash ~/.claude/statusline-command.sh"}' \
~/.claude/settings.json > "$TMP" && mv "$TMP" ~/.claude/settings.json
else
printf '%s\n' '{"statusLine":{"type":"command","command":"bash ~/.claude/statusline-command.sh"}}' \
| jq . > ~/.claude/settings.json
fiЕсли jq упал — НЕ перезаписывай файл; восстанови из
бэкапа и сообщи пользователю.
Запусти скрипт с моковым JSON-инпутом и убедись, что он печатает строку:
echo '{"model":{"id":"claude-opus-4-7"},"workspace":{"current_dir":"/tmp"},"rate_limits":{"five_hour":{"used_percentage":30,"resets_at":'$(($(date +%s)+7200))'},"seven_day":{"used_percentage":50,"resets_at":'$(($(date +%s)+86400))'}},"context_window":{"used_percentage":42},"cost":{"total_cost_usd":1.23}}' \
| bash ~/.claude/statusline-command.sh
echoОжидаемо: одна строка с
• tmp | 5h:70% ... | 7d:50% ... | ctx:42% | $1.23 | ... | opus 4.7.
Если пусто или ошибка — диагностируй (см. TROUBLESHOOTING).
Выполни всё и убедись, что нет ошибок:
jq . ~/.claude/settings.json > /dev/null && echo "json_ok"
jq -e '.statusLine.command' ~/.claude/settings.json > /dev/null && echo "statusline_ok"
test -x ~/.claude/statusline-command.sh && echo "script_ok"Одно короткое сообщение, формат:
✓ Статус-бар установлен.
- Скрипт: ~/.claude/statusline-command.sh
- settings.json: добавлен ключ statusLine, остальное не тронуто
- Бэкап: ~/.claude/settings.json.bak.<ts> (если был оригинал)
Перезапусти Claude Code — внизу появится строка с лимитами 5h/7d, контекстом, ценой сессии и моделью.
Если были warnings (старая версия CC, free-тариф без
rate_limits) — добавь отдельной строкой.
| Симптом | Причина | Действие |
|---|---|---|
| Step 4 даёт пустой вывод | jq или awk не найден |
Перепроверь command -v jq awk |
jq: error в Step 3 |
settings.json уже сломан | Восстанови из последнего .bak, повтори Step 3 |
Скрипт печатает \033[..m буквально |
Тест запущен в pipe без ANSI; в реальном терминале будет цвет | Игнорируй |
claude --version не находится |
Claude Code не в PATH | Спроси пользователя, где установлен |
| После рестарта статус-бар не виден | settings.json не подхватился | Проверь jq .statusLine ~/.claude/settings.json |
Если пользователь просит изменить:
# Session cost и убери cost из финального
parts.project_name добавь:
git_branch=$(git -C "$current_dir" branch --show-current 2>/dev/null)
[ -n "$git_branch" ] && project_name="${project_name} (${git_branch})"50 /
20 (лимиты) и 50 / 80 (контекст)
ищи в скрипте.| в
финальном printf/сборке parts.После любой кастомизации повтори Step 4 и сохрани новую версию скрипта.
• <project> — basename текущей рабочей
директории.5h:NN% Xh Ym — остаток 5-часового лимита Pro/Max и
время до сброса. Зелёный >50%, жёлтый 20–50%, красный <20%.7d:NN% Xd Yh — то же для недельного лимита.ctx:NN% — заполнение контекстного окна. Зелёный
<50%, жёлтый 50–80%, красный ≥80%.$X.XX — суммарная стоимость текущей сессии.effort:<level> — текущий effort из
settings.json (xhigh/high — фиолетовый, medium — жёлтый,
low — серый).<model> — короткое имя (opus 4.7,
sonnet 4.6, haiku 4.5) + 1M если
включён 1M-контекст.waiting… (серым) — лимиты ещё не пришли; на free-тарифе
остаётся всегда.JSON со структурой (используются только эти поля):
{
"model": { "id": "claude-opus-4-7" },
"workspace": { "current_dir": "/abs/path" },
"cwd": "/abs/path",
"rate_limits": {
"five_hour": { "used_percentage": 0-100, "resets_at": <unix_ts> },
"seven_day": { "used_percentage": 0-100, "resets_at": <unix_ts> }
},
"context_window": { "used_percentage": 0-100 },
"cost": { "total_cost_usd": <float> }
}Любые поля могут отсутствовать — скрипт это переживает (использует
// empty в jq).
Запиши дословно в
~/.claude/statusline-command.sh:
#!/bin/bash
# Claude Code Status Line — shows project, 5h/7d limits, model
input=$(cat)
# Extract fields
model_id=$(echo "$input" | jq -r '.model.id // "unknown"')
current_dir=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""')
# Project name from directory
dir_name=$(basename "${current_dir:-$(pwd)}")
project_name="$dir_name"
# Rate limits (available for Pro/Max subscribers, v2.1.80+)
five_hr=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
five_hr_reset=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
seven_day=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
seven_day_reset=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')
# Build limits display
limits=""
if [ -n "$five_hr" ] && [ "$five_hr" != "null" ]; then
five_remain=$(awk "BEGIN {printf \"%.0f\", 100 - $five_hr}")
five_reset_str=""
if [ -n "$five_hr_reset" ] && [ "$five_hr_reset" != "null" ]; then
now=$(date +%s)
diff=$(( five_hr_reset - now ))
if [ $diff -gt 0 ]; then
h=$(( diff / 3600 ))
m=$(( (diff % 3600) / 60 ))
if [ $h -ge 1 ]; then
five_reset_str=" ${h}h${m}m"
else
five_reset_str=" ${m}m"
fi
fi
fi
if [ "$five_remain" -gt 50 ]; then
five_color="\033[32m"
elif [ "$five_remain" -gt 20 ]; then
five_color="\033[33m"
else
five_color="\033[31m"
fi
limits="${five_color}5h:${five_remain}%${five_reset_str}\033[0m"
fi
if [ -n "$seven_day" ] && [ "$seven_day" != "null" ]; then
seven_remain=$(awk "BEGIN {printf \"%.0f\", 100 - $seven_day}")
seven_reset_str=""
if [ -n "$seven_day_reset" ] && [ "$seven_day_reset" != "null" ]; then
now=$(date +%s)
diff=$(( seven_day_reset - now ))
if [ $diff -gt 0 ]; then
d=$(( diff / 86400 ))
h=$(( (diff % 86400) / 3600 ))
if [ $d -ge 1 ]; then
seven_reset_str=" ${d}d${h}h"
else
seven_reset_str=" ${h}h"
fi
fi
fi
if [ "$seven_remain" -gt 50 ]; then
seven_color="\033[32m"
elif [ "$seven_remain" -gt 20 ]; then
seven_color="\033[33m"
else
seven_color="\033[31m"
fi
if [ -n "$limits" ]; then
limits="${limits} ${seven_color}7d:${seven_remain}%${seven_reset_str}\033[0m"
else
limits="${seven_color}7d:${seven_remain}%${seven_reset_str}\033[0m"
fi
fi
if [ -z "$limits" ]; then
limits="\033[90mwaiting...\033[0m"
fi
# Context window usage
ctx_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
ctx=""
if [ -n "$ctx_pct" ] && [ "$ctx_pct" != "null" ]; then
ctx_int=$(awk "BEGIN {printf \"%.0f\", $ctx_pct}")
if [ "$ctx_int" -lt 50 ]; then
ctx_color="\033[32m"
elif [ "$ctx_int" -lt 80 ]; then
ctx_color="\033[33m"
else
ctx_color="\033[31m"
fi
ctx="${ctx_color}ctx:${ctx_int}%\033[0m"
fi
# Session cost
cost_usd=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
cost=""
if [ -n "$cost_usd" ] && [ "$cost_usd" != "null" ]; then
cost="\033[36m\$$(awk "BEGIN {printf \"%.2f\", $cost_usd}")\033[0m"
fi
# Short model name — detect 1M context variant
ctx_suffix=""
case "$model_id" in
*\[1m\]*|*-1m*|*_1m*) ctx_suffix=" 1M" ;;
esac
case "$model_id" in
*opus*4-7*|*opus-4-7*|*opus*4*7*) model_base="opus 4.7" ;;
*opus*4-6*|*opus-4-6*|*opus*4*6*) model_base="opus 4.6" ;;
*opus*4-5*|*opus-4-5*|*opus*4*5*) model_base="opus 4.5" ;;
*sonnet*4-6*|*sonnet-4-6*|*sonnet*4*6*) model_base="sonnet 4.6" ;;
*sonnet*4-5*|*sonnet-4-5*|*sonnet*4*5*) model_base="sonnet 4.5" ;;
*sonnet*4*|*sonnet-4*) model_base="sonnet 4" ;;
*haiku*4-5*|*haiku-4-5*) model_base="haiku 4.5" ;;
*haiku*) model_base="haiku" ;;
*) model_base="${model_id:-claude}" ;;
esac
model_short="${model_base}${ctx_suffix}"
# Effort level from settings.json
effort=""
effort_level=$(jq -r '.effortLevel // empty' ~/.claude/settings.json 2>/dev/null)
if [ -n "$effort_level" ]; then
case "$effort_level" in
xhigh|high) effort_color="\033[35m" ;;
medium) effort_color="\033[33m" ;;
low) effort_color="\033[90m" ;;
*) effort_color="\033[37m" ;;
esac
effort="${effort_color}effort:${effort_level}\033[0m"
fi
# Assemble: project | limits | ctx | cost | effort | model
parts="$limits"
[ -n "$ctx" ] && parts="$parts | $ctx"
[ -n "$cost" ] && parts="$parts | $cost"
[ -n "$effort" ] && parts="$parts | $effort"
printf "• %s | %b | %s" "$project_name" "$parts" "$model_short"