-
Notifications
You must be signed in to change notification settings - Fork 0
Dev Guide claude code
pytmux 안에서 동작하는 Claude Code 세션을 감시·보조하는 종합 플러그인이자 저장소에서 가장 큰 플러그인이다(~8천 줄). 이 페이지는 플러그인을 확장·유지보수하는 개발자를 위한 심화 가이드다. 철학(왜 결정론적 개입인가)은 개요 페이지 Claude-Code-Plugins 가 다루고, 여기서는 코드 구조·등록·상태머신·데이터 모델에 집중한다.
결정론(deterministic) 우선. 이 플러그인의 모든 자동 개입은 명시적 규칙과 임계값으로 정의되며 재현 가능하다 — 같은 화면 입력에 같은 동작이 나온다. 목표는 사용자의 습관을 바꾸지 않으면서 토큰 과소비를 줄이는 것이다. 적응형·휴리스틱 학습 기반(비결정론) 완화는 계획된 미래 방향이며 아직 구현돼 있지 않다 — 현재 화면 파싱은 휴리스틱이지만 그 위의 개입 결정은 전부 고정 규칙이다.
- 플러그인 아키텍처 & 파일 맵
- 등록: Registry 훅 전수
- 서버 믹스인 합성 패턴
- Claude 감지 상태머신
- 결정론적 토큰 완화 개입과 트리거
- 토큰 회계 데이터 모델
- 그림자
/usage프로브 - 클라이언트측 표시: 배지·렌더·팝업
- 확장·테스트하는 법
- 관련 문서
pytmuxlib/plugins/claude-code/ 디렉터리 하나가 플러그인 전체다. 코어는 이
디렉터리를 직접 import 하지 않고 레지스트리 훅으로만 닿으므로, 디렉터리를 통째로
지우면 모든 Claude 명령·팝업·상태줄 배지·자동개입·토큰 추적이 조용히 사라지고
코어는 무에러로 계속 동작한다(delete-to-disable).
| 파일 | 역할 |
|---|---|
__init__.py |
플러그인 진입점. _ClaudeCodePlugin 클래스(모든 레지스트리 훅 메서드)·명령 메타데이터·i18n 카탈로그·token-saver 팝업 행 정의·클라이언트 글루 설치(attach_client). |
claude.py |
순수 함수 감지·파싱 레이어. 화면 텍스트 → 상태(claude_state)·리밋·하드스톱·API 에러·사용량·모델·계정·권한모드·리셋 시각 파싱. textual·코어 미의존이라 단위 테스트가 쉽다. |
servermixin.py |
ServerClaudeMixin — 런타임에 Server 의 동적 베이스로 합성되는 서버측 로직(_scan_claude 30Hz 스캔 루프·자동개입·토큰 커밋·DB 연결). |
panestate.py |
pane_init/pane_reset/pane_serialize/pane_restore 훅이 위임. 패널별 Claude/토큰 필드(~50개)를 소유한다. |
tokens.py |
토큰 누계 상태머신(step/reset/parse_running_tokens). 응답별 peak 합산. |
usagedb.py |
SQLite 백엔드 — 스키마·마이그레이션(v1→v5)·insert/query·한도 스냅샷 이력(limits 테이블)·대사(reconcile). |
usagelog.py |
레코드 생성·버킷 집계(시/일/주/월×계정/세션)·신뢰 계정 판정·뷰 포맷. 클라가 라운드트립 없이 집계하는 순수 규칙. |
usageprobe.py |
숨은 claude 세션을 띄워 /usage·/status 패널을 스크랩하는 그림자 프로브(PTY/ConPTY). |
clientstatus.py |
하단 상태줄 Claude 세그먼트(모델 배지·컨텍스트%·5h%·계정·경고·카운트다운)와 클릭존. |
clientrender.py |
콘텐츠 레이어 위 Claude 프롬프트 헤더·footer 클릭존 스캔(client_render 훅). |
screens.py |
textual 팝업(토큰 로그·사용량 한도·모델 변경·권한모드·시작 규칙 편집·token-saver 설정). 실제로 열 때 지연 import. |
db/ |
SQLite DB 파일이 사는 플러그인 하위 디렉터리(버전관리 제외·호스트 로컬). |
경량 규약: __init__.py 는 textual 을 import 하지 않는다 — 서버 프로세스도
plugins.load() 로 이 모듈을 읽기 때문이다. textual 화면(screens.py)과 서버 로직
(servermixin.py)은 실제로 필요할 때만 함수 안에서 지연 import 한다.
코어의 pytmuxlib/plugins/__init__.py Registry 가 모든 훅 계약을 한곳에 모은다.
_ClaudeCodePlugin 은 그 훅 메서드들을 구현하고, 모듈 끝에서 PLUGIN = _ClaudeCodePlugin() 싱글턴을 노출한다. 각 훅은 코어가 레지스트리로만 호출하므로,
디렉터리를 지우면 훅이 no-op 가 된다.
-
name/description/category— 플러그인 매니저 표시용. -
commands(COMMANDS) —(이름, 설명, 카테고리)튜플 목록. 코어COMMANDS/COMPLETIONS에 병합. -
noarg(NOARG) — 인자 없이 즉시 실행하는 명령 집합. -
command_options(COMMAND_OPTIONS) — 팔레트에서 on/off/토글을 키보드로 고르는 선택지 스키마.
-
server_mixin()→ServerClaudeMixin반환(§3). 이 한 줄이 서버측 Claude 로직 전체를Server에 붙인다. -
server_init(server)→server._init_token_state()— 토큰 DB 런타임 상태 설치. -
server_opts_init(server, opts)/server_opts_serialize(server)—opts.json의plugin_opts네임스페이스를 읽고/쓴다(코어는 키 의미를 모르고 불투명하게 저장). 마이그레이션 shim 으로 구 top-level 키를 폴백 읽기 한다.
-
server_scan(server, sess, win)→_scan_claude()— 30Hz flush 스캔의 핵심 진입점. -
server_status(server, sess, win, msg, full)— status 메시지에 Claude 필드 in-place 채움. -
server_pane_overview(server, pane, info)— 트리/개요에 Claude 상태·토큰 덧붙임. -
server_input(server, pane, data)/server_paste(server, pane, data)— 사용자 입력의 부수효과(프롬프트 추적 + 무장된 자동 액션 해제 — 사용자가 직접 이어받음). -
server_pending(server, pane)— 무장된 자동 액션 카운트다운{kind, eta}. -
server_usage_refresh(server)(async) — 그림자/usage자동 갱신 1회. -
server_command(server, client, sess, action, msg)—set_*명령 액션 디스패치 (명시적 if/elif 라우팅). 반환값'handled'/'send_full'/'broadcast'가 코어 후속을 지시. -
handle_server_request(server, sess, action, msg)—request_token_log요청을 SQLite 에서 읽어 회신(코어 serverio 가 더는 usagedb 를 import 하지 않게 함). -
pane_closing(server, pane)— 닫히는 Claude 패널 토큰을 같은 계정 생존 패널로 이관 (_carry_tokens_on_close) + 무장 타이머 해제.
-
pane_init/pane_reset/pane_serialize/pane_restore→panestate모듈 위임. 코어Pane에는 없는 Claude/토큰 필드를 플러그인이 소유한다.
-
attach_client(app)— 앱 인스턴스에 클라이언트 글루(클로저 메서드)를 설치 (open_model_config·open_token_log·open_perm_mode·_saver_*등).PytmuxApp이 팩토리 내부 지역 클래스라 동적 믹스인을 못 써 클로저 설치 패턴을 쓴다. -
client_render(app, cells, W, H)— 콘텐츠 레이어 위 Claude 헤더·클릭존(clientrender). -
client_status(app, msg)— status 의 Claude 필드 흡수 + 절감 에스컬레이션 훅 발화. -
client_statusbar_init/client_statusbar_update/client_statusbar— 하단 상태줄 Claude 세그먼트 초기화·흡수·렌더(clientstatus). -
handle_message(app, msg)— 서버token_log회신 →TokenLogScreen팝업. -
handle_command(app, c, args)—claude-rules·token-saver·token-log등 명령 핸들러.
훅 추가 패턴: 새 기능이 코어의 어떤 지점에 붙어야 하면, 먼저 코어가 그 지점에서
registry.<hook>(...)를 부르는지 확인하고(없으면 코어에 훅 호출 추가), 그 다음 이 플러그인 클래스에 같은 이름의 메서드를 구현한다. 코어는 훅 이름만 알고 구현은 모른다.
Server 클래스(server.py)에는 _scan_claude·set_autoresume·refresh_usage 같은
메서드가 소스에 없다. 이들은 런타임에 합성된다:
flowchart LR
A["server_mixin()"] --> B["ServerClaudeMixin"]
B --> C["Server 의 동적 베이스 클래스로 합성<br/>(self.plugins 에 claude 가 있으면)"]
-
server_mixin()이ServerClaudeMixin을 반환하고, 코어가server_mixins()결과를Server의 베이스에 끼워 합성 클래스를 만든다. - 그래서 jump-to-def 가
Server._scan_claude에 안 닿으면servermixin.py를 grep 해야 한다(이 함정은server.py의class Server위 주석에도 적혀 있다). -
불변식:
self.plugins에 claude 가 있으면Server에ServerClaudeMixin도 합성돼 있다.server_init등 형제 런타임 훅은 이 불변식에 기댄다.
ServerClaudeMixin 의 메서드는 screen_text(p.screen)(파일 상단 헬퍼)로 패널 화면을
한 문자열로 떠서 claude.py 의 순수 파서에 먹이고, pane.pty.write(...) 로 개입을
주입한다. 모든 PTY 쓰기는 if pane.pty is None: return 가드를 거친다.
런타임 비활성과 합성의 차이: 플러그인 매니저(
:plugins)로 런타임에 끄면 훅 (server_scan등)이 안 불려 동작이 멈추지만,ServerClaudeMixin메서드 자체는 import 시 이미 합성돼 있다. 메서드까지 완전히 빼려면 서버 재시작이 필요하다.
플러그인은 비신뢰 패널 출력(Claude Code CLI 가 그린 TUI 화면)을 스크랩해 상태를
추정한다. Claude 가 고정 위치에 구조화된 신호를 주지 않으므로 전부 휴리스틱
파서(claude.py)다. 핵심 원칙: 지어내지 않는다 — 신뢰 신호가 없으면 None 을 내고
호출부는 발화를 보류한다.
반환 "limit" / "busy" / "idle" / None. 판정 순서가 중요하다(모드 footer 는
busy 중에도 보이므로 busy 를 먼저):
-
claude_limit(text)→ 사용량 리밋 배너(차단)면"limit". - 작업 스피너(
_BUSY_SPINNER_RE) 또는esc to interrupt→"busy". - 권한 모드 footer(
shift+tab to·mode on (shift)·단축키 힌트 →"idle". - 어느 것도 아니면
None(Claude Code 아님).
서로 다른 멈춤 상태를 별도 파서로 구분한다 — 각각 다른 개입이 필요하기 때문이다:
| 파서 | 의미 | 올바른 대응 |
|---|---|---|
claude_limit |
사용량/rate 5h 리밋(시간 지나면 풀림) | 리셋 시각까지 대기 후 자동재개 |
claude_context_hardstop |
대화 컨텍스트가 꽉 참(시간이 지나도 안 풀림) |
즉시 /compact
|
claude_api_error |
전송 에러(API Error·rate_limit_error·overloaded) | 백오프 후 "계속" 재시도 |
오탐 가드의 실제 사례:
-
_claude_body(text)가 사용자 입력 줄(>)·소스/diff 줄·슬래시 메뉴 행을 떼어내 사용자가 친 "rate limit"·소스 리터럴·/usage-credits도움말의 'hit a limit' 오탐을 막는다. -
claude_context_hardstop은 화면에 실제/compact또는/clear리터럴이 떠 있을 때만 True(하드스톱 안내는 항상 "· /compact or /clear to continue" 동반). -
claude_api_error는 맨단어 "rate limit" 을 떼고 배너 앵커(API Error:/()와 산문에 못 나오는 JSON 에러타입(rate_limit_error/overloaded_error)만 본다 — Claude 가 자기 설명 문자열을 화면에 띄운 idle 프레임의 오탐을 막은 결과다.
-
claude_usage/claude_context_pct— 컨텍스트 잔량%·토큰 수. 둘은 의미가 반대:claude_usage는 표시용 사용량%(100-잔량)를,claude_context_pct는 자동화 트리거용 잔량%(작을수록 꽉 참)를 낸다. -
claude_model— 모델 배지(Opus 4.8→opus-4.8). 패밀리 화이트리스트는 환경변수PYTMUX_CLAUDE_MODEL_FAMILIES로 코드 수정 없이 확장 가능. -
claude_account/claude_account_full— 계정 식별. 이메일 기반 신뢰 신호만 본다: ①<email>'s Organization② 계정 라벨(Login:/Email:) 바로 뒤 이메일. 산문·코드·git URL 의 임의 이메일과 RFC 예약 도메인(example.com등)은 배제. 못 잡으면 None → 서버가 "unknown" 으로 묶는다. -
claude_welcome— 버전 splash 배너(/clear·세션 시작 = 컨텍스트 비워짐 신호). -
claude_remote_active/claude_remote_menu/claude_remote_blocked— 원격 제어 (/rc) 상태·관리 메뉴·정책 차단. -
claude_feedback_prompt— 세션 종료 피드백 배너. -
parse_usage/parse_inline_limit/parse_reset_delay/parse_reset_ts—/usage패널·인라인 한도·리셋 시각 파싱.
ReDoS 주의: 여러 정규식이 길이 상한(
{1,9}·{1,64}등)으로 묶여 있다 — 무제한+/*는 거대 빈화면·숫자열·문자열에서 O(n²) 백트래킹으로 폭주한다(실측 ~14–22초). 새 파서를 추가할 때 같은 상한 규약을 따른다.
모든 탭의 모든 패널을 매 flush 마다 훑는다(활성 윈도우만이 아니라 — 백그라운드 탭 완료 알림 #22 때문). 한 패널당 흐름:
-
dirty 게이팅: 마지막 스캔 이후 출력이 없으면(
_feed_seq불변) 스캔을 통째로 건너뛴다. 단 프레임 카운터로 도는 디바운스(완료 안정·헤더 미스·/rc메뉴 디바운스·busy 이탈 확정)가 진행 중인pending패널은 화면이 정적이어도 계속 스캔. -
txt = screen_text(p.screen)→new_cl = claude_state(txt). -
포맷 미인식 가시화(§3.7): 파서가 None 인데 포그라운드 프로세스가 실제
claude면(_fg_is_claude, ps 검사라 throttle)_update_fmt_unknown이 ⚠ 경고를 세워 추적 중단을 가시화한다(화면 포맷과 무관한 ground-truth). - 원격 제어 메뉴 자동 Dismiss·하드스톱 자동복구·실측 한도 캡처(패널/인라인).
-
세션 경계 처리:
-
None→Claude: 토큰 누계 리셋·세션 id 부여·계정 재감지·시작 규칙 주입 예약· auto-launch(/rc+권한 auto) 예약·컨텍스트 디바운스 해제. - 수동
/clear(환영 배너 새로 뜸):_reset_token_session으로 누계 끊기. -
→None: 예약 해제·권한모드 비움·auto_token_on_exit발화(진짜 셸 복귀 교차검증).
-
-
토큰 step:
tokens.parse_running_tokens(txt)+tokens.step(...)으로 응답 peak 를 누계에 확정(committed>0→_log_tokens영속). - busy 이탈 히스테리시스(§3.4): busy→idle 첫 프레임은 리페인트 깜빡임일 수 있어 연속 2프레임 idle 일 때만 응답 경계로 확정.
- 완료 경계 개입 분기(busy→idle): 프롬프트 단위 클리어·자동 doc/clear·컨텍스트 잔량 정리·반복 루프 카운트·모델 힌트 평가(§5).
상태 변화가 있으면 True 반환 → 코어가 broadcast 한다.
모든 개입은 고정 규칙·임계값이고 토글로 켜고 끈다(대부분 기본 OFF 또는 안전
기본값). token-saver 팝업에서 토글하며 opts.json plugin_opts 에 영속한다.
시간 지연이 있는 모든 자동 주입(_fire_resume·_fire_retry)은 발화 직전 화면을
재확인한다 — 예약과 발화 사이에 사용자가 직접 대응했거나 화면이 바뀌었으면 주입을
취소해 작업 중인 Claude 에 끼어들지 않는다. 또한 server_input 이 사용자 입력 시
무장된 모든 타이머를 거둔다(사용자가 작업을 이어받음).
- 트리거:
claude_state == "limit"+parse_reset_delay로 리셋 시각 파싱. -
_maybe_schedule_resume가delay + 5초뒤_fire_resume예약. -
_fire_resume: 화면이 여전히 limit 이고 실측 게이트를 안 넘었을 때만resume_msg("continue") 주입. -
실측 게이트(
_usage_gate_over):/usage실측 세션%가usage_gate_session_pct(기본 95) 이상이면 자동재개 보류 — 한도 직전에 더 태우지 않는다. 실측 부재·stale· 계정 불일치면 fail-open(개입 안 함).
- 트리거:
claude_context_hardstop(txt)True(컨텍스트 꽉 참, 시간이 지나도 안 풀림). - idle-기반
auto_compact(N초 지속 후)와 다른 트리거 — 즉시/compact1회 주입. -
_hardstop_fired로 같은 하드스톱 화면 반복 주입 방지(화면 벗어나면 재무장),_auto_cc_blocked쿨다운으로 연속 압축 방지.
- 트리거: busy→idle 완료 경계(가장 값싼 정리 시점)에서
claude_context_pct < ctx_threshold. - 방식(
ctx_action):"compact"(/compact한 줄) 또는"doc-clear"(문서화+/clear상태기계). - 빈도 상한(
ctx_min_interval, M14)·디바운스(_ctx_fired, 임계+5%p 회복 시 재무장). - 우선순위 정리(M15): 실측 사용량이 게이트 임계 이상이고 이 패널이 그 계정에서 가장 꽉 찬 idle 세션이면, 개별 임계 미만이 아니어도 정리 — 멀티세션 누적 시 가장 비싼 세션부터 비운다.
- 트리거:
_hdr_claude(디바운스된 Claude 신호) +claude_api_error(txt)+ autoresume 미무장. - 백오프
_RETRY_DELAYS = (60, 120, 300)— 1·2차 빠른 재시도 후 5분 케이던스로 무기한. -
_fire_retry: 여전히 에러이고 busy 아닐 때만 "계속" 주입.
- 트리거: idle 이 N초(기본 30초) 지속.
_adc_arm/_acpt_arm으로 무장, idle 끊기면 해제.
- idle 시 권한모드를 shift+tab 폐루프로 순환 주입.
bypass(명시적 위험)는 불간섭. - 실측 한도 압박(게이트 임계의 80%) 시
claude_budget_plan이plan모드 유도.
-
장기 턴 경고(
long_turn)·반복 루프 경고(repeat_alert,track_repeat). -
모델 과선택 힌트(
model_overselect_hint): Opus 로 반복 작업 + 컨텍스트 여유 충분이면 "가벼운 모델 고려" 헤더 힌트만. 자동 모델 전환은 설계상 비채택 — 모델 교체는 작업 의미를 바꿀 위험이 커서.
-
_hdr_claudeTrue→False(30프레임 디바운스 = 진짜 종료) +_claude_really_exited(포그라운드 셸 복귀 교차검증) 시 한도 요약을 패널 스크롤백에 주입.
Claude 의 busy footer 는 ↑/↓ N tokens 처럼 현재 응답 한 건의 running 토큰을
보인다(세션 누계도, 프레임 델타도 아님). 정의: 세션 누계 = 각 응답의 최종(peak) 합.
-
parse_running_tokens—↑/↓가 앞에 붙은 토큰만 합산(누계 언급과 구분). -
step(state, running, busy)— 응답 종료(busy 끝 또는 running 급감=새 응답 시작)에 peak 를 total 에 확정하고 그 양을 반환(committed>0→ 영속 로깅 이벤트). -
잔상 가드(
idle_mark): 응답 종료 후에도↑/↓ N tokens텍스트가 화면에 남으면 비-busy 프레임마다 같은 값이 재확정되던 버그가 있었다(라이브 하루치의 83%, 한 응답 최대 117회 중복). 비-busy 확정 시 그 값을idle_mark로 기억하고 busy 복귀까지 mark 이하 running 을 잔상으로 무시한다. - 표시 누계 =
total + peak(진행 중 응답 포함, 경계에서 연속·이중계산 없음).
DB 파일은 플러그인 디렉터리 하위 db/ 에 산다(delete-to-disable 가 데이터까지
포함). PYTMUX_HOME 설정 시 <home>/db/ 로, PYTMUX_TOKENS_DB 로 강제 지정 가능
(테스트 격리). 첫 연결 시 레거시 위치에서 1회 마이그레이션(WAL 사이드카 동반).
PRAGMA user_version = 5. WAL 모드 + synchronous=NORMAL(응답마다 fsync 안 함).
TABLE usage (ts, tab, pane, session, account, tokens, tzoff)
TABLE limits (ts, account, session_pct, session_reset,
week_all_pct, week_all_reset,
week_sonnet_pct, week_sonnet_reset, source)
| 버전 | 내용 |
|---|---|
| v1 |
usage 테이블(레코드 스키마 = usagelog 와 동일). |
| v2 |
limits 테이블 추가(실측 /usage 스냅샷 이력). CREATE IF NOT EXISTS 라 v1 DB 자동 업그레이드. |
| v3 |
데이터 정리: 잔상 가드 이전에 쌓인 중복 커밋(60초 내 같은 pane·session·tokens 연쇄)을 첫 건만 남기고 usage_dup_archive 로 격리(하드 삭제 아님). |
| v4 |
데이터 정정: @ 없는 가짜 계정(화면 스크랩 약신호가 적재한 산문 구절)을 unknown 으로 일괄 정정. 원값은 usage_acct_fixlog 에 보존. |
| v5 |
usage.tzoff(쓰기 시점 로컬 UTC 오프셋) 컬럼 추가 — DST/여행으로 시스템 tz 가 바뀌어도 hour 버킷이 재분류되지 않게(레거시 NULL 은 시스템 로컬 폴백). |
마이그레이션은 단계별로 실패 시 user_version 을 보류해 다음 connect 에서 재시도한다.
- 패널마다
_claude_session_id를 가지며None→Claude전이·수동/auto/clear마다 새 id 를 부여(_next_claude_session_id). -
_seed_session_seq: 서버 부팅마다 카운터가 0 으로 초기화돼 재시작 후 같은 id 가 옛 세션과 병합되던 문제를, 첫 부여 직전 DB 의max(session)으로 시드해 막는다.
서버는 records 만 돌려주고(request_token_log 회신), 클라가 aggregate/agg_view
로 시/일/주/월×계정/세션 버킷을 라운드트립 없이 만든다. 신뢰 계정 판정(is_trusted)·
unknown 폴딩(fold_unknown)·tzoff 기반 버킷 키(bucket_key)가 순수 규칙으로 공유된다.
서버는 추가로 total_all(전체 이력 합)·daily(일자별 합성 레코드)·reconcile(실측
Δ vs 스크랩 Σ 대사)·daily_pct/hourly_pct/hourly_week_pct(권위 /usage 한도 %)를
함께 보낸다.
실측 /usage 값이 바뀐 순간만 insert_limits 가 적는다(직전과 동일값이면 skip).
출처(source)는 "panel"(/usage 전체)·"inline"(footer 인라인)·"probe"(그림자).
reconcile 뷰가 실측 스냅샷 Δpct 와 스크랩 Σ 를 대조해 진단을 돕는다.
usageprobe.query_usage 는 숨은 claude 세션을 PTY(_PosixSession)/ConPTY
(_WinSession)로 띄워 /usage·/status 패널을 스크랩한다 — 사용자 화면 무간섭.
- 부팅 대기(입력 박스 신호:
shortcuts·shift+tab·for agents중 하나). - 부팅 화면에서 계정 캡처(별칭
acct= 디스크 영속용, 전체acct_full= 휘발성 표시용). -
/usage\r주입 →% used대기 →parse_usage로 세션 5h·주 전체·주 Sonnet % 파싱. - 계정 미식별 시에만
Esc+/status\r1회 추가 스크랩(계정 라벨은 Status 탭에만 존재). - 즉시
kill/close.
서버측 refresh_usage(async)가 executor 스레드에서 이를 돌려(타임아웃 35초) self._usage
에 저장하고 broadcast 한다. 자동 갱신 주기(usage_refresh_sec, 기본 600초)에 더해
이벤트 트리거(응답 종료 디바운스·임계 부근 주기 단축)로 보강한다. spawn 이 비싸므로
(부팅 ~12초) 중복 방지(_usage_busy)·디바운스(_schedule_usage_refresh)가 핵심이다.
그림자 세션이 폰/데스크탑 앱과 다른 계정이면 한도 %가 실제로 다르므로, 사용자가 눈으로 대조할 수 있게
account를 결과에 함께 싣는다. 계정이 패널과 다르면 게이트는 그 한도로 이 패널을 막지 않는다(_usage_gate_pctsfail-open).
-
상태줄(
clientstatus.py):init_defaults(필드 설치)·absorb(status 흡수)·render_segs(좌하단 세그먼트 — 모델 배지·컨텍스트%·토큰Σ·예산·카운트다운·경고 + 클릭존). 임계 80%/100% 에 노랑/빨강 ⚠, 무장된 자동 액션은 ⏳+남은 초. -
콘텐츠 레이어(
clientrender.py):render가 Claude 프롬프트 헤더를 그리고_scan_all_footer_zones가 권한모드·원격제어·busy interrupt 클릭존을 채운다. -
팝업(
screens.py, 지연 import):TokenLogScreen·InfoScreen(usage 한도)·ModelCtxScreen·PermModeScreen·RulesEditScreen·ClaudeSaverScreen.
서버발 사용자 표면(원격 notice 등)은 서버가 t() 를 못 부르므로(로케일 미지) key+kw
만 싣고 한국어 text 폴백을 동반, 클라가 _notice_text 로 번역한다. 플러그인 자체 토스트
문자열은 __init__.py 의 ccmsg.* i18n 카탈로그(ko/en 대칭)에 모여 있다.
servermixin.py(~2천 줄)·screens.py(~1900 줄)·__init__.py(~1천 줄)는 한 컨텍스트에
안 들어온다. grep -n '^class \|^ def \|^def ' 로 위치를 잡고 Read offset/limit 으로
관심 영역만 본다. 명령 라우팅은 명시적 if/elif 라 grep '"set_autoresume"' 처럼
문자열로 핸들러를 바로 찾을 수 있다.
-
claude.py에 순수 함수로 파서를 추가(텍스트 in, 판정 out). ReDoS 길이 상한 준수. -
tests/fixtures/claude/에 실 캡처 골든 픽스처를 두고 회귀 고정 — 현행 Claude UI 포맷에 강결합돼 있어 포맷이 바뀌면 조용히 멈춘다(§3.7_fmt_unknown이 그걸 가시화). -
_scan_claude에서 그 파서를 호출하고, 개입이면 발화직전 재확인을 거친다.
-
_OPTS_KEYS에(key, default, cast)추가 →opts.jsonplugin_opts영속 자동. -
set_<key>메서드(servermixin)·server_command디스패치 분기·SAVER_ROWS/saver_display/saver_action(__init__.py) 추가. -
server_status의full블록에 정적 옵션이면 실어 클라에 전달.
커밋 전 필수: python3 tests/run.py 로 헤드리스 전체 스위트를 돌려 요약줄
N passed, 0 failed 를 확인한다(run.py 는 실패해도 종료코드 0 일 수 있으니 요약줄을
본다). 서브셋 실행은 플러그인 믹스인 poison 으로 가짜 실패가 날 수 있어 권위는 항상
전체 스위트다. 관련 테스트: test_claude(파서 단위)·test_server(스캔/개입/토큰)·
test_client(상태줄/팝업). 실 PTY·실 ConPTY·실 Claude 패널은 driver 검증 불가다.
- Claude-Code-Plugins — 개요·설계 철학(왜 결정론적 개입인가)
- Plugin-Authoring-Guide — 플러그인 작성 일반 가이드
- Plugin-System — 레지스트리·delete-to-disable·동적 합성 메커니즘
소개 · 사용
- Project-Overview
- User-Manual
- Screenshots
- Settings-Popup
- Single-Session-Model
- Tmux-Feature-Comparison
플러그인
Claude Code 플러그인
- Claude-Code-Plugins
- Dev-Guide-claude-code
- Dev-Guide-claude-token-usage-view
- Dev-Guide-claude-prompt-history
- Dev-Guide-claude-resume
- Dev-Guide-claude-disable-feedback
플랫폼 · 성능
품질 · 보안
리뷰·분석 보고서
연혁
기여