바닥줄 SessionMode 자리에 컨텍스트 사용량 라벨을 더하는 미니멀 mod

Claude Code 바닥줄(prompt footer) 오른쪽 모드 표시 자리에 컨텍스트 창 사용량을 한 줄로 덧붙이는 미니멀 mod.
-- INSERT -- ⏵⏵ auto mode on (shift+tab to cycle) ctx 53% · 531k/1000k
넓은 화면에서는 긴 형식, 좁은 화면(기준 폭 96열 미만)에서는 ctx 53%로 줄어든다.
SessionMode 자리에 라벨 하나를 더한다.$.session.usage() 수치만 읽는다.third_party/dashband/).| 문서 | 내용 |
|---|---|
| docs/01-feature-definition.md | 기능 정의·요구사항·인수 기준 |
| docs/02-spec-analysis.md | API·문서 근거 분석, dashband 차용 범위, 미확인 |
| docs/03-design.md | 설계(모듈·상태·렌더·형식)·스캐폴딩·테스트·배포 |
| docs/04-team-and-env.md | herdr 기반 에이전트 팀 구성과 환경 구축 스크립트 설계 |
| docs/05-work-plan.md | 단계별 상세 작업계획서 |
| docs/06-spike-results.md | P2 스파이크 실측(U1–U5)·타입 시그니처 확정 |
| docs/07-acceptance.md | P5 실화면 검증(인수 기준 A1–A5)·기준 폭 96 확정 근거 |
P0–P6 완료(2026-10-11, 0.1.0 설치 확인). 릴리스 태그 대기. 라이선스 MIT. 요구: Claude Code 2.1.287 이상(시험 환경 2.1.296).
요구: Claude Code 2.1.287 이상(시험 환경 2.1.296). 아래 한 줄 설치 명령은 2.1.292 이상에서 동작한다.
태그 없이 mrsono0/ctx-footer를 쓰면 기본 브랜치 main의 최신 판이 설치된다.
셸에서 한 줄(user scope로 설치된다):
claude plugin install ctx-footer --marketplace mrsono0/ctx-footer
또는 Claude Code 세션 안에서:
/plugin marketplace add mrsono0/ctx-footer
/plugin install ctx-footer@ctx-footer
주소 뒤에 #<태그>를 붙이면 그 판에 고정된다. 릴리스 태그는 v0.1.0부터 붙인다.
claude plugin install ctx-footer --marketplace mrsono0/ctx-footer#v0.1.0
또는 세션 안에서:
/plugin marketplace add mrsono0/ctx-footer#v0.1.0
/plugin install ctx-footer@ctx-footer
최신 설치와 고정 설치를 서로 바꾸려면 마켓플레이스를 지운 뒤(claude plugin marketplace remove ctx-footer) 원하는 형태로 다시 추가한다. 같은 이름의 마켓플레이스는 하나만 등록된다.
설치 뒤 새 세션(또는 /reload-plugins)부터 첫 응답이 끝나면 바닥줄 오른쪽에 라벨이 보인다.
공식 마켓플레이스 디렉터리에는 등록하지 않는다. GitHub 주소로만 설치한다.
주의: 커스텀 statusLine을 쓰고 있으면 라벨은 모드 줄이 아니라 statusLine 줄의 오른쪽 끝에 붙는다. 그러면 바닥줄은 한 줄이 아니게 된다(docs/06 U1).
claude plugin marketplace update ctx-footer
claude plugin update ctx-footer@ctx-footer
최신 설치는 이 두 명령(또는 자동 업데이트)으로 새 릴리스를 받는다. 새 릴리스는 plugin.json의 version이 올라갈 때만 전달된다. 버전 고정 설치는 그 태그에 머문다. 업데이트 뒤에는 새 세션을 시작하거나 /reload-plugins로 새 버전을 적용한다. 자동 업데이트는 세션 안 /plugin의 Marketplaces 화면에서 ctx-footer에 대해 켠다.
claude plugin uninstall ctx-footer@ctx-footer
claude plugin marketplace remove ctx-footer
설치 전에 쓰던 커스텀 statusLine을 다시 쓰려면 ~/.claude/settings.json의 statusLine 항목을 직접 되살린다. 이 플러그인은 statusLine을 바꾸지 않는다.
hooks/register.ts 38 lines1// Portions adapted from dashband (MIT, (c) 2026 Egon Leitner):
2// https://github.com/EgonLeitner/dashband — usage reading pattern, SessionMode hook shape.
3import { atom, read, update } from 'claude-code'
4import type { Register, SessionContextUsage } from 'claude-code'
5import type { ContextReading } from '../types'
6
7// 폭 기준값(셀 수) — P5 확정(docs/07 M5): 가장 긴 모드 힌트에서 최대 라벨이 한 줄에 드는 최소 폭 94 + 여유 2.
8export const WIDE_COLUMNS = 96
9
10const ctx = atom({ plugin: 'ctx-footer', key: 'context' } as const, null)
11
12export const toReading = (c: SessionContextUsage): ContextReading | null =>
13 c.percent == null ? null : { percent: c.percent, tokens: c.tokens ?? null, window: c.window }
14
15export const label = (r: ContextReading, columns: number | null): string => {
16 const pct = `ctx ${r.percent}%`
17 if (columns === null || columns < WIDE_COLUMNS || r.tokens === null) return pct
18 return `${pct} · ${Math.round(r.tokens / 1000)}k/${Math.round(r.window / 1000)}k`
19}
20
21export const register: Register = on => {
22 on('session.start', async ($, e, next) => {
23 const { context } = await $.session.usage()
24 await update($, ctx, () => toReading(context))
25 return next(e)
26 })
27 on('session.measure', async ($, e, next) => {
28 await update($, ctx, () => toReading(e.context))
29 return next(e)
30 })
31 on('ui.render', { component: 'SessionMode' }, async ($, e, next) => {
32 const r = await read($, ctx)
33 if (r === null) return next(e)
34 const columns = e.viewport?.columns ?? null
35 return next({ ...e, props: { ...e.props, modes: [...e.props.modes, label(r, columns)] } })
36 })
37}
38types/index.d.ts 10 lines1// ctx-footer PluginState 계약 (docs/03 D-4). 이 파일의 내보낸 이름은
2// hooks 모듈이 'claude-code'에서 다시 가져오지 않고 여기서 직접 쓴다.
3export type ContextReading = { percent: number; tokens: number | null; window: number }
4
5declare module 'claude-code' {
6 interface PluginState {
7 'ctx-footer': { context: ContextReading | null }
8 }
9}
10