클로드 코드 Statusline — 터미널 하단에 실시간 대시보드를 깔아두는 법

클로드 코드 Statusline

클로드 코드로 긴 작업 돌리다 보면 습관적으로 `/cost` 치게 되잖아요. 컨텍스트 윈도우 얼마나 썼나, 비용은 지금 얼마나 나갔나. 그때마다 작업 흐름이 끊기더라고요. `/model`까지 확인하면 이미 3초는 날아간 뒤예요.

Statusline은 이 정보를 터미널 맨 아래에 항상 띄워두는 기능이에요. 셸 스크립트 하나 짜두면 컨텍스트 사용률, 비용, Git 브랜치 같은 걸 실시간 대시보드처럼 볼 수 있어요. API 토큰도 안 쓰고요. 한번 설정하면 /cost를 다시 칠 일이 없어져요.

셸 스크립트 하나가 stdin으로 JSON을 받는다

동작 원리가 단순해요. 클로드 코드가 세션 데이터를 JSON 형태로 스크립트의 stdin에 넘기고, 스크립트가 필요한 정보를 뽑아 stdout으로 출력하면 화면 하단에 나타나요. 끝.

스크립트가 다시 실행되는 타이밍은 세 가지 — 어시스턴트 응답 직후, 권한 모드 변경, vim 모드 토글. 빠르게 연속으로 바뀌면 300ms 디바운스가 걸려서 깜빡임 없이 갱신돼요. 로컬에서 실행되니까 API 토큰을 소비하지도 않고요.

가장 편한 첫 설정법은 `/statusline` 명령어예요. 자연어로 원하는 걸 설명하면 Claude가 스크립트를 자동 생성해줘요.

``` /statusline 모델 이름이랑 컨텍스트 사용률을 프로그레스 바로 보여줘 ```

이렇게 치면 `~/.claude/` 디렉토리에 스크립트 파일이 생기고 settings.json도 자동으로 업데이트돼요. 필요 없어지면 `/statusline delete`로 깔끔하게 제거할 수 있고요.

직접 작성하고 싶다면 settings.json에 `statusLine` 필드를 추가하면 됩니다.

```json { "statusLine": { "type": "command", "command": "~/.claude/statusline.sh", "padding": 2 } } ```

`type`은 현재 `"command"`만 지원하고, `command`에는 실행할 스크립트 경로나 인라인 명령어를 넣어요. `padding`은 좌우 여백을 문자 단위로 지정하는 선택 옵션. 한 줄짜리 인라인 명령어로도 가능해요.

```json { "statusLine": { "type": "command", "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'" } } ```

간단한 정보만 표시할 때는 파일 하나 덜 관리해도 되니까 이쪽이 편해요. 조건 분기나 색상이 필요해지면 그때 스크립트 파일로 분리하는 게 낫고요.

컨텍스트부터 비용까지 — 쓸 수 있는 JSON 필드 총정리

클로드 코드가 넘겨주는 JSON에 들어 있는 필드가 꽤 다양하더라고요.

가장 기본적인 건 모델과 워크스페이스 정보. `model.display_name`으로 현재 모델명을, `workspace.current_dir`로 작업 디렉토리를 확인할 수 있어요.

아마 가장 자주 쓰게 될 필드는 컨텍스트 윈도우 관련이에요. `context_window.used_percentage`로 사용률을 가져오고, `context_window.context_window_size`로 전체 크기(기본 200k, 확장 시 1M)도 확인돼요. `context_window.remaining_percentage`는 남은 비율을 미리 계산해주니까 스크립트에서 산수할 필요가 없어요.

비용 추적도 됩니다. `cost.total_cost_usd`가 세션 누적 비용, `cost.total_duration_ms`가 세션 총 경과 시간. `cost.total_lines_added`와 `cost.total_lines_removed`로 이 세션에서 코드를 얼마나 수정했는지까지 볼 수 있어요.

Claude.ai Pro/Max 구독자라면 rate limit 필드도 활용할 수 있고요. `rate_limits.five_hour.used_percentage`로 5시간 롤링 윈도우 사용률을, `rate_limits.seven_day.used_percentage`로 7일 사용률을 확인하면 돼요.

그 외에 `session_id`, `version`, `vim.mode`, `agent.name`, `worktree.branch`, `worktree.path` 같은 필드도 있어요.

주의할 점 하나. 첫 번째 API 호출 전에는 일부 필드가 `null`일 수 있어요. jq에서 `// 0` 같은 폴백 처리를 꼭 넣어줘야 빈 화면이 뜨는 걸 막을 수 있거든요.

프로그레스 바에서 멀티라인 대시보드까지 — 실전 예제 5가지

가장 인기 있는 형태는 모델 이름과 컨텍스트 사용률을 프로그레스 바로 보여주는 거예요.

```bash #!/bin/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%" ```

출력 결과는 `[Claude 4.6 Opus] ▓▓░░░░░░░░ 25%`. 간단하지만 컨텍스트가 차오르는 걸 시각적으로 바로 알 수 있어서 꽤 실용적이에요. Python이 편하다면 jq 없이도 되는 Python 버전도 가능하고요.

