Files
company-haness/.claude/commands/design-system.md
T

12 KiB

description
description
기존 프로젝트를 먼저 discovery하고 reuse/adapt/create를 판단한 뒤, design-brief(제약층)에서 코드 디자인 시스템+화면을 만들고 headless chrome으로 실제 UI를 렌더·품질검증한다. Figma 불필요·rate-limit 없음.

당신은 Orchestrator다. DESIGN-SYSTEM — 상위 제약(design-brief)에서 코드 디자인 시스템 + 화면 + 실제 UI 미리보기·품질검증을 산출한다. 입력(인자): 주제/제품 + 대상 디렉터리(기본 design-system/). 예: /design-system <프로젝트> 개발자 콘솔 · dir=design-system.

층 관계(중요): design-brief=제약(무엇을), design-craft skill=방법(어떻게), 디자인 시스템=코드로 굳힌 tokens+컴포넌트(재사용 실체), 프론트 코드=매체. DESIGN.md·skill의 대체가 아니라 완성이다.

조직 정본은 org-os/08-design/이다. generated/DESIGN.md는 그 정본에서 생성된 도구 어댑터일 뿐이며 제품 전략·IA·와이어프레임을 대신하지 않는다. 프로젝트는 전체 정본을 복사하지 않고 selected release exact ref/SHA + component subset + 명시적 delta만 ui-design.design-system-bindings에 연결한다.

대원칙: 스택을 못박지 않는다. discovery가 정한다. 기존 프로젝트가 있으면 그 stack·토큰·컴포넌트를 먼저 재사용한다. 스택은 고정값이 아니라 **preset(선택지)**다 — 그린필드일 때만 greenfield-react 프리셋을 쓴다. 예전처럼 React+CSS+Vite를 전사 기본으로 강제하면, 이미 Vue/Tailwind/디자인시스템/브랜드가 있는 프로젝트를 무시하고 밀도·컨벤션이 안 맞는 화면을 찍어낸다.

절차

  1. Pre-work: report_tags.py --tag <주제>로 관련 과거 결정 must-read. workflow-id 정한다(wf-<slug>).

0b. design-direction 승인 게이트(Task 13 — Blocker 10): /design-system/design 3b를 거치지 않고 단독으로도 호출될 수 있으므로, 여기서 다시 확인한다 — design.md의 선행 게이트를 우회해 곧장 이 커맨드로 들어오는 경로를 막는다. 부모 cascade workflow(<PARENT-cascade-wf> — 이 design-system 작업이 속한 상위 제품 cascade. design-direction child workflow가 아니다)를 대상으로:

python3 .claude/hooks/state_engine.py check-direction-approved --workflow <PARENT-cascade-wf>

부모로 질의해야 하는 이유: _has_direction_approval의 parent-shape 는 child 가 design-direction-approved stage 까지 실제로 종료됐음을 요구한다 — child workflow-id 로 질의하면 design-direction-finalize 단계에서도 YES 가 나올 수 있어 "전이 가능"과 "최종 승인"을 혼동한다(design-direction.md 6번 참고).

  • standard/heavy tier + NO(exit 3) → 진행하지 않는다. BlockedReport(사유: 승인된 design-direction 없음 — 먼저 /design-direction을 완주하거나 /design의 선행 게이트를 통해 진입해야 함)를 내고 종료.
  • light tier + NO → 하드 블록 아님. 경고를 report-header risks 에 남기고, 기존에 부모 원장에 기록된 승인이 있으면(과거 cycle) 그것을 상속해 진행한다(없으면 승인 없이 진행 — light 는 과설계 금지 원칙상 허용).
  • YES(exit 0) → 정상 진행.
  • brief-phase 요구: 이 게이트를 통과했다는 것은 design-direction 이 이미 finalize(brief-phase=system-ready 로 취급)를 지났다는 뜻 — 이 커맨드는 그 승인된 방향의 locked-invariants/selected-direction 을 존중하며 시스템을 만든다(방향을 재발산하지 않는다).

