Back to skills
SkillHub ClubShip Full StackFull Stack

hook-capabilities

Claude Code Hook system reference for capabilities, possibilities, and limitations. Use when you want to know what hooks can do.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
0
Hot score
74
Updated
March 20, 2026
Overall rating
C2.6
Composite score
2.6
Best-practice grade
F37.6

Install command

npx @skill-hub/cli install chkim-su-skillmaker-hook-capabilities

Repository

chkim-su/skillmaker

Skill path: skills/hook-capabilities

Claude Code Hook system reference for capabilities, possibilities, and limitations. Use when you want to know what hooks can do.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: chkim-su.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install hook-capabilities into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/chkim-su/skillmaker before adding hook-capabilities to shared team environments
  • Use hook-capabilities for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: hook-capabilities
description: Claude Code Hook system reference for capabilities, possibilities, and limitations. Use when you want to know what hooks can do.
allowed-tools: ["Read"]
---

# Claude Code Hook Capabilities

Reference for **what hooks can do** in Claude Code.

## Why Hooks Matter: The Only Guarantee

```
Hook = 100% execution guarantee (event-based)
Skill/Agent/MCP = ~20-80% (Claude's judgment)
```

**Key insight**: Hooks are the ONLY mechanism that executes without Claude's decision.
See [orchestration-patterns.md](references/orchestration-patterns.md) for forcing skill/agent activation.

## 5 Hook Roles

| Role | Description | Examples |
|------|-------------|----------|
| **Gate** | Block/allow tool execution | Prevent dangerous commands, workflow precondition checks |
| **Side Effect** | Auto-actions after tool execution | Formatters, linters, auto-commit |
| **State Manager** | Workflow state management | State file creation/deletion, phase tracking |
| **External Integrator** | External system integration | MCP calls, HTTP API, WebSocket, Slack |
| **Context Injector** | Session context injection | Load project settings, activate services |

## Event Types and Characteristics

| Event | Block | Special Features | Verification |
|-------|-------|------------------|--------------|
| SessionStart | No | source (compact/new) | Verified |
| UserPromptSubmit | Yes | **stdout auto-injects into Claude context** | Verified |
| PreToolUse | Yes | **updatedInput modifies input**, tool_use_id | Verified |
| PermissionRequest | Yes | **allow/deny/ask + input modification** | Unverified |
| PostToolUse | No | **tool_response** (access results) | Verified |
| Stop | Yes | **stop_hook_active** (loop prevention) | Verified |
| SubagentStop | Yes | parent-child correlation via tool_use_id | Unverified |
| Notification | No | includes notification_type | Verified |
| PreCompact | No | trigger (auto/manual) | Verified |
| SessionEnd | No | On session end | Unverified |

## 22 Universal Approaches

### Control Patterns

| Approach | Description | Event |
|----------|-------------|-------|
| **Iteration Control** | Track iteration count + max limit | Stop |
| **Force Continuation** | Use exit 2 to continue Claude work | Stop |
| **Promise Detection** | Detect Claude response patterns, conditional exit | Stop |
| **Infinite Loop Prevention** | Prevent recursion via parent_tool_use_id | UserPromptSubmit |
| **Threshold Branching** | Branch based on error/warning count | Stop |

### Input Manipulation

| Approach | Description | Event |
|----------|-------------|-------|
| **Input Modification** | Modify tool input via updatedInput | PreToolUse, PermissionRequest |
| **Path Normalization** | Auto-convert relative to absolute paths | PreToolUse |
| **Environment Injection** | Auto-inject environment variables | PreToolUse |
| **Dry-run Enforcement** | Auto-add --dry-run to dangerous commands | PreToolUse |

### Context Management

| Approach | Description | Event |
|----------|-------------|-------|
| **Context Injection** | stdout auto-injects into Claude context | UserPromptSubmit |
| **Progressive Loading** | Load context/skills on demand | UserPromptSubmit |
| **Skill Auto-Activation** | Keywords trigger skill suggestions | UserPromptSubmit |
| **Transcript Parsing** | Read and analyze previous responses | Stop |
| **Transcript Backup** | Backup session transcript | PreCompact |

### State Management

| Approach | Description | Event |
|----------|-------------|-------|
| **Session Cache** | Accumulate per-session state + aggregate results | PostToolUse |
| **Session Lifecycle** | Initialize/cleanup state via SessionStart/End | SessionStart/End |
| **Checkpoint Commit** | Checkpoint on every change, then squash | PostToolUse, Stop |
| **Session Branching** | Auto-isolate Git branches per session | Pre/PostToolUse |

### External Integration

| Approach | Description | Event |
|----------|-------------|-------|
| **Notification Forwarding** | Forward notifications to Slack/Discord/external | Notification |
| **Desktop/Audio Alert** | osascript, notify-send, TTS | Notification |
| **Subagent Correlation** | Track parent-child via tool_use_id | SubagentStop |

### Security & Compliance

| Approach | Description | Event |
|----------|-------------|-------|
| **Auto-Approval** | Auto-approve specific tools/commands | PermissionRequest |
| **Secret Scanning** | Detect and block API keys/secrets | PreToolUse |
| **Compliance Audit** | Compliance logging + violation detection | PostToolUse |

### Implementation Techniques

| Approach | Description | Event |
|----------|-------------|-------|
| **TypeScript Delegation** | Delegate complex logic to .ts | Any |
| **Hook Chaining** | Execute multiple hooks sequentially | Any |
| **Background Execution** | Async via run_in_background | Any |
| **Argument Pattern Matching** | Match arguments like `Bash(npm test*)` | PreToolUse |
| **MCP Tool Matching** | Match MCP like `mcp__memory__.*` | PreToolUse |
| **Prompt-Type Hook** | LLM evaluation via type: "prompt" | Any |

## Capabilities vs Limitations

| Possible | Not Possible |
|----------|--------------|
| File create/delete/modify | Block in PostToolUse |
| MCP/HTTP/WebSocket calls | Direct Claude context modification |
| UserPromptSubmit stdout to context | Delete existing context |
| PreToolUse/PermissionRequest input modification | Cancel already-executed tools |
| Continue work from Stop | Unlimited forcing (infinite loop risk) |

## Data Passing Methods (Important)

### stdin JSON (Verified)
All session/project info is passed via **stdin JSON**:
- `session_id` - Session UUID
- `cwd` - Project directory
- `transcript_path` - Session log file path
- `tool_use_id` - Tool call ID (PreToolUse/PostToolUse)

### stdin JSON Structure by Event

```bash
# UserPromptSubmit
{"prompt": "user message", "session_id": "...", "cwd": "/path"}

# PreToolUse / PostToolUse
{"tool_name": "Bash", "tool_input": {"command": "npm test"}, "session_id": "..."}

# PermissionRequest
{"tool_name": "Bash", "tool_input": {...}, "permission_type": "execute"}

# Stop
{"stop_reason": "end_turn", "session_id": "..."}

# SubagentStop
{"agent_name": "backend-dev", "result": "...", "session_id": "..."}
```

### Environment Variables (Verified)
`CLAUDE_PROJECT_DIR`, `CLAUDE_SESSION_ID` etc. are **NOT environment variables**!

Actually set environment variables:
```bash
CLAUDE_CODE_ENABLE_CFC="false"
CLAUDE_CODE_ENTRYPOINT="cli"
```

### Settings Reload
- `settings.json` changes **only apply in new sessions**

## Exit Code Reference

| Exit Code | Meaning | Behavior |
|-----------|---------|----------|
| **0** | Success/Allow | Normal proceed |
| **1** | Error | Hook failure, show warning |
| **2** | Block/Continue | Varies by event |

**Exit 2 behavior by event**:

| Event | exit 2 Behavior |
|-------|-----------------|
| **PreToolUse** | Block tool execution |
| **PostToolUse** | Ignore result (prompt retry) |
| **PermissionRequest** | Deny permission request |
| **Stop** | Force Claude to continue |
| **UserPromptSubmit** | Abort prompt processing |

## Hook Execution Order

```
Multiple hooks on same event → Sequential execution (definition order)
One hook exits 2 → Subsequent hooks don't run
```

## Timeout Setting

```json
{"type": "command", "command": "script.sh", "timeout": 10000}
```

Default: 60000ms (1 minute)

## Common Mistakes

| Mistake | Problem | Solution |
|---------|---------|----------|
| Not reading stdin | Missing JSON input | `INPUT=$(cat)` required |
| stdout debug output | Context pollution | Use stderr (`>&2`) |
| exit 1 vs exit 2 confusion | Unintended behavior | exit 1=error, exit 2=block |
| Parsing without jq | Unstable | Install and use jq |

## References

- [Event Details](references/event-details.md) - 10 event specifications
- [Pattern Details](references/patterns-detailed.md) - Role, usage, examples
- [Orchestration Patterns](references/orchestration-patterns.md) - **Force skill/agent activation**
- [Real-World Examples](references/real-world-examples.md) - Implementation case studies
- [Advanced Patterns](references/advanced-patterns.md) - Complex combinations


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/orchestration-patterns.md

```markdown
# Hook Orchestration Patterns

Patterns for forcing skill/agent activation via hooks.

## The Core Problem: Claude's Goal-Focused Behavior

```
Claude focuses on goal achievement → skips skill/agent checks → works directly

"Skills just sit there. You have to remember to use them."
— diet103 (GitHub, 7.6k stars)
```

**Why this happens**:
- No algorithmic routing (embeddings, classifiers)
- Pure LLM inference on description text
- Goal-oriented behavior bypasses "optional" resources

## Activation Reliability Stats

| Method | Success Rate | Source |
|--------|--------------|--------|
| **Hook** | **100%** | Event-based auto-execution |
| Skill + Forced Eval Hook | **84%** | Scott Spence (200+ tests) |
| Skill + Simple Hook | ~50% | "coin flip" |
| Skill (default) | **~20%** | Description matching only |
| Subagent | ~70-80% | Description quality dependent |
| MCP (all tools loaded) | **~13%** | Tool overload |
| MCP (Tool Search) | ~43% | Subset search |

**Key insight**: Hook is the ONLY 100% guaranteed mechanism.

## Pattern 1: Forced Evaluation (84% Success)

### skill-rules.json Structure

```json
{
  "description": "Skill activation triggers",
  "skills": {
    "backend-dev-guidelines": {
      "type": "domain",
      "enforcement": "suggest",
      "priority": "high",

      "promptTriggers": {
        "keywords": ["backend", "API", "controller", "service"],
        "intentPatterns": [
          "(create|add|implement).*?(route|endpoint|API)",
          "(fix|debug).*?(error|exception)"
        ]
      },

      "fileTriggers": {
        "pathPatterns": ["services/**/*.ts", "controllers/**/*.ts"],
        "contentPatterns": ["import.*Prisma"]
      }
    }
  }
}
```

### Forced Eval Hook (UserPromptSubmit)

```bash
#!/bin/bash
INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt')

MATCHED_SKILLS=()

if echo "$PROMPT" | grep -qiE "backend|API|controller|service"; then
  MATCHED_SKILLS+=("backend-dev-guidelines")
fi

