본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 05. 12:38

Claude Code의 상태 표시줄(Status Line)을 직접 제작했다: effort, 사용량 게이지, 응답 1회당 API 처리 시간을 한

요약

Claude Code의 기본 푸터 정보를 보완하기 위해 effort, 사용량 게이지, API 응답 시간을 표시하는 커스텀 상태 표시줄(Status Line) 제작 방법을 소개합니다. Node.js를 활용하여 세션 상태 JSON을 가공하고, 구현 과정에서 마주친 데이터 누락 및 턴 경계 판정 문제를 해결하는 기술적 노하우를 다룹니다.

핵심 포인트

  • Claude Code의 settings.json을 활용한 커스텀 상태 표시줄 구현
  • 계약 플랜 정보는 .credentials.json에서 별도로 추출 필요
  • 응답당 처리 시간은 누적값의 차분 방식을 통해 계산
  • 도구 실행 결과와 실제 사용자 발화를 구분하는 정교한 턴 판정 로직 필요

Claude Code의 기본 푸터(Footer)는 정보가 적다. "지금의 effort는?", "5시간 할당량 중 얼마나 남았지?", "방금 응답은 몇 초 동안 생각한 거지?" —— 이 모든 것을 한 줄에 표시하는 상태 표시줄(Status Line)을, Claude Code 자신에게 요구 사항을 전달하며 만들게 했다 (AI에게 측정기를 만들게 하여 AI를 측정하는 구도).

최종 형태:

⚡ Opus 4.8 │ 💎 Max │ 🧠 xHigh │ ⏱ 12.4s │ 📊 5시간[████░░░░░░]사용35% 3h後 · 7日間[█░░░░░░░░░]사용8% 5d後

원리는 간단하다. settings.jsonstatusLine 명령어를 등록하면, Claude Code가 세션 상태의 JSON을 stdin(표준 입력)으로 흘려보내 주기 때문에, Node.js로 이를 정형화하여 stdout(표준 출력)으로 반환하기만 하면 된다. 다만, 구현 과정에서 "그렇게 간단하지 않은" 포인트가 3가지 있었다.

참고로 이것은 ~/.claude/settings.json에 연결된 Claude Code 본체의 기능이므로, 터미널 환경을 가리지 않는다. VS Code, Cursor, JetBrains 등 IDE의 통합 터미널에서 실행하든, Windows Terminal 단독으로 실행하든 동일한 상태 표시줄이 표시된다 (설정은 한 번만 하면 된다).

귀찮은 분들을 위해: Claude Code에게 시키는 프롬프트

내용에 관심이 없다면, Claude Code에게 다음과 같이 던지면 비슷한 결과물이 나온다. 단, 출력의 완성도는 보장할 수 없다 (LLM의 출력은 매번 달라진다). 동작 확인은 필수이며, 한 번에 완성을 노리기보다 나온 결과물에 요구 사항을 거듭하며 키워 나가는 것이 현실적이다 (필자도 2번의 세션을 거쳐 완성했다).

Claude Code의 상태 표시줄(Status Line)을 직접 만들고 싶어. 의존성 패키지가 없는 Node.js 스크립트
(~/.claude/statusline/usage-statusline.js)를 작성하고, settings.json에 등록하는 것까지 해줘.
요구 사항:
...

빠지기 쉬운 함정 1: 원하는 정보의 절반은 stdin에 없다

stdin의 JSON에는 model, cost, effort.level, rate_limits ( /usage 와 동일한 공식 사용량!)가 들어 있다. 반면 계약 플랜 (Max/Pro)은 어디에도 없다.

~/.claude/.credentials.jsonsubscriptionType만 읽어서 해결 ( 액세스 토큰에는 일절 건드리지 않는다. 읽는 것은 플랜 이름 문자열뿐이다).

빠지기 쉬운 함정 2: 응답 1회당 처리 시간이 존재하지 않는다

cost.total_api_duration_ms세션 누적값이며, 트랜스크립트(Transcript)에도 요청당(per-request) 시간은 없다.

턴(Turn) 시작 시점의 누적값을 baseline으로 하여 state 파일에 저장하고, "현재 누적값 - baseline"을 표시하는 차분 방식으로 구현했다. state는 session_id 키로 분리하며, 데이터가 소실되었을 때는 "발화 수로 첫 번째 턴인지 판정하여 다시 측정하는" 안전장치를 넣었다.

빠지기 쉬운 함정 3: "사용자 발화" 판정이 함정이다

턴 경계는 트랜스크립트(JSONL)의 실제 사용자 발화로 검출하지만, 도구 실행 결과(Tool execution result)도 role: "user"로 기록된다. 게다가 서브 에이전트는 isSidechain, 시스템 주입은 isMeta이다. 이것들을 제외하지 않으면 턴 경계를 잘못 검출하게 된다.

function isRealUserPrompt(obj) {
if (obj.type !== 'user' || obj.isSidechain || obj.isMeta) return false;
const c = obj.message && obj.message.content;
...

설계에서 배운 점

  • 시간 표시를 처음에는 "프롬프트 전송 ~ 응답 완료까지의 실제 시간"으로 만들었으나, 도구 대기 시간이나 인간의 응답 대기 시간이 섞이기 때문에 API 처리 시간 기반으로 변경했다 ("Claude가 실제로 생각한 시간"만 나오도록).
  • 상태 표시줄은 이벤트 드리븐(Event-driven) 방식의 일회성 프로세스다. 트랜스크립트 전체를 읽는 것과 같은 무거운 처리는 한 번만 수행한다.
  • 데이터가 없는 세그먼트는 nullfilter(Boolean)를 통해 자동으로 제거한다.

전체 코드와 스키마는 풀 버전에서

stdin으로 전달되는 JSON 스키마의 실측 요약, usage-statusline.js

전체 코드(의존성 없는 Node.js 단일 파일), stdin에 JSON을 흘려보내는 테스트 방법, Git Bash의 경로 변환 등 Windows에서의 주의사항은 블로그의 풀 버전(Full version)에 정리해 두었습니다:

(이것은 Opus 4.8의 effort 레벨별 소비량을 실측하기 위한 프로젝트를 위해 만든 측정기로, 실측 편도 곧 공개될 예정입니다)

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0