0c. experience + 조직 release 게이트:

  • python3 .claude/hooks/state_engine.py check-experience-foundation --workflow <PARENT-cascade-wf>NO면 해당 workload가 요구하는 foundation을 먼저 완주한다.
  • python3 .claude/hooks/compile_design_system.py --checkpython3 .claude/hooks/design_registry.py --surface <surface> --state <candidate|stable>로 필요한 최소 subset을 조회한다.
  • org-os/08-design/releases/<version>.yaml의 exact SHA와 release-id, component-ids, 프로젝트 delta(tokens/components)를 ui-design.design-system-bindings에 기록한다. release state와 project delta는 별도이며 로컬 복제를 stable 정본처럼 승격하지 않는다.
  1. ① DISCOVERY (필수·최우선 — brief보다 먼저): 대상 프로젝트에 기존 시스템이 있는지 먼저 조사한다. 아무 것도 조사하지 않고 스택을 고르는 것은 금지.

    • stack: package.json/lockfile/설정으로 프레임워크(React/Vue/Svelte/…)·번들러(Vite/Next/…)·언어·CSS 방식(CSS변수/Tailwind/CSS-in-JS) 식별. (없으면 = greenfield)
    • design-system: 기존 디자인시스템/컴포넌트 라이브러리/테마 존재 여부·위치(예: design-system/, packages/ui, MUI/Chakra/자체).
    • tokens·brand: 기존 토큰 SoT(CSS 변수/theme 파일)·브랜드 색·타이포·로고·간격 규율.
    • components: 재사용 가능한 기존 컴포넌트 인벤토리(무엇이 이미 있나 → 다시 만들지 말 것).
    • data-density: 데이터 밀도(대시보드/테이블 과밀 vs 마케팅/저밀도) — 토큰·레이아웃 결정에 직결.
    • 산출: discovery 노트를 design-brief.yamlexisting-system(있으면)에 기록.
  2. ② 판단: reuse / adapt / create (근거를 design-brief.yamlstack-decision에):

    • reuse — 적합한 기존 디자인시스템/토큰/컴포넌트가 있으면 그것을 소비한다. 새 시스템을 만들지 않는다. 대상 디렉터리 대신 기존 컴포넌트·토큰 위에서 화면을 조립.
    • adapt — 부분적 시스템(토큰만/일부 컴포넌트)이면 그 컨벤션 안에서 확장한다. 새 축을 함부로 도입하지 않는다.
    • create — 기존 시스템이 없거나(그린필드) 부적합하면 preset을 골라 새로 만든다.
      • preset greenfield-react: React + CSS 변수(tokens.css) + Vite. (이것이 유일한 preset이 아니라 그린필드 React용 기본 preset이다.)
      • 대상 프로젝트가 이미 다른 스택이면 create여도 그 스택의 토큰·컴포넌트 관례를 따른다(React를 강요하지 않는다).
  3. ③ design-brief (skill: design-craft + design-brief-spec.yaml): 대상에 design-brief.yaml을 세운다 — brief(무엇/누구/달성) → references(구체 신호 3~6, "modern/clean" 금지) → tokens(값+의도+경계) → decisions(판단로직) → donts(5+). references·tokens는 discovery 결과(기존 브랜드·데이터밀도)를 반영한다(빈 추론층=generic). 이게 없으면 컴포넌트 생성 금지.

  4. ④ 구현 (판단에 따라):

    • reuse/adapt — 기존 토큰/컴포넌트 위에서 화면(screens)을 조립. 기존 컴포넌트에 없는 것만 그 시스템의 관례로 추가.
    • context-package(spawn 전 필수 게이트, finding P0-2): des-platform 및 FAM-ENG-FRONTEND 후보에서 planner가 고른 concrete role을 띄우기 전 python3 .claude/hooks/context_package.py --compile … && python3 .claude/hooks/context_package.py <pkg>(exit 0)로 패키지를 만들고, 출력된 package path/hash를 spawn 프롬프트에 포함한다. design-brief는 must-read/shared-constraints로 동봉한다.
    • create · greenfield-react preset (subagent des-platform → 선택된 frontend concrete role):
      • src/tokens.css — 토큰을 CSS 변수로(값+경계 주석). --accent는 primary/focus 전용 등 경계 반영.
      • src/components/*.jsx (+components.css) — Button(variant)·Card·Input 등 재사용 컴포넌트, 토큰만 소비(var(--*), 하드코딩 색 금지). 컴포넌트별 판단로직·금지 반영. :focus-visible 가시 표식 필수(outline을 죽이면 box-shadow 등으로 대체).
      • src/screens/*.jsx — 컴포넌트를 조립만(새 스타일 금지). src/preview.jsx에 컴포넌트 갤러리 + 화면 + 상태(loading/empty/error/overflow) 데모를 건다.
    • 근거·산출은 .report.yaml(report-header BLUF).
  5. ⑤ 미리보기 + 품질 게이트(실제 UI 검증): python3 .claude/hooks/verify_run.py --workflow <wf> --agent <role> --session <id> --category acceptance-criteria --subject ui-render-gate [--source-revision-sha256 <sha>] -- python3 .claude/hooks/preview_ui.py <dir> --out <dir>/preview.png --viewports 360,768,1280 --check-css [--states "loading=/#/loading,empty=/#/empty,error=/#/error"] → npm install→vite build→로컬서버→렌더 검증(dump-dom)+반응형 스크린샷+정적 CSS 품질(대비·포커스). Figma·rate-limit 없이 실제 렌더. 중요 — 스크린샷 존재 ≠ 품질: preview_ui는 build 성공+PNG 존재만으로 통과시키지 않는다. 앱이 런타임에 안 붙어 #root가 비면(빈 화면), 빌드가 빈 번들이면, WCAG 대비가 critical이면, 포커스 표식이 없으면 **게이트가 실패(비영점)**한다. 스크린샷을 읽어 육안 검증도 병행(accent 남발·하드코딩색·정렬·클리핑·데이터밀도).

  6. ⑥ 게이트/보고: report-header(BLUF)로 종합 + 산출 경로(패키지·PNG들·게이트 결과). 게이트 실패 시 고치고 preview 재실행(개선 루프). python3 .claude/hooks/lint_design_system_adherence.py --ui-report <ui-design.report.yaml> --target <dir>로 release SHA, raw color token, local component-id 중복, 조직 component의 무신고 로컬 재구현을 검사한다. 정당한 로컬 확장만 delta.components에 id와 사유를 남긴다. DESIGN.md 변경 검토는 python3 .claude/hooks/compile_design_system.py --diff <project-DESIGN.md>로 정본 대비 unified diff를 확인한다.

스택 (preset — 고정 아님)

기본 스택은 없다. discovery가 결정한다.

  • 기존 프로젝트 있음 → 그 stack/tokens/components 우선 재사용(reuse/adapt). 다른 스택을 덮어씌우지 않는다.
  • greenfield-react preset(그린필드 React용): React + CSS 변수 + Vite. tokens는 tokens.css의 CSS 변수 = design-brief 토큰 1:1(SoT). 컴포넌트는 var(--*)만 소비(하드코딩 색 금지). Tailwind-first(토큰 갇힘)·순수HTML(컴포넌트 없음) 아님.
  • 그 외 스택(create이지만 non-React) → 해당 생태계의 토큰·컴포넌트 관례로.

규칙 / 불변식

  • discovery-first: 기존 stack/design-system/brand/components/data-density를 조사하지 않고 스택을 못박지 않는다. 기존 시스템이 있으면 create보다 reuse/adapt 우선.
  • design-brief 없이 컴포넌트 생성 금지(제약>묘사). references는 형용사가 아니라 구체 신호(기존 브랜드·밀도 반영).
  • 컴포넌트는 토큰만 소비 — 하드코딩 색 금지(component CSS에 hex 금지, 토큰은 tokens.css/기존 토큰 SoT에만).
  • 화면은 컴포넌트 조립 — 화면에서 새 컴포넌트 스타일을 만들지 않는다(디자인 시스템 SoT 보존).
  • 품질은 게이트를 통과해야 성립: preview_ui의 렌더 검증·대비·포커스·반응형 게이트를 통과하지 못하면 "완료"가 아니다. 스크린샷 존재만으로 품질 주장 금지. 품질은 반복 개선 루프(build→검증→고치기)에서 나온다 — 무료 Figma와 달리 여기선 무제한.
  • report-header 없이 종료 금지. evidence 실존. external side-effect(배포/PR 등) 기본 금지 — npm/vite/chrome 로컬 빌드는 허용 범위.

산출/handoff

  • <dir>/(또는 reuse 시 기존 시스템 위): design-brief.yaml(+existing-system·stack-decision)·tokens·components·screens·preview + preview.png(들, 반응형).
  • engine 선택은 tool-neutral이다. local HTML/Stitch/Figma/v0/Framer 중 가용 adapter를 쓰되 .claude/schemas/design-engine-output.artifact.schema.jsonscreen-refs/editable-source/preview-url/screenshots/design-system-ref/source-provenance/verification을 항상 내고 validate_design_engine_output.py로 검증한다.
  • 다음: 실제 제품 연결은 이 컴포넌트로 화면 확장(/build), 또는 디자인 검토가 필요하면 이 코드를 Figma로(선택, gated).