2026년 3월 31일 npm 소스맵 사고로 드러난 Claude Code 내부. 4단계 실행, 7가지 모드, 11단계 Agent Loop의 전체 구조를 분석
2026년 3월 31일, 보안 연구자 Chaofan Shou가 npm 패키지에서 이상한 점을 발견했습니다. Anthropic이 @anthropic-ai/claude-code v2.1.88을 배포하면서 .npmignore 설정 오류로 59.8MB 소스맵을 포함시킨 것입니다. 소스맵에는 전체 TypeScript 원본이 복원 가능한 상태로 들어 있었습니다. 512,000줄, 1,884개 파일. X(구 트위터)에 올라간 게시물은 수시간 만에 2,880만 뷰를 기록했습니다.
뒤이은 사건도 주목할 만합니다. Sigrid Jin이 한국시간 새벽 4시에 Claw Code(Python/Rust 클린룸 재구현)를 공개하자 2시간 만에 GitHub 스타 5만 개를 돌파했고, ccunpacked.dev가 비주얼 아키텍처 분석 사이트로 개설되었습니다. Anthropic은 8,100개 이상의 포크에 DMCA 테이크다운을 요청하고, npm 배포에서 네이티브 인스톨러 방식으로 전환했습니다.
같은 시간대에 npm 공급망 공격(supply-chain attack)도 병행되었습니다. 악성 axios 패키지(RAT 포함)가 유포되어, 유출 사태와 맞물리며 npm 생태계 전체의 보안 경각심을 높였습니다. 소스맵 포함 사고 자체는 Bun 런타임의 번들링 버그가 원인으로 추정됩니다.
이 글은 “Claude Code 해부학” 시리즈의 첫 번째 편으로, 유출 소스에서 확인된 전체 아키텍처를 분석합니다.
기술 스택
| 레이어 | 기술 | 역할 |
|---|---|---|
| 언어 | TypeScript (strict) | 전체 코드베이스, Zod 기반 런타임 검증 |
| UI 프레임워크 | React + Ink | 터미널 UI를 React 컴포넌트로 구성 (TUI) |
| 상태 관리 | Zustand | 불변 상태 트리, DeepImmutable 타입 |
| 런타임 | Bun | 빌드 및 실행 |
| 레이아웃 | Yoga (flexbox) | 터미널 내 flexbox 레이아웃 엔진 |
| API 통신 | SSE (Server-Sent Events) | 토큰 스트리밍 |
| 셸 파싱 | Tree-sitter | 23단계 AST 보안 분석 |
핵심은 React 기반 TUI(Terminal UI)입니다. 웹 브라우저 대신 터미널을 렌더 타겟으로 사용하되, 컴포넌트 구조와 상태 관리는 웹 React 앱과 동일한 패턴을 따릅니다. 전체 애플리케이션은 단일 약 800KB 번들(main.tsx)로 컴파일됩니다.
소스 디렉터리 구조
유출 소스의 디렉터리별 파일 수입니다.
| 디렉터리 | 파일 수 | 역할 |
|---|---|---|
utils/ | 564 | 유틸리티, 헬퍼 함수 |
components/ | 389 | React TUI 컴포넌트 |
commands/ | 189 | 슬래시 커맨드 정의 |
tools/ | 184 | 52개 빌트인 도구 구현 |
services/ | 130 | API, 인증, 텔레메트리 |
hooks/ | 104 | React/상태 훅 |
ink/ | 96 | Ink TUI 확장 |
bridge/ | 31 | claude.ai 연동 브리지 |
| 기타 | 197+ | 테스트, 설정, 타입 |
| 합계 | ~1,884 |
utils/가 전체의 30%를 차지한다는 점이 눈에 띕니다. 프로덕션 시스템의 복잡성이 “핵심 로직”이 아니라 “주변 인프라”에 집중된다는 현실을 보여줍니다.
4단계 실행 모델
Claude Code의 실행 흐름은 4개의 명확한 페이즈로 나뉩니다.
flowchart LR
subgraph P1["Phase 1: Startup"]
A1["병렬 I/O\n프리페치"]
A2["인증\n5가지 방식"]
A3["모델 결정\n도구 조립"]
A1 --> A2 --> A3
end
subgraph P2["Phase 2: Query Loop"]
B1["전처리\nsnip/compact"]
B2["API 스트리밍\nSSE"]
B3["에러 복구\nWithhold"]
B4["도구 실행"]
B1 --> B2 --> B3 --> B4
end
subgraph P3["Phase 3: Tool Execution"]
C1["52개 도구\n10단계 파이프라인"]
end
subgraph P4["Phase 4: Display"]
D1["React 조정기\nYoga flexbox\n이중 버퍼"]
end
P1 --> P2 --> P3 --> P4
P3 -->|"tool_use 존재"| P2
Phase 1: Startup (기동)
6단계 초기화가 진행됩니다. 핵심은 병렬 I/O 프리페치입니다.
- 병렬 I/O 프리페치 — Git 상태, Keychain 읽기 등 독립 작업을 동시에 실행 (약 135ms 중 65ms 절약)
- 조건부 모듈 로딩 — Feature-gated 코드(COORDINATOR_MODE, KAIROS)는 활성 시에만 로드
- 초기 설정 — CLI 플래그, bare 모드 파싱
- 인증 — OAuth, API Key, AWS Bedrock, Google Vertex, Azure Foundry 5가지 순차 시도
- 모델 결정 — 티어 기반 자동 선택 (Max/Team Premium은 Opus, 그 외 Sonnet)
- 초기 상태 — REPL 또는 Headless 모드 진입
Phase 2: Query Loop (질의 루프)
사용자 입력이 들어오면 query.ts와 QueryEngine.ts가 핵심 역할을 합니다.
전처리 단계에서 4가지 압축이 순서대로 작동합니다: Snip Compact(오래된 메시지 제거), Microcompact(tool_use 블록 축소), Context Collapse(컨텍스트 약축), Auto-Compact(토큰 임계값 context_window minus 13,000 초과 시 요약).
API 스트리밍은 SSE로 토큰을 실시간 수신합니다. 에러 복구(Withhold and Recover)는 복구 가능한 에러를 사용자에게 바로 표시하지 않고 자동 치유를 시도합니다. 413이면 collapse drain 후 reactive compact, Max Output Tokens이면 8K에서 64K로 에스컬레이션.
도구 실행 시 안전한 도구는 최대 10개 병렬, 위험한 도구는 순차 단독 실행합니다.
Phase 3: Tool Execution (도구 실행)
52개 빌트인 도구가 공통 10단계 파이프라인을 거칩니다: 이름 조회, 중단 확인, 입력 검증, PreToolUse 훅, 권한 확인, 실행, 결과 매핑, 크기 검사, PostToolUse 훅, 텔레메트리.
Phase 4: Display (화면 출력)
일반 CLI의 console.log가 아니라, React Reconciler, Yoga flexbox, 이중 버퍼, ANSI 시퀀스 파이프라인을 거칩니다. Int32Array 기반 ASCII 버퍼로 50배 캐시 성능 향상을 달성했고, CharPool/StylePool 인턴 풀로 메모리를 최적화합니다.
7가지 실행 모드
단일 바이너리지만 실행 컨텍스트에 따라 7가지 모드로 동작합니다.
| 모드 | 설명 | UI | 핵심 특징 |
|---|---|---|---|
| REPL | 대화형 터미널 | Full TUI | 기본 모드, 전체 도구 사용 |
| Headless | 비대화형 SDK | 없음 | CI/CD, 스크립팅용 |
| Coordinator | 멀티 에이전트 리더 | 최소 | 워커별 격리된 git worktree |
| Bridge | claude.ai 연동 | 양방향 | 최대 32 병렬 세션 |
| Kairos | 상시 실행 보조 | 백그라운드 | Dream 모드, GitHub 웹훅, 크론 |
| Daemon | tmux 백그라운드 | 없음 | 터미널 종료에도 생존 |
| Viewer | 읽기 전용 원격 관찰 | 읽기 전용 | 도구 실행 불가 |
graph TB
Q["query(deps)"]
Q --> R["REPL\nFull UI + 전체 도구"]
Q --> H["Headless\nNo UI + 전체 도구"]
Q --> C["Coordinator\n위임 + 워커"]
Q --> B["Bridge\nWeb 동기화"]
Q --> K["Kairos\n백그라운드 + Dream"]
Q --> D["Daemon\ntmux + UDS"]
Q --> V["Viewer\n읽기 전용"]
모든 모드가 동일한 query() 루프를 공유합니다. 차이는 Dependency Injection으로 처리합니다. query() 함수가 deps 파라미터를 받아 도구 풀, 권한 컨텍스트, 렌더링 타겟을 교체합니다.
11단계 에이전트 루프
Claude Code의 핵심 실행 단위입니다. 매 턴마다 이 11개 단계를 순회합니다.
flowchart TB
S1["1. User Input\nTextInput.tsx"]
S2["2. Message Creation\nmessages.ts"]
S3["3. History Append\nhistory.ts"]
S4["4. System Prompt Assembly\ncontext.ts"]
S5["5. API Streaming\nquery.ts SSE"]
S6["6. Token Parsing\nQueryEngine.ts"]
S7["7. Tool Detection\ntools.ts"]
S8["8. Tool Execution Loop\nStreamingToolExecutor.ts"]
S9["9. Response Rendering"]
S10["10. Post-Sampling Hooks\nautoCompact.ts"]
S11["11. Await"]
S1 --> S2 --> S3 --> S4 --> S5 --> S6 --> S7
S7 -->|"tool_use 감지"| S8
S8 -->|"결과 -> 이력 -> API 재호출"| S5
S7 -->|"tool_use 없음"| S9 --> S10 --> S11
S11 -->|"새 입력"| S1
1-3단계: 입력 처리. 사용자 메시지를 TextInput.tsx에서 수신하고, createUserMessage()로 구조화된 메시지 객체를 생성한 뒤, history.ts의 인메모리 배열에 추가합니다. API 호출 전 트랜스크립트를 디스크에 저장 — 크래시 안전성 보장.
4단계: 시스템 프롬프트 합성. context.ts가 두 소스를 결합합니다:
- 시스템 컨텍스트 (메모이제이션): Git 브랜치, git status(최대 2,000자), 최근 커밋, 사용자명
- 사용자 컨텍스트 (메모이제이션): CLAUDE.md 파일, 현재 날짜
세션 1회만 계산하고 매 턴 재사용합니다. API 프롬프트 캐싱(1시간 캐시)의 적중률을 극대화하는 전략입니다.
5-6단계: API 호출과 스트리밍. SSE로 토큰을 실시간 수신하면서 mutableMessages[], totalUsage, permissionDenials[]를 가변 상태로 유지합니다. maxBudgetUsd 초과 시 세션이 중단됩니다.
7-8단계: 에이전틱 루프. 모델 응답에 tool_use 블록이 있으면 findToolByName()으로 도구를 식별하고, canUseTool()로 접근을 검증한 뒤, StreamingToolExecutor.ts에 넘깁니다. 도구 결과가 이력에 추가되고 API를 재호출 — AI 판단, 도구 실행, 결과 피드백의 반복이 도구 호출 없는 텍스트 응답이 나올 때까지 계속됩니다.
9-11단계: 완료. 응답 렌더링, 후처리 훅(Auto-Compact, 메모리 추출), 다음 입력 대기.
상태 관리: 불변성과 자동 부수효과
전역 상태는 AppState라는 단일 객체에 DeepImmutable 타입이 적용됩니다. Zustand의 set 함수를 통해서만 변경되며, 변경 시 자동 부수효과(권한 변경 시 리스너 알림, 모델 변경 시 설정 저장, 설정 변경 시 캐시 무효화)가 트리거됩니다.
설계를 관통하는 3가지 원칙
1. 안전 우선 (Safety First)
23단계 bash AST 검사, 5단계 권한 파이프라인, fail-closed 기본 방어. “실행 전에 안전을 증명하라” 원칙이 일관됩니다.
2. 성능 집착 (Performance Obsession)
병렬 I/O 프리페치(65ms 절약), 도구 이름순 정렬(프롬프트 캐싱 보전), 이중 버퍼링(터미널 깜빡임 제거). 개별적으로 작지만 수백만 세션에 곱하면 인프라 비용 차이입니다.
3. 확장성 (Extensibility)
7가지 모드, 44개 Feature Flag, MCP 5가지 트랜스포트. 새 모드나 도구를 추가할 때 기존 코드를 수정하지 않고 확장 가능한 구조입니다.
Sources & Limitations
이 시리즈는 아래 공개 분석 자료를 종합하여 작성했으며, 유출된 소스 코드를 직접 포함하지 않습니다.
| Source | URL | 특징 |
|---|---|---|
| ccunpacked.dev | ccunpacked.dev | 시각적 아키텍처 가이드, 도구/커맨드 카탈로그 |
| Wikidocs 분석서 | wikidocs.net/338204 | 한국어 상세 기술 분석 (실행 흐름, 상태 관리, 렌더링) |
| PyTorch KR | discuss.pytorch.kr | GeekNews 기반 커뮤니티 분석 + HN 의견 종합 |
| Claw Code | github.com/ultraworkers/claw-code | 클린룸 재구현 (Rust/Python), PARITY.md 패리티 갭 분석 |
분석 시점: 2026-04-02. Anthropic은 유출 직후 DMCA로 8,100+ 포크를 차단하고 npm 배포를 중단했으므로, 일부 소스의 접근성이 변경되었을 수 있습니다. 또한 Feature Flag 뒤의 미공개 기능은 출시 전 변경되거나 폐기될 수 있습니다.
관련 글

에이전트 시스템 설계 캔버스 — Claude Code 유출이 증명한 12가지 프로덕션 패턴
Claude Code 소스 유출(512K줄 TS)에서 확인된 에이전트 시스템 설계의 6-Layer 캔버스와 8+4 핵심 패턴. 250K/일 API 낭비를 3줄로 해결한 Circuit Breaker부터, 23단계 bash AST 보안까지.

Anthropic의 96시간 — Access, Capability, Execution 3개 레이어 해부
2026년 4월 4일·7일·8일에 발표된 Anthropic의 세 건을 Access·Capability·Execution 3개 레이어로 분해해 수직 통합 전략을 읽어낸 분석

52개 도구, 23단계 보안: 에이전트 Tool System의 실제
52개 빌트인 도구의 공통 인터페이스, 10단계 실행 파이프라인, 안전=병렬/위험=순차 동시성 모델, 5단계 권한 파이프라인, 888KB 23단계 bash 보안