클로드 코드(Claude Code) 상태 표시줄에 작업 진행률과 남은 시간 표시하기
클로드 코드 상태 표시줄에 작업 진행률과 남은 시간을 추정해 표시하는 플러그인 제작 사례입니다. 컨텍스트 비율과 완료율의 차이, 과거 127개 세션의 오차, 설치 후 확인과 복구 방법을 설명합니다.

세 줄로 먼저 읽기
- 클로드 코드 상태 표시줄의 컨텍스트 비율은 작업 완료율과 다른 값이며 claude-code-eta 플러그인은 대화 기록의 도구 호출 수로 진행률과 남은 시간을 추정합니다.
- 세션 127개로 검증한 결과 중앙 오차는 56%였고 예측이 실제의 2배 안에 든 비율은 57%로 고정값 방식의 32%보다 높았습니다.
- 설치 명령 세 개는 한 줄씩 넣어야 하며 settings.json의 statusLine 백업이 생겼는지 봐 두면 이전 상태 표시줄로 되돌릴 수 있습니다.
클로드 코드 상태 표시줄은 작업 화면 아래에 모델이나 사용량 같은 정보를 띄우는 기능입니다. stdin은 프로그램이 데이터를 전달받는 표준 입력 통로입니다. 클로드 코드가 이 통로로 세션 정보를 보내면 별도 스크립트가 필요한 내용을 골라 표시합니다. 컨텍스트 사용량, 비용, git 브랜치를 띄우는 설정은 널리 쓰입니다. 그런데 정작 궁금한 정보 하나가 빠져 있습니다. 지금 돌아가는 작업이 언제 끝나는지입니다.
파일을 복사할 때는 남은 시간이 보입니다. 늘어나기도 하고 줄어들기도 하지만 기다릴지 다른 일을 할지 정하는 데는 충분합니다. 클로드 코드에 큰 리팩터링을 맡겼을 때 그 정보가 없으면 화면만 보고 있게 됩니다. 이 궁금증에서 시작해 상태 표시줄에 진행률과 남은 시간을 붙였고, 그 과정에서 측정한 것들을 정리했습니다.
위 화면의 42%는 컨텍스트, 즉 모델이 지금 참고하는 문맥이 얼마나 찼는지를 나타내는 비율이고, 작업 진행률과는 다른 값입니다. 이 글의 ETA는 Estimated Time of Arrival에서 온 표현으로, 여기서는 작업 완료까지 남은 예상 시간을 가리킵니다.
본문의 실측 수치는 2026년 8월 7일 제작 당시의 기록이고, 설치 조건과 기능 설명은 2026년 10월 4일 공식 문서와 프로젝트 코드 기준입니다.
클로드 코드 상태 표시줄이 받는 데이터와 갱신 방식
상태 표시줄에 무엇을 그릴 수 있는지는 클로드 코드가 무엇을 넘겨주는지에 달려 있습니다. JSON은 이름과 값을 짝지어 담는 데이터 형식이고, 공식 문서는 stdin으로 전달되는 JSON 필드를 공개합니다. 이번 사례에서 쓰는 값은 다음과 같습니다.
model.display_name: 현재 모델 이름context_window.used_percentage: 미리 계산된 컨텍스트 사용 비율cost.total_duration_ms: 세션이 실행된 총 시간, 재개한 구간은 합치고 실행되지 않은 기간은 뺌transcript_path: 대화 기록 파일의 경로session_id: 세션마다 고유한 식별자
이 가운데 마지막 두 개가 이번 작업의 출발점이 됐습니다. transcript_path가 가리키는 대화 기록 파일은 JSON을 한 줄씩 저장하는 JSONL 형식이며, 어떤 도구를 언제 호출했고 언제 결과가 돌아왔는지가 한 줄씩 남습니다. 남은 시간을 계산할 재료가 이미 내 컴퓨터에 다 있었습니다.
갱신 방식도 문서에 적혀 있습니다. 디바운스는 짧은 시간에 몰린 변화를 한 번으로 묶는 처리입니다.
상태 표시줄이 다시 그려지는 순서
1. 갱신 이벤트세션 시작이나
새 답변이 생김
2. 0.3초 묶기300밀리초 안의 변화를
한 번으로 묶음
3. 스크립트 실행stdin으로 받은 JSON에서
필요한 값을 읽음
4. 화면에 표시스크립트가 출력한 글자가
상태 표시줄에 뜸
0.3초마다 도는 타이머가 아니라, 변화가 있을 때만 이 순서로 실행됩니다. 여기에 중요한 제약이 하나 붙습니다.
스크립트가 여전히 실행 중인 동안 새 업데이트가 트리거되면 진행 중인 실행이 취소됩니다.
문서의 문제 해결 항목에는 느린 스크립트가 끝날 때까지 상태 표시줄 갱신이 막힌다는 설명도 있습니다. 상태 표시줄을 그리는 로컬 실행 자체는 API 토큰을 쓰지 않고, 스크립트에 별도 API 호출을 넣었다면 그 호출의 비용만 따로 듭니다. 대신 스크립트가 느리면 화면이 그만큼 늦게 바뀝니다. 이 제약은 뒤에서 실제 숫자로 이어집니다.
경과 시간에는 사용자 대기가 섞입니다
처음에는 단순하게 접근했습니다. 과거 기록에서 같은 스킬을 실행한 구간을 찾아 걸린 시간을 평균 내면 될 것 같았습니다. 세션 기록 전체를 훑어 측정한 결과는 이랬습니다.
| 스킬 | 실행 횟수 | 최소 | 최대 |
|---|---|---|---|
| 글쓰기 스킬 | 15회 | 1.2분 | 81.5분 |
| 문체 검수 스킬 | 10회 | 2.1분 | 72.6분 |
같은 작업인데 수십 배씩 벌어집니다. 당시 전체 스킬 집계에서는 같은 스킬의 최소와 최대가 166배까지 차이 났습니다.
원인은 다른 숫자에서 드러났습니다. 중앙값은 값을 작은 순서대로 놓았을 때 가운데 값입니다. 사용자에게 질문을 던지는 도구는 중앙값과 평균이 크게 달랐습니다.
사용자에게 질문하는 도구의 대기 시간
가운데 값은 1분보다 짧은데, 가끔 사람이 몇 시간씩 자리를 비운 시간이 평균에 그대로 들어갑니다. 클로드가 일한 시간이 아니라 사람이 답을 고민하거나 자리를 비운 시간이 통째로 섞여 있었습니다.
그래서 90초가 넘는 공백을 사용자 대기로 보고 뺐습니다. 이 90초는 경험으로 정한 기준이라, 오래 걸린 명령이나 네트워크 지연도 함께 빠질 수 있습니다. 대기를 뺀 뒤 구한 호출당 소요 시간은 다음과 같습니다.
| 스킬 | 당시 호출당 소요 집계 |
|---|---|
| 글쓰기 스킬 | 13.4초 |
| 문체 검수 스킬 | 13.0초 |
| 영상 편집 스킬 | 11.1초 |
위 숫자는 과거 여러 실행을 모아 구한 값입니다. 당시 전체 스킬의 호출당 소요 집계는 11초에서 23초 사이였고, 표는 그 가운데 세 사례입니다. 도구 호출은 파일 읽기나 명령 실행처럼 AI가 도구를 한 번 쓰는 일입니다. 기본 계산은 남은 호출 수에 호출당 시간을 곱하는 방식입니다.
진행률 = 지금까지 도구 호출 수 / 예상 총 호출 수
남은 시간 = (예상 총 호출 수 - 지금까지) × 호출당 소요 시간예를 들어 호출당 12초인 작업의 진행률과 남은 시간은 이렇게 바뀝니다.
예상 총 호출 수가 바뀌면 진행률도 바뀝니다
3회 / 10회진행률 30%
남은 시간 7 × 12 = 84초
5회 / 10회진행률 50%
남은 시간 60초
5회 / 20회예상 총량이 20회로 늘면
진행률이 25%로 내려감
세 번째처럼 진행률이 내려가는 것은 예상 총량이라는 분모가 커졌기 때문이고, 이미 한 파일 변경은 그대로 남아 있습니다.
진행률이 100%에서 멈추지 않게 만드는 조건부 분포
여기서 문제가 하나 더 나옵니다. 예상 총 호출 수를 과거 중앙값으로 고정하면, 작업이 그 수를 넘어가는 순간 진행률이 100%에 붙어 움직이지 않습니다. 실제로는 아직 한참 남았는데 화면에는 다 끝난 것처럼 표시됩니다.
해결 방법은 질문을 바꾸는 것이었습니다. 이 작업이 보통 몇 번에 끝나는지를 묻는 대신, 이미 20번 호출한 경우들이 몇 번에서 끝났는지를 과거 표본에서 다시 뽑습니다. 현재 조건을 만족하는 사례만 다시 보는 이 방식을 조건부 분포라고 합니다. 현재 코드는 중앙값을 그대로 쓰지 않고 분포의 45% 지점 같은 조정값을 씁니다.
호출 수가 예상을 넘었을 때 두 방식의 차이
| 상황 | ||
|---|---|---|
| 호출 수가 예상 총량을 넘음 | 100%에 붙어 멈춤 | 분모를 다시 키워 계속 움직임 |
| 오래 걸리는 작업의 예상 시간 | 처음 값 그대로 | 함께 늘어남 |
파일 복사는 전체 크기가 정해져 있지만, 클로드 코드의 작업은 총량이 정해져 있지 않습니다. 총 작업량 없이 진행률을 표시해야 한다는 점이 가장 큰 제약입니다.
작업이 끝나는 시점을 잡는 것도 따로 처리가 필요했습니다. 처음에는 다음 사용자 입력이 들어올 때 작업을 닫도록 만들었는데, 그러면 응답이 끝나고 입력을 기다리는 동안 진행률이 94% 같은 어중간한 값에 멈춰 있었습니다. 대화 기록에는 stop_reason이 end_turn으로 남는 순간이 있어서, 현재 코드는 end_turn이면서 추가 도구 호출이 없는 응답을 종료 신호로 씁니다. 이때의 100%는 그 응답 구간이 끝났다는 표시이고, 결과물이 맞는지는 따로 봐야 합니다.
위 이미지는 별도 프로젝트인 claude-hud의 화면입니다. 상태 표시줄 플러그인은 이처럼 여러 줄에 걸쳐 도구 활동까지 띄울 수 있습니다.
실제 세션 127개로 측정한 정확도
직접 만든 도구는 잘 맞는 것처럼 보이기 쉬워서 검증 방법을 먼저 정했습니다. 세션 127개를 시간순으로 나눠 앞 70%로만 학습하고, 뒤 30%는 실시간인 것처럼 재생하면서 중간중간 예측을 내게 했습니다. 각 시점에서 추정기가 볼 수 있는 정보는 그 순간까지의 기록뿐입니다.
검증에 쓴 기록의 규모
127개세션앞 70%로 학습, 뒤 30%로 검증
252개작업
756개측정 시점
결과는 고정값 방식과 나란히 놓고 봤습니다.
예측이 실제 남은 시간에 가까웠던 비율
“2배 이내”는 예측이 실제의 절반에서 두 배 사이에 든 비율이고, “표시 범위가 실제를 포함”은 화면에 띄운 범위 안에 실제 값이 들어간 비율입니다. 69%는 검증 기간에 실제 값이 범위에 들어간 비율로, 앞으로 매번 지켜진다고 약속하는 신뢰수준과는 다른 값입니다.
오차는 예측과 실제의 차이를 부호 없이 구해 실제 남은 시간으로 나눈 값이고, 너무 짧은 값에는 최소 분모를 적용합니다. 그 오차들의 중앙값이 56%입니다. 중앙값 하나로는 “5분 남음이면 실제 3분에서 11분” 같은 구간을 끌어낼 수 없으므로, 이 숫자는 기다릴지 다른 일을 할지 정하는 참고값으로 씁니다.
공개 저장소 README에는 243개 턴, 729개 시점, 중앙 오차 55%로 따로 집계한 값이 실려 있습니다. 집계 범위가 달라서 위 숫자와 섞지 않습니다. 세션 기록이 쌓이면 학습과 검증에 쓰이는 데이터가 함께 늘어나, 같은 도구를 다시 돌려도 몇 퍼센트포인트씩 달라집니다.
오차가 어디서 오는지도 나눠 봤습니다. 총 호출 수를 실제 값으로 바꿔 넣은 경우와 다른 추정 방식을 현재 방식과 나란히 놓으면 이렇습니다.
무엇을 바꿨을 때 중앙 오차가 어떻게 달라졌나
총 호출 수만 맞히면 오차가 절반 아래로 떨어지고, 호출당 소요 시간을 실제 값으로 바꾸면 오히려 나빠졌습니다. 예측이 어려운 쪽은 속도가 아니라 작업의 총량이었습니다. 요청 문장의 길이로 총량을 짐작할 수 있는지도 측정했지만, 두 값의 직선 관계를 나타내는 상관계수가 0.12로 약했습니다.
측정 결과 가운데 예상과 달랐던 것이 하나 있습니다. 같은 스킬을 자주 쓰면 예측이 정확해질 것 같지만, 표본이 쌓이는 것과 정확도는 생각만큼 붙어 있지 않았습니다. 변동계수는 평균에 비해 값이 얼마나 퍼져 있는지 나타내는 수치로, 이 표에서는 작을수록 호출 수가 일정했다는 뜻입니다.
| 분류 | 표본 | 중앙 호출 수 | 변동계수 |
|---|---|---|---|
| 일반 실행 작업 | 200회 | 7회 | 1.24 |
| 스킬 A | 11회 | 26회 | 0.60 |
| 스킬 B | 6회 | 60회 | 0.20 |
표본이 6개뿐인 스킬 B가 표본 200개인 일반 실행 작업보다 훨씬 일정했습니다. 실제 오차도 스킬 구간이 52%, 일반 작업이 56%로 표본이 적은 쪽이 나았습니다. 이 표본에서는 표본 수보다 작업이 비슷한 분량으로 끝나는지가 정확도를 더 크게 좌우했습니다.
그래서 표시 방식을 근거 수준에 맞췄습니다. 표본이 충분하면 숫자 하나를, 부족하면 범위와 함께 표본이 부족하다는 사실을 적습니다.
⏳ ░░░░░░░░░░ 작업 시간 계산 중 (경과 25초)
⏳ 코드 작업 ███░░░░░░░ 30% 남은 시간 ~2분 (툴콜 3/10, 경과 50초)
⏳ 문서 작성 ███░░░░░░░ ~33% 남은 시간 3분~13분 (표본 부족) (툴콜 16/48)
✓ 코드 작업 ██████████ 100% 완료 (툴콜 93, 27분)남은 시간에서 초 단위를 뺀 것도 같은 이유입니다. 오차가 56%인 값에 "2분 40초"라고 적으면 없는 정밀도를 내세우게 됩니다.
잦은 갱신과 기록 전체를 읽는 비용
성능은 처음부터 다룰 생각이 없었는데 측정 과정에서 문제가 드러났습니다. 기존에 쓰던 상태 표시줄 플러그인이 86MB짜리 세션 기록을 읽는 데 0.3초에서 1.1초를 쓰고 있었습니다. 파일이 운영체제 캐시에 올라와 있는지에 따라 편차가 크지만, 업데이트를 묶는 간격인 300밀리초보다 오래 걸리는 경우가 잦았습니다. 앞서 인용한 문서 내용대로라면 실행 중이던 스크립트가 계속 취소되는 상황입니다.
원인은 매번 기록 전체를 처음부터 읽는 방식이었습니다. 지금 필요한 정보는 현재 작업 구간뿐인데 몇 달 치를 다 훑고 있었습니다. 그래서 두 가지로 나눠 처리했습니다.
- 처음 실행: 파일 끝에서 거꾸로 올라가며 현재 작업이 시작된 지점을 찾고, 그 앞은 읽지 않습니다.
- 이후 갱신: 지난번에 읽은 바이트 위치부터 새로 붙은 부분만 읽습니다.
ms는 밀리초로, 1,000ms가 1초입니다.
기록을 읽는 방식에 따른 처리 시간
0.3~1.1초기록 전체를 매번 읽기첫 실행과 갱신 모두
3ms필요한 부분만, 첫 실행90MB 세션 기준
0~1ms필요한 부분만, 이후 갱신
거꾸로 읽을 때는 요령이 하나 필요했습니다. 도구 결과와 실제 사용자 입력은 기록에서 둘 다 user 타입으로 남습니다. 도구 결과 쪽이 훨씬 많고 용량도 크기 때문에, JSON을 파싱하기 전에 tool_result 문자열이 든 줄을 먼저 걸러내면 거꾸로 훑는 비용이 크게 줄어듭니다. 이 처리를 넣기 전에는 작업 하나가 16MB를 넘는 세션에서 시작 지점을 찾지 못하고 멈추는 경우가 있었습니다.
읽는 방식을 바꿨으니 결과가 같은지도 맞춰 봤습니다. 가장 큰 기록 6개와 가장 작은 4개를 골라 전체를 읽은 결과와 대조했고, 10건 모두 일치했습니다.
설치와 첫 확인 순서
만든 플러그인은 claude-code-eta 저장소에 공개해 뒀습니다. 이 플러그인은 Node.js 18 이상이 필요합니다. Claude Code를 네이티브 설치로 깔았다면 Node.js 없이도 돌아가므로, 컴퓨터에 Node.js가 없을 수 있습니다.
설정 과정은 사용자 설정의 statusLine 항목을 바꾸므로 다른 프로젝트의 상태 표시줄도 함께 바뀝니다. ~는 사용자 홈 폴더입니다. 설치 스크립트는 기존 파일을 .claude-code-eta-backup 접미사의 파일로 복사하려 하지만, 백업에 실패해도 설치는 계속 진행됩니다. 그래서 설치 전에 기존 값을 적어 두고, 설치 뒤에는 복구할 백업이 실제로 생겼는지 봅니다.
설치 전 점검부터 첫 표시까지
1. Node 버전Claude Code 밖의 셸에서
node --version 결과가 18 이상
2. 기존 값 적기~/.claude/settings.json의
statusLine 값을 따로 적음
3. 마켓플레이스 추가/plugin marketplace add 뒤
소스 칸에 저장소 경로만 입력
4. 설치와 설정/plugin install 뒤
/claude-code-eta:setup
5. 표시 확인짧은 작업 하나를 맡겨
화면 아래에 진행률이 뜨면 성공
3번에서 /plugin marketplace add를 실행하면 소스를 묻는 칸이 나옵니다. 이 칸에는 저장소 경로만 넣습니다.
osomahong/claude-code-eta
4번은 아래 두 명령을 한 줄씩 입력합니다.
/plugin install claude-code-eta@claude-code-eta
/claude-code-eta:setup
세 줄을 첫 입력칸에 한꺼번에 붙여 넣으면 Invalid marketplace source format 오류가 납니다. 소스 칸은 저장소 경로만 받기 때문입니다.
5번은 평소 하는 짧은 작업으로 충분합니다. 예를 들어 프로젝트의 README 파일 하나를 읽고 세 줄로 요약해 달라고 요청한 뒤 상태 표시줄을 봅니다. 처음에는 기록이 적어서 “계산 중”이나 “표본 부족”이 뜨고, 금방 끝나는 작업에서는 중간 ETA가 지나가 버려 완료 표시만 보일 수도 있습니다. 완료 표시가 떠도 요약이 맞는지는 답변을 읽고 따로 판단합니다.
표시가 아예 없다면 터미널 창을 넓히고 도움말이나 승인 창을 닫아 봅니다. 그래도 없으면 Node 경로, settings.json에 설정된 명령, 설치 결과의 오류 문구를 차례로 봅니다. 대화 기록을 지우거나 설정 파일 전체를 초기화하지는 않습니다.
이전 상태 표시줄로 되돌리기
되돌릴 때는 설치된 플러그인의 실제 폴더를 찾은 뒤, 그 폴더의 tools/install.js를 셸에서 실행합니다.
node "확인한 플러그인 절대경로/tools/install.js" --uninstall따옴표 안은 설정 단계에서 출력된 실제 플러그인 경로로 바꿔 넣습니다. 이 명령은 백업의 statusLine만 현재 설정에 되돌리고 다른 설정은 그대로 둡니다. 백업이 생기지 않았다면 설치 전에 적어 둔 statusLine 값을 settings.json에 직접 넣습니다.
플러그인은 통계를 계산하려고 대화 기록을 읽고, 통계 파일에는 시간과 호출 관련 값을 저장합니다. 통계 계산은 내 컴퓨터 안에서 처리되고, 통신은 플러그인을 내려받을 때와 Claude에 대화를 보낼 때 일어납니다. 설치 전에 처리 코드를 한 번 열어 보고, 원본 대화 기록 파일은 외부에 올리지 않습니다.
남은 한계와 비슷한 시도
가장 큰 한계는 작업 막바지의 추정입니다. 작업 구간을 넷으로 나눠 오차를 보면 이렇습니다.
작업 구간별 중앙 오차
마지막 구간에서는 곧 끝나는 상황을 미리 알아채지 못해 남은 시간을 실제보다 길게 잡습니다. 총 작업량을 모른 채 추정하는 구조에서 나오는 문제입니다. 그래서 막바지에 뜨는 남은 시간은 넉넉하게 잡힌 값으로 보고 판단합니다.
비슷한 시도가 이미 있는지도 찾아봤습니다. 할 일 목록의 완료 간격으로 남은 시간을 계산하는 플러그인이 있는데, 할 일 목록을 쓰지 않는 세션에서는 표시가 나오지 않습니다. 도구 호출을 직접 집계하면 그 제약이 없습니다. 상태 표시줄에 완료 예상 시간을 넣어 달라는 요청이 클로드 코드 저장소에 올라온 적도 있지만, 계획 없음으로 닫혔습니다.
자주 묻는 질문
남은 시간을 왜 초 단위까지 보여주지 않나요?
중앙 오차가 56%인 추정치를 초 단위로 표시하면 실제보다 정밀해 보이기 때문입니다. 표본이 부족할 때는 숫자 하나 대신 범위와 함께 그 사실을 표시합니다.
같은 작업을 자주 할수록 예측이 정확해지나요?
표본 수와 정확도는 생각만큼 붙어 있지 않았습니다. 실행 11회와 6회짜리 스킬이 200회짜리 일반 작업보다 변동계수가 낮았고 실제 오차도 더 작았습니다. 이 표본에서는 작업이 비슷한 분량으로 끝나는지가 정확도를 더 크게 좌우했습니다.
설치 명령 세 줄을 한 번에 붙여 넣어도 되나요?
한 줄씩 넣어야 합니다. 마켓플레이스 소스를 묻는 칸은 저장소 경로만 받기 때문에, 세 줄을 한꺼번에 붙이면 Invalid marketplace source format 오류가 납니다. 나중에 되돌리려면 백업 파일이 실제로 있는지와 설치된 플러그인 경로를 알아 둬야 합니다.
Sources
3줄 요약
-
클로드 코드 상태 표시줄의 컨텍스트 비율은 작업 완료율과 다른 값이며 claude-code-eta 플러그인은 대화 기록의 도구 호출 수로 진행률과 남은 시간을 추정합니다.
-
세션 127개로 검증한 결과 중앙 오차는 56%였고 예측이 실제의 2배 안에 든 비율은 57%로 고정값 방식의 32%보다 높았습니다.
-
설치 명령 세 개는 한 줄씩 넣어야 하며 settings.json의 statusLine 백업이 생겼는지 봐 두면 이전 상태 표시줄로 되돌릴 수 있습니다.

제대로 이해했는지 한 문제로 확인해 볼까요?
답을 고르면 바로 풀이가 나와요.
과거 세션의 경과 시간으로 남은 시간을 추정할 때 먼저 구분해야 할 것은 무엇인가요?

새 글과 AI 소식을 메일로 받아 보세요
AI가 바꾸는 일과 도구, 측정 실무 이야기를 매주 한 번 보내 드려요.
이 글이 도움이 되었나요?
CLAUDE.md, 권한 모드, 스킬, 훅, 비용 관리까지 클로드 코드를 실무에서 쓰는 순서입니다
코스 전체 보기 →