Claude Code Status Line 커스터마이징 — 세션 정보를 터미널에 항상 띄우는 법
솔직히 Claude Code를 처음 쓸 때 가장 불안했던 건 "지금 컨텍스트를 얼마나 쓰고 있지?", "비용이 얼마나 나가고 있지?" 같은 것들이었습니다. /usage 명령어를 수시로 치는 건 작업 흐름을 끊기도 하고, 뭔가 대시보드처럼 항상 보이면 좋겠다는 생각이 들었죠. 그러다 발견한 게 Status Line(상태줄) 기능입니다.
Claude Code의 상태줄은 터미널 하단에 항상 떠 있는 정보 바인데, 핵심은 셸 스크립트 하나만 등록하면 모델명, 컨텍스트 사용률, 누적 비용, Git 상태까지 원하는 정보를 실시간으로 볼 수 있다는 점입니다. API 토큰도 소비하지 않고, 로컬에서 돌아가니 추가 비용 걱정도 없습니다. 글을 따라하면 5분 안에 터미널 하단에 모델명·비용·컨텍스트가 실시간으로 뜨는 나만의 대시보드를 만들 수 있습니다.
이 글은 macOS/Linux 환경 기준으로 작성되었습니다. Windows 사용자는 WSL 환경에서 동일하게 적용할 수 있습니다.
완성된 상태줄은 이런 모습입니다:
📦 Claude Sonnet 4.6 | 📊 42% | 💰 $1.37 | 📁 my-project핵심 개념
동작 원리: stdin → 처리 → stdout 파이프라인
상태줄의 아키텍처는 놀라울 정도로 단순합니다. ~/.claude/settings.json에 셸 명령어를 등록해두면, Claude Code가 특정 이벤트가 발생할 때마다(어시스턴트 메시지 완료, 권한 모드 변경, 도구 호출 완료 등) 그 명령을 실행하면서 현재 세션 상태를 JSON으로 stdin에 파이프합니다. 스크립트가 stdout으로 뱉는 문자열이 그대로 터미널 하단에 렌더링되는 구조입니다.
셸 스크립팅에 익숙하지 않은 분들을 위해 간단히 정리하면 — stdin은 프로그램이 입력을 받는 통로, stdout은 출력을 내보내는 통로입니다. 여기서는 Claude Code가 JSON 데이터를 stdin으로 넣어주면, 스크립트가 그걸 가공해서 stdout으로 출력하는 겁니다. 리눅스의 파이프(
|) 개념과 동일합니다.
설정 파일의 전체 구조에서 statusLine이 어디에 위치하는지 먼저 보겠습니다:
{
"permissions": {
"allow": ["Read"],
"deny": []
},
"statusLine": {
"type": "command",
"command": "sh ~/.claude/statusline.sh",
"refreshInterval": 5,
"padding": 0
}
}statusLine은 settings.json의 최상위 키입니다. 각 옵션을 정리하면:
| 옵션 | 설명 |
|---|---|
type |
현재는 "command"만 지원 |
command |
실행할 셸 명령어 또는 스크립트 경로 |
refreshInterval |
초 단위 주기적 갱신 간격. 미설정 시 이벤트 기반으로만 갱신 |
padding |
상태줄 텍스트 좌우에 추가되는 공백 수. 0이면 꽉 차게, 숫자를 늘리면 여백이 생김 |
refreshInterval은 이벤트와 무관하게 N초마다 상태줄을 강제 갱신합니다. 장시간 도구 실행 중에도 최신 정보를 유지하고 싶다면 5~10초 정도로 설정하면 됩니다. 미설정 시에는 도구 호출 완료, 어시스턴트 응답 완료, 권한 변경 같은 이벤트가 발생할 때만 갱신됩니다.
stdin으로 들어오는 JSON 구조
스크립트가 받는 JSON에는 생각보다 풍부한 정보가 담겨 있습니다.
| 필드 | 내용 |
|---|---|
model.display_name |
현재 사용 중인 모델명 |
context_window.used_percentage |
컨텍스트 윈도우 사용률 (%) |
context_window.remaining_percentage |
남은 컨텍스트 비율 |
cost.total_cost_usd |
세션 누적 비용 (USD) |
cost.total_lines_added / removed |
추가/삭제된 라인 수 |
workspace.current_dir |
현재 작업 디렉토리 |
workspace.git_worktree |
Git worktree 경로 |
rate_limits.five_hour.used_percentage |
5시간 기준 API 사용률 |
rate_limits.seven_day.used_percentage |
7일 기준 API 사용률 |
rate_limits.*.resets_at |
리셋 시간 (ISO 8601 형식, 예: 2026-04-20T15:30:00Z) |
session_id |
현재 세션 식별자 |
version |
Claude Code 버전 |
먼저 직접 확인해보기
본격적인 스크립트를 작성하기 전에, 실제로 어떤 JSON이 들어오는지 눈으로 확인하는 게 훨씬 이해가 빠릅니다. 아래 설정으로 stdin 내용을 파일에 덤프해볼 수 있습니다:
{
"statusLine": {
"type": "command",
"command": "tee /tmp/claude-status.json | cat"
}
}설정 후 Claude Code를 재시작하고, 한두 번 대화를 나눈 뒤 cat /tmp/claude-status.json으로 확인하면 실제 JSON 구조를 볼 수 있습니다. 이렇게 한 번 직접 보고 나면 이후 스크립트 작성할 때 어떤 필드를 어떻게 꺼내 쓸지 감이 잡힙니다.
/statusline — 자연어로 바로 생성하기
스크립트 작성이 부담스럽다면 Claude Code 내에서 /statusline 명령을 쓸 수 있습니다. 자연어로 원하는 정보를 설명하면 스크립트 생성과 settings.json 등록까지 자동으로 처리해줍니다.
/statusline 모델명, 컨텍스트 사용률 프로그레스 바, 비용, Git 브랜치를 보여줘이 한 줄이면 바로 동작하는 상태줄이 만들어집니다. 나중에 세부 조정이 필요할 때 생성된 스크립트를 직접 수정하면 되니, 진입점으로는 최고입니다.
실전 적용
예시 1: Bash 스크립트로 핵심 정보 한 줄에 담기
가장 기본적이면서도 실용적인 구성입니다. JSON 파싱 도구인 jq만 설치되어 있으면 바로 쓸 수 있습니다. (jq는 JSON 데이터를 터미널에서 필터링·추출하는 경량 도구로, brew install jq 또는 apt install jq로 설치할 수 있습니다.)
#!/bin/bash
# ~/.claude/statusline.sh
INPUT=$(cat)
# jq를 한 번만 호출해서 필요한 값을 모두 추출
read -r MODEL CTX COST DIR <<< $(echo "$INPUT" | jq -r '[
.model.display_name,
(.context_window.used_percentage | tostring),
(.cost.total_cost_usd | tostring),
(.workspace.current_dir | split("/") | last)
] | @tsv')
printf "📦 %s | 📊 %.0f%% | 💰 $%.2f | 📁 %s" "$MODEL" "$CTX" "$COST" "$DIR"| 라인 | 역할 |
|---|---|
INPUT=$(cat) |
stdin으로 들어온 JSON 전체를 변수에 저장 |
jq -r '[...] | @tsv' |
필요한 필드를 한 번의 jq 호출로 탭 구분 추출 |
read -r ... <<< $(...) |
추출된 값을 각 변수에 할당 |
printf |
이모지와 함께 포맷팅된 문자열을 stdout으로 출력 |
처음에는
jq를 필드마다 따로 호출하는 방식으로 작성했었는데, 매번 JSON을 파싱하는 건 낭비라는 걸 나중에 깨달았습니다. 위처럼 한 번의jq호출로 여러 값을 뽑으면 성능도 좋고 코드도 깔끔해집니다.
설정 후 chmod +x ~/.claude/statusline.sh를 잊지 않으면 됩니다(이거 빼먹어서 10분 날린 적 있습니다).
예시 2: Rate Limit 경고 시각화
Max 플랜이나 팀 플랜에서 API 한도에 근접하면 당황스러운데, 이걸 상태줄에서 미리 감지할 수 있습니다.
#!/bin/bash
INPUT=$(cat)
read -r FIVE_HR RESETS <<< $(echo "$INPUT" | jq -r '[
(.rate_limits.five_hour.used_percentage | tostring),
.rate_limits.five_hour.resets_at
] | @tsv')
if (( $(echo "$FIVE_HR > 80" | bc -l) )); then
ICON="🔴"
elif (( $(echo "$FIVE_HR > 60" | bc -l) )); then
ICON="🟡"
else
ICON="🟢"
fi
printf "%s Rate: %.0f%% | Reset: %s" "$ICON" "$FIVE_HR" "$RESETS"이 스크립트는
bc명령어에 의존합니다. macOS에는 기본 포함되어 있지만, 일부 최소화된 Linux 이미지(Alpine 등)에서는apk add bc같은 별도 설치가 필요할 수 있습니다.
80%를 넘으면 빨간 원으로 바뀌니, 작업 속도를 조절하거나 잠시 쉬어갈 타이밍을 직관적으로 알 수 있습니다. 여기서는 ANSI 이스케이프 코드 대신 이모지를 사용했는데, Claude Code 상태줄에서 ANSI 색상 코드가 렌더링되는지는 터미널 환경에 따라 다를 수 있기 때문입니다. 이모지 방식이 호환성 면에서 더 안전합니다.
예시 3: ccstatusline으로 Powerline 스타일 적용
직접 스크립트를 관리하기 싫고 예쁜 UI를 원한다면 커뮤니티 도구를 활용하는 것도 좋습니다.
{
"statusLine": {
"type": "command",
"command": "ccstatusline"
}
}ccstatusline은 Powerline 화살표 구분자, 빌트인 테마, 토큰 속도 위젯까지 지원합니다. ccstatusline config 명령으로 인터랙티브하게 설정할 수 있어서, 터미널 꾸미기를 좋아하는 분들에게 특히 추천합니다.
주의:
npx -y ccstatusline@latest로 설정하면 매 실행마다 패키지 다운로드 여부를 확인하기 때문에refreshInterval과 결합하면 눈에 띄게 느려질 수 있습니다.npm install -g ccstatusline으로 글로벌 설치한 뒤 위처럼"command": "ccstatusline"으로 직접 호출하는 게 훨씬 빠릅니다.
Powerline 폰트란 터미널에서 화살표형 구분자(, )를 렌더링하기 위한 특수 폰트입니다. Nerd Fonts나 MesloLGS NF 같은 폰트를 설치하면 지원됩니다.
예시 4: 프로젝트별 설정 분리
전역 설정은 ~/.claude/settings.json에, 프로젝트 특화 설정은 프로젝트 루트의 .claude/settings.json에 두면 됩니다. 실무에서 자주 맞닥뜨리는 상황인데, 예를 들어 모노레포에서는 worktree 정보를 강조하고, 개인 프로젝트에서는 비용 중심으로 보는 식의 분리가 가능합니다.
my-project/
├── .claude/
│ └── settings.json # 프로젝트 전용 상태줄
│ └── statusline.sh # 프로젝트 전용 스크립트
├── src/
└── ...
~/.claude/
├── settings.json # 전역 기본 상태줄
└── statusline.sh # 전역 기본 스크립트프로젝트 루트에 .claude/settings.json이 있으면 해당 설정이 전역 설정을 덮어쓰게 됩니다. 모노레포에서 여러 worktree를 오가며 작업할 때, 각 프로젝트에 맞는 정보가 자동으로 전환되니 컨텍스트 스위칭 비용이 크게 줄어듭니다.
장단점 분석
장점
| 항목 | 내용 |
|---|---|
| API 토큰 미소비 | 로컬에서 실행되어 추가 비용이 전혀 없음 |
| 완전한 자유도 | 셸에서 실행 가능한 모든 것을 표시 가능 — 시스템 리소스, 외부 서비스 상태 등 |
| 낮은 진입 장벽 | /statusline 명령으로 자연어 한 줄이면 즉시 생성 |
| 풍부한 세션 데이터 | 모델, 컨텍스트, 비용, rate limit, workspace 정보를 JSON으로 제공 |
| 커뮤니티 생태계 | Bash, Go, Rust, Node.js, Python 등 다양한 구현체를 바로 가져다 쓸 수 있음 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| Stale 데이터 | refreshInterval 미설정 시 장시간 작업 중 갱신 안 됨 |
"refreshInterval": 5 설정 |
| 외부 의존성 | jq, Node.js, bc 등이 설치되어 있어야 함 | 스크립트 상단에 command -v jq >/dev/null 같은 체크 로직 추가 |
| 터미널 호환성 | ANSI 코드, Powerline 폰트 지원이 터미널마다 다름 | 이모지 기반 fallback 준비 |
| 성능 이슈 | 무거운 외부 명령 호출 시 지연 발생 | 결과를 임시 파일에 캐싱하고 refreshInterval을 30초 이상으로 늘리거나, ccstatusline의 block timer cache 활용 |
실무에서 캐싱이 구체적으로 어떻게 동작하냐면, 외부 API 호출 결과를 /tmp/claude-cache.txt에 저장하고 파일의 수정 시각이 N초 이내면 캐시된 값을 쓰는 식입니다. 이렇게 하면 상태줄 갱신 주기와 무거운 연산 주기를 분리할 수 있습니다.
실무에서 가장 흔한 실수
chmod +x빠뜨리기 — 스크립트 작성 후 실행 권한을 안 주면 아무것도 표시되지 않습니다. 에러 메시지도 없어서 원인 찾기가 은근 어렵습니다.- jq 미설치 상태에서 Bash 스크립트 실행 — macOS에도 기본 설치되어 있지 않은 경우가 있어
brew install jq가 필요합니다. 리눅스에서는apt install jq또는yum install jq로 설치할 수 있습니다. - refreshInterval 없이 "왜 안 바뀌지?" 고민하기 — 기본은 이벤트 기반 갱신이라, 도구가 실행되고 있는 동안에는 업데이트가 안 됩니다. 주기적 갱신이 필요하면 반드시 설정에 추가하면 됩니다.
마치며
Claude Code 상태줄은 "셸 스크립트 하나 = 나만의 실시간 대시보드"라는 단순한 공식으로, 세션 상태의 가시성을 크게 높여주는 기능입니다. 비용 초과 자체를 막아주지는 않지만, 지금 어디쯤 있는지 항상 눈에 보인다는 것만으로도 안정감이 꽤 다릅니다.
지금 바로 시작해볼 수 있는 3단계:
- Claude Code를 열고
/statusline 모델명, 컨텍스트 사용률, 비용을 보여줘를 입력해봅니다. 가장 빠르게 상태줄을 경험할 수 있는 방법입니다. - 생성된
~/.claude/statusline.sh파일을 열어보고, 본문의 Rate Limit 예시처럼 자신에게 필요한 정보를 추가해봅니다.~/.claude/settings.json에"refreshInterval": 5도 넣어두면 좋습니다. - 기본 스크립트가 익숙해지면 ccstatusline 같은 커뮤니티 도구를 시도하거나, 프로젝트별
.claude/settings.json으로 상황에 맞는 상태줄을 분리 구성해봅니다.
참고 자료
핵심 문서
- Customize your status line — Claude Code 공식 문서
- Creating The Perfect Claude Code Status Line | AI Hero
- ccstatusline GitHub
추가 참고
- Building a Custom Claude Code Statusline to Track Worktrees and Usage | Dan Does Code
- ClaudeCodeStatusLine GitHub
- claude-statusline (Go) 블로그
- claude-code-status-line (Rust) — crates.io
- I Replaced /usage and /context with a Single Statusline — DEV Community
- Custom status lines for Claude Code | PhotoStructure
- How to Customize Your Claude Code Status Line | alexop.dev