Git 상태까지 보고 싶으면 ANSI 이스케이프 코드로 색상을 넣을 수 있어요. 스테이징된 파일은 초록색 `+`로, 수정된 파일은 노란색 `~`로 표시하는 식이죠. 근데 여기서 git 명령어에 `-C "$DIR"`을 붙여야 하는 이유가 있어요. statusline 스크립트는 클로드 코드의 작업 디렉토리가 아닌 별도 환경에서 실행될 수 있거든요. 디렉토리를 명시 안 하면 엉뚱한 결과가 나옵니다.

API 요금제 사용자라면 비용과 시간 추적 버전이 필수예요.

``` [Claude 4.6 Opus] $1.37 | 12m 34s ```

Opus 같은 고성능 모델로 긴 작업을 할 때 비용이 실시간으로 보이니까 모델 전환 타이밍을 잡기 좋아요. (솔직히 $5 넘어가는 거 보면 좀 무섭잖아요.)

`echo`를 여러 번 호출하면 멀티라인이 돼요. 이걸 활용하면 첫째 줄에 모델과 Git 정보, 둘째 줄에 컨텍스트 바와 비용을 배치한 종합 대시보드를 만들 수 있어요. 컨텍스트 사용률이 70%를 넘으면 노란색, 90%를 넘으면 빨간색으로 바뀌니까 컨텍스트 부족해지기 전에 대응할 수 있고요.

Pro/Max 구독자라면 rate limit 모니터링도 추가할 수 있어요. 5시간 윈도우와 7일 윈도우 사용률을 함께 표시하는 건데, `rate_limits` 필드는 Pro/Max 구독자의 첫 API 응답 이후에만 나타나요. `// empty`로 빈 값 처리를 해줘야 하고, API 요금제 사용자에게는 아예 없으니까 자연스럽게 모델 이름만 표시됩니다.

Git 느린 저장소에서 캐싱으로 지연 줄이기

Git 명령어는 큰 저장소에서 느려질 수 있어요. statusline이 매번 `git diff`를 돌리면 응답이 끝날 때마다 살짝 지연이 생기거든요. 모노레포 같은 대규모 저장소에서 특히요.

해법은 캐싱. `/tmp/statusline-git-cache` 파일에 Git 정보를 저장하고 5초마다 갱신하는 거예요. 5초 사이에 업데이트가 여러 번 일어나도 캐시된 값을 쓰니까 Git 명령어를 반복 실행하지 않아요.

```bash CACHE_FILE="/tmp/statusline-git-cache" CACHE_MAX_AGE=5

cache_is_stale() { [ ! -f "$CACHE_FILE" ] || \ [ $(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0))) -gt $CACHE_MAX_AGE ] } ```

캐시가 5초보다 오래됐으면 갱신하고, 아니면 기존 값을 그대로 쓰는 구조. 단순한데 효과 확실해요.

statusline 안 보일 때 확인할 것들

설정했는데 아예 안 나타나는 경우, 체크 리스트가 있어요.

먼저 스크립트 실행 권한. `chmod +x ~/.claude/statusline.sh`를 빠뜨리기 쉬워요. 스크립트가 stderr가 아닌 stdout으로 출력하는지도 봐야 하고요. 설정에서 `disableAllHooks`가 `true`로 되어 있으면 statusline도 함께 비활성화되니까 이것도 체크. 그래도 안 되면 `claude --debug`로 에러 메시지를 확인해보면 돼요.

값이 `--`나 빈칸으로 나오는 건 대부분 첫 API 호출 전이라 필드가 `null`인 상태예요. 폴백만 넣으면 해결.

ANSI 컬러 코드가 그대로 보이면 `echo -e` 대신 `printf '%b'`를 써보세요. 터미널에 따라 이스케이프 시퀀스 처리가 다르거든요. macOS 기본 Terminal.app은 OSC 8 링크를 지원하지 않으니까 iTerm2나 Kitty, WezTerm 쓰는 게 좋습니다.

workspace trust도 빠뜨리기 쉬운 부분이에요. statusline은 hooks와 마찬가지로 workspace trust를 승인한 디렉토리에서만 동작해요. `statusline skipped · restart to fix` 알림이 보이면 trust 다이얼로그를 다시 확인해보세요.

클로드 코드 없이 독립 테스트도 된다

스크립트 수정할 때 매번 클로드 코드를 재시작하기 귀찮잖아요. JSON을 파이프로 넘기면 독립적으로 테스트할 수 있어요.

```bash echo '{"model":{"display_name":"Opus"},"context_window":{"used_percentage":42},"cost":{"total_cost_usd":0.73,"total_duration_ms":180000}}' | ~/.claude/statusline.sh ```

새 필드를 추가하거나 조건문을 바꿀 때 반복 작업이 훨씬 빨라져요.

결국 작은 기능인데, 한번 설정하면 생각보다 자주 쳐다보게 돼요. 컨텍스트 사용률이 빨간색으로 바뀌면 새 세션 타이밍이고, 비용 올라가는 거 보이면 모델 바꿔볼까 싶어지고, Git 브랜치가 항상 보이니까 엉뚱한 브랜치에서 작업하는 실수도 줄어들고요. 처음에는 컨텍스트 진행 바 하나만 넣어보세요. 뭐가 더 보고 싶은지는 쓰다 보면 알게 됩니다.