
Claude Code, Codex, Gemini cli, Openclaw 등 여러 에이전트와 omc 등의 하네스를 사용해보며, 진짜 생산성 차이는 Harness를 얼마나 잘 세팅하느냐에서 갈린다고 느낍니다.
AI Templates, Vercel의 Skills 등 커뮤니티에서 만들어둔 것을 npx로 설치하기는 쉽지만, 직접 이해하고 스스로 필요한 기능을 만들지 못하는 경우가 많은 것 같습니다.
(Skills만 해도 사용자가 직접 호출하는 방식, 모델이 자동 호출하는 방식, 둘을 결합하는 방식 등 여러 선택지가 있는데, 이런 옵션이 있다는 것 자체를 모르는 분들도 계신 것 같습니다.)
특히 skill_creator 등으로 custom skill을 사용하는 경우가 많은데, 모든 지시사항을 전부 skill로 만들어서 활용하는 경우가 종종 있는 것 같습니다.
따라서 이번 포스팅에서는 Claude Code의 Harness Engineering 기능들을 전체적으로 조사하고, 각 기능이 어떤 문제를 해결하는지, 그리고 어떤 구조로 직접 만드는지를 정리하려고 합니다.
1편에서는 메모리, Hooks, Skills, Subagents, MCP Servers를 다루고, 2편에서 Permissions/Sandbox, Plugins, 세션 관리, Agent Teams 등을 다뤄보도록 하겠습니다.
Claude Code의 세션은 매번 빈 컨텍스트로 시작됩니다. 어제 "type hint 꼭 붙여"라고 말한 것을 오늘은 모릅니다. 이 문제를 해결하는 메커니즘이 세 가지 있습니다.
세 가지 모두 고우선순위(high priority)로 컨텍스트에 로딩된다. Claude는 일반 채팅 메시지보다 이 지침들을 더 엄격하게 따릅니다.
CLAUDE.md는 Claude Code가 세션 시작 시 자동으로 읽는 설정 파일입니다. 일반적으로 빌드 명령, 코딩 컨벤션, 아키텍처 결정, 금지 패턴 등을 기록합니다.
여러 위치에 둘 수 있으며, 위치에 따라 범위가 달라집니다.
| 위치 | 범위 | 용도 |
|---|---|---|
| 관리자 정책* | 조직 (제외 불가) | 조직 정책 강제 |
~/.claude/CLAUDE.md | 전역 | 개인 작업 스타일 |
./CLAUDE.md 또는 .claude/CLAUDE.md | 프로젝트 | 팀 규칙 (VCS 커밋) |
./CLAUDE.local.md | 프로젝트 (개인) | 로컬 설정 (자동 .gitignore) |
하위디렉토리/CLAUDE.md | 디렉토리 | 해당 디렉토리 작업 시 온디맨드 |
*macOS: /Library/Application Support/ClaudeCode/CLAUDE.md, Linux: /etc/claude-code/CLAUDE.md
상위 디렉토리의 CLAUDE.md는 세션 시작 시 전부 로딩되고, 하위 디렉토리의 것은 Claude가 해당 디렉토리의 파일을 읽을 때 온디맨드로 로딩됩니다.
CLAUDE.md 안에서 @경로 문법으로 다른 파일을 인라인 참조할 수 있습니다. 로드 시점에 확장되며(lazy가 아님), 재귀 참조는 최대 5단계까지 지원됩니다. 코드 블록 안의 @경로는 무시됩니다.
불필요한 상위 CLAUDE.md를 제외할 수도 있습니다.
특정 목적의 Harness를 소속/외부 팀에 공유할 때 상위 지시사항 때문에 성능 저하가 발생하거나, 외부 plugin이나 harness를 설치해서 사용하는 등의 상황에 활용할 수 있습니다.
// .claude/settings.local.json
{
"claudeMdExcludes": [
"**/monorepo/CLAUDE.md",
"/home/user/monorepo/other-team/.claude/rules/**"
]
}
CLAUDE.md가 200줄을 넘어가기 시작하면 문제가 생긴다고 경고하고 있습니다. .claude/rules/는 규칙을 주제별 파일로 분리하고, 특정 파일을 다룰 때만 해당 규칙이 로딩되도록 경로 스코핑을 걸 수 있습니다.
paths frontmatter가 없으면 세션 시작 시 항상 로딩됩니다. paths가 있으면 매칭되는 파일을 Claude가 읽을 때만 로딩됩니다.
---
paths:
- "src/api/**/*.py"
- "src/handlers/**/*.py"
---
# API 개발 규칙
- 모든 엔드포인트에 입력 검증 포함
- 표준 에러 응답 형식: {"error": str, "code": int}
assets, scripts 등 다양한 경우에 활용할 수 있기 때문에, 최대한 활용하는 것을 권장합니다. 지시사항을 dynamic하게 넣어주어 성능도 향상하고 시간과 비용을 모두 줄이도록 합시다.
심볼릭 링크도 지원되기 때문에, 여러 프로젝트 간 공통 규칙을 공유할 수 있습니다.
# 사내 표준 security rules를 참조.
ln -s ~/company-standards/security.md .claude/rules/security.md
정리하면, 모든 작업에 공통인 내용은 CLAUDE.md에, 특정 파일 유형에만 적용되는 내용은 rules에 paths와 함께 배치하는 것이 기본 원칙입니다.
CLAUDE.md와 rules는 사용자가 직접 작성합니다. 반면 Auto Memory는 Claude가 세션 중 사용자의 교정과 선호를 자동으로 기록하는 시스템입니다.
저장 위치는 ~/.claude/projects/<프로젝트>/memory/이고, 프로젝트 경로는 git 레포 기준으로 파생됩니다. 동일 레포의 모든 worktree가 하나의 메모리를 공유하고, (/memory 명령으로 현재 로딩된 메모리를 확인하고 에디터에서 편집할 수 있습니다./memory 명령은 현재 세션에 입력된 CLAUDE.md 파일 목록 확인 및 편집) 일반 마크다운 파일이므로 직접 삭제도 가능합니다.
메모리 시스템(CLAUDE.md, rules)은 프롬프트 기반이기 때문에, Claude에게 "rm -rf 쓰지 마"라고 적어두면 대부분 따르지만 100%는 아닙니다. Hooks는 이런 문제를 해결하는 기능입니다.
Claude Code 라이프사이클의 특정 시점에 결정론적으로 실행됩니다. LangChain Middleware와 유사한 구조인데, Claude Code에서는 셸 스크립트, HTTP 호출, 프롬프트, 에이전트를 핸들러로 실행합니다.
settings.json 설정 구조settings.json에서 Hook을 설정하는 기본 구조는 다음과 같습니다.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate-bash.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write",
"pathPattern": "*.py",
"hooks": [
{
"type": "command",
"command": "python -m black $CLAUDE_FILE_PATH"
}
]
}
]
}
}
$CLAUDE_PROJECT_DIR 접두사를 사용하면 작업 디렉토리에 관계없이 안정적인 경로 해석이 가능합니다. 설정 변경 후에는 세션을 재시작해야 합니다(세션 시작 시 Hook 설정을 스냅샷).
| 이벤트 | 시점 | exit 2 동작 | 주요 용도 |
|---|---|---|---|
SessionStart | 세션 시작/재개 | - | 환경 초기화 |
UserPromptSubmit | 프롬프트 제출, Claude 처리 전 | - | 프롬프트 검증, 컨텍스트 주입 |
PreToolUse | 도구 실행 직전 | 도구 차단 | 위험 명령 차단 |
PostToolUse | 도구 실행 완료 후 | - | 자동 포맷팅, 테스트 |
PermissionRequest | 권한 다이얼로그 시 | 권한 거부 | 자동 승인/거부 |
Notification | 알림 발송 시 | - | 데스크톱/Slack 알림 |
Stop | 응답 완료 시 | Claude 계속 실행 | 후처리 |
SubagentStop | Subagent 완료 시 | - | 결과 후처리 |
PreCompact | 컨팩션 전 | - | 트랜스크립트 백업 |
이 외에도 PostCompact, InstructionsLoaded, ConfigChange, WorktreeCreate/Remove 등이 있습니다.
(PreToolUse와 PostToolUse는 claude 실행 시 기본 내장)
| 타입 | 설명 | 적합한 용도 |
|---|---|---|
| command | 셸 명령/스크립트 실행 | 포맷팅, 차단, 로깅 (가장 일반적) |
| http | 외부 서비스에 HTTP 요청 | Slack 알림, 외부 API |
| prompt | Claude 모델에 판단 위임 | 의미적 조건 평가 (예: "인증 로직 변경 여부") |
| agent | subagent에 처리 위임 | 복잡한 다단계 추론 |
command 핸들러가 가장 일반적입니다. stdin으로 이벤트 JSON을 받고, exit code로 결과를 제어합니다. exit 0은 허용, exit 2는 차단(PreToolUse에서 도구 실행 차단, Stop에서 Claude 계속 실행)입니다.
(구체적인 활용 방법에 관한 예시는 포스팅 맨 밑에 'Appendix/Hook-command 활용 예시' 참고)
http 핸들러는 주로 외부 서비스 (대부분 webhook 기반 알림?)에 활용합니다. url과 REST API method로 구성할 수 있습니다.
prompt 핸들러는 셸 스크립트로 표현하기 어려운 의미적 조건을 평가할 때 유용합니다. "이 편집이 인증 로직을 변경하는가?" 같이 regex로 잡기 어려운 경우 Claude 모델이 직접 판단하는 방식입니다. (대신 latency, cost에서 손실이 있습니다.)
Matcher는 특정 도구/파일에 대해서만 Hook이 발동하도록 필터링합니다. 생략하면 해당 이벤트의 모든 발생에 대해 실행됩니다. 여러 matcher를 지정하면 AND 로직으로 작동합니다.
| 필드 | 설명 |
|---|---|
matcher | 도구 이름 매칭. 예: "Bash", "Write" |
pathPattern | 파일 경로 glob. 예: "*.py" |
mcpTool | MCP 도구 매칭. 예: "server/tool" |
Ctrl+O: verbose 모드 토글. Hook stdout/stderr를 트랜스크립트에 표시합니다.claude --debug: 매칭된 Hook과 exit code 등 상세 로그를 출력합니다.
.claude/commands/의 slash command는 Skills에 통합되었습니다. 기존 commands/ 파일은 계속 동작하지만, 새로운 작업은 Skills로 만드는 것을 권장하고 있습니다. 동일 이름이 양쪽에 존재하면 skills/가 우선합니다.
메모리 시스템은 항상 컨텍스트에 로딩됩니다. 이것이 장점이자 단점입니다. 배포 절차, PR 리뷰 체크리스트, 보안 감사 가이드 같은 것까지 CLAUDE.md에 넣으면 컨텍스트가 금방 차버리기 때문입니다.
Skills는 필요할 때만 로딩되는 재사용 가능한 지침서입니다. 세션 시작 시에는 각 스킬의 name과 description만 시스템 프롬프트에 올라가고, 실제 내용은 호출 시점에 로딩됩니다(Progressive Disclosure). 수십 개의 스킬을 등록해두어도 컨텍스트 부담이 거의 없습니다.
(plugin으로 다운받아서, 사용하지 않는 스킬을 100개 이상 들고 쓰시는 분들도 많이 있으신 것 같습니다.)
| 위치 | 범위 |
|---|---|
~/.claude/skills/스킬명/SKILL.md | 전역 (모든 프로젝트) |
.claude/skills/스킬명/SKILL.md | 프로젝트 (VCS 커밋) |
스킬 디렉토리 안에 scripts/, references/, assets/ 등 보조 파일을 함께 둘 수 있으며, 이것들도 Claude가 필요할 때만 읽으므로 토큰 소비가 없습니다.
SKILL.md는 YAML frontmatter + Markdown body로 구성된다. frontmatter가 어떻게 실행될지를 설정하고, body가 무엇을 할지를 지시합니다.
---
name: deploy
description: Deploy the application to production. Use when user asks to deploy or release.
disable-model-invocation: true
allowed-tools: Bash, Read
context: fork
agent: general-purpose
argument-hint: [environment]
---
$ARGUMENTS 환경으로 배포를 수행한다.
## 현재 상태
- 브랜치: !`git branch --show-current`
## 절차
1. 테스트 실행
2. 빌드
3. 배포
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
name | string | 디렉토리명 | 스킬 이름. /name으로 호출 |
description | string | (필수 권장) | Claude가 자동 호출 판단에 사용하는 핵심 필드. "언제" 사용해야 하는지 명확히 기술 |
disable-model-invocation | boolean | false | true면 Claude 자동 호출 불가. /name으로만 호출 가능 |
user-invocable | boolean | true | false면 사용자 호출 불가. Claude만 자동 사용 |
allowed-tools | string | 전체 | 스킬 활성 시 사용 가능 도구 제한. 예: Read, Grep, Glob |
model | string | inherit | 실행 모델 (sonnet, opus, haiku) |
effort | string | - | 사고 수준 (low, medium, high, max; max는 max 전용) |
context | string | inherit | inherit: 현재 대화, fork: 별도 subagent 격리 실행 |
agent | string | general-purpose | context: fork 시 사용할 에이전트 타입 |
argument-hint | string/array | - | 커맨드 피커에서 인자 힌트 표시 |
version | string | - | 버전 관리 메타데이터 |
mode | boolean | false | true면 "Mode Commands" 섹션에 별도 표시 |
hooks | object | - | 스킬 전용 훅 |
docs가 최신 버전이 아니어서, 이제 안 쓰는 내용이 꽤 있음. effort는 현재 의미 X.
이 중에서도 호출 방식을 결정하는 세 필드가 가장 중요합니다.
| 설정 | 호출 주체 | 적합한 용도 |
|---|---|---|
| 기본값 | 사용자 + Claude 모두 | 코드 리뷰, 분석 등 안전한 작업 |
disable-model-invocation: true | 사용자만 (/name) | 배포, 커밋 등 부작용이 있는 작업 |
user-invocable: false | Claude만 (자동) | 레거시 시스템 컨텍스트 등 배경 지식 |
"누가 이 스킬의 실행 시점을 결정해야 하는가?"에 따라 달라집니다. 보통, 배포처럼 부작용이 있으면 사용자가, 배경 지식처럼 판단이 필요하면 Claude가 결정하는 것이 자연스러운 흐름인 것 같습니다.
context: fork는 스킬을 별도 subagent에서 격리 실행합니다. 메인 대화의 컨텍스트를 오염시키지 않으므로, 코드베이스 탐색처럼 중간 과정이 많은 작업에 적합합니다.
(자세한 내용 2편 참고)
! + backtick 문법으로 스킬 로드 시 셸 명령 결과를 주입할 수 있다. 전처리(preprocessing)이므로, Claude가 스킬을 보기 전에 명령이 실행되고 Claude는 결과만 보게 됩니다.
- 현재 브랜치: !`git branch --show-current`
- PR diff: !`gh pr diff`
$ARGUMENTS로 호출 시 전달된 인자를 받습니다. /fix-issue 42면 $ARGUMENTS가 42로 치환된다. 위치별 접근은 $ARGUMENTS[0] 또는 $0. 본문에 $ARGUMENTS가 없으면 Claude Code가 자동으로 끝에 추가합니다.
본문 어디서든 "ultrathink"를 포함하면 확장 사고가 활성화됩니다.
(이 기능은 없어진 것으로 알고 있고, 'Ultrathink no longer does anything. Thinking budget is now max by default.' 라는 알림 메세지가 나옵니다. docs가 업데이트가 안되었나봐요.)
${CLAUDE_SESSION_ID}, ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PLUGIN_DATA} 등을 본문에서 사용할 수 있다.
/deploy staging # 사용자 직접 호출
/skills # 사용 가능한 스킬 목록 확인
Claude 자동 호출의 경우, description과 대화 맥락이 매칭되면 Claude가 자동으로 로드합니다. description을 얼마나 구체적으로 쓰느냐가 자동 호출의 정확도를 결정합니다. "코드 리뷰"보다 "Use when user asks for code review, PR feedback, or security audit of changed files"처럼 사람을 위한 description보다는 모델을 위한 description으로 생각하고 적는 것이 좋습니다. 구체적인 트리거 역할.
Subagents는 메인 세션에서 독립된 컨텍스트 윈도우(200K 토큰)를 가진 별도 Claude 인스턴스를 생성하고, 작업 완료 후 결과 요약만 반환합니다.
가장 중요한 점은 context isolation(컨텍스트 격리)입니다. 코드베이스 탐색 중 수천 토큰의 중간 결과가 생기더라도 메인 대화에는 최종 요약만 들어옵니다. 장시간 세션에서 컨텍스트가 노이즈로 가득 차면서 응답 품질이 떨어지는 문제를 방지합니다.
built-in으로 Explore(읽기 전용 탐색, Haiku), Plan(전략 수립, Haiku), General-purpose(범용, 세션 모델 상속) 세 가지가 제공됩니다.
| 위치 | 범위 | 우선순위 |
|---|---|---|
.claude/agents/이름.md | 프로젝트 | 높음 |
~/.claude/agents/이름.md | 전역 | 낮음 |
Skills와 마찬가지로 YAML frontmatter + Markdown으로 구성됩니다. 다만 Markdown 본문은 시스템 프롬프트이지, 사용자 프롬프트가 아닙니다. "이 PR을 리뷰해줘"가 아니라 "당신은 시니어 코드 리뷰 전문가이다"처럼 적어야 합니다.
---
name: code-reviewer
description: Reviews code for bugs, security, and style. Use after modifying code.
model: sonnet
tools:
- Read
- Grep
- Glob
skills:
- api-conventions
---
당신은 시니어 코드 리뷰 전문가이다.
버그, 보안, 성능, 가독성, 컨벤션을 검사한다.
심각도별로 정리하여 보고한다.
항상 비판적으로 평가한다.
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
name | string | (필수) | 에이전트 식별자 |
description | string | (필수) | Claude가 자동 위임 판단에 사용 |
model | string | inherit | sonnet, opus, haiku, inherit, 전체 ID |
tools | array | 전체 상속 | 사용 가능 도구. 생략 시 전체 접근 |
permissionMode | string | default | bypassPermissions는 모든 승인을 건너뛰므로 주의 |
color | string | - | 터미널 표시 색상 |
skills | array | - | 시작 시 전체 콘텐츠를 주입할 스킬 목록 |
hooks | object | - | 에이전트 전용 훅 |
memory | string | - | 전용 auto memory 경로 |
maxTurns | number | - | 최대 턴 수 제한 |
skills 필드는 Skills와 Subagents를 연결하는 지점입니다. 여기에 스킬 이름을 나열하면 에이전트 시작 시 해당 스킬의 전체 콘텐츠가 즉시 컨텍스트에 주입됩니다. 에이전트가 스킬을 스스로 발견/로드하는 과정을 건너뛰고, 확실하게 특정 지식을 갖춘 상태로 시작하게 됩니다.
/agents 커맨드로 대화형으로 쉽게 생성할 수 있습니다. 이 경우, Claude가 프로젝트 컨텍스트와 요구사항, 인터뷰 내용을 기반으로 적절한 에이전트를 생성해줍니다.(미세한 조정은 어려움) 파일을 직접 작성해도 되며(개인적인 권장), claude agents로 CLI에서 목록을 확인할 수 있습니다.
자연어("code-reviewer 에이전트로 최근 커밋을 검사해줘"), 태그(@code-reviewr), 또는 description 기반 자동 위임으로 호출할 수 있습니다.
claude mcp add github -- npx -y @modelcontextprotocol/server-github
claude mcp list
.mcp.json 설정.mcp.json에 직접 추가하여 파일시스템으로 관리할 수 있습니다.
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
},
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"]
}
}
}
settings.json에서 활성/비활성을 제어할 수도 있습니다.
{
"enableAllProjectMcpServers": true,
"enabledMcpjsonServers": ["github", "context7"],
"disabledMcpjsonServers": ["filesystem"]
}
enableAllProjectMcpServers: 전체 mcp 서버 활성/제어enabledMcpjsonServers: 사용할 mcp 서버 선택 (white list 방식)disabledMcpjsonServers: 사용하지 않을 mcp 서버 선택 (black list 방식)위 옵션을 선택하여 설정할 수 있습니다.
Claude for Teams 또는 Enterprise 요금제를 사용하는 조직에서는, 관리자가 사용자의 mcp와 기타 설정을 제어할 수 있습니다.
managed-mcp.json 파일로 관리되며, /etc/claude-code/ 경로에서 관리됩니다. (linux 기준)
관리자가 Claude.ai의 설정 탭에서 제어할 수 있습니다.
Anthropic에서는 lazy loading으로 MCP 서버가 필요할 때만 로드하여 컨텍스트 부담을 크게 줄였습니다. (MCP 서버는 원래 MCP 클라이언트와 연결될 때, description과 args 등이 전부 dump되는 구조여서 context window를 매우 많이 잡아먹었음) 그래도 MCP 서버는 프로젝트 단위로 스코핑하는 것이 좋습니다. 전역 설정 시 관련 없는 쿼리에서도 로드를 시도할 수 있기 때문입니다.
Claude Code가 아닌 코딩 에이전트에서는 아직 MCP lazy load 개념이 도입되지 않은 곳이 많은데, 그런 경우에 활용할 수 있는 repo가 공유되어서, codex를 같이 활용하시는 유저분들은 참고하시면 좋을 것 같습니다.
이번 포스팅에서는 Claude Code의 Harness Engineering 기능 중 메모리, Hooks, Skills, Subagents, MCP Servers를 소개했습니다. 각 기능이 해결하는 문제를 요약하면 다음과 같습니다.
| 기능 | 해결하는 문제 |
|---|---|
| CLAUDE.md + rules | 매 세션 반복되는 설명, 컨벤션 드리프트 |
| Auto Memory | 수동 기록 없이 선호/교정 유지 |
| Hooks | 프롬프트 기반 규칙의 불확실성 |
| Skills | 컨텍스트 상시 점유 없이 전문 지식 활용 |
| Subagents | 장시간 세션의 컨텍스트 오염 |
| MCP Servers | 외부 도구/API 단절 |
ClaudeCode Harness Engineering -2편에서는 Permissions/Sandbox, Plugins, 세션 관리(Worktrees, Remote Control, /loop, /batch), Agent Teams, 기능 간 연동 패턴, 그리고 외부 배포 방법 등을 다뤄보도록 하겠습니다.
~/.claude/ # 전역 개인
CLAUDE.md # 전역 규칙
settings.json # 전역 설정
rules/ # 전역 규칙
skills/ # 전역 스킬
agents/ # 전역 에이전트
projects/<project>/memory/ # 프로젝트별 auto memory
프로젝트/
CLAUDE.md # 프로젝트 규칙 (팀 공유)
CLAUDE.local.md # 개인 설정
.mcp.json # MCP 서버
.claude/
settings.json # 프로젝트 설정 (Hooks, Permissions)
settings.local.json # 개인 설정 (.gitignore)
rules/ # 모듈형 스코프 규칙
skills/스킬명/SKILL.md # 프로젝트 스킬
agents/에이전트명.md # 프로젝트 에이전트
commands/ # 레거시 (skills에 통합)
hooks/ # 훅 스크립트
| 파일 | 우선순위 |
|---|---|
| 관리자 정책 (시스템) | 최고 |
.claude/settings.json (프로젝트) | 높음 |
.claude/settings.local.json (개인) | 중간 |
~/.claude/settings.json (전역) | 낮음 |
커밋: CLAUDE.md, .claude/settings.json, .claude/rules/, .claude/skills/, .claude/agents/, .mcp.json
.gitignore: CLAUDE.local.md, .claude/settings.local.json
목표: rm -rf나 sudo 명령을 Claude가 실행하지 못하게 차단
.claude/hooks/block-dangerous.sh 설정#!/bin/bash
# stdin으로 이벤트 JSON을 받음
event=$(cat)
# JSON에서 실행할 명령어 추출
command=$(echo "$event" | jq -r '.tool_input.command // ""')
# 위험한 패턴 체크
if echo "$command" | grep -qE 'rm -rf|sudo|dd |mkfs'; then
echo "❌ 위험한 명령 차단: $command" >&2
exit 2 # exit 2 = 도구 실행 차단
fi
exit 0 # exit 0 = 허용
.claude/settings.json 설정{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash", // Bash 도구 사용 시에만
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/block-dangerous.sh"
}
]
}
]
}
}
요즘 하네스에 대하여 생각 많이 하는데 정리감사합니다