
Claude Code 치트시트
명령어 · 스킬 · 훅 · 에이전트를 한 페이지에.
최근 주요 변경
10/cd <경로>는 진행 중인 세션을 새 작업 디렉토리로 옮긴다(v2.1.169~). 핵심은 프롬프트 캐시를 그대로 유지한다는 것 — 시스템 프롬프트를 재구축하지 않고, 새 디렉토리의 [[claude-md-scopes|CLAUDE.md]]를 메시지로 덧붙인다.
세션 자체도 새 디렉토리의 프로젝트 저장소로 재배치돼 거기서--resume·--continue로 다시 잡힌다.
처음 가는 디렉토리면 trust 프롬프트로 한 번 묻는다.
[[add-dir|/add-dir]]이 "여기도 읽기·편집 가능하게 해줘"라면,/cd는 "여기로 이사 가자"에 가깝다.활용
- 모노레포 안에서 다른 패키지로 옮기기 →
/cd packages/api(캐시 살리고 그 패키지의CLAUDE.md로 컨텍스트 전환) - 이사 후 다시 세션 찾기 → 새 디렉토리에서
claude --resume - 옮기지 말고 접근만 추가하고 싶을 때 → [[add-dir|
/add-dir]] 사용 /cd대상 화이트리스트 →settings.json의permissions.allow에Cd(...)규칙:{ "permissions": { "allow": ["Cd(~/code/**)"] } }/cd자체를 막기 →permissions.deny에"Cd"한 줄
주의
- v2.1.169 미만에서는
Unknown command: /cd. 팀 공유 환경이면 버전 게이트 확인. Cd규칙은 모델이 호출할 수 없는 사용자 전용 권한 —/cd를 직접 칠 때만 평가된다.- allow 규칙이 하나라도 있으면 화이트리스트 모드로 전환 — 매칭 안 되면 거절.
- 모노레포 안에서 다른 패키지로 옮기기 →
/plugin list는 인터랙티브 세션 안에서 설치된 플러그인을 인라인 한 줄로 보여 주는 명령이다(v2.1.163~). 버전·출처 마켓플레이스·활성 상태가 같은 행에 깔린다./plugin메뉴를 띄우지 않고 빠르게 무엇이 들어 있는지 확인할 때 쓰고,--enabled·--disabled로 상태를 한 번에 좁힐 수 있다.
CLI의claude plugin list와 같은 데이터셋을 다른 진입점에서 본다./plugin메뉴를 열어 탭을 옮길 필요 없이 한 줄 명령으로 인벤토리가 잡힌다.활용
- 설치된 플러그인 즉시 확인 →
/plugin list(또는 짧게/plugin ls) - 지금 켜진 것만 추리기 →
/plugin list --enabled - 꺼진 채 남아 있는 것만 확인 →
/plugin list --disabled - CLI 쪽 동일 출력 →
claude plugin list(대화 밖 스크립트 용도). JSON으로 받기:claude plugin list --json
주의
--enabled·--disabled·ls단축은 인터랙티브/plugin list에서만 인식된다 —claude plugin listCLI는--json·--available만 받는다.--available(마켓플레이스 미설치분 포함)은 CLI 쪽에서--json과 함께만 동작한다.
- 설치된 플러그인 즉시 확인 →
availableModels화이트리스트만 걸어두면/model피커의 명시적 모델 선택은 막히지만, "Default" 옵션은 그 제한을 벗어나 사용자의 플랜 티어 기본 모델로 그대로 해석된다.enforceAvailableModels: true를 managed/policy 설정에 같이 박으면 Default도availableModels안에 묶이고, 티어 기본이 allowlist에 없을 때는 첫 번째 허용 항목으로 자동 폴백한다 (v2.1.175~). 관리자가/model표면을 전부 닫으려 할 때 마지막 빈틈을 메우는 스위치.Managed/policy 레벨에서 설정하면 user·project 레벨이 이 값을 덮어쓰지 못한다 —
availableModels와 동일한 머지 규칙.availableModels가 빈 배열일 때는 enforcement 자체가 동작하지 않으니, 반드시 비어있지 않은 allowlist와 짝지어 쓴다.활용
- Sonnet·Haiku만 쓰게 강제, Opus 티어 기본까지 봉인 (managed settings):
{ "availableModels": ["sonnet", "haiku"], "enforceAvailableModels": true } - 특정 버전 핀까지 묶기 —
model로 초기값,availableModels로 picker 제한,enforceAvailableModels로 Default까지 같은 풀:{ "model": "claude-sonnet-4-5", "availableModels": ["claude-sonnet-4-5", "haiku"], "enforceAvailableModels": true, "env": { "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-5" } } availableModels만 걸고 Default 옵션은 티어 기본 그대로 두고 싶을 때 →enforceAvailableModels생략 (기본 동작이 그렇다)
주의
availableModels: [](빈 배열)이면enforceAvailableModels: true도 무시된다 — 빈 allowlist는 enforcement 트리거가 아니다.- managed/policy 설정에서만 의미가 있다. user·project 레벨에만 두면 머지 규칙상 효력이 약하다.
- Sonnet·Haiku만 쓰게 강제, Opus 티어 기본까지 봉인 (managed settings):
settings.json의language는 Claude 응답 언어를 한 줄로 고정하는 문자열 필드다 —"korean","japanese","spanish"처럼 자연어 이름을 넣는다.
응답 본문은 물론 음성 입력(voice dictation) 언어도 함께 잡힌다.
(v2.1.176~) 세션 제목 역시 대화 언어를 따라 자동 생성되고, 이 필드를 박아두면 세션 제목 언어까지 한 줄로 고정된다 — 매 프롬프트마다 "한국어로 답해"를 덧붙이거나 영문·국문이 섞인 세션 제목으로 agents view가 어지러워지지 않는다.활용
- 한국어로 응답·세션 제목 모두 고정:
{ "language": "korean" } - 일본어로 응답·세션 제목·
/voice받아쓰기 한 언어로 통일 →"language": "japanese" - 미지정 — 세션 제목은 그때그때 대화 언어를 따라 자동 생성 (v2.1.176~)
- 한국어로 응답·세션 제목 모두 고정:
API_FORCE_IDLE_TIMEOUT은 모델 응답 스트림에 바이트가 5분간 없으면 요청을 끊는 idle 워치독을 조정하는 환경변수다(v2.1.169~). 기본 동작은 프로바이더별로 갈린다 — Anthropic 직결·Claude Platform on AWS는 자체 바이트 단위 watchdog이 있어 비활성, 그 외(Vertex AI·Foundry·Mantle·Bedrock·LLM gateway)는 활성이라 멈춘 스트림이 무한 대기 대신 끊긴다.
느린 게이트웨이·로컬 모델이 5분 넘게 청크 없이 생각할 때 워치독이 정상 응답을 끊는 사고를 막거나, 반대로 모든 프로바이더에서 멈춤 보호를 강제할 때 쓴다.활용
- 느린 LLM gateway·로컬 모델이 5분 넘게 무응답 →
API_FORCE_IDLE_TIMEOUT=0으로 워치독 해제 - Anthropic 직결인데도 멈춤 보호가 필요 →
API_FORCE_IDLE_TIMEOUT=1로 모든 프로바이더에 강제 - 쉘에서 일회성 적용:
API_FORCE_IDLE_TIMEOUT=0 claude
주의
- 미설정이 곧 "꺼짐"이 아니다. 기본값은 프로바이더별로 다르므로(
0/1한쪽으로 통일하고 싶으면 명시적으로 지정), 게이트웨이·서드파티에서 갑자기 stall이 잡힌다면 워치독이 작동 중인지부터 본다. 0으로 끄면 진짜 죽은 스트림도 무한 대기로 빠진다 — gateway 쪽 별도 타임아웃이 있는지 확인.
- 느린 LLM gateway·로컬 모델이 5분 넘게 무응답 →
claude --safe-mode(또는 환경변수CLAUDE_CODE_SAFE_MODE=1)로 띄우면 CLAUDE.md·스킬·플러그인·훅·MCP 서버·커스텀 명령/에이전트·출력 스타일·워크플로우·테마·키바인딩·statusline·파일 제안·LSP 서버·자동 메모리가 일제히 로드되지 않는다(v2.1.169~). 인증·모델 선택·내장 툴·권한은 평소대로 작동한다.
"방금 깨졌는데 내 커스터마이즈 중 어느 게 원인인지" 한 번에 끊고 들어가기 위한 토글이다.활용
- 시작 시 한 번만 →
claude --safe-mode - 환경에서 강제 →
export CLAUDE_CODE_SAFE_MODE=1후claude - Fable 5 자동 폴백이 자기 커스터마이즈 때문인지 확인 → safe-mode로 같은 작업 재현 후 동작 비교
- 같은 "최소 부트" 효과지만 더 깊게 끄고 싶을 때 → 인증·툴·권한까지 우회하는
--bare
주의
- managed settings 정책은 그대로 적용된다 — 정책 훅·정책 statusline·정책 file-suggestion은 살아 있다. managed plugins·managed skills·managed CLAUDE.md·정책 MCP 서버는 끊긴다.
--bare와 다른 점: safe-mode는 인증·모델·내장 툴·권한을 유지한다.--bare는 그것까지 끊고 더 가볍게 띄운다.- 진단용 토글이지 일상 토글이 아니다. 원인 좁히고 나면 다시 평상시 모드로.
- 시작 시 한 번만 →
disableBundledSkills: true(설정) 또는CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1(환경변수)을 켜면 Claude Code와 함께 출하되는 번들 스킬·워크플로우가 통째로 제거된다(v2.1.169~)./init같은 내장 슬래시 명령은 사용자가 직접 칠 수는 있지만 모델에게는 보이지 않는다. 플러그인·.claude/skills/·.claude/commands/의 스킬은 영향 없음.
조직이 깐 자체 스킬만 모델에게 보여주고 기본 도구 표면을 좁히고 싶을 때 managed settings에 한 줄 박고 끝낸다.활용
- 사용자 전체에 박기 →
~/.claude/settings.json:{ "disableBundledSkills": true } - 환경변수로 (런타임 결정·CI) →
export CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1 - 조직 정책으로 잠그기 → managed settings에 같은 키 (사용자 override 불가)
- 효과:
/code-review·/debug등 번들 스킬이 모델 컨텍스트에서 사라지지만 사용자가 직접 타이핑하면 여전히 실행 - 스킬은 살리되 셸 인젝션만 끄고 싶을 때 → 대신
disableSkillShellExecution - 워크플로우(
ultracode키워드·동적 디스패치)만 노리고 끄고 싶을 때 → [[disable-workflows]]
주의
- 번들 스킬과 워크플로우만 대상. 플러그인 스킬·
.claude/skills/·.claude/commands/는 그대로 활성 — "내 커스텀 스킬도 빠진 것 같다" 싶으면 그 위치가 진짜 플러그인인지부터 확인. - 내장 슬래시 명령(
/init등)은 숨김이지 비활성이 아니다. 손으로 치면 동작 — 정말로 막으려면 permission 규칙 추가. - managed settings로 잠가도 정책 채널이 따로 푸는 키는 없다 — 풀려면 키 자체를 삭제.
- 사용자 전체에 박기 →
if: "Bash(...)"로 좁힌 훅은 단일 호출뿐 아니라&&·;복합 명령,$()·백틱으로 감싼 서브쉘 안쪽까지 검사한다.npm test && git push나echo $(rm -rf /)처럼 위험한 서브커맨드를 숨겨도 패턴이 적중하면 훅이 발화한다.
명령 이름까지만 좁힌 패턴은 정확히 매칭하고, 인자까지 제한한 패턴은$()·백틱·$VAR안에선fail-open— 변수 치환 결과를 정적으로 알 수 없을 때 안전 쪽으로 항상 발화한다.활용
-
매칭 사례 (docs 표 그대로):
if패턴Bash 명령 발화? 이유 Bash(git *)FOO=bar git push✅ 앞 변수 할당이 벗겨지고 git push매칭Bash(git *)npm test && git push✅ 각 서브커맨드 별도 검사 Bash(rm *)echo $(rm -rf /)✅ $()·백틱 안쪽도 검사Bash(rm *)echo $(date)❌ 안쪽 명령이 rm *에 안 맞음Bash(git push *)echo $(date)✅ 인자까지 제한한 패턴은 $()에서 fail-open -
위험한 호출을 차단하려면 명령 이름 단위로 좁힌다 →
Bash(rm:*)deny +if: "Bash(rm *)"훅을 같이 걸어 서브쉘 우회까지 차단 -
인자 패턴(
Bash(git push *))이 들어가면 무관한 명령에서도 훅이 떠 비용이 늘 수 있음 — 정말 필요한 곳에만 사용
주의
이 매칭 규칙은
if필드에만 적용된다(PreToolUse·PostToolUse·PermissionRequest·PermissionDenied같은 툴 이벤트에서).matcher필드는 툴 이름만 본다.
(v2.1.163~ 인자 패턴의 fail-open이 명시적으로 문서화됐다.)-
기본·
acceptEdits모드에서 WebFetch는 처음 보는 도메인엔 프롬프트를 띄우지만, 공식 docs 호스트로 구성된 사전 승인 셋은 묻지 않고 바로 가져온다.WebFetch(domain:...)형태의 명시적 권한 규칙은 이 사전 승인 셋 위에서 deny·ask·allow 어느 쪽이든 우선 적용된다 — 사전 승인된 도메인을 막거나 매번 확인을 요구하도록 덮을 수 있다 (v2.1.162~).활용
- 사전 승인된 docs 도메인에도 매번 확인을 요구하고 싶다:
{ "permissions": { "ask": ["WebFetch(domain:docs.anthropic.com)"] } } - 특정 도메인은 자동 허용에서 빼낸다 →
"deny": ["WebFetch(domain:medium.com)"] - 외부 도메인 한 곳만 미리 통과시킨다 →
"allow": ["WebFetch(domain:example.com)"]
주의
WebFetch 규칙은 그 툴만 막는다.
Bash가 열려 있으면 Claude가curl·wget로 같은 URL에 갈 수 있어 — 진짜 네트워크 차단은 [[sandbox-network]]가 필요하다.auto·bypassPermissions모드는 프롬프트 자체를 건너뛰므로 ask 규칙도 의미가 없다.- 사전 승인된 docs 도메인에도 매번 확인을 요구하고 싶다:
permission 규칙의 와일드카드는 본래
Bash(curl *)처럼 인자 자리에서만 통했다.
v2.1.166부터 deny 규칙의 도구 이름 자리에도 글롭이 들어간다 —"*"하나면 모든 도구가 거부된다.
한편 allow 규칙은 도구 이름 자리의 non-MCP 글롭을 거부하고(MCP 글롭만 허용), deny에 존재하지 않는 도구 이름을 넣으면 시작 시 경고를 띄운다.
오타로 deny가 조용히 무력화되던 일이 사라지고, 도구 전체 차단을 규칙 한 줄로 표현할 수 있다.활용
- 모든 도구를 한 번에 차단 →
settings.json의permissions.deny에"*":{ "permissions": { "deny": ["*"] } } - 특정 MCP 서버의 모든 도구만 허용 → allow는 MCP 글롭을 받는다:
{ "permissions": { "allow": ["mcp__github__*"] } } - allow에 non-MCP 글롭(
Bash*같은 도구 이름 와일드카드) → 거부됨. allow는 구체 도구나 MCP 글롭으로 적어야 한다. - deny에 오타·없는 도구 이름 → 시작 시 경고로 표면화 (조용히 무시 ✕)
주의
- 글롭이 새로 도는 곳은 도구 이름 자리 한정. 인자 자리 와일드카드(
Bash(curl *))는 이전부터 동작하던 별개 기능. - 도구 이름 글롭의 비대칭 — deny는 non-MCP 글롭(
"*")을 받지만 allow는 MCP 글롭만 받는다. - 공식 docs는 아직 도구 이름 자리 글롭을 명시하지 않는다 — v2.1.166 릴리스 노트 기준.
- 모든 도구를 한 번에 차단 →