check-design-system.sh

prototypes/ 파일 편집 시 Design System 토큰 위반(typography, color)을 자동 감지하고 차단한다.

Trigger

PostToolUse (Write | Edit)

Source Code

1#!/bin/bash
2# Design System enforcement hook (PostToolUse)
3# prototypes/ 내 파일 편집 시 typography/color 위반을 자동 감지한다.
4
5INPUT=$(cat)
6
7FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
8
9# 파일 경로가 없거나 prototypes/ 외부면 스킵
10if [ -z "$FILE_PATH" ] || [[ "$FILE_PATH" != *"/prototypes/"* ]]; then
11  exit 0
12fi
13
14# sokind-hompage는 독립 디자인 체계를 사용하므로 스킵
15if [[ "$FILE_PATH" == *"/prototypes/sokind-hompage/"* ]]; then
16  exit 0
17fi
18
19# 외부 라이브러리 컴포넌트(ReactBits 등)는 내부 스타일 유지 필요하므로 스킵
20if [[ "$FILE_PATH" == *"/components/ui/staggered-menu/"* ]] || \
21   [[ "$FILE_PATH" == *"/components/ui/shuffle/"* ]] || \
22   [[ "$FILE_PATH" == *"/components/ui/orb/"* ]] || \
23   [[ "$FILE_PATH" == *"/components/ui/border-glow/"* ]]; then
24  exit 0
25fi
26
27# tsx, ts, jsx, css 파일만 검사
28if [[ ! "$FILE_PATH" =~ \.(tsx|ts|jsx|css)$ ]]; then
29  exit 0
30fi
31
32# globals.css는 DS 정의 파일이므로 스킵
33if [[ "$FILE_PATH" == *"globals.css"* ]]; then
34  exit 0
35fi
36
37# 파일이 존재하지 않으면 스킵
38if [ ! -f "$FILE_PATH" ]; then
39  exit 0
40fi
41
42VIOLATIONS=""
43
44# 1. Tailwind 기본 font-size 클래스
45FOUND=$(grep -nE '\btext-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)\b' "$FILE_PATH" 2>/dev/null || true)
46if [ -n "$FOUND" ]; then
47  VIOLATIONS="${VIOLATIONS}[Typography] Tailwind 기본 font-size 클래스 감지. typo-{style}-{weight} 사용 필요 (예: typo-body-1-normal-medium):\n${FOUND}\n\n"
48fi
49
50# 2. Tailwind 기본 font-weight 클래스
51FOUND=$(grep -nE '\bfont-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)\b' "$FILE_PATH" 2>/dev/null || true)
52if [ -n "$FOUND" ]; then
53  VIOLATIONS="${VIOLATIONS}[Typography] Tailwind 기본 font-weight 클래스 감지. DS typography에 weight 포함됨 (예: typo-heading-1-bold):\n${FOUND}\n\n"
54fi
55
56# 3. Tailwind 기본 leading/tracking 클래스
57FOUND=$(grep -nE '\b(leading-(none|tight|snug|normal|relaxed|loose|[3-9]|1[0-2])|tracking-(tighter|tight|normal|wide|wider|widest))\b' "$FILE_PATH" 2>/dev/null || true)
58if [ -n "$FOUND" ]; then
59  VIOLATIONS="${VIOLATIONS}[Typography] Tailwind 기본 leading/tracking 클래스 감지. DS typography에 포함됨:\n${FOUND}\n\n"
60fi
61
62# 4. 임의 typography 값 (arbitrary values)
63FOUND=$(grep -nE '(text-\[[0-9]|font-\[[0-9]|leading-\[|tracking-\[)' "$FILE_PATH" 2>/dev/null || true)
64if [ -n "$FOUND" ]; then
65  VIOLATIONS="${VIOLATIONS}[Typography] 임의 typography 값 감지. DS 토큰 사용 필요:\n${FOUND}\n\n"
66fi
67
68# 5. 임의 색상 값 (arbitrary color values)
69FOUND=$(grep -nE '(text|bg|border|ring|outline|shadow|from|to|via)-\[#' "$FILE_PATH" 2>/dev/null || true)
70if [ -n "$FOUND" ]; then
71  VIOLATIONS="${VIOLATIONS}[Color] 임의 색상 값 감지. DS 시멘틱 컬러 토큰 사용 필요 (예: text-label-normal, bg-brand):\n${FOUND}\n\n"
72fi
73
74# 6. Tailwind 기본 색상 팔레트 직접 사용 (semantic token 대신)
75FOUND=$(grep -nE '\b(text|bg|border|ring)-(red|blue|green|yellow|purple|pink|indigo|orange|amber|emerald|teal|cyan|sky|violet|fuchsia|rose|lime|stone|zinc|slate|gray|neutral)-[0-9]+\b' "$FILE_PATH" 2>/dev/null || true)
76if [ -n "$FOUND" ]; then
77  VIOLATIONS="${VIOLATIONS}[Color] Tailwind 기본 색상 팔레트 직접 사용 감지. DS 시멘틱 컬러 토큰 사용 필요:\n${FOUND}\n\n"
78fi
79
80# 위반 있으면 Claude에게 피드백
81if [ -n "$VIOLATIONS" ]; then
82  REASON=$(printf "Design System 위반 발견 (%s):\n\n%b수정 방법:\n- Typography → globals.css의 @utility 클래스 사용 (typo-display-1-bold, typo-body-1-normal-medium 등)\n- Color → globals.css의 @theme 시멘틱 토큰 사용 (text-label-normal, bg-bg-alternative, border-line-normal, text-brand 등)\n- 전체 토큰 목록: prototypes/sokind-admin/src/app/globals.css 참조" "$(basename "$FILE_PATH")" "$VIOLATIONS")
83
84  jq -n --arg reason "$REASON" '{"decision":"block","reason":$reason}'
85  exit 0
86fi
87
88exit 0
89