if [ ${#MATCHED_SKILLS[@]} -gt 0 ]; then
  cat << EOF
MANDATORY SKILL CHECK

Step 1 - EVALUATE: For each skill, state YES/NO with reason
Step 2 - ACTIVATE: Use Skill() tool NOW
Step 3 - IMPLEMENT: Only after activation

Relevant skills:
$(for s in "${MATCHED_SKILLS[@]}"; do echo "- $s"; done)

CRITICAL: Evaluation is WORTHLESS unless you ACTIVATE.
EOF
fi
exit 0
```

**Why 84%**: Writing "YES - need this" creates commitment → compels activation.

### Enforcement Levels

| Level | Behavior | Use Case |
|-------|----------|----------|
| **suggest** | Recommend skill usage | General guidelines |
| **block** | Block action + require skill | Required rules/security |

## Pattern 2: Hook → Agent → Skill (100% Success)

Use Agent as skill "container":
- Hook forces Agent invocation
- Agent's `skills` field guarantees skill loading
- Context isolation + cost savings

### Architecture

```
UserPromptSubmit Hook
    │
    └─→ stdout: "MANDATORY: Use [agent-name] agent"
                              ↓
Claude Main
    │
    └─→ Task(subagent_type="backend-dev", prompt="...")
                              ↓
Subagent (backend-dev)
    ├── skills: backend-dev-guidelines ✅ Auto-loaded
    ├── tools: Restricted set
    ├── model: haiku (cost savings)
    └── Isolated context
```

### Agent Router Hook

```bash
#!/bin/bash
INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt')

if echo "$PROMPT" | grep -qiE "backend|API|controller|service|prisma"; then
  cat << 'EOF'
MANDATORY AGENT DELEGATION

This task requires the **backend-dev** agent.
The agent has specialized skills pre-loaded.

ACTION REQUIRED:
Use Task tool with subagent_type="backend-dev"

DO NOT proceed without delegating to this agent.
EOF
fi
exit 0
```

### Agent Definition (.claude/agents/backend-dev.md)

```yaml
---
name: backend-dev
description: Use PROACTIVELY for backend - APIs, controllers, services
skills: backend-dev-guidelines
tools: Read, Edit, Bash, Grep, Glob
model: sonnet
---

You are a backend development specialist.

RULES:
1. Always follow the loaded backend-dev-guidelines skill
2. Use repository pattern for database access
3. Include proper error handling with Sentry
4. Write tests for new functionality
```

### Comparison

| Method | Context | Skill Load | Cost | Isolation |
|--------|---------|------------|------|-----------|
| Hook → Skill (Forced Eval) | Shared | 84% | Same | ❌ |
| Hook → Agent → Skill | Isolated | **100%** | Reduced | ✅ |

### ⚠️ Critical Limitation: Task Tool and Agent Types

```
┌───────────────────────────────────────────────────────────────┐
│  Task tool only recognizes plugin-registered agents           │
│  Local agents (.claude/agents/*.md) CANNOT be called via Task │
└───────────────────────────────────────────────────────────────┘
```

| Agent Type | Definition Location | Task Tool | Invocation Method |
|------------|--------------------|-----------|--------------------|
| **Plugin Agent** | `.claude-plugin/agents/*.md` | ✅ Works | `Task(subagent_type="name")` |
| **Local Agent** | `.claude/agents/*.md` | ❌ Fails | `/agents` or Claude's judgment |

**Actual Behavior**:
```python
# When hook outputs "Use backend-dev agent"
if "backend-dev" in plugin_registered_agents:
    # Task(subagent_type="backend-dev") works
else:
    # Task tool doesn't recognize → error or ignored
```

**Solutions**:
1. Register agent as plugin (`.claude-plugin/agents/`)
2. Or use Hook → Skill pattern (Forced Eval) directly

### Agent `skills` Field Behavior

**Works for**:
- Local agents (`.claude/agents/*.md`) - 100% skill loading guaranteed
- Plugin agents - via `skills` frontmatter field

**Does NOT guarantee invocation**:
- The `skills` field ensures loading when agent runs
- But agent invocation itself still depends on Claude's judgment (unless forced via Hook)

## Selection Guide

| Situation | Recommended |
|-----------|-------------|
| Simple project | Hook → Skill (Forced Eval) |
| Large project | Hook → Agent → Skill |
| Cost optimization | Agent (model: haiku) |
| Context isolation needed | Agent |
| External API connection | MCP |
| Auto-validation | Hook (PostToolUse) |
| Required rules enforcement | Hook (block) |

## References

- [diet103/claude-code-infrastructure-showcase](https://github.com/diet103/claude-code-infrastructure-showcase)
- [Scott Spence - How to Make Claude Code Skills Activate Reliably](https://scottspence.com/posts/how-to-make-claude-code-skills-activate-reliably)
- [Anthropic - Agent Skills](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview)

```

### references/event-details.md

```markdown
# Event Details

각 Hook Event의 상세 스펙.

## SessionStart

**Trigger**: 세션 시작 또는 재개 시
**Block 가능**: ❌
**입력 데이터** (검증됨):
```json
{
  "session_id": "uuid",
  "transcript_path": "/home/user/.claude/projects/.../session.jsonl",
  "cwd": "/project/path",
  "hook_event_name": "SessionStart",
  "source": "compact"  // "compact" (재개) 또는 "new" (신규)
}
```

**활용**:
- MCP 서버 활성화 (SSE 연결, tools/call)
- 프로젝트 컨텍스트 로드
- 환경 변수 설정
- 워커 프로세스 시작

---

## UserPromptSubmit

**Trigger**: 사용자가 메시지 전송 시 (Claude 처리 전)
**Block 가능**: ✅
**입력 데이터** (검증됨):
```json
{
  "session_id": "uuid",
  "transcript_path": "/home/user/.claude/projects/.../session.jsonl",
  "cwd": "/project/path",
  "permission_mode": "default",
  "hook_event_name": "UserPromptSubmit",
  "prompt": "사용자 입력 텍스트"
}
```

**★ 특별 기능: Context Injection**
- **stdout이 Claude 컨텍스트로 자동 주입됨**
- 프롬프트에 추가 정보 삽입 가능

**활용**:
- 프롬프트 검증/필터링
- 키워드 기반 스킬 제안
- 컨텍스트 자동 주입 (git status, TODO 등)
- 보안 필터링

---

## PreToolUse

**Trigger**: 도구 실행 직전
**Block 가능**: ✅ (exit 2)
**입력 데이터** (검증됨):
```json
{
  "session_id": "uuid",
  "transcript_path": "/home/user/.claude/projects/.../session.jsonl",
  "cwd": "/project/path",
  "permission_mode": "bypassPermissions",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "ls -la",
    "description": "List files"
  },
  "tool_use_id": "toolu_01..."
}
```

**Matcher 패턴**:
```
"Bash"                    # 정확한 매칭
"Edit|Write|MultiEdit"    # OR 매칭
"Bash(npm test*)"         # 인자 패턴 매칭
"mcp__memory__.*"         # MCP 도구 매칭
"*"                       # 전체 매칭
```

**활용**:
- 위험 명령 차단 (rm -rf, sudo)
- 보호 파일 수정 방지 (.env, .git)
- 워크플로우 전제조건 검사
- Subagent 타입별 분기 처리
- Secret Scanning (API 키 감지)

---

## PostToolUse

**Trigger**: 도구 실행 완료 후
**Block 가능**: ❌ (이미 실행됨)
**입력 데이터** (검증됨):
```json
{
  "session_id": "uuid",
  "transcript_path": "/home/user/.claude/projects/.../session.jsonl",
  "cwd": "/project/path",
  "permission_mode": "bypassPermissions",
  "hook_event_name": "PostToolUse",
  "tool_name": "Bash",
  "tool_input": { "command": "...", "description": "..." },
  "tool_response": { ... },  // 도구 실행 결과
  "tool_use_id": "toolu_01..."
}
```

> **Note**: `tool_result`가 아닌 `tool_response` 필드명 사용

**활용**:
- 상태 파일 생성/삭제
- 결과 기반 조건부 처리
- 자동 포맷팅 (prettier, black)
- 자동 커밋 (git add && commit)
- 변경 사항 추적/로깅
- 외부 서버 알림
- 세션별 브랜치 분리

---

## PermissionRequest

**Trigger**: 권한 다이얼로그 표시 시
**Block 가능**: ✅
**입력 데이터**:
```json
{
  "session_id": "uuid",
  "tool_name": "Bash",
  "tool_input": { "command": "npm install" },
  "cwd": "/project/path"
}
```

**★ 특별 기능: Input Modification**
```json
{
  "hookSpecificOutput": {
    "decision": {
      "behavior": "allow",
      "updatedInput": {
        "command": "npm install --save-dev"
      }
    }
  }
}
```

**활용**:
- 특정 작업 자동 승인
- 도구 입력 자동 수정/보강
- 정책 기반 권한 관리

---

## Stop

**Trigger**: Claude가 응답 종료하려 할 때
**Block 가능**: ✅ (exit 2로 계속 유도)
**입력 데이터** (검증됨):
```json
{
  "session_id": "uuid",
  "transcript_path": "/home/user/.claude/projects/.../session.jsonl",
  "cwd": "/project/path",
  "permission_mode": "bypassPermissions",
  "hook_event_name": "Stop",
  "stop_hook_active": false  // 무한 루프 방지 플래그
}
```

> **Note**: `stop_hook_active`가 `true`면 이미 Stop 훅이 실행 중이므로 추가 블록 금지

**활용**:
- End-of-turn 품질 검사
- 의존성 설치 강제
- 미커밋 변경사항 경고
- 워크플로우 상태 요약
- 반복 횟수 제한
- Promise Detection

---

## SubagentStop

**Trigger**: Task(Subagent)가 종료하려 할 때
**Block 가능**: ✅
**입력 데이터**: Stop과 유사

**활용**:
- Subagent 결과 검증
- Subagent별 품질 기준 적용

---

## Notification

**Trigger**: Claude가 알림 발생 시
**Block 가능**: ❌
**입력 데이터** (검증됨):
```json
{
  "session_id": "uuid",
  "transcript_path": "/home/user/.claude/projects/.../session.jsonl",
  "cwd": "/project/path",
  "hook_event_name": "Notification",
  "message": "Claude is waiting for your input",
  "notification_type": "idle_prompt"  // 알림 유형
}
```

**활용**:
- 데스크톱 알림 (osascript, notify-send)
- TTS 음성 피드백
- 외부 로깅

---

## PreCompact

**Trigger**: Context compact 직전
**Block 가능**: ❌
**입력 데이터** (검증됨):
```json
{
  "session_id": "uuid",
  "transcript_path": "/home/user/.claude/projects/.../session.jsonl",
  "cwd": "/project/path",
  "hook_event_name": "PreCompact",
  "trigger": "auto",  // "auto" 또는 "manual"
  "custom_instructions": null  // 커스텀 지시 (있으면 문자열)
}
```

**활용**:
- 중요 컨텍스트 보존
- 상태 백업

---

## SessionEnd

**Trigger**: 세션 종료 시
**Block 가능**: ❌

**활용**:
- 정리 작업
- 메트릭 내보내기
- 세션 요약 생성

---

## Hook Type: Prompt

`type: "command"` 외에 `type: "prompt"` 지원:

```json
{
  "hooks": [{
    "type": "prompt",
    "prompt": "이 작업이 안전한지 평가해주세요: {{tool_input}}"
  }]
}
```

LLM이 평가하여 결정 (비용 발생, 느림)

---

## 공통 필드 및 환경변수

### 모든 이벤트에 공통으로 포함되는 필드
| 필드 | 설명 |
|------|------|
| `session_id` | 세션 고유 ID (UUID) |
| `transcript_path` | 세션 transcript 파일 경로 |
| `cwd` | 현재 작업 디렉토리 |
| `hook_event_name` | 이벤트 타입명 |

### 환경변수 (⚠️ 중요 수정사항)

**검증 결과**: 문서에 언급된 `CLAUDE_PROJECT_DIR`, `CLAUDE_SESSION_ID` 등은 **환경변수가 아닙니다**.

이 정보들은 **stdin JSON**을 통해 전달됩니다:
- `session_id` → stdin JSON의 필드
- `cwd` → stdin JSON의 필드 (프로젝트 디렉토리)
- `transcript_path` → stdin JSON의 필드

**실제 설정되는 환경변수** (검증됨):
```bash
CLAUDE_CODE_ENABLE_CFC="false"
CLAUDE_CODE_ENTRYPOINT="cli"
```

### 설정 리로드
- `settings.json` 변경은 **새 세션에서만 적용**됨
- 런타임 중 훅 설정 변경 → 세션 재시작 필요

```

### references/patterns-detailed.md

```markdown
# Hook 범용 접근법 상세

30가지 패턴의 역할, 사용법, 예시.

> **Note**: 2025-12-30 검증 결과 반영. `tool_response` (not `tool_result`), stdin JSON 기반 데이터 전달.

---

## 1. 제어 패턴 (Control)

### 1.1 Iteration Control

**역할**: 반복 횟수를 추적하고 최대 제한을 강제하여 무한 루프 방지

**사용법**:
- Stop Hook에서 반복 횟수 파일 관리
- 임계값 도달 시 exit 0으로 종료 허용

**예시**:
```bash
#!/bin/bash
# .claude/hooks/iteration-control.sh
COUNTER_FILE="/tmp/claude-iterations-$SESSION_ID"

# 카운터 증가
COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
COUNT=$((COUNT + 1))
echo "$COUNT" > "$COUNTER_FILE"

MAX_ITERATIONS=10
if [ "$COUNT" -ge "$MAX_ITERATIONS" ]; then
    echo "⚠️ Maximum iterations ($MAX_ITERATIONS) reached" >&2
    rm -f "$COUNTER_FILE"
    exit 0  # 종료 허용
fi

exit 0
```

```json
{"hooks": {"Stop": [{"hooks": [{"type": "command", "command": ".claude/hooks/iteration-control.sh"}]}]}}
```

---

### 1.2 Force Continuation

**역할**: Claude가 종료하려 할 때 작업 계속하도록 강제

**사용법**:
- Stop Hook에서 조건 검사 후 exit 2 반환
- stderr로 이유 전달 → Claude가 읽고 계속 작업

**예시**:
```bash
#!/bin/bash
# 테스트 통과 전까지 종료 불가
if ! npm test --silent 2>/dev/null; then
    echo "❌ Tests failing - continue fixing" >&2
    exit 2  # Claude 계속 작업
fi
exit 0
```

```python
#!/usr/bin/env python3
# TODO 남아있으면 계속
import subprocess
result = subprocess.run(['grep', '-rn', 'TODO', 'src/'], capture_output=True)
if result.stdout:
    print("❌ TODOs remain - please complete them", file=sys.stderr)
    sys.exit(2)
```

**⚠️ 주의**: 무한 루프 위험. Iteration Control과 함께 사용 권장.

---

### 1.3 Promise Detection

**역할**: Claude 응답에서 특정 패턴 감지하여 조건부 종료/계속

**사용법**:
- Stop Hook에서 최근 트랜스크립트 파싱
- "DONE", "COMPLETE" 등 패턴 감지

**예시**:
```bash
#!/bin/bash
# 최근 응답에서 완료 패턴 확인
TRANSCRIPT="$HOME/.claude/projects/$(basename $PWD)/transcript.jsonl"
LAST_RESPONSE=$(tail -1 "$TRANSCRIPT" | jq -r '.content // ""')

if echo "$LAST_RESPONSE" | grep -qiE 'TASK COMPLETE|DONE|FINISHED'; then
    echo "✓ Task completion detected"
    exit 0
fi

# 미완료 패턴 감지
if echo "$LAST_RESPONSE" | grep -qiE 'TODO|FIXME|WIP'; then
    echo "❌ Incomplete work detected" >&2
    exit 2
fi
exit 0
```

---

### 1.4 Infinite Loop Prevention

**역할**: Subagent 재귀 호출로 인한 무한 루프 방지

**사용법**:
- UserPromptSubmit에서 parent_tool_use_id 확인
- Subagent 컨텍스트면 Hook 스킵

**예시**:
```python
#!/usr/bin/env python3
import json, sys

input_data = json.load(sys.stdin)

# Subagent 컨텍스트 확인
if input_data.get('parent_tool_use_id'):
    # 이미 Subagent 내부 → Hook 스킵
    sys.exit(0)

# 메인 에이전트만 처리
# ... 로직 ...
```

---

### 1.5 Threshold Branching

**역할**: 에러/경고 수에 따라 다른 동작 수행

**사용법**:
- PostToolUse에서 에러 카운트 누적
- Stop에서 임계값 기반 분기

**예시**:
```bash
#!/bin/bash
# PostToolUse: 에러 카운트 누적
ERROR_FILE="/tmp/claude-errors-$SESSION_ID"
INPUT=$(cat)
RESULT=$(echo "$INPUT" | jq -r '.tool_response // ""')

if echo "$RESULT" | grep -qiE 'error|failed|exception'; then
    COUNT=$(cat "$ERROR_FILE" 2>/dev/null || echo 0)
    echo $((COUNT + 1)) > "$ERROR_FILE"
fi
```

```bash
#!/bin/bash
# Stop: 임계값 분기
ERROR_FILE="/tmp/claude-errors-$SESSION_ID"
COUNT=$(cat "$ERROR_FILE" 2>/dev/null || echo 0)

if [ "$COUNT" -ge 5 ]; then
    echo "❌ Too many errors ($COUNT) - stopping for review" >&2
    rm -f "$ERROR_FILE"
    exit 0  # 강제 종료
elif [ "$COUNT" -ge 3 ]; then
    echo "⚠️ Multiple errors ($COUNT) - please review" >&2
fi
```

---

## 2. 입력 조작 패턴 (Input Manipulation)

### 2.1 Input Modification

**역할**: 도구 실행 전 입력 파라미터 자동 수정

**사용법**:
- PreToolUse 또는 PermissionRequest에서 JSON 응답
- `updatedInput` 필드로 수정된 입력 전달

**예시**:
```python
#!/usr/bin/env python3
# npm install에 --save-dev 자동 추가
import json, sys

input_data = json.load(sys.stdin)
tool_input = input_data.get('tool_input', {})
command = tool_input.get('command', '')

if command.startswith('npm install') and '--save-dev' not in command:
    modified_command = command + ' --save-dev'
    print(json.dumps({
        "hookSpecificOutput": {
            "decision": {"behavior": "allow", "updatedInput": {"command": modified_command}}
        }
    }))
else:
    print(json.dumps({}))
```

---

### 2.2 Path Normalization

**역할**: 상대 경로를 절대 경로로 자동 변환

**사용법**:
- PreToolUse에서 file_path 검사
- 상대 경로면 절대 경로로 변환하여 updatedInput

**예시**:
```python
#!/usr/bin/env python3
import json, sys, os

input_data = json.load(sys.stdin)
tool_input = input_data.get('tool_input', {})
file_path = tool_input.get('file_path', '')

if file_path and not file_path.startswith('/'):
    # cwd는 stdin JSON에서 가져옴 (환경변수 아님!)
    project_dir = input_data.get('cwd', os.getcwd())
    absolute_path = os.path.join(project_dir, file_path)
    
    updated_input = tool_input.copy()
    updated_input['file_path'] = absolute_path
    
    print(json.dumps({
        "hookSpecificOutput": {
            "permissionDecision": "allow",
            "updatedInput": updated_input
        }
    }))
else:
    print(json.dumps({}))
```

---

### 2.3 Environment Injection

**역할**: 명령 실행 전 필요한 환경 변수 자동 주입

**사용법**:
- PreToolUse에서 Bash 명령 감지
- 환경 변수 prefix 추가

**예시**:
```python
#!/usr/bin/env python3
import json, sys

input_data = json.load(sys.stdin)
tool_input = input_data.get('tool_input', {})
command = tool_input.get('command', '')

# Node.js 명령에 NODE_ENV 주입
if 'npm' in command or 'node' in command:
    env_prefix = 'NODE_ENV=development'
    if not command.startswith(env_prefix):
        modified = f"{env_prefix} {command}"
        print(json.dumps({
            "hookSpecificOutput": {
                "permissionDecision": "allow",
                "updatedInput": {"command": modified}
            }
        }))
        sys.exit(0)

print(json.dumps({}))
```

---

### 2.4 Dry-run Enforcement

**역할**: 위험한 명령에 --dry-run 플래그 자동 추가

**사용법**:
- PreToolUse에서 위험 명령 감지
- --dry-run 또는 유사 플래그 추가

**예시**:
```python
#!/usr/bin/env python3
import json, sys, re

input_data = json.load(sys.stdin)
command = input_data.get('tool_input', {}).get('command', '')

# 위험 명령 패턴
dangerous_patterns = [
    (r'^rm\s+-rf', '--dry-run'),  # rm -rf → 불가 (dry-run 없음)
    (r'^git push', '--dry-run'),
    (r'^npm publish', '--dry-run'),
    (r'^docker rm', '--dry-run'),
]

for pattern, flag in dangerous_patterns:
    if re.search(pattern, command) and flag not in command:
        if flag == '--dry-run' and 'rm -rf' in command:
            # rm은 dry-run 없으므로 차단
            print(f"❌ Blocked: {command}", file=sys.stderr)
            sys.exit(2)
        
        modified = f"{command} {flag}"
        print(json.dumps({
            "hookSpecificOutput": {
                "permissionDecision": "allow",
                "updatedInput": {"command": modified}
            }
        }))
        sys.exit(0)

print(json.dumps({}))
```

---

## 3. 컨텍스트 관리 패턴 (Context)

### 3.1 Context Injection

**역할**: UserPromptSubmit stdout이 Claude 컨텍스트로 자동 주입

**사용법**:
- UserPromptSubmit Hook에서 stdout 출력
- Claude가 사용자 프롬프트와 함께 받음

**예시**:
```bash
#!/bin/bash
# 현재 git 상태와 TODO를 컨텍스트로 주입
echo "=== Current Context ==="
echo "Git Status:"
git status --short 2>/dev/null | head -10

echo ""
echo "Recent TODOs:"
grep -rn "TODO" src/ 2>/dev/null | head -5

echo ""
echo "Last 3 commits:"
git log --oneline -3 2>/dev/null
echo "===================="
```

**결과**: 사용자 프롬프트에 위 정보가 자동으로 추가됨

---

### 3.2 Progressive Loading

**역할**: 필요할 때만 컨텍스트/스킬 로드하여 토큰 절약

**사용법**:
- UserPromptSubmit에서 키워드 감지
- 관련 컨텍스트만 stdout으로 출력

**예시**:
```python
#!/usr/bin/env python3
import json, sys

input_data = json.load(sys.stdin)
prompt = input_data.get('prompt', '').lower()

# 키워드 기반 컨텍스트 로딩
if 'database' in prompt or 'db' in prompt:
    print("=== Database Context ===")
    print(open('.claude/context/database.md').read())

if 'api' in prompt or 'endpoint' in prompt:
    print("=== API Context ===")
    print(open('.claude/context/api.md').read())

if 'test' in prompt:
    print("=== Testing Context ===")
    print(open('.claude/context/testing.md').read())
```

---

### 3.3 Skill Auto-Activation

**역할**: 프롬프트 키워드 분석하여 관련 스킬 자동 제안

**사용법**:
- UserPromptSubmit에서 키워드 매칭
- 스킬 사용 권장 메시지 출력

**예시**:
```python
#!/usr/bin/env python3
import json, sys

input_data = json.load(sys.stdin)
prompt = input_data.get('prompt', '').lower()

skill_mapping = {
    ('refactor', 'clean', 'solid'): 'serena-refactor',
    ('test', 'coverage', 'jest'): 'testing-patterns',
    ('api', 'endpoint', 'rest'): 'api-design',
    ('hook', 'automation'): 'hook-capabilities',
}

for keywords, skill in skill_mapping.items():
    if any(kw in prompt for kw in keywords):
        print(f"📚 Recommended: Use Skill('{skill}')")
        break
```

---

### 3.4 Transcript Parsing

**역할**: Claude의 이전 응답을 읽고 분석

**사용법**:
- Stop Hook에서 트랜스크립트 파일 읽기
- 패턴 분석 후 조건부 동작

**예시**:
```python
#!/usr/bin/env python3
import json, sys, os
from pathlib import Path

# 트랜스크립트 위치
project = os.path.basename(os.getcwd())
transcript_path = Path.home() / '.claude' / 'projects' / project / 'transcript.jsonl'

if transcript_path.exists():
    with open(transcript_path) as f:
        lines = f.readlines()
    
    # 최근 5개 메시지 분석
    recent = [json.loads(line) for line in lines[-5:]]
    
    # 에러 패턴 감지
    error_count = sum(1 for msg in recent if 'error' in str(msg).lower())
    
    if error_count >= 3:
        print("⚠️ Multiple errors detected in recent messages", file=sys.stderr)
```

---

### 3.5 Transcript Backup

**역할**: Compact 전에 트랜스크립트 백업

**사용법**:
- PreCompact Hook에서 현재 트랜스크립트 복사
- 타임스탬프로 백업 파일 생성

**예시**:
```bash
#!/bin/bash
# PreCompact: 트랜스크립트 백업
PROJECT=$(basename "$PWD")
TRANSCRIPT="$HOME/.claude/projects/$PROJECT/transcript.jsonl"
BACKUP_DIR="$HOME/.claude/backups"

mkdir -p "$BACKUP_DIR"

if [ -f "$TRANSCRIPT" ]; then
    TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    cp "$TRANSCRIPT" "$BACKUP_DIR/${PROJECT}-${TIMESTAMP}.jsonl"
    echo "✓ Transcript backed up"
fi
```

---

## 4. 상태 관리 패턴 (State)

### 4.1 Session Cache

**역할**: 세션 내 상태 누적 및 도구 결과 집계

**사용법**:
- PostToolUse에서 결과를 캐시 파일에 누적
- Stop에서 집계 데이터 활용

**예시**:
```bash
#!/bin/bash
# PostToolUse: 변경된 파일 추적
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')

CACHE_DIR="/tmp/claude-cache-$SESSION_ID"
mkdir -p "$CACHE_DIR"

if [ -n "$FILE_PATH" ]; then
    echo "$FILE_PATH" >> "$CACHE_DIR/modified-files.txt"
fi
```

```bash
#!/bin/bash
# Stop: 세션 요약
CACHE_DIR="/tmp/claude-cache-$SESSION_ID"

if [ -d "$CACHE_DIR" ]; then
    echo "=== Session Summary ==="
    echo "Modified files:"
    sort -u "$CACHE_DIR/modified-files.txt" 2>/dev/null
    
    # 정리
    rm -rf "$CACHE_DIR"
fi
```

---

### 4.2 Session Lifecycle

**역할**: 세션 시작/종료 시 상태 초기화/정리

**사용법**:
- SessionStart: 초기 상태 설정
- SessionEnd: 정리 작업

**예시**:
```bash
#!/bin/bash
# SessionStart: 초기화
SESSION_DIR="/tmp/claude-session-$(date +%s)"
mkdir -p "$SESSION_DIR"
echo "$SESSION_DIR" > /tmp/claude-current-session

echo "✓ Session initialized: $SESSION_DIR"
```

```bash
#!/bin/bash
# SessionEnd: 정리
SESSION_DIR=$(cat /tmp/claude-current-session 2>/dev/null)

if [ -d "$SESSION_DIR" ]; then
    # 메트릭 내보내기
    echo "$(date -Iseconds) Session ended" >> ~/.claude/session-log.txt
    rm -rf "$SESSION_DIR"
fi
```

---

### 4.3 Checkpoint Commit

**역할**: 모든 파일 변경마다 checkpoint 커밋 생성

**사용법**:
- PostToolUse에서 매 변경마다 커밋
- Stop에서 squash 또는 정리

**예시**:
```bash
#!/bin/bash
# PostToolUse: checkpoint 커밋
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

if [ -n "$FILE_PATH" ] && [ -f "$FILE_PATH" ]; then
    git add "$FILE_PATH"
    git commit -m "checkpoint: $(basename $FILE_PATH)" --no-verify 2>/dev/null
fi
```

```bash
#!/bin/bash
# Stop: checkpoint squash
CHECKPOINT_COUNT=$(git log --oneline | grep -c "^checkpoint:")

if [ "$CHECKPOINT_COUNT" -gt 1 ]; then
    echo "💡 $CHECKPOINT_COUNT checkpoints created"
    echo "Run 'git rebase -i HEAD~$CHECKPOINT_COUNT' to squash"
fi
```

---

### 4.4 Session Branching

**역할**: 세션별로 Git 브랜치 자동 격리 (GitButler 패턴)

**사용법**:
- PreToolUse: 세션별 인덱스 생성
- PostToolUse: 세션 인덱스에 파일 추가
- Stop: 세션 브랜치에 커밋

**예시**:
```bash
#!/bin/bash
# PreToolUse: 세션 인덱스 초기화
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')

INDEX_FILE="/tmp/git-index-$SESSION_ID"
if [ ! -f "$INDEX_FILE" ]; then
    # HEAD 기준으로 새 인덱스 생성
    GIT_INDEX_FILE="$INDEX_FILE" git read-tree HEAD
fi
```

```bash
#!/bin/bash
# PostToolUse: 세션 인덱스에 추가
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

if [ -n "$FILE_PATH" ]; then
    INDEX_FILE="/tmp/git-index-$SESSION_ID"
    GIT_INDEX_FILE="$INDEX_FILE" git add "$FILE_PATH"
fi
```

```bash
#!/bin/bash
# Stop: 세션 브랜치에 커밋
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')

INDEX_FILE="/tmp/git-index-$SESSION_ID"
if [ -f "$INDEX_FILE" ]; then
    TREE=$(GIT_INDEX_FILE="$INDEX_FILE" git write-tree)
    COMMIT=$(git commit-tree "$TREE" -p HEAD -m "Session $SESSION_ID")
    git update-ref "refs/heads/claude/$SESSION_ID" "$COMMIT"
    
    echo "✓ Changes committed to branch: claude/$SESSION_ID"
    rm -f "$INDEX_FILE"
fi
```

---

## 5. 외부 연동 패턴 (Integration)

### 5.1 Notification Forwarding

**역할**: Claude 알림을 외부 서비스로 전달

**사용법**:
- Notification Hook에서 메시지 파싱
- HTTP POST로 Slack/Discord 등에 전달

**예시**:
```python
#!/usr/bin/env python3
import json, sys, os
import urllib.request

input_data = json.load(sys.stdin)
message = input_data.get('message', '')

# Slack Webhook
webhook_url = os.environ.get('SLACK_WEBHOOK_URL')
if webhook_url:
    payload = json.dumps({"text": f"🤖 Claude: {message}"})
    req = urllib.request.Request(webhook_url, 
                                  data=payload.encode(),
                                  headers={'Content-Type': 'application/json'})
    urllib.request.urlopen(req)
```

---

### 5.2 Desktop/Audio Alert

**역할**: 데스크톱 알림 또는 TTS 음성 피드백

**사용법**:
- Notification Hook에서 OS별 알림 명령 실행
- TTS 라이브러리로 음성 출력

**예시**:
```bash
#!/bin/bash
# 플랫폼별 데스크톱 알림
INPUT=$(cat)
MESSAGE=$(echo "$INPUT" | jq -r '.message // "Claude needs attention"')

case "$(uname)" in
    Darwin)
        osascript -e "display notification \"$MESSAGE\" with title \"Claude Code\""
        # TTS
        say "Claude needs your input"
        ;;
    Linux)
        notify-send "Claude Code" "$MESSAGE"
        # TTS (espeak)
        espeak "Claude needs your input" 2>/dev/null
        ;;
esac
```

---

### 5.3 Subagent Correlation

**역할**: tool_use_id로 부모-자식 Subagent 관계 추적

**사용법**:
- SubagentStop에서 tool_use_id 기록
- 부모 에이전트와 상관관계 분석

**예시**:
```python
#!/usr/bin/env python3
import json, sys
from datetime import datetime

input_data = json.load(sys.stdin)
tool_use_id = input_data.get('tool_use_id', 'unknown')
parent_id = input_data.get('parent_tool_use_id', 'root')

# 상관관계 로깅
log_entry = {
    "timestamp": datetime.now().isoformat(),
    "tool_use_id": tool_use_id,
    "parent_id": parent_id,
    "type": "subagent_stop"
}

with open('/tmp/claude-subagent-trace.jsonl', 'a') as f:
    f.write(json.dumps(log_entry) + '\n')

print(f"✓ Subagent {tool_use_id[:8]} completed (parent: {parent_id[:8]})")
```

---

## 6. 보안/규정 패턴 (Security)

### 6.1 Auto-Approval

**역할**: 특정 도구/명령 자동 승인하여 반복 권한 요청 제거

**사용법**:
- PermissionRequest Hook에서 패턴 매칭
- "allow" 결정 반환

**예시**:
```python
#!/usr/bin/env python3
import json, sys, re

input_data = json.load(sys.stdin)
tool_name = input_data.get('tool_name', '')
tool_input = input_data.get('tool_input', {})
command = tool_input.get('command', '')

# 자동 승인 패턴
auto_approve_patterns = [
    r'^npm (test|run|install)',
    r'^git (status|log|diff|branch)',
    r'^ls\b',
    r'^cat\b',
    r'^grep\b',
]

for pattern in auto_approve_patterns:
    if re.search(pattern, command):
        print(json.dumps({
            "hookSpecificOutput": {
                "decision": {"behavior": "allow"}
            }
        }))
        sys.exit(0)

# 기본: 사용자 확인 요청
print(json.dumps({}))
```

---

### 6.2 Secret Scanning

**역할**: API 키, 비밀번호 등 민감 정보 감지 및 차단

**사용법**:
- PreToolUse에서 파일 내용/명령 검사
- 민감 정보 패턴 발견 시 차단

**예시**:
```python
#!/usr/bin/env python3
import json, sys, re

input_data = json.load(sys.stdin)
tool_input = input_data.get('tool_input', {})

# 검사 대상: 파일 내용 또는 명령
content = tool_input.get('content', '') + tool_input.get('command', '')

# 민감 정보 패턴
secret_patterns = [
    (r'AKIA[0-9A-Z]{16}', 'AWS Access Key'),
    (r'sk-[a-zA-Z0-9]{48}', 'OpenAI API Key'),
    (r'ghp_[a-zA-Z0-9]{36}', 'GitHub Token'),
    (r'-----BEGIN (RSA |EC )?PRIVATE KEY-----', 'Private Key'),
    (r'password\s*=\s*["\'][^"\']+["\']', 'Hardcoded Password'),
]

for pattern, name in secret_patterns:
    if re.search(pattern, content):
        print(f"🚫 BLOCKED: Potential {name} detected", file=sys.stderr)
        sys.exit(2)
```

---

### 6.3 Compliance Audit

**역할**: 규정 준수 로깅 및 위반 감지

**사용법**:
- PostToolUse에서 모든 작업 로깅
- 정책 위반 시 경고

**예시**:
```python
#!/usr/bin/env python3
import json, sys
from datetime import datetime

input_data = json.load(sys.stdin)

# 감사 로그 생성
audit_entry = {
    "timestamp": datetime.now().isoformat(),
    "tool": input_data.get('tool_name'),
    "input": input_data.get('tool_input'),
    "user": os.environ.get('USER'),
    "cwd": input_data.get('cwd')
}

# 로깅
with open('/var/log/claude-audit.jsonl', 'a') as f:
    f.write(json.dumps(audit_entry) + '\n')

# 정책 위반 검사
file_path = input_data.get('tool_input', {}).get('file_path', '')
if '/production/' in file_path or '/prod/' in file_path:
    print("⚠️ WARNING: Production file modified - logged for review", file=sys.stderr)
```

---

## 7. 구현 기법 패턴 (Implementation)

### 7.1 TypeScript Delegation

**역할**: 복잡한 로직을 TypeScript 파일로 위임

**사용법**:
- Bun 또는 tsx로 TypeScript 직접 실행
- 타입 안전한 Hook 로직 구현

**예시**:
```json
{"hooks": {"PreToolUse": [{"matcher": "*", "hooks": [{"type": "command", "command": "bun run .claude/hooks/validator.ts"}]}]}}
```

```typescript
// .claude/hooks/validator.ts
import { stdin } from 'process';

interface HookInput {
  session_id: string;
  tool_name: string;
  tool_input: Record<string, unknown>;
}

let data = '';
stdin.on('data', chunk => data += chunk);
stdin.on('end', () => {
  const input: HookInput = JSON.parse(data);
  
  // 타입 안전한 검증 로직
  if (input.tool_name === 'Bash') {
    const command = input.tool_input.command as string;
    if (command.includes('rm -rf /')) {
      console.error('❌ Blocked dangerous command');
      process.exit(2);
    }
  }
});
```

---

### 7.2 Hook Chaining

**역할**: 여러 Hook을 순서대로 실행

**사용법**:
- hooks 배열에 여러 Hook 정의
- 순서대로 실행, 하나라도 실패 시 중단

**예시**:
```json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [
        {"type": "command", "command": ".claude/hooks/format.sh"},
        {"type": "command", "command": ".claude/hooks/lint.sh"},
        {"type": "command", "command": ".claude/hooks/track.sh"}
      ]
    }]
  }
}
```

---

### 7.3 Background Execution

**역할**: 비동기로 Hook 실행하여 Claude 응답 차단 안함

**사용법**:
- 명령 끝에 `&` 추가
- 또는 설정에서 `run_in_background: true`

**예시**:
```json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": ".claude/hooks/slow-analysis.sh &"
      }]
    }]
  }
}
```

---

### 7.4 Argument Pattern Matching

**역할**: 특정 인자 패턴에만 Hook 적용

**사용법**:
- Matcher에 `Tool(pattern*)` 형식 사용
- 인자 기반 필터링

**예시**:
```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(npm test*)",
        "hooks": [{"type": "command", "command": "echo '🧪 Running tests...'"}]
      },
      {
        "matcher": "Bash(git push*)",
        "hooks": [{"type": "command", "command": ".claude/hooks/pre-push-check.sh"}]
      }
    ]
  }
}
```

---

### 7.5 MCP Tool Matching

**역할**: MCP 서버 도구에 Hook 적용

**사용법**:
- Matcher에 `mcp__servername__toolname` 패턴
- 와일드카드 `.*` 지원

**예시**:
```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__memory__.*",
        "hooks": [{"type": "command", "command": "echo '💾 Memory operation'"}]
      },
      {
        "matcher": "mcp__github__create_pull_request",
        "hooks": [{"type": "command", "command": ".claude/hooks/pr-check.sh"}]
      }
    ]
  }
}
```

---

### 7.6 Prompt-Type Hook

**역할**: LLM이 Hook 결정을 평가 (비용 발생)

**사용법**:
- `type: "prompt"` 설정
- LLM이 평가하여 결정

**예시**:
```json
{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "prompt",
        "prompt": "Review whether the task is complete. If all requirements are met, respond with 'complete'. If work remains, respond with 'continue' and specify what needs to be done."
      }]
    }]
  }
}
```

**⚠️ 주의**: API 비용 발생, 느림. 단순 규칙은 command 타입 권장.

---

## 빠른 참조표

| # | 패턴 | Event | 핵심 메커니즘 |
|---|------|-------|--------------|
| 1 | Iteration Control | Stop | 카운터 파일 + exit 2/0 |
| 2 | Force Continuation | Stop | exit 2 → Claude 계속 |
| 3 | Promise Detection | Stop | transcript 분석 |
| 4 | Infinite Loop Prevention | Stop | stop_hook_active 확인 |
| 5 | Threshold Branching | Stop | 에러 카운트 임계값 |
| 6 | Input Modification | PreToolUse | updatedInput JSON |
| 7 | Path Normalization | PreToolUse | cwd + 상대경로 |
| 8 | Environment Injection | PreToolUse | 명령 프리픽스 |
| 9 | Dry-run Enforcement | PreToolUse | 플래그 자동 추가 |
| 10 | Context Injection | UserPromptSubmit | stdout → 컨텍스트 |
| 11 | Progressive Loading | UserPromptSubmit | 키워드 조건부 로드 |
| 12 | Skill Auto-Activation | UserPromptSubmit | 패턴 → 스킬 제안 |
| 13 | Transcript Parsing | Stop | jsonl 파일 분석 |
| 14 | Transcript Backup | PreCompact | 파일 복사 |
| 15 | Session Cache | PostToolUse | JSON 파일 누적 |
| 16 | Session Lifecycle | Start/End | 초기화/정리 |
| 17 | Checkpoint Commit | PostToolUse | git commit |
| 18 | Session Branching | SessionStart | git branch 격리 |
| 19 | Notification Forwarding | Notification | HTTP webhook |
| 20 | Desktop/Audio Alert | Notification | osascript/notify-send |
| 21 | Subagent Correlation | SubagentStop | tool_use_id 추적 |
| 22 | Auto-Approval | PermissionRequest | permissionDecision: allow |
| 23 | Secret Scanning | PreToolUse | regex 패턴 차단 |
| 24 | Compliance Audit | PostToolUse | 감사 로그 기록 |
| 25 | TypeScript Delegation | Any | bun/tsx 실행 |
| 26 | Hook Chaining | Any | hooks 배열 순차 실행 |
| 27 | Background Execution | Any | & 또는 background 옵션 |
| 28 | Argument Pattern | PreToolUse | Bash(npm test*) |
| 29 | MCP Tool Matching | PreToolUse | mcp__*__.* |
| 30 | Prompt-Type Hook | Any | type: "prompt" |

---

## 검증 상태 (2025-12-30)

| 항목 | 상태 | 참고 |
|------|------|------|
| stdin JSON 전달 | ✅ 검증됨 | session_id, cwd, transcript_path |
| tool_response (PostToolUse) | ✅ 검증됨 | tool_result 아님 |
| stop_hook_active | ✅ 검증됨 | Stop 이벤트 전용 |
| tool_use_id | ✅ 검증됨 | Pre/PostToolUse |
| updatedInput | 미검증 | 새 세션 필요 |
| permissionDecision | 미검증 | PermissionRequest 필요 |
| prompt-type hook | 미검증 | 별도 테스트 필요 |

```

### references/real-world-examples.md

```markdown
# Real-World Examples

검증된 실제 구현 사례 분석.

---

## 1. serena-refactor: State Machine Pattern

**출처**: `~/.claude/plugins/cache/serena-refactor-marketplace/serena-refactor/`

### 구조
```
워크플로우 Phase:
analyze → plan → execute → audit → complete

상태 파일:
.refactor-analysis-done
.refactor-plan-approved
.refactor-execution-done
.refactor-audit-passed
```

### PreToolUse: Phase Gate
```bash
# executor 실행 전 검사
SUBAGENT=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // ""')
[[ "$SUBAGENT" != *"executor"* ]] && exit 0

BLOCKED=0
if [ ! -f .refactor-analysis-done ]; then
    echo "❌ BLOCKED: Analysis not completed"
    BLOCKED=1
fi
if [ ! -f .refactor-plan-approved ]; then
    echo "❌ BLOCKED: Plan not approved"
    BLOCKED=1
fi

[ $BLOCKED -eq 1 ] && exit 1
```

### PostToolUse: State Creation
```bash
# analyzer 완료 후
SUBAGENT=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // ""')
[[ "$SUBAGENT" != *"analyzer"* ]] && exit 0

touch .refactor-analysis-done
echo "✓ Analysis Complete - [.refactor-analysis-done] created"
```

### PostToolUse: Conditional State (Result-Based)
```bash
# auditor 결과 검사
OUTPUT=$(echo "$INPUT" | jq -r '.tool_result // ""')

# PASS면 상태 정리
if echo "$OUTPUT" | grep -qE 'VERDICT: PASS'; then
    touch .refactor-audit-passed
    rm -f .refactor-analysis-done .refactor-plan-approved .refactor-execution-done
fi
```

### Stop: Workflow Summary
```bash
# 세션 종료 시 상태 요약
if ls .refactor-* 2>/dev/null | grep -q .; then
    echo "⚠️ In-progress workflow:"
    ls -la .refactor-* | awk '{print "  " $NF}'
fi
```

**핵심 인사이트**:
- Hook이 State를 직접 관리 (파일 기반)
- tool_result 파싱으로 조건부 상태 변경
- PreToolUse로 phase transition 강제

---

## 2. serena-project-sync: MCP Integration

**출처**: `~/.claude/scripts/serena-project-sync.py`

### SessionStart에서 MCP 호출
```python
async def activate_project(project: str):
    base_url = "http://localhost:8765"
    
    async with httpx.AsyncClient() as client:
        # 1. SSE 연결
        async with client.stream("GET", f"{base_url}/sse") as sse:
            async for line in sse.aiter_lines():
                # 2. session_id 획득
                if "session_id=" in line:
                    session_id = line.split("session_id=")[1]
                    
                    # 3. MCP initialize
                    await client.post(
                        f"{base_url}/messages/?session_id={session_id}",
                        json={"jsonrpc": "2.0", "method": "initialize", ...}
                    )
                    
                    # 4. tools/call
                    await client.post(
                        f"{base_url}/messages/?session_id={session_id}",
                        json={
                            "jsonrpc": "2.0",
                            "method": "tools/call",
                            "params": {"name": "activate_project", "arguments": {...}}
                        }
                    )
```

**핵심 인사이트**:
- Hook에서 MCP 서버와 직접 통신 가능
- SSE 프로토콜로 양방향 통신
- 세션 시작 시 자동 프로젝트 활성화

---

## 3. GitButler: Branch Management

**출처**: GitButler Docs

### 구조
```json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Edit|MultiEdit|Write",
      "hooks": [{ "command": "but claude pre-tool" }]
    }],
    "PostToolUse": [{
      "matcher": "Edit|MultiEdit|Write",
      "hooks": [{ "command": "but claude post-tool" }]
    }],
    "Stop": [{
      "hooks": [{ "command": "but claude stop" }]
    }]
  }
}
```

**핵심 인사이트**:
- 파일 변경마다 GitButler에 알림
- 세션별 브랜치 자동 분리
- 병렬 Claude 세션도 브랜치 격리

---

## 4. claude-code-hooks-observability: Dashboard

**출처**: disler/claude-code-hooks-multi-agent-observability

### PostToolUse: 외부 서버 전송
```bash
uv run .claude/hooks/send_event.py \
    --source-app PROJECT_NAME \
    --event-type PostToolUse \
    --summarize
```

### 서버 처리
```
Event → HTTP POST → SQLite 저장 → WebSocket broadcast → Vue 대시보드
```

**핵심 인사이트**:
- Hook → HTTP → 실시간 대시보드
- 멀티 에이전트 모니터링
- 이벤트 기반 아키텍처

---

## 5. 공식 문서: Auto-formatting

**출처**: Claude Code Docs

### PostToolUse: Prettier
```json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "command": "jq -r '.tool_input.file_path' | xargs -I {} prettier --write {}"
      }]
    }]
  }
}
```

### Stop: Quality Gate
```bash
#!/bin/bash
pnpm install
pnpm check  # biome format + lint

if ! pnpm test:e2e; then
    echo "e2e failed" >&2
    exit 2  # Claude 계속 작업하게
fi
```

**핵심 인사이트**:
- PostToolUse로 자동 포맷팅
- Stop으로 품질 강제
- exit 2로 작업 계속 유도

---

## 6. claude-mem: Observation Storage

**출처**: `~/.claude/plugins/cache/thedotmack/claude-mem/`

### PostToolUse: 자동 저장
```javascript
// save-hook.js
// 모든 도구 결과를 자동으로 claude-mem에 저장
POST http://127.0.0.1:37777/api/sessions/observations
{
  "claudeSessionId": "...",
  "tool_name": "...",
  "tool_input": "...",
  "tool_response": "..."
}
```

### SessionStart: 컨텍스트 로드
```javascript
// context-hook.js
// 최근 observation 로드하여 Claude 컨텍스트에 주입
```

**핵심 인사이트**:
- Hook으로 모든 작업 자동 기록
- Worker HTTP API로 구조화 저장
- 세션 간 지속성 확보

---

## 패턴 요약

| 사례 | Hook 역할 | 핵심 기술 |
|------|-----------|-----------|
| serena-refactor | State Manager | 파일 기반 state machine |
| serena-project-sync | External Integrator | MCP SSE 프로토콜 |
| GitButler | Side Effect + Integrator | 외부 CLI 호출 |
| observability | External Integrator | HTTP + WebSocket |
| 공식 포맷팅 | Side Effect | 자동 도구 실행 |
| claude-mem | State + Integrator | HTTP API + 자동 저장 |

```

### references/advanced-patterns.md

```markdown
# Advanced Hook Patterns

고급 Hook 패턴의 일반론적 접근법과 구현 예제.

---

## 1. Iteration Control (반복 제어)

### 일반론적 접근

**목적**: Claude가 작업을 반복 수행하도록 강제하고, 최대 반복 횟수를 제한

**핵심 원리**:
1. 상태 파일에 현재 iteration 저장
2. Stop hook에서 iteration 체크
3. 최대 도달 전 → exit 2로 종료 차단 + 프롬프트 재전송
4. 최대 도달 후 → exit 0으로 종료 허용

**적용 시나리오**:
- 자율 에이전트 루프 (무한 반복 방지)
- 자동 리팩토링 사이클
- 테스트-수정 반복 루프

### 구현 예제

**상태 파일 형식** (`.claude/loop-state.md`):
```markdown
---
iteration: 3
max_iterations: 10
task: "버그 수정 완료까지 반복"
---
[Claude에게 전달할 프롬프트]
```

**Stop Hook** (`iteration-control.sh`):
```bash
#!/bin/bash
set -euo pipefail

STATE_FILE=".claude/loop-state.md"
HOOK_INPUT=$(cat)

# 상태 파일 없으면 종료 허용
[[ ! -f "$STATE_FILE" ]] && exit 0

# YAML frontmatter 파싱
ITERATION=$(sed -n '/^---$/,/^---$/p' "$STATE_FILE" | grep '^iteration:' | sed 's/iteration: *//')
MAX_ITER=$(sed -n '/^---$/,/^---$/p' "$STATE_FILE" | grep '^max_iterations:' | sed 's/max_iterations: *//')

# 최대 반복 도달 시 종료 허용
if [[ $ITERATION -ge $MAX_ITER ]]; then
    echo "🛑 최대 반복($MAX_ITER) 도달"
    rm "$STATE_FILE"
    exit 0
fi

# iteration 증가
NEXT=$((ITERATION + 1))
sed -i "s/^iteration: .*/iteration: $NEXT/" "$STATE_FILE"

# 프롬프트 추출 (frontmatter 이후)
PROMPT=$(awk '/^---$/{i++; next} i>=2' "$STATE_FILE")

# 종료 차단 + 프롬프트 재전송
jq -n --arg p "$PROMPT" --arg m "🔄 Iteration $NEXT/$MAX_ITER" \
  '{"decision":"block", "reason":$p, "systemMessage":$m}'
```

### 작동 시나리오

```
사용자: "모든 테스트가 통과할 때까지 버그를 수정해"

[Iteration 1] Claude: 첫 번째 버그 수정
→ Stop hook: iteration=1 < max=5, 종료 차단
→ "버그 수정 완료까지 반복" 프롬프트 재전송

[Iteration 2] Claude: 두 번째 버그 수정
→ Stop hook: iteration=2 < max=5, 종료 차단

[Iteration 3] Claude: 테스트 모두 통과!
→ 사용자가 /cancel-loop 실행 또는 max 도달까지 계속
```

---

## 2. Promise Detection (약속 패턴 감지)

### 일반론적 접근

**목적**: Claude가 특정 문구를 출력하면 조기에 루프 종료

**핵심 원리**:
1. 상태 파일에 `completion_promise` 정의
2. Stop hook에서 transcript 파싱
3. Claude 응답에 `<promise>...</promise>` 태그 감지
4. promise 내용이 일치하면 종료 허용

**적용 시나리오**:
- 목표 달성 시 자동 종료
- 조건부 완료 (테스트 통과, 빌드 성공 등)
- 에이전트 자율 판단 종료

### 구현 예제

**상태 파일** (`.claude/promise-loop.md`):
```markdown
---
iteration: 0
max_iterations: 20
completion_promise: "모든 테스트 통과"
---
테스트를 실행하고 실패하면 수정하세요.
완료되면 <promise>모든 테스트 통과</promise>를 출력하세요.
```

**Stop Hook** (`promise-detection.sh`):
```bash
#!/bin/bash
set -euo pipefail

STATE_FILE=".claude/promise-loop.md"
HOOK_INPUT=$(cat)

[[ ! -f "$STATE_FILE" ]] && exit 0

# completion_promise 추출
PROMISE=$(sed -n '/^---$/,/^---$/p' "$STATE_FILE" | \
  grep '^completion_promise:' | sed 's/completion_promise: *//' | \
  sed 's/^"\(.*\)"$/\1/')

# transcript에서 마지막 assistant 응답 추출
TRANSCRIPT=$(echo "$HOOK_INPUT" | jq -r '.transcript_path')
LAST_OUTPUT=$(grep '"role":"assistant"' "$TRANSCRIPT" | tail -1 | \
  jq -r '.message.content | map(select(.type=="text")) | map(.text) | join("\n")')

# <promise>...</promise> 태그 추출
PROMISE_TEXT=$(echo "$LAST_OUTPUT" | \
  perl -0777 -pe 's/.*?<promise>(.*?)<\/promise>.*/$1/s' 2>/dev/null || echo "")

# promise 일치 시 종료 허용
if [[ -n "$PROMISE_TEXT" ]] && [[ "$PROMISE_TEXT" = "$PROMISE" ]]; then
    echo "✅ Promise 달성: $PROMISE"
    rm "$STATE_FILE"
    exit 0
fi

# promise 미달성 → 계속
# (iteration control과 결합 가능)
exit 0  # 또는 iteration 로직
```

### 작동 시나리오

```
사용자: 테스트 통과까지 수정 반복 설정

[Iteration 1] Claude: 테스트 실행 → 3개 실패, 수정 시도
[Iteration 2] Claude: 재실행 → 1개 실패, 추가 수정
[Iteration 3] Claude: 재실행 → 모두 통과!
             출력: "<promise>모든 테스트 통과</promise>"
→ Stop hook: promise 감지! 루프 종료
```

---

## 3. Transcript Parsing (응답 분석)

### 일반론적 접근

**목적**: Claude의 이전 응답을 읽고 분석하여 조건부 처리

**핵심 원리**:
1. Stop hook의 입력에서 `transcript_path` 획득
2. JSONL 형식 transcript 파일 파싱
3. `role: assistant` 메시지 필터링
4. 텍스트 내용 추출 및 패턴 매칭

**적용 시나리오**:
- 응답 품질 검사
- 특정 패턴/키워드 감지
- 에러 메시지 자동 처리

### 구현 예제

```bash
#!/bin/bash
# transcript-analyzer.sh

HOOK_INPUT=$(cat)
TRANSCRIPT=$(echo "$HOOK_INPUT" | jq -r '.transcript_path')

# 모든 assistant 응답 추출
RESPONSES=$(grep '"role":"assistant"' "$TRANSCRIPT")

# 마지막 응답만
LAST=$(echo "$RESPONSES" | tail -1)

# 텍스트 추출
TEXT=$(echo "$LAST" | jq -r '
  .message.content |
  map(select(.type == "text")) |
  map(.text) |
  join("\n")
')

# 패턴 분석 예시
if echo "$TEXT" | grep -q "ERROR:"; then
    echo "❌ 에러 감지됨 - 수정 필요" >&2
    exit 2
fi

if echo "$TEXT" | grep -q "TODO:"; then
    echo "⚠️ 미완료 작업 존재" >&2
    exit 2
fi

exit 0
```

---

## 4. Session Cache (세션 캐시)

### 일반론적 접근

**목적**: 세션 동안 발생한 이벤트/결과를 누적 저장

**핵심 원리**:
1. PostToolUse에서 도구 실행 결과 캐시
2. 세션 ID 기반 디렉토리 분리
3. Stop hook에서 누적 데이터 분석
4. 세션 종료 시 캐시 정리

**적용 시나리오**:
- 편집된 파일 목록 추적
- 영향받은 repository 관리
- 빌드 명령 자동 수집

### 구현 예제

**PostToolUse Hook** (`session-cache.sh`):
```bash
#!/bin/bash
set -euo pipefail

INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')

CACHE_DIR=".claude/session-cache/$SESSION_ID"
mkdir -p "$CACHE_DIR"

# Edit/Write 도구면 파일 경로 기록
if [[ "$TOOL_NAME" =~ ^(Edit|Write|MultiEdit)$ ]]; then
    FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
    if [[ -n "$FILE_PATH" ]]; then
        echo "$FILE_PATH" >> "$CACHE_DIR/edited-files.txt"

        # 중복 제거
        sort -u "$CACHE_DIR/edited-files.txt" -o "$CACHE_DIR/edited-files.txt"
    fi
fi

# Bash 도구면 명령어 기록
if [[ "$TOOL_NAME" == "Bash" ]]; then
    COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
    echo "$COMMAND" >> "$CACHE_DIR/commands.txt"
fi

exit 0
```

**Stop Hook에서 활용** (`session-summary.sh`):
```bash
#!/bin/bash

INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')
CACHE_DIR=".claude/session-cache/$SESSION_ID"

if [[ -f "$CACHE_DIR/edited-files.txt" ]]; then
    FILE_COUNT=$(wc -l < "$CACHE_DIR/edited-files.txt")
    echo "📝 이 세션에서 $FILE_COUNT 개 파일 수정됨"

    # TypeScript 파일이 있으면 tsc 실행
    if grep -q "\.tsx\?$" "$CACHE_DIR/edited-files.txt"; then
        if ! npx tsc --noEmit 2>&1; then
            echo "❌ TypeScript 에러 발견" >&2
            exit 2
        fi
    fi
fi

exit 0
```

### 작동 시나리오

```
[PostToolUse] Edit src/auth.ts → 캐시에 기록
[PostToolUse] Edit src/login.tsx → 캐시에 기록
[PostToolUse] Write tests/auth.test.ts → 캐시에 기록

[Stop] 세션 캐시 분석:
→ 3개 파일 수정됨
→ .ts/.tsx 파일 존재 → tsc 실행
→ 에러 발견 → exit 2 → Claude 계속 작업
```

---

## 5. Threshold Branching (임계값 분기)

### 일반론적 접근

**목적**: 에러/경고 수에 따라 다른 처리 전략 적용

**핵심 원리**:
1. 도구 실행 결과에서 에러 수 카운트
2. 임계값에 따른 분기 처리
3. 소량 에러 → 직접 수정 요청
4. 대량 에러 → 전문 에이전트 위임

**적용 시나리오**:
- TypeScript 컴파일 에러 처리
- 린트 경고 처리
- 테스트 실패 처리

### 구현 예제

```bash
#!/bin/bash
# threshold-handler.sh (Stop hook)

# TSC 실행 및 에러 카운트
TSC_OUTPUT=$(npx tsc --noEmit 2>&1 || true)
ERROR_COUNT=$(echo "$TSC_OUTPUT" | grep -cE "\.tsx?.*error TS[0-9]+" || echo 0)

if [[ $ERROR_COUNT -eq 0 ]]; then
    echo "✅ TypeScript 컴파일 성공"
    exit 0

elif [[ $ERROR_COUNT -le 3 ]]; then
    # 소량 에러 → 직접 수정 요청
    echo "⚠️ $ERROR_COUNT 개 에러 발견 - 직접 수정하세요:" >&2
    echo "$TSC_OUTPUT" >&2
    exit 2

elif [[ $ERROR_COUNT -le 10 ]]; then
    # 중간 에러 → 상세 정보 제공
    echo "🔶 $ERROR_COUNT 개 에러 발견" >&2
    echo "가장 심각한 에러들:" >&2
    echo "$TSC_OUTPUT" | head -20 >&2
    exit 2

else
    # 대량 에러 → 에이전트 위임 제안
    echo "🔴 $ERROR_COUNT 개 에러 - auto-error-resolver 사용 권장" >&2
    echo "에러 요약: 타입 불일치, 누락된 import 등" >&2
    exit 2
fi
```

### 작동 시나리오

```
[시나리오 1: 에러 0개]
→ "✅ TypeScript 컴파일 성공"
→ exit 0 → 종료 허용

[시나리오 2: 에러 2개]
→ "⚠️ 2개 에러 발견" + 상세 에러
→ exit 2 → Claude가 직접 수정

[시나리오 3: 에러 15개]
→ "🔴 15개 에러 - auto-error-resolver 사용 권장"
→ exit 2 → Claude가 에이전트 호출 결정
```

---

## 6. TypeScript Delegation (TS 위임)

### 일반론적 접근

**목적**: 복잡한 로직을 TypeScript로 구현하여 유지보수성 향상

**핵심 원리**:
1. Bash wrapper가 stdin을 TypeScript로 전달
2. TypeScript에서 복잡한 파싱/분석 수행
3. JSON 출력으로 결과 반환
4. npx tsx로 즉시 실행 (컴파일 불필요)

**적용 시나리오**:
- 복잡한 JSON 파싱
- 파일 분석 로직
- 외부 API 호출

### 구현 예제

**Bash Wrapper** (`skill-activation.sh`):
```bash
#!/bin/bash
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

cat | npx tsx skill-activation.ts
```

**TypeScript Handler** (`skill-activation.ts`):
```typescript
import { readFileSync } from 'fs';

interface HookInput {
  session_id: string;
  prompt: string;
  cwd: string;
}

interface SkillRule {
  keywords: string[];
  skill: string;
  description: string;
}

async function main() {
  // stdin 읽기
  const input: HookInput = JSON.parse(
    readFileSync('/dev/stdin', 'utf-8')
  );

  // skill-rules.json 로드
  const rules: SkillRule[] = JSON.parse(
    readFileSync('.claude/skill-rules.json', 'utf-8')
  );

  // 프롬프트 분석
  const prompt = input.prompt.toLowerCase();
  const suggestions: string[] = [];

  for (const rule of rules) {
    if (rule.keywords.some(kw => prompt.includes(kw))) {
      suggestions.push(`/${rule.skill} - ${rule.description}`);
    }
  }

  // 제안 출력 (stdout → 사용자에게 표시)
  if (suggestions.length > 0) {
    console.log('💡 추천 스킬:');
    suggestions.forEach(s => console.log(`  ${s}`));
  }
}

main().catch(console.error);
```

---

## 7. Skill Auto-Activation (스킬 자동 활성화)

### 일반론적 접근

**목적**: 사용자 프롬프트나 파일 컨텍스트 분석하여 관련 스킬 자동 제안

**핵심 원리**:
1. UserPromptSubmit hook에서 프롬프트 분석
2. `skill-rules.json`에 키워드-스킬 매핑 정의
3. 매칭되는 스킬 stdout으로 제안
4. 사용자가 선택적으로 사용

**적용 시나리오**:
- "커밋" 언급 시 /commit 스킬 제안
- TypeScript 파일 수정 시 타입 체크 스킬 제안
- 테스트 관련 질문 시 테스트 스킬 제안

### 구현 예제

**skill-rules.json**:
```json
[
  {
    "keywords": ["커밋", "commit", "git add"],
    "skill": "commit",
    "description": "변경사항 커밋"
  },
  {
    "keywords": ["리뷰", "review", "PR", "pull request"],
    "skill": "review-pr",
    "description": "코드 리뷰"
  },
  {
    "keywords": ["테스트", "test", "jest", "vitest"],
    "skill": "run-tests",
    "description": "테스트 실행"
  }
]
```

**UserPromptSubmit Hook**:
```bash
#!/bin/bash

INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt' | tr '[:upper:]' '[:lower:]')

# 간단한 키워드 매칭 (복잡하면 TS 위임)
if echo "$PROMPT" | grep -qE "커밋|commit"; then
    echo "💡 추천: /commit - 변경사항 커밋하기"
fi

if echo "$PROMPT" | grep -qE "리뷰|review|pr"; then
    echo "💡 추천: /review-pr - 코드 리뷰하기"
fi

exit 0
```

---

## 8. Progressive Loading (점진적 로딩)

### 일반론적 접근

**목적**: 필요할 때만 컨텍스트나 스킬을 로드하여 효율성 향상

**핵심 원리**:
1. 초기 로드는 최소화
2. 특정 조건 충족 시 추가 컨텍스트 로드
3. PreToolUse에서 도구별 컨텍스트 주입
4. 불필요한 정보 로드 방지

**적용 시나리오**:
- 대규모 프로젝트 가이드라인 선택적 로드
- 도구별 전문 지침 주입
- 파일 타입별 규칙 로드

### 구현 예제

**PreToolUse Hook** (`progressive-context.sh`):
```bash
#!/bin/bash

INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')

# 도구별 컨텍스트 로드
case "$TOOL_NAME" in
    "Edit"|"Write")
        FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

        # TypeScript 파일이면 TS 가이드라인 로드
        if [[ "$FILE_PATH" == *.ts ]] || [[ "$FILE_PATH" == *.tsx ]]; then
            if [[ -f ".claude/guides/typescript.md" ]]; then
                echo "📘 TypeScript 가이드라인:"
                cat ".claude/guides/typescript.md"
            fi
        fi

        # 테스트 파일이면 테스트 가이드라인 로드
        if [[ "$FILE_PATH" == *.test.* ]] || [[ "$FILE_PATH" == *.spec.* ]]; then
            if [[ -f ".claude/guides/testing.md" ]]; then
                echo "📘 테스트 작성 가이드라인:"
                cat ".claude/guides/testing.md"
            fi
        fi
        ;;

    "Bash")
        COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

        # git 명령이면 git 가이드라인 로드
        if echo "$COMMAND" | grep -q "^git "; then
            if [[ -f ".claude/guides/git-conventions.md" ]]; then
                echo "📘 Git 컨벤션:"
                cat ".claude/guides/git-conventions.md"
            fi
        fi
        ;;
esac

exit 0
```

### 작동 시나리오

```
[Claude가 src/auth.ts 수정 시도]
→ PreToolUse: Edit 도구, .ts 파일 감지
→ typescript.md 가이드라인 stdout으로 출력
→ Claude가 가이드라인 참고하여 수정

[Claude가 auth.test.ts 작성 시도]
→ PreToolUse: Write 도구, .test.ts 파일 감지
→ testing.md 가이드라인 stdout으로 출력
→ Claude가 테스트 규칙 따라 작성
```

---

## 패턴 조합 예시

### 자율 에이전트 루프

**Iteration Control + Promise Detection + Threshold Branching** 조합:

```bash
#!/bin/bash
# autonomous-agent.sh (Stop hook)

STATE_FILE=".claude/agent-state.md"
HOOK_INPUT=$(cat)

[[ ! -f "$STATE_FILE" ]] && exit 0

# 1. Promise Detection
TRANSCRIPT=$(echo "$HOOK_INPUT" | jq -r '.transcript_path')
LAST=$(grep '"role":"assistant"' "$TRANSCRIPT" | tail -1 | jq -r '...')
if echo "$LAST" | grep -q "<promise>TASK_COMPLETE</promise>"; then
    echo "✅ 작업 완료!"
    rm "$STATE_FILE"
    exit 0
fi

# 2. Threshold Branching
ERROR_COUNT=$(npx tsc --noEmit 2>&1 | grep -c "error TS" || echo 0)
if [[ $ERROR_COUNT -gt 10 ]]; then
    echo "🔴 에러 과다 - 전략 재검토 필요" >&2
fi

# 3. Iteration Control
ITER=$(grep '^iteration:' "$STATE_FILE" | sed 's/iteration: *//')
MAX=$(grep '^max_iterations:' "$STATE_FILE" | sed 's/max_iterations: *//')

if [[ $ITER -ge $MAX ]]; then
    echo "🛑 최대 반복 도달"
    rm "$STATE_FILE"
    exit 0
fi

# 계속 진행
sed -i "s/^iteration: .*/iteration: $((ITER + 1))/" "$STATE_FILE"
PROMPT=$(awk '/^---$/{i++; next} i>=2' "$STATE_FILE")

jq -n --arg p "$PROMPT" --arg m "🔄 Iteration $((ITER+1))/$MAX | Errors: $ERROR_COUNT" \
  '{"decision":"block", "reason":$p, "systemMessage":$m}'
```

---

## 9. Input Modification (입력 수정)

### 일반론적 접근

**목적**: PermissionRequest에서 도구 입력을 자동으로 수정/보강

**핵심 원리**:
1. PermissionRequest hook에서 tool_input 분석
2. `updatedInput` 필드로 수정된 입력 반환
3. Claude가 수정된 입력으로 도구 실행

**적용 시나리오**:
- npm 명령에 자동으로 플래그 추가
- 파일 경로 자동 보정
- 명령어 보안 강화

### 구현 예제

```bash
#!/bin/bash
# input-modifier.sh (PermissionRequest hook)

INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# npm install에 자동으로 --save-dev 추가
if [[ "$TOOL_NAME" == "Bash" ]] && echo "$COMMAND" | grep -q "^npm install"; then
    MODIFIED=$(echo "$COMMAND" | sed 's/npm install/npm install --save-dev/')

    jq -n --arg cmd "$MODIFIED" '{
      "hookSpecificOutput": {
        "decision": {
          "behavior": "allow",
          "updatedInput": {"command": $cmd}
        }
      }
    }'
    exit 0
fi

# 기본: 그대로 허용
echo '{"hookSpecificOutput":{"decision":{"behavior":"allow"}}}'
```

### 작동 시나리오

```
[Claude가 실행하려는 명령]
npm install lodash

[PermissionRequest hook]
→ npm install 감지
→ --save-dev 플래그 추가

[실제 실행되는 명령]
npm install --save-dev lodash
```

---

## 10. Context Injection (컨텍스트 주입)

### 일반론적 접근

**목적**: UserPromptSubmit에서 자동으로 추가 컨텍스트를 Claude에게 주입

**핵심 원리**:
1. UserPromptSubmit hook에서 stdout 출력
2. 출력 내용이 Claude 컨텍스트에 자동 추가
3. Claude가 추가 정보를 참고하여 응답

**적용 시나리오**:
- git status 자동 주입
- TODO 목록 자동 표시
- 최근 에러 로그 주입

### 구현 예제

```bash
#!/bin/bash
# context-injector.sh (UserPromptSubmit hook)

# 현재 git 상태 주입
echo "📋 현재 Git 상태:"
git status --short 2>/dev/null || echo "(git 저장소 아님)"
echo ""

# 미완료 TODO 주입
if [[ -f "TODO.md" ]]; then
    echo "📝 미완료 TODO:"
    grep -E "^\s*-\s*\[ \]" TODO.md | head -5
    echo ""
fi

# 최근 에러 로그 주입
if [[ -f ".claude/last-error.log" ]]; then
    echo "⚠️ 마지막 에러:"
    tail -5 ".claude/last-error.log"
    echo ""
fi

exit 0
```

### 작동 시나리오

```
[사용자 입력]
"버그 수정해줘"

[UserPromptSubmit hook 실행]
stdout 출력:
📋 현재 Git 상태:
 M src/auth.ts
 M src/login.tsx

📝 미완료 TODO:
- [ ] 로그인 에러 핸들링

⚠️ 마지막 에러:
TypeError: Cannot read property 'user' of undefined

[Claude가 받는 컨텍스트]
사용자 입력 + 위 정보 자동 포함
→ Claude가 맥락을 파악하고 정확한 수정
```

---

## 11. Secret Scanning (비밀 정보 감지)

### 일반론적 접근

**목적**: API 키, 비밀번호 등이 코드에 포함되면 차단

**핵심 원리**:
1. PreToolUse에서 Edit/Write 도구 입력 검사
2. 정규식으로 비밀 정보 패턴 감지
3. 감지 시 exit 2로 차단 + 경고

**적용 시나리오**:
- API 키 하드코딩 방지
- 비밀번호 노출 방지
- 개인정보 보호

### 구현 예제

```bash
#!/bin/bash
# secret-scanner.sh (PreToolUse hook, matcher: "Edit|Write")

INPUT=$(cat)
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // .tool_input.new_string // empty')

# 비밀 정보 패턴
PATTERNS=(
    'AKIA[0-9A-Z]{16}'                    # AWS Access Key
    'sk-[a-zA-Z0-9]{48}'                  # OpenAI API Key
    'ghp_[a-zA-Z0-9]{36}'                 # GitHub Personal Token
    'password\s*[:=]\s*["\x27][^"\x27]+'  # password = "..."
    'api[_-]?key\s*[:=]\s*["\x27][^"\x27]+' # api_key = "..."
)

for PATTERN in "${PATTERNS[@]}"; do
    if echo "$CONTENT" | grep -qiE "$PATTERN"; then
        echo "🔴 비밀 정보 감지됨!" >&2
        echo "패턴: $PATTERN" >&2
        echo "환경변수나 .env 파일을 사용하세요." >&2
        exit 2
    fi
done

exit 0
```

### 작동 시나리오

```
[Claude가 시도하는 코드]
const apiKey = "sk-abc123...";  // OpenAI API Key

[PreToolUse hook]
→ 패턴 매칭: sk-[a-zA-Z0-9]{48}
→ "🔴 비밀 정보 감지됨!"
→ exit 2 → 쓰기 차단

[Claude 응답]
"비밀 정보가 감지되어 차단되었습니다.
환경변수를 사용하도록 수정하겠습니다:
const apiKey = process.env.OPENAI_API_KEY;"
```

---

## 12. Desktop/Audio Alert (데스크톱 알림)

### 일반론적 접근

**목적**: Notification 이벤트를 데스크톱 알림이나 음성으로 전달

**핵심 원리**:
1. Notification hook에서 메시지 추출
2. OS별 알림 도구 호출
3. 선택적으로 TTS(Text-to-Speech) 사용

**적용 시나리오**:
- 장시간 작업 완료 알림
- 에러 발생 즉시 알림
- 중요 이벤트 음성 안내

### 구현 예제

```bash
#!/bin/bash
# desktop-alert.sh (Notification hook)

INPUT=$(cat)
MESSAGE=$(echo "$INPUT" | jq -r '.message')

# macOS
if [[ "$OSTYPE" == "darwin"* ]]; then
    osascript -e "display notification \"$MESSAGE\" with title \"Claude Code\""
    # TTS (선택)
    say "$MESSAGE" &

# Linux
elif command -v notify-send &>/dev/null; then
    notify-send "Claude Code" "$MESSAGE"
    # TTS (선택)
    if command -v espeak &>/dev/null; then
        espeak "$MESSAGE" &
    fi

# Windows (WSL)
elif command -v powershell.exe &>/dev/null; then
    powershell.exe -Command "[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType=WindowsRuntime] | Out-Null; \$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText01); \$template.GetElementsByTagName('text')[0].AppendChild(\$template.CreateTextNode('$MESSAGE')) | Out-Null; [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Claude').Show([Windows.UI.Notifications.ToastNotification]::new(\$template))"
fi

exit 0
```

---

## 13. Prompt-Type Hook (LLM 기반 평가)

### 일반론적 접근

**목적**: 복잡한 판단이 필요한 경우 LLM으로 평가

**핵심 원리**:
1. `type: "prompt"` 훅 정의
2. 템플릿에 도구 입력 삽입
3. LLM이 평가하여 허용/차단 결정

**주의사항**:
- API 비용 발생
- 응답 지연 있음
- 복잡한 판단에만 사용

### 구현 예제

**settings.json**:
```json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "prompt",
        "prompt": "다음 bash 명령이 안전한지 평가하세요:\n\n명령: {{tool_input.command}}\n\n위험한 경우 'BLOCK: [이유]'로 시작하고,\n안전한 경우 'ALLOW'로 시작하세요."
      }]
    }]
  }
}
```

### 작동 시나리오

```
[Claude가 실행하려는 명령]
rm -rf /tmp/cache/*

[Prompt-Type Hook]
LLM에게 질문:
"다음 bash 명령이 안전한지 평가하세요:
명령: rm -rf /tmp/cache/*"

[LLM 응답]
"ALLOW - /tmp/cache 디렉토리 정리는 안전합니다."

[결과]
→ 명령 실행 허용
```

---

## 패턴 조합 예시

### 보안 강화 파이프라인

**Secret Scanning + Input Modification + Threshold Branching** 조합:

```bash
#!/bin/bash
# security-pipeline.sh

INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name')

# 1. Secret Scanning
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // empty')
if echo "$CONTENT" | grep -qiE 'sk-[a-zA-Z0-9]{48}'; then
    echo "🔴 API 키 감지 - 차단" >&2
    exit 2
fi

# 2. Input Modification (Bash 명령 안전화)
if [[ "$TOOL" == "Bash" ]]; then
    CMD=$(echo "$INPUT" | jq -r '.tool_input.command')
    # rm 명령에 -i 플래그 강제
    if echo "$CMD" | grep -q "^rm "; then
        SAFE_CMD=$(echo "$CMD" | sed 's/^rm /rm -i /')
        jq -n --arg c "$SAFE_CMD" '{
          "hookSpecificOutput": {
            "decision": {"behavior":"allow", "updatedInput":{"command":$c}}
          }
        }'
        exit 0
    fi
fi

# 3. 기본 허용
exit 0
```

---

## 요약

| 패턴 | 핵심 기술 | 주요 용도 |
|------|----------|----------|
| Iteration Control | 상태 파일 + sed | 반복 제한 |
| Promise Detection | Transcript + perl | 조건부 종료 |
| Transcript Parsing | jq + grep | 응답 분석 |
| Session Cache | 세션별 디렉토리 | 결과 누적 |
| Threshold Branching | 에러 카운트 + 조건문 | 분기 처리 |
| TS Delegation | npx tsx | 복잡 로직 |
| Skill Auto-Activation | 키워드 매칭 | 스킬 제안 |
| Progressive Loading | 조건부 cat | 선택적 컨텍스트 |
| **Input Modification** | updatedInput JSON | 입력 자동 수정 |
| **Context Injection** | stdout → 컨텍스트 | 자동 정보 주입 |
| **Secret Scanning** | 정규식 패턴 매칭 | 비밀 정보 차단 |
| **Desktop Alert** | osascript/notify-send | 알림 연동 |
| **Prompt-Type Hook** | type: "prompt" | LLM 기반 평가 |

---

## 14. Hook에서 LLM 호출

Hook에서 Claude CLI나 SDK를 통해 LLM을 호출하는 패턴은 별도 스킬로 분리되었습니다.

**→ [hook-sdk-integration](../../hook-sdk-integration/SKILL.md) 스킬 참조**

포함 내용:
- CLI 직접 호출 패턴
- u-llm-sdk / claude-only-sdk 사용법
- Background Agent (비차단 실행)
- 비용 최적화 전략
- 실제 GitHub 프로젝트 사례

```

hook-capabilities | SkillHub