Claude Codeã®ã¹ããŒã¿ã¹ã©ã€ã³å®å šã«ã¹ã¿ã â JSONé§åã§æ®éã»ã³ã¹ãã»å¥å šæ§ã3è¡è¡šç€º
ååãCodexãšworktreeã§AIã䞊åã«èµ°ãããè©±ãæžããŸãããä»åã¯ãã®è¶³å Žã®è©± ââ åžžæèŠããŠããã¹ããŒã¿ã¹ã©ã€ã³ã®å®è£ ã§ãã
çµè«ãã: automation-health.shïŒlaunchd/hooks/äŒè©±ãã°ãªã©èªåŸåºç€ã®æ»æŽ»ç£èŠã¹ã¯ãªããïŒã宿ž¬ããã1å78.23ç§ããããŸããïŒuser 4.43s + system 7.81sã--deepãªãã§ãããïŒããããæ¯ã¿ãŒã³çŽ çŽã«åŒãã ãäŒè©±ãæ¢ãŸããŸããçãã¯ã300ç§ãã£ãã·ã¥ïŒããã¯ã°ã©ãŠã³ãèµ·åãã§ããã£ãã·ã¥ãããæã¯ãµãããã»ã¹èµ·åãŒãã»ãã¡ã€ã«read1åã ãã§ãããã®èšäºã¯ãã®å®è£
ãå
šéšèŠããŸãã
å°ãããšïŒæ®éãèŠããªããšç¡äººãžã§ããæ¢ãæãªã
åã åã®èªåŸã«ãŒãèšäºã§ãã³ã¹ãæ ãæ°å€ã§å ã«ãã§ãã¯ãããä»çµã¿ãæžããŸãããããããã人éåŽãä»ã®æ¶è²»ããŒã¹ãç»é¢ã®å€ã«çœ®ããŠãããæ°ã¥ãã®ãé ããŸãã5æéãããã¯ã®æ®éã7æ¥æ ã®æ®éãã³ã³ããã¹ã䜿çšçãã»ãã·ã§ã³èª²éé¡ ââ ãããæ¯ã¿ãŒã³èŠãããšããã«åºãããã
幞ããClaude Codeã®settings.jsonã«statusLine.commandãæžããšãããããå«ãJSONãæ¯ã¿ãŒã³ãã®ãŸãŸã·ã§ã«ã®stdinã«æµããŠããŸããèªèšŒãAPIã³ãŒã«ãèŠããŸããã
"statusLine": {
"type": "command",
"command": "~/.claude/scripts/statusline.sh",
"padding": 0
},
ãã®ã³ãã³ããæšæºåºåã«è¿ããæååããã®ãŸãŸã¹ããŒã¿ã¹ã©ã€ã³ã«ãªããŸããããšã¯äžèº«ãã©ãæçãããã ãã®è©±ã§ãã
JSONã®äžèº«ïŒæ¬²ããå€ã¯å šéšstdinã«ãã
statusline.shåé ã®ã³ã¡ã³ãã仿§æžä»£ããã«ãªã£ãŠããŸãã
# Plan-limit % and resets come straight from Claude Code's statusline stdin
# (.rate_limits.{five_hour,seven_day}.{used_percentage,resets_at}) â no auth,
# no endpoint call. Context % is .context_window.used_percentage (pre-calc).
# rate_limits is "only present for subscribers after first API response", so we
# fall back to "--" until the first turn lands. Costs: session = stdin
# .cost.total_cost_usd; today = ccusage daily (the only external call, cached).
å®éã®æœåºã¯ããã ãã§ãã
MODEL=$(j '.model.display_name // .model.id // "claude"' | sed 's/claude-//')
EFFORT=$(j '.effort.level // empty')
FAST=$(j '.fast_mode // empty')
CWD=$(j '.workspace.current_dir // .cwd // ""' | sed "s|$HOME|~|")
SESSION_USD=$(j '.cost.total_cost_usd // 0')
CTX=$(j '.context_window.used_percentage // empty')
H5=$(j '.rate_limits.five_hour.used_percentage // empty')
H5R=$(j '.rate_limits.five_hour.resets_at // empty')
D7=$(j '.rate_limits.seven_day.used_percentage // empty')
D7R=$(j '.rate_limits.seven_day.resets_at // empty')
rate_limitsã¯ããµãã¹ã¯ã§æåã®APIå¿çãè¿ã£ãããšã«ã ãçŸãããã®ã§ãã»ãã·ã§ã³éå§çŽåŸã¯--衚瀺ã«ãã©ãŒã«ããã¯ããŸããããã§äŸå€ãæããã空æåã®ãŸãŸ%èšç®ããããããªãã®ããã€ã³ãã§ãpct()ãã«ããŒã空å€ã--ã«äžžããŸãã
pct() { [ -n "$1" ] && printf '%.0f%%' "$1" || printf '%s' "--"; }
æ¥æ¬¡èª²éã ãã¯ccusageãšããå€éšã³ãã³ããèŠãå¯äžã®å€ã§ããããã¯30åãã£ãã·ã¥ïŒ/tmp/cc-daily-cache.jsonãAGE -lt 1800ïŒã«ããŠãããã¯ãã£ã¬ã¯ããªã§å€éèµ·åãé²ãã€ã€ããã¯ã°ã©ãŠã³ãã§æŽæ°ããŸãã
find "${DAY_CACHE}.lock" -maxdepth 0 -mmin +5 -exec rmdir {} \; 2>/dev/null
[ "$NEED" = true ] && mkdir "${DAY_CACHE}.lock" 2>/dev/null && \
( "$CCUSAGE" daily --json --offline 2>/dev/null > "${DAY_CACHE}.tmp" \
&& mv "${DAY_CACHE}.tmp" "$DAY_CACHE"; rmdir "${DAY_CACHE}.lock" ) &
è²ã%ã§åãæ¿ãã
3å€ïŒcontext% / 5h% / 7d%ïŒã¯ãã¹ãŠåãpcolor()ãéããŸããç·50%æªæºã»é»50ã79%ã»èµ€80%以äžã®3段éã ãã®åçŽãªãããå€ã§ãã
pcolor() { local n="${1%%.*}"; [ -z "$n" ] && { printf '%s' "$DIM"; return; }
if [ "$n" -ge 80 ] 2>/dev/null; then printf '%s' "$RED"
elif [ "$n" -ge 50 ] 2>/dev/null; then printf '%s' "$YEL"
else printf '%s' "$GRN"; fi; }
å°æ°ç¹ãå
¥ã£ãŠããŠã${1%%.*}ã§æŽæ°éšã ãåãåºããŠãã-geæ¯èŒããã®ã§ãjqãè¿ã42.7ã®ãããªå€ã§ãå£ããŸããã3è¡ã®çµã¿ç«ãŠã¯ãããªããŸãã
L1=$(printf "${DIM}ð${R} ${CYAN}%s${R}%s%s" "$DIRNAME" "$BR" "$WT")
L2=$(printf "${MAG}ð€ %s%s${R} ${DIM}·${R} ${CTXC}ð§ ctx %s${R} ${DIM}·${R} ${C5}ð 5h %s${R}%b ${DIM}·${R} ${C7}ð
7d %s${R}%b" \
"$MODEL" "$EFF" "$(pct "$CTX")" "$(pct "$H5")" "$R5" "$(pct "$D7")" "$R7")
L3=$(printf "${DIM}ðŽ session${R} %s ${DIM}仿¥${R} %s%b" \
"$(yen "$SESSION_USD")" "$(yen "$DAY_USD")" "$PROJ_HEALTH_SEG")
printf "%b\n%b\n%b" "$L1" "$L2" "$L3"
ð dir â¥branch / ð€ model ctx% 5h% 7d% / ðŽ session Â¥x 仿¥ Â¥y <health> ã®3è¡æ§æã§ãã
ãµãããã»ã¹ãŒãèªã¿åºãïŒ78ç§ããã£ãã·ã¥ã§æ¶ã
ãããããæ¬é¡ã§ããautomation-health.shã¯launchdã»hooksã»skill-harvestã»äŒè©±ãã°ã»Obsidian飿ºãŸã§ã暪æãã§ãã¯ããã¹ã¯ãªããã§ãå®éã«æéãæž¬ã£ããããã§ããã
( bash ~/.claude/scripts/automation-health.sh > /tmp/ah-test-out.txt 2>&1; )
4.43s user 7.81s system 15% cpu 1:18.23 total
78ç§ã§ããã¹ããŒã¿ã¹ã©ã€ã³ã¯æ¯ã¿ãŒã³åæç»ãããã®ã§ããããåæã§åŒãã ç¬éã«äœæéåºŠãæ»ã«ãŸããã ããstatusline.shã¯ãã®çµæã5åãã£ãã·ã¥ãããã£ãã·ã¥ãæ°ãããã°ãã¡ã€ã«ã1åcatããã ãã§æžãŸããŸãã
HEALTH_CACHE="/tmp/cc-health-cache"; HEALTH=""
if [ -f "$HEALTH_CACHE" ]; then
HAGE=$(($(date +%s) - $(stat -f %m "$HEALTH_CACHE" 2>/dev/null || echo 0)))
[ "$HAGE" -lt 300 ] && HEALTH=$(cat "$HEALTH_CACHE" 2>/dev/null)
fi
if [ -z "$HEALTH" ]; then
( h=$(~/.claude/scripts/automation-health.sh 2>&1 | grep -oE "ALL GREEN|WARN|FAIL" | head -1)
case "$h" in
"ALL GREEN") echo "ð¢" > "$HEALTH_CACHE" ;;
"WARN") echo "ð¡" > "$HEALTH_CACHE" ;;
"FAIL") echo "ðŽ" > "$HEALTH_CACHE" ;;
*) echo "â«" > "$HEALTH_CACHE" ;;
esac ) &
HEALTH="·"
fi
ãã£ãã·ã¥ã5å以å
ãªãstatã ãã§å®äºãæéåããªãããã¯ã°ã©ãŠã³ãã§éãæ¬äœãèµ·åããŠçŸåšã®ã¿ãŒã³ã¯Â·ïŒèªã¿èŸŒã¿äžïŒãåºããæ¬¡ã®ã¿ãŒã³ä»¥éã§ð¢/ð¡/ðŽã«çœ®ãæãããŸããåæã§åŸ
ããªãã®ãèã§ãçµ±èšçã«ã¯ã»ãŒå
šã¿ãŒã³ããã£ãã·ã¥ãããã«ãªãã®ã§ãäœæã³ã¹ãã¯ããã¡ã€ã«ã®statïŒæ¡ä»¶åå²ãã ãã«åãŸããŸãã
project-health.shåŽã¯ããã«æ®µéãåããŠããŠã4æé(14400ç§)ãè¶
ããã1800ç§ã¹ãããã«ã®èæ¯æŽæ°ã25æé(90000ç§)ãè¶
ãããçµéæéã€ãã§å€ãã衚瀺ããšãã2段æ§ãã§ãã
if [ "$PH_AGE" -gt 14400 ] && [ "$PH_AGE" -lt 90000 ]; then
PH_RFILE="/tmp/cc-ph-bg-refresh-ts"
PH_ROK=true
if [ -f "$PH_RFILE" ]; then
RLAG=$(($(date +%s) - $(stat -f %m "$PH_RFILE" 2>/dev/null || echo 0)))
[ "$RLAG" -lt 1800 ] && PH_ROK=false
fi
[ "$PH_ROK" = true ] && { touch "$PH_RFILE"; ( ~/.claude/scripts/project-health.sh >/dev/null 2>&1 ) & }
fi
ãéãåŠçãæ¯ååŒã¶ããšããã£ãã·ã¥ãäžçæŽæ°ããªããã®äžéãããã§ãããã£ãã·ã¥æéåããæ€ç¥ããã¿ãŒã³ã¯å€ãå€ã®ãŸãŸå³è¿ããæŽæ°ã¯ããã¯ã°ã©ãŠã³ãã®åããã»ã¹ã«æããŠèªåã¯åŸ ããªããã¹ããŒã¿ã¹ã©ã€ã³ã®ããã«ãæ¯ååæã§åŒã°ãããé å»¶ã¯èš±ãããªããå Žæã§ã¯ããã®éåæãªãã¬ãã·ã¥ãã»ãŒå¿ é ã®åã§ããã
åå©çšã§ããæå°çïŒclaude-limits-segment.sh
statusline.shã¯ãããžã§ã¯ãåºæã®å¥å
šæ§è¡šç€ºãŸã§æ±ããŠããŠéãã®ã§ãæ®éã»ã°ã¡ã³ãã ãã仿ïŒå¥ã®ããã³ãã衚瀺ãtmuxãªã©ïŒã«åã蟌ã¿ããæã®ããã«ãåããã£ãã·ã¥JSONãèªãã ãã®51è¡ã®ç¬ç«ã¹ã¯ãªããã眮ããŠããŸããå
šæã³ããã§åããŸãã
#!/usr/bin/env bash
set -euo pipefail
STATUS_JSON="${CLAUDE_STATUSLINE_JSON:-/tmp/cc-statusline-last.json}"
if [ ! -s "$STATUS_JSON" ]; then
printf 'ð 5h -- · ð
7d --'
exit 0
fi
age=$(( $(date +%s) - $(stat -f %m "$STATUS_JSON" 2>/dev/null || echo 0) ))
jq_field() {
jq -r "$1 // empty" "$STATUS_JSON" 2>/dev/null
}
pct() {
local v="$1"
if [ -n "$v" ]; then
printf '%.0f%%' "$v"
else
printf -- '--'
fi
}
h5=$(jq_field '.rate_limits.five_hour.used_percentage')
h5r=$(jq_field '.rate_limits.five_hour.resets_at')
d7=$(jq_field '.rate_limits.seven_day.used_percentage')
d7r=$(jq_field '.rate_limits.seven_day.resets_at')
stale=''
[ "$age" -gt 600 ] && stale='*'
printf 'ð 5h %s' "$(pct "$h5")"
[ -n "$h5r" ] && printf ' âª%s' "$(date -r "$h5r" '+%H:%M' 2>/dev/null)"
printf ' · ð
7d %s' "$(pct "$d7")"
[ -n "$d7r" ] && printf ' âª%s' "$(date -r "$d7r" '+%-m/%-d %H:%M' 2>/dev/null)"
printf '%s' "$stale"
statusline.shã/tmp/cc-statusline-last.jsonã«æ¯ã¿ãŒã³æžãåºããŠããçJSONããå¥ããã»ã¹ããèªãã ãã®èšèšã§ããage -gt 600ïŒ10å)ã§æ«å°Ÿã«*ãä»ããŠãããã¯å€ãããŒã¿ã§ããããšèŠåããã®ããå®ã¯æ¬äœã®statusline.shã«ã¯ãªãæ°é
ãã§ãïŒæ¬¡ã®èœãšã穎ã§è§ŠããŸãïŒã
èžãã èœãšã穎
automation-health.shãåæã§åŒãã ã78ç§åºãŸã â 5åãã£ãã·ã¥ïŒããã¯ã°ã©ãŠã³ãèµ·åãåœã¿ãŒã³ã¯Â·ãè¿ãrate_limitsã¯ååAPIå¿çãŸã§ååšããªã â 空å€ãªãäŸå€ã«ããpct()ã§--ã«ãã©ãŒã«ããã¯automation-health.shèªèº«ãå€éèµ·åã¬ãŒãïŒmkdirããã¯ïŒãæã€ â statuslineåŽã®è£èµ·åãšcron宿å®è¡ãè¡çªãããš"å¥ã€ã³ã¹ã¿ã³ã¹çšŒåäžã®ããã¹ããã"ã§exit 0ã«ãªããçµæãæŸããâ«ïŒäžæïŒã5åãã£ãã·ã¥ããŠããŸãstat -f %mã¯BSD/macOSå°çšæ§æ â Linuxã«æã£ãŠãããš|| echo 0ã®ãã©ãŒã«ããã¯ãåžžã«çºåãããã£ãã·ã¥ã®å¹Žéœ¢èšç®ãå£ããŠæ¯åâæéåãâæ±ãã«ãªãïŒãšã©ãŒã¯åºãªãã®ã§æ°ã¥ãã«ããïŒ- æ¬äœã®
statusline.shã¯stdinã空ã§ãé»ã£ãŠå€ãJSONã«ãã©ãŒã«ããã¯ãç¶ãã鮮床èŠåããªã â å°ããæ¹ã®claude-limits-segment.shã ããage -gt 600ã§*ãåºãã2æ¬ãæ¯ã¹ãŠåããŠéå¯Ÿç§°ã«æ°ã¥ãã
ãŸãšã
settings.jsonã®statusLine.commandã«æããJSONã«ã¯ãèªèšŒãAPIåŒã³åºãããªãã§æ®éã»ã³ã³ããã¹ã%ã»èª²éé¡ãå šéšä¹ã£ãŠãã- è²åãã¯
pcolor()1颿°ããããå€ã¯ç·50%æªæºã»é»50ã79%ã»èµ€80%以äžã ãã®ã·ã³ãã«èšèš - **78ç§ãããéããã«ã¹ãã§ãã¯ã¯ã5åãã£ãã·ã¥ïŒããã¯ã°ã©ãŠã³ãèµ·åã§ãåœã¿ãŒã³ã¯å€ãå€ãå³è¿ãã**ã«åããšãäœæã³ã¹ãã¯ãã¡ã€ã«readã ãã«ãªã
- åããã£ãã·ã¥JSONãèªãã ãã®å°ããã¹ã¯ãªãããåé¢ããŠãããšãä»ã®å Žæãžã®åã蟌ã¿ã䜿ãåããå¹ã
- 2æ¬ã®ã¹ã¯ãªãããæ¯ã¹ããšãçæ¹ã«ãããªã鮮床èŠåã®ãããªéå¯Ÿç§°ã«æ°ã¥ãããåãããŒã¿ãèªãå®è£ ã¯è€æ°æžããŠçªãåãããã®ãå°å³ã«å¹ã
次åã¯ããã®ãã£ãã·ã¥å±€ãããäžæ®µæãäžããŠãããã¯ã°ã©ãŠã³ãæŽæ°ãéãªã£ããšãã®ç«¶åãã©ã朰ããããæžãäºå®ã§ãã
LilyïŒ@bokuwalilyïŒâ å人éçºè ãClaude Code ã§èªåååºç€ãçµã¿ãªãããiOSã¢ããªãWebãµãŒãã¹ãéç£ããŠããŸã
- AIã§ãå¯ãŠãŠãåãä»çµã¿ããäœã£ãŠæ120äžã«ãã話㯠noteã®ææèšäº ã«ð°
- OSS: github.com/bokuwalily ð
- ææ°æ å ±ã»ãåãåãã㯠X @bokuwalily ãžð
- AIå°å ¥ã»èªååã®çžè«ãšå®è£ ãã³ãã¬7æ¬ã®é åžã¯ å ¬åŒLINE ããð¬
çããã® â€ïž ãã·ã§ã¢ãå±ã¿ã«ãªããŸãïŒ