Claude Code 권한 설정과 Hook을 이용한 자동 린트

2025. 3. 11.

권한 설정

Claude Code는 명령을 실행할 때마다 사용자에게 권한을 묻는다. 반복되는 승인이 번거롭다면 ~/.claude/settings.json에 화이트리스트를 설정할 수 있다.

// ~/.claude/settings.json
{
  "permissions": {
    "allow": [
      "Read(/Users/사용자/Workspace/**)",
      "Edit(/Users/사용자/Workspace/**)",
      "Write(/Users/사용자/Workspace/**)",
      "Bash(git:*)",
      "Bash(yarn:*)",
      "Bash(npm:*)",
      "Bash(npx:*)",
      "Bash(node:*)",
      "Bash(ls:*)",
      "Bash(cat:*)",
      "Bash(grep:*)",
      "Bash(find:*)"
    ],
    "deny": [
      "Read(**/.env*)",
      "Read(**/secrets/**)",
      "Bash(rm -rf:*)",
      "Bash(sudo:*)",
      "Bash(git push --force:*)"
    ]
  }
}
  • allow: 확인 없이 바로 실행되는 명령어 목록. 와일드카드(*, **)를 사용할 수 있다.
  • deny: 무조건 차단되는 명령어 목록. allow보다 우선 적용된다.
  • Read, Edit, Write는 경로를 지정해서 특정 디렉토리 하위에서만 허용할 수 있다.
  • Bash는 경로 제한이 불가능하므로 mv, cp, rm 같은 명령어는 허용 목록에서 빼고 필요할 때 승인하는 것이 안전하다.

PostToolUse Hook으로 자동 lint

Hook은 도구 실행 전후에 끼어드는 스크립트다. PostToolUse를 이용하면 파일 수정 후 자동으로 lint를 실행할 수 있다.

#!/bin/bash
# ~/.claude/hooks/auto-lint.sh

INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

if [[ ! "$FILE_PATH" =~ \.(ts|tsx|js|jsx)$ ]]; then
  exit 0
fi

# 프로젝트 루트를 찾아서 lint config가 있는 경우에만 실행
DIR=$(dirname "$FILE_PATH")
while [[ "$DIR" != "/" ]]; do
  if [[ -f "$DIR/.eslintrc" || -f "$DIR/.eslintrc.js" || -f "$DIR/.eslintrc.json" || -f "$DIR/.eslintrc.yml" || -f "$DIR/eslint.config.js" || -f "$DIR/eslint.config.mjs" ]]; then
    cd "$DIR" && npx eslint --fix "$FILE_PATH" 2>&1
    exit 0
  fi
  DIR=$(dirname "$DIR")
done

exit 0

스크립트를 만든 후 실행 권한을 부여한다.

chmod +x ~/.claude/hooks/auto-lint.sh

그리고 settings.json에 hook을 등록한다.

// ~/.claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/auto-lint.sh"
          }
        ]
      }
    ]
  }
}

이제 Claude Code가 파일을 수정할 때마다 eslint config가 있는 프로젝트에서 자동으로 lint가 실행된다.