docs(ai): split SW usage into general / viewer mode in packaged AI guides

- Usage types are now Web / SW (general mode, viewer mode) / OrgChart / mixed.
  Shared AI_GUIDE step 1 asks for the SW mode only when the request or the
  project setting (HMDesign 사용 유형: SW 일반 | SW 뷰어) leaves it open;
  examples B0/B1/B2 cover "HMDesign SW로 화면을 만들어 주세요", general and viewer.
- Missing-component handling in three steps (reuse in the chosen type/mode ->
  build with that mode's tokens -> HMDesign-consistent style, reported as
  "AI 구성 값 — 디자인 확인 필요"), plus SW general/viewer separation rules.
- sw/ai: AI_USAGE §0 mode selection, catalog §8 lists all 33 SWViewer* exports,
  DESIGN_RULES §11 viewer tokens, PATTERNS 7 viewer composition; examples B/F
  marked as general mode. ui/ai and org-chart/ai aligned with the new types.
- AGENTS_SNIPPET, AGENTS.md and MAINTAINING updated; copies synced.
- scripts/ai-docs.mjs: shared-copy check ignores CRLF/LF (core.autocrlf=true
  checks out packages/sw as LF and the rest as CRLF).
- Verification record updated (code samples typechecked, built and rendered).
This commit is contained in:
shkim4 committed 2026-10-19 17:34:15 +09:00
1 parent be7a04a847
commit 7621934f69
25 files changed
+779 -235

No files matched your search

+6 -6
View File
@@ -1,16 +1,16 @@
## HMDesign 디자인 시스템
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 프로젝트에 맞게 고치거나, 정하지 않았으면 그 줄을 지운다. -->
<!-- HMDesign 패키지의 ai/AGENTS_SNIPPET.md에서 복사. 아래 "사용 유형"을 하나로 고치거나(SW는 모드까지: SW 일반 / SW 뷰어), 정하지 않았으면 그 줄을 지운다. -->
HMDesign 사용 유형: Web | SW | OrgChart | 혼합(영역별로 적기)
HMDesign 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart | 혼합(영역별로 적기, SW 영역은 모드까지)
화면·컴포넌트를 구현하거나 수정하기 전에 다음을 지킨다.
1. 설치된 HMDesign 패키지의 공통 가이드를 먼저 읽는다: `node_modules/@hm-design/<설치된 패키지>/ai/AI_GUIDE.md` (`ui`, `sw`, `org-chart`, `org-chart-react` 중 아무 사본이나 내용이 같다).
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW 3. OrgChart 4. 혼합 사용"을 묻는다. 정해져 있으면 다시 묻지 않는다.
2. 위 "사용 유형"이 없고 요청으로도 정할 수 없으면 코드 작성 전에 "어떤 HMDesign 디자인 시스템을 사용하시겠습니까? 1. Web 2. SW (일반 모드 / 뷰어 모드) 3. OrgChart 4. 혼합 사용"을 묻는다. SW인데 모드(일반/뷰어)가 불명확하면 "SW 화면을 어떤 모드로 만들까요? 1. SW 일반 모드 2. SW 뷰어 모드"를 묻는다(근거는 `@hm-design/sw/ai/AI_USAGE.md` §0). 정해져 있으면 다시 묻지 않는다.
3. 선택한 패키지의 `ai/AI_USAGE.md` → `COMPONENT_CATALOG.md` → `DESIGN_RULES.md` → `COMPOSITION_PATTERNS.md` 순으로 필요한 절을 읽는다.
- Web: `node_modules/@hm-design/ui/ai/`
- SW: `node_modules/@hm-design/sw/ai/`
- SW: `node_modules/@hm-design/sw/ai/` (뷰어 모드는 `AI_USAGE.md` §0 다음 `VIEWER.md`)
- OrgChart: `node_modules/@hm-design/org-chart/ai/` (React는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`도)
4. 기존 컴포넌트 → Props → 조합 → (없는 부분만) 패키지 토큰으로 신규 구현 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사·새 디자인 값 생성은 하지 않는다.
5. Web / SW / OrgChart 스타일을 영역별로 분리하고, 완료 후 AI_GUIDE의 결과 보고 형식으로 재사용·신규·토큰·검증·NOT VERIFIED를 보고한다.
4. 선택한 유형·모드 안에서 기존 컴포넌트 → Props → 조합 → (없는 부분만) 그 모드의 토큰·스타일로 신규 → (참고 값도 없으면) HMDesign 공통 규칙과 조화되게 구성하고 "AI 구성 값"으로 보고하는 순서를 지킨다. 패키지 파일 수정·내부 경로 import·구현 복사는 하지 않는다.
5. Web / SW 일반 / SW 뷰어 / OrgChart 스타일을 영역별로 분리하고(한 SW 화면에 일반·뷰어 컴포넌트를 섞지 않음), 완료 후 AI_GUIDE의 결과 보고 형식으로 유형·모드, 재사용·신규·토큰·AI 구성 값·검증·NOT VERIFIED를 보고한다.
+92 -32
View File
@@ -2,18 +2,19 @@
> 이 파일은 HMDesign 패키지(`@hm-design/ui`, `@hm-design/sw`, `@hm-design/org-chart`, `@hm-design/org-chart-react`)의 `ai/AI_GUIDE.md`에 **같은 내용으로** 들어 있습니다. 원본은 HMDesign 저장소 `docs/ai/AI_GUIDE.md`이며 패키지 사본은 `npm run sync:ai-docs`로 갱신합니다. 사본을 직접 고치지 않습니다.
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~6단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
사용자가 "HMDesign 패키지를 기준으로 화면을 구현해 주세요", "HMDesign SW로 화면을 만들어 주세요"처럼 요청하면 AI 코딩 도구는 이 파일의 1~7단계를 순서대로 따릅니다. 이 문서와 각 패키지의 `ai/` 문서는 실제 공개 API·CSS에서 확인한 내용만 적습니다. 여기에 없는 컴포넌트·Props·토큰은 없는 것으로 취급합니다.
## 0. 읽는 순서
1. **이 파일**(어느 패키지의 사본이든 같음)
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md`
2. 선택한 패키지의 `ai/AI_USAGE.md` → `ai/COMPONENT_CATALOG.md` → `ai/DESIGN_RULES.md` → `ai/COMPOSITION_PATTERNS.md` (SW 뷰어 모드는 `AI_USAGE.md` §0 다음에 `ai/VIEWER.md`를 먼저 읽고 카탈로그의 뷰어 절을 봅니다)
3. API가 의심스러우면 그 패키지의 `dist/*.d.ts`(공개 진입점에서 export되는 것만)
| 유형 | 패키지 | 지침 위치(설치 후) | JS 진입점 | CSS |
|---|---|---|---|---|
| ① Web UI | `@hm-design/ui` | `node_modules/@hm-design/ui/ai/` | `@hm-design/ui`, `@hm-design/ui/theme` | `@hm-design/ui/tailwind.css` + `@hm-design/ui/theme.css`(Tailwind CSS 4 필요), 선택 `@hm-design/ui/dashboard-status.css` |
| ② SW UI | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` | `@hm-design/sw` | `@hm-design/sw/styles.css` |
| ② SW UI — 일반 모드 | `@hm-design/sw` | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 모드 선택 → 일반 모드 문서) | `@hm-design/sw` | `@hm-design/sw/styles.css` |
| ② SW UI — 뷰어 모드 | `@hm-design/sw`(같은 패키지) | `node_modules/@hm-design/sw/ai/` (`AI_USAGE.md` §0 → `VIEWER.md`) | `@hm-design/sw` | `@hm-design/sw/styles.css`(같은 파일) |
| ③ OrgChart | `@hm-design/org-chart`(Core) + React면 `@hm-design/org-chart-react` | `node_modules/@hm-design/org-chart/ai/` (React 어댑터 안내는 `node_modules/@hm-design/org-chart-react/ai/AI_USAGE.md`) | `@hm-design/org-chart`, `@hm-design/org-chart-react`, 선택 `@hm-design/org-chart-react/hm-dialog` | `@hm-design/org-chart/engine.css`, `@hm-design/org-chart/style.css`(URL로 전달 — Shadow DOM 안에 로드) |
| 기타 | `@hm-design/center-graphic` | AI 지침 없음. 패키지 `README.md`만 | `@hm-design/center-graphic` | 자동 import |
@@ -21,12 +22,19 @@
## 1단계. 사용 목적 확인
화면 구현 요청을 받으면 코드 작성 전에 **사용 유형**을 정합니다. 유형은 다음 넷이고, SW는 다시 두 모드로 나뉩니다.
1. Web
2. SW — **SW 일반 모드**(편집용: `SWHeader`, `SWPopup` …) / **SW 뷰어 모드**(보기 전용: `SWViewerHeader`, `SWViewerMenu`, `SWViewerPanel` …)
3. OrgChart
4. 혼합 사용(영역마다 위 유형 하나)
다음 순서로 판단하고, **판단되면 다시 묻지 않습니다.**
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9).
1. 소비 프로젝트의 `AGENTS.md`·`CLAUDE.md` 등에 `HMDesign 사용 유형:` 설정이 있으면 그대로 따릅니다(§9). 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: …)`입니다. 값이 `SW`뿐이면 유형은 정해진 것이고 모드만 아래 4번으로 정합니다.
2. 사용자 요청이 유형을 분명히 말하면 그대로 따릅니다.
- Web: 웹 화면, 관리자·업무 화면, 목록·검색·Form, 대시보드, GNB/LNB, Dialog, Table …
- SW: 데스크톱 SW, 뷰어, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup …
- SW: 데스크톱 SW, 도면·CAD, SW Header, 툴바, 레이어/색상/선스타일, 속성창·SW Popup, 뷰어 …
- OrgChart: 조직도, 조직 계층·직원 카드, 조직 JSON/CSV/Excel 시각화 …
- 둘 이상이 함께 나오면 ④ 혼합(예: "업무 화면 안에 조직도" = Web + OrgChart).
3. 위로 정할 수 없으면 코드 작성 전에 **그대로** 묻습니다.
@@ -34,12 +42,21 @@
> 어떤 HMDesign 디자인 시스템을 사용하시겠습니까?
>
> 1. Web
> 2. SW
> 2. SW (일반 모드 / 뷰어 모드)
> 3. OrgChart
> 4. 혼합 사용
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다.
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다.
4. **SW가 정해졌거나 포함됐는데 모드가 불명확하면** 코드 작성 전에 묻습니다. 설정 값(`SW 일반`/`SW 뷰어`)이나 요청이 모드를 분명히 말하면 묻지 않습니다. 판단 근거와 질문 문구는 `@hm-design/sw/ai/AI_USAGE.md` §0을 따릅니다. 유형 질문이 필요한 경우에는 같은 메시지에서 2번 선택 시의 모드도 함께 묻습니다(한 번에 끝냄).
> SW 화면을 어떤 모드로 만들까요?
>
> 1. SW 일반 모드 — 편집용 Header(`SWHeader`)·속성창·SW Popup
> 2. SW 뷰어 모드 — 보기 전용 Header(`SWViewerHeader`)·뷰어 메뉴·뷰어 패널
- "HMDesign SW로 화면을 만들어 주세요"처럼 SW만 말하고 모드 근거가 없으면 유형은 SW로 확정하고 4번의 모드 질문만 합니다.
- `package.json`에 설치된 패키지가 하나뿐이어도 그것만으로 유형을 확정하지 않습니다(설치가 덜 된 상태일 수 있음). 요청 내용과 맞을 때만 근거로 씁니다. SW 모드도 같은 패키지이므로 설치 상태로는 판단하지 않습니다.
- 정해진 유형·모드는 결과 보고(7단계)에 적고, 작업 중에 다른 유형·모드의 컴포넌트·스타일을 임의로 섞지 않습니다(5단계).
- 혼합을 고르면 영역별 패키지(예: "페이지 = Web, 가운데 영역 = OrgChart")를 확인합니다. SW 영역이 있으면 그 영역의 모드(일반/뷰어)까지 정합니다.
- **OrgChart가 포함되고 생성 방식이 없으면** 같은 메시지에서 다음도 묻습니다(이미 말했으면 묻지 않음): "조직도만 기존 페이지에 삽입할까요(Chart Only), 아니면 레이아웃까지 구성한 새 페이지 전체를 생성할까요(Full Page)?" 상세는 `@hm-design/org-chart/ai/AI_USAGE.md` §1.
- 선택한 패키지가 설치되어 있지 않으면 설치가 필요하다고 보고합니다. 다른 HMDesign 패키지나 임의 라이브러리로 대신하지 않습니다.
@@ -57,8 +74,9 @@
| 요청 항목 | 판단 | 근거(카탈로그의 실제 이름) |
|---|---|---|
| 예: 상단 메뉴 | 재사용 | Web `GNB` + `GNBMobileMenu` |
| 예: 레이어 선택 | 재사용 | SW `SWHeaderLayerMenu` |
| 예: 검색 상자(SW) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + SW 토큰 |
| 예: 레이어 선택(SW 일반) | 재사용 | SW `SWHeaderLayerMenu` |
| 예: 상단 메뉴(SW 뷰어) | Props 설정 | SW `SWViewerHeader`의 `groups` |
| 예: 검색 상자(SW 일반) | 신규 | SW 카탈로그에 없음 → `SWHeaderInput` 재사용 + 일반 모드 토큰 |
판단 값은 **재사용**(그대로) / **Props 설정**(기존 Variant·Props) / **조합**(기존 컴포넌트 배치) / **신규**(소비 프로젝트에 최소 구현) 중 하나입니다.
@@ -69,31 +87,44 @@
1. 선택 패키지의 기존 컴포넌트·Pattern을 그대로 사용
2. 기존 Variant / Props / Callback으로 해결
3. 기존 컴포넌트 조합(배치용 CSS만 소비 프로젝트에 작성)
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 패키지 토큰만 읽고, 안쪽에 기존 컴포넌트를 재사용
4. 조합으로 안 되는 부분만 **소비 프로젝트에** 새로 구현 — 아래 "없는 컴포넌트 처리 3단계"
모든 단계는 **1단계에서 정한 유형·모드 안에서만** 찾습니다. SW 뷰어 모드는 뷰어 컴포넌트(`SWViewer*`)를, SW 일반 모드는 일반 컴포넌트(`SWHeader`·`SWPopup` …)를 먼저 씁니다. 다른 모드에 같은 역할의 컴포넌트가 있어도 가져오지 않습니다.
### 없는 컴포넌트 처리 3단계
| 단계 | 조건 | 할 일 | 결과 보고 |
|---|---|---|---|
| ① 재사용 | 선택 유형·모드에 컴포넌트·Variant·Props·조합이 있음 | 그대로 사용(위 1~3) | 재사용 / Props 설정 / 조합 |
| ② 같은 모드 스타일로 신규 | 컴포넌트는 없지만 그 모드의 토큰·확인값·상태 표현이 있음 | 소비 프로젝트에 최소 구현. 그 유형·모드의 토큰과 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 크기·색·상태 표현만 읽고, 안쪽에는 그 모드의 공개 컴포넌트를 재사용 | 신규 · 읽은 토큰 목록 |
| ③ HMDesign과 조화되는 새 스타일 | ②로 참고할 토큰·확인값이 없음 | HMDesign 공통 규칙(아래)과 선택 유형·모드의 가장 가까운 토큰을 기준으로 새 스타일을 구성 | 신규 · **"AI 구성 값 — 디자인 확인 필요"** 목록(속성·값·이유) |
- 토큰·확인값이 있으면 ②에서 반드시 그것을 씁니다. ③은 참고할 값이 정말 없을 때만이며, ③에서 만든 값은 확정 디자인이 아니라 확인 대상입니다. 화면 인상을 크게 바꾸는 값(주요 색·Header 높이 등)이 필요하면 구현 전에 사용자에게 먼저 확인합니다.
- 유형·모드별 구체 토큰과 예는 각 패키지 `ai/AI_USAGE.md`에 있습니다.
규칙:
- `node_modules` 안 패키지 파일을 수정하지 않습니다. 패키지 `dist` 구현이나 내부 CSS 블록을 복사해 같은 컴포넌트를 다시 만들지 않습니다.
- 이미 있는 컴포넌트와 같은 역할의 컴포넌트를 새로 만들지 않습니다(예: Web에 `Dialog`가 있는데 자체 Modal 작성 금지).
- 새 디자인 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`의 토큰·확인값만 씁니다. 값이 없으면 추측하지 말고 사용자에게 확인합니다.
- 토큰·확인값이 있는 속성에 새 값을 만들지 않습니다. 색·크기·간격·radius·그림자는 각 패키지 `DESIGN_RULES.md`(SW 뷰어는 `VIEWER.md`도)의 토큰·확인값을 씁니다. 값이 없을 때만 위 ③으로 구성하고 "AI 구성 값"으로 보고합니다(추측한 값을 확정값처럼 쓰지 않음).
- 공통: Font Weight는 400 / 500 / 700만 씁니다(600 없음). Light/Dark 분기를 만들지 않습니다. 새 컴포넌트 CSS에 `html`·`body`·`*` 전역 규칙을 넣지 않습니다. 새 class는 소비 프로젝트 접두사(예: `app-`)를 씁니다.
- 요청에 없는 메뉴·통계·설명·다운로드·외부 API·AI 입력 UI를 추가하지 않습니다. 필요해 보이면 제안으로만 보고합니다.
### 없는 UI를 같은 스타일로 만들 때 확인할 항목
신규 항목마다 아래를 선택 패키지 `DESIGN_RULES.md`에서 찾아 그대로 적용합니다. 찾을 수 없는 항목은 "값 없음 — 사용자 확인 필요"로 보고합니다.
신규 항목마다 아래를 선택 유형·모드의 문서에서 찾아 그대로 적용합니다(②). 찾을 수 없는 항목은 ③으로 구성하고 "AI 구성 값 — 디자인 확인 필요"로 보고합니다.
| 항목 | Web(`@hm-design/ui`) | SW(`@hm-design/sw`) | OrgChart |
|---|---|---|---|
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 |
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | 카드·간격 변경 금지(승인 디자인) |
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | 공개 입력만 |
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | Core 내장 |
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | Core 내부 Zoom/Pan |
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | Core 내장 |
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | Core 팝업 / HM Dialog / 어댑터 |
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | Core 키보드(Pan, Alt+M 이동 등) |
| 항목 | Web(`@hm-design/ui`) | SW 일반 모드(`@hm-design/sw`) | SW 뷰어 모드(`@hm-design/sw`) | OrgChart |
|---|---|---|---|---|
| 토큰·CSS 변수 | `--hm-sem-*`, `--hm-color-*`, `--hm-radius-*`(`:root`) | `--hm-sw-header-*`, `--hm-sw-property-*`(`SWTheme` 범위) | `--hm-sw-viewer-*` + 두 Header가 공유하는 `--hm-sw-header-document-*`·`object-*`·`property-*`(SW 범위) | `--hm-orgchart-*` 공개 입력(Shadow DOM 상속) |
| 색·Typography | DESIGN_RULES §2·§3 | DESIGN_RULES §2·§3 | VIEWER.md `SWViewerHeader`·디자인 변경 절 | DESIGN_RULES §2·§3 |
| 크기·여백 | DESIGN_RULES §4 | DESIGN_RULES §1 | VIEWER.md 디자인 변경 절(52px Header 등 실측값) | 카드·간격 변경 금지(승인 디자인) |
| Border·Radius·배경·그림자 | DESIGN_RULES §2·§4 | DESIGN_RULES §2·§8 | VIEWER.md `SWViewerPanel` 절(프레임은 SWPopup과 같음) | 공개 입력만 |
| 아이콘 | `lucide-react`(패키지 의존성) | 패키지 내장 SVG만, 새 아이콘은 사용자 제공 | 프로그램 제공 16px `currentColor` 아이콘, 외곽선은 `SWViewerIcon` | Core 내장 |
| 스크롤바 | `ScrollArea`(Radix), DESIGN_RULES §6 | 전용 디자인 없음 — 브라우저 기본(AI_USAGE §2) | 전용 디자인 없음 — 패널 본문 스크롤은 `SWViewerPanel` | Core 내부 Zoom/Pan |
| Hover / Active / Focus / Disabled | DESIGN_RULES §5 | DESIGN_RULES §4 | VIEWER.md `SWViewerHeader` 절 상태 표현 | Core 내장 |
| Popup·Panel | `Dialog`·`AlertDialog`·`Sheet`·`Drawer`·`Popover` | `SWPopup` + `SWPopupSection`/`SWPopupRow` | `SWViewerPanel`(+ `modal`) + `SWViewerSection`/`SWViewerField` | Core 팝업 / HM Dialog / 어댑터 |
| 동작·키보드 | Radix 동작 유지 | 카탈로그 "공통 키보드" | VIEWER.md `SWViewerMenu`·`SWViewerPanel` 키보드 | Core 키보드(Pan, Alt+M 이동 등) |
## 5단계. 패키지별 디자인 분리 (혼합 사용 포함)
@@ -102,20 +133,30 @@
| 패키지 | 스타일이 적용되는 범위 | 주의 |
|---|---|---|
| Web | `theme.css`의 토큰은 `:root, [data-hm-theme]`. `tailwind.css`는 Tailwind base에서 `*`(border·outline), `body`(배경·글자), `html`(글꼴)을 **문서 전체에** 적용. 앱이 import하는 `tailwindcss`의 Preflight도 전역 | Web CSS를 넣은 문서에서는 다른 영역에도 전역 초기화가 적용됨 |
| SW | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`(`<SWTheme>`)에만 정의. 전역 선택자 없음 | Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
| SW(일반·뷰어 공통) | 토큰은 `.hm-sw-header`와 `.hm-sw-theme`에만 정의(뷰어 토큰 `--hm-sw-viewer-*`도 같은 범위). 전역 선택자 없음. `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`은 자기 root에 `hm-sw-theme`를 가짐 | 일반 모드의 Header 밖 SW 부품은 반드시 `<SWTheme>` 안 |
| OrgChart | Core가 자기 open Shadow DOM에만 CSS 로드. 호스트 CSS selector는 안쪽에 닿지 않고 **Custom Property 상속만** 통과 | 호스트 class로 카드 모양을 바꾸려 하지 않음 |
혼합 규칙:
1. 영역마다 하나의 패키지를 정하고 그 영역의 신규 UI는 그 패키지의 토큰만 읽습니다. Web 토큰(`--hm-sem-*`)을 SW 영역에, SW 토큰(`--hm-sw-*`)을 Web 영역에 쓰지 않습니다. OrgChart 내부는 `--hm-orgchart-*`만 씁니다.
2. 다른 패키지 컴포넌트는 **문서에 허용된 지점에서만** 씁니다.
- SW `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
- SW 일반 모드 `SWPopup`의 `children` 안 Web 컨트롤(SW 카탈로그가 허용, 예: Popup 하단 `Button`)
- SW 뷰어 모드 `SWViewerPanel`의 `children` 안 Web 컨트롤 — `SWViewer*` 컨트롤로 안 될 때만(SW `AI_USAGE.md` §0.4)
- OrgChart Full Page의 바깥 레이아웃 = Web(또는 요청된 패키지)
- OrgChart React의 직원 팝업 = 선택 `@hm-design/org-chart-react/hm-dialog`(Web `Dialog`, Web Theme CSS 필요)
3. 패키지 class(`hm-sw-*`, `hm-orgchart-*`, Web `data-slot`)를 소비 코드에서 덮어쓰지 않습니다. 배치는 `className`·`style`과 소비 프로젝트 class로 합니다.
4. **Web + SW를 한 문서에 함께 쓰면** Web의 전역 base(위 표)가 SW 화면에도 적용됩니다. SW는 자기 범위에서 버튼 등을 초기화하지만 이 조합의 시각 결과는 패키지에서 검증된 적이 없습니다(NOT VERIFIED). 이 조합이면 브라우저에서 SW 부품의 글꼴·테두리·배경을 직접 확인하고 차이를 보고합니다. 가능하면 Web CSS가 없는 SW 전용 화면(별도 entry)으로 분리합니다.
5. Web Scoped Theme(`[data-hm-theme]`)는 body Portal(Select·Popover·DatePicker 팝업)에 전달되지 않습니다. Web 영역만 다른 테마로 바꾸려면 Global Theme를 쓰거나 차이를 보고합니다.
### SW 일반 모드 ↔ 뷰어 모드 분리
SW 일반 모드와 뷰어 모드는 같은 패키지·같은 CSS 파일이지만 **서로 다른 디자인**입니다. 한 화면(한 Header 영역)에는 한 모드만 씁니다.
1. 일반 모드 화면: `SWHeader`·개별 컨트롤·`SWPopup`·`SWHeaderPropertyPanel`·`SWToolButton`/`SWToolGroup`. `SWViewer*` 컴포넌트와 `--hm-sw-viewer-*` 토큰을 쓰지 않습니다.
2. 뷰어 모드 화면: `SWViewerHeader`·`SWViewerMenu`·`SWViewerPanel`과 뷰어 패널 컨트롤(`SWViewerSection`·`SWViewerField` …). `SWHeader`에 뷰어 메뉴를 억지로 넣거나 `SWPopup`을 뷰어처럼 재스타일하지 않습니다.
3. 패키지가 실제로 공유하는 부분은 혼합이 아닙니다: `SWViewerPanel`은 `SWPopup` 프레임을 그대로 렌더링하고, 두 Header는 파일명·객체 수정·속성 면 토큰(`--hm-sw-header-document-*`·`object-*`·`property-*`)을 공유합니다. 소비 코드가 이 공유를 흉내 내 다른 모드 부품을 섞어도 된다는 뜻은 아닙니다.
4. 프로그램이 두 모드를 모두 가지면 모드 전환 시 Header 컴포넌트를 바꿔 끼웁니다(파일·패널 상태는 프로그램 상태로 유지). 세부는 `@hm-design/sw/ai/AI_USAGE.md` §0과 `VIEWER.md`.
## 6단계. 디자인 검증
소비 프로젝트에서 실제로 실행한 것만 PASS로 적습니다.
@@ -123,20 +164,22 @@
1. Typecheck(`tsc --noEmit` 등)와 Production Build
2. 브라우저 렌더링: 재사용한 컴포넌트가 HM 외형으로 보이는지(CSS 진입점 누락 확인), 신규 UI가 같은 토큰을 쓰는지
3. 상태·동작: Hover / Focus(키보드) / Disabled, Popup 열기·닫기·Escape·Focus 복귀, 선택 패키지의 핵심 동작
4. 폭: Web 390 / 768 / 1280 / 1440px, SW는 대상 창 폭(Header는 반응형 More 포함), OrgChart는 캔버스 크기·초기 Fit
5. 혼합이면 영역 경계에서 스타일 침범이 없는지(§5)
4. 폭: Web 390 / 768 / 1280 / 1440px, SW 일반 모드는 대상 창 폭(Header는 반응형 More 포함), SW 뷰어 모드는 대상 창 폭과 항목 `collapseBelow`·`iconOnlyBelow` 경계 전후(More 이동·아이콘만 표시), OrgChart는 캔버스 크기·초기 Fit
5. 혼합이면 영역 경계에서 스타일 침범이 없는지, SW면 선택하지 않은 모드의 컴포넌트·토큰이 섞이지 않았는지(§5)
6. 실행하지 못한 항목은 `NOT VERIFIED`로 남깁니다.
## 7단계. 결과 보고 형식
```md
## HMDesign 적용 결과
- 사용 유형: Web | SW | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
- 사용 유형: Web | SW 일반 | SW 뷰어 | OrgChart(Chart Only|Full Page) | 혼합(영역별: …)
- 유형·모드 판단 근거: 프로젝트 설정 | 요청 문구 "…" | 사용자 답변
- 패키지·버전: @hm-design/ui 0.1.0, …
- 재사용한 컴포넌트: …(Props 설정 포함)
- 조합한 부분: …
- AI가 새로 구현한 부분: 파일 경로 · 이유(카탈로그에 없음) · 안쪽에서 재사용한 컴포넌트
- 적용한 디자인 토큰: --hm-… (신규 UI가 읽은 것)
- AI 구성 값 — 디자인 확인 필요: 없음 | 속성 · 값 · 이유(4단계 ③)
- 카탈로그와 .d.ts 차이: 없음 | …
- 검증: Typecheck PASS · Build PASS · 브라우저(폭/상태) … · NOT VERIFIED: …
- 제안(구현하지 않음): …
@@ -161,9 +204,14 @@
import { Button, Card, CardContent, FilterBar, FilterBarActions, FilterBarSearch, PageHeader, PageHeaderContent, PageHeaderTitle } from "@hm-design/ui"
```
### 예시 B — SW 뷰어
### 예시 B0 — "HMDesign SW로 화면을 만들어 주세요" (모드 미지정)
- 읽기: `node_modules/@hm-design/sw/ai/` → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`
- 유형은 SW로 확정, 모드 근거가 없으므로 코드 작성 전에 1단계 4번의 모드 질문만 합니다. 답에 따라 B1 또는 B2로 진행합니다.
- 소비 프로젝트 설정이 `HMDesign 사용 유형: SW 일반` 또는 `SW 뷰어`이면 묻지 않고 바로 B1/B2입니다.
### 예시 B1 — SW 일반 모드 (편집 Header + 도구 막대 + 설정 Popup)
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(일반 모드) → COMPOSITION_PATTERNS "6. 파일 열기 + 도구 막대", 예제 `ai/examples/ExampleF-ViewerToolbar.tsx`(파일 이름의 Viewer는 과거 명칭이며 일반 모드 `SWHeader` 예제)
- 재사용: `SWHeader`(`documentOpenPlacement="header"`, `controls`, `tools`), `SWToolGroup` + `SWToolButton`(Model/Layout 탭, Fit 등), `SWPopup` + `SWPopupSection` + `SWPopupRow` + `SWHeaderInput`(설정 Popup)
- 신규: SW에 없는 기능(예: 검색) → 소비 프로젝트 컴포넌트, `<SWTheme>` 안, `--hm-sw-header-*` 토큰, 안쪽 입력은 `SWHeaderInput`(예제 `ExampleD-SearchExtension.tsx`)
@@ -172,6 +220,18 @@ import { SWHeader, SWPopup, SWTheme, SWToolButton, SWToolGroup } from "@hm-desig
import "@hm-design/sw/styles.css"
```
### 예시 B2 — SW 뷰어 모드 (뷰어 Header + 메뉴 + 패널)
- 읽기: `node_modules/@hm-design/sw/ai/` → AI_USAGE §0(뷰어 모드) → `VIEWER.md`, 예제 `ai/examples/ExampleH-ViewerMode.tsx`
- 재사용: `SWViewerHeader`(`groups` 데이터: `button`·`toggle`·`menu`·`tabs`·`switch`·`custom` 항목, `onCommand`, `trailing`에 `SWViewerStatus`·`SWViewerHeaderButton`), Dropdown은 `type: "menu"` 항목의 `entries`(단독·우클릭은 `SWViewerMenu`), 팝업은 `SWViewerPanel` + `SWViewerSection`·`SWViewerField`·`SWViewerSwitch`·`SWViewerSlider`·`SWViewerInput`·`SWViewerButton`
- 신규: 뷰어에 없는 패널 콘텐츠 → 소비 프로젝트 컴포넌트를 `SWViewerPanel`의 `children`에, 안쪽은 `SWViewerField` + `SWViewerInput` 등, 외형은 `--hm-sw-viewer-*` 토큰
- 하지 않음: `SWHeader`·`SWPopup`을 뷰어 화면에 섞기, 로고가 없다고 임의 문자·아이콘 넣기, 연결할 명령이 없는 메뉴를 가짜 동작으로 만들기(제외 또는 `disabled` + 미연결 보고)
```tsx
import { SWViewerHeader, SWViewerPanel, SWViewerSection, SWViewerField, SWViewerSwitch, type SWViewerHeaderGroup } from "@hm-design/sw"
import "@hm-design/sw/styles.css"
```
### 예시 C — 조직도만 (Chart Only)
- 읽기: `node_modules/@hm-design/org-chart/ai/` → COMPOSITION_PATTERNS "1. Chart Only"
@@ -198,7 +258,7 @@ import coreUrl from "@hm-design/org-chart/style.css?url"
AI 코딩 도구는 보통 **프로젝트 루트의** `AGENTS.md`(Codex 등)·`CLAUDE.md`(Claude Code)·도구별 규칙 파일만 자동으로 읽고 `node_modules`는 읽지 않습니다. 패키지 설치만으로 지침이 자동 적용되지는 않으므로 소비 프로젝트에서 한 번 연결합니다.
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
1. 패키지에 들어 있는 `ai/AGENTS_SNIPPET.md`를 루트 `AGENTS.md`(없으면 새로 만듦)에 붙여 넣고 `HMDesign 사용 유형:` 줄을 프로젝트에 맞게 고칩니다. 값은 `Web` / `SW 일반` / `SW 뷰어` / `OrgChart` / `혼합(영역별: 예 "페이지 = Web, 중앙 = OrgChart")` 중 하나입니다. SW 프로젝트면 모드까지 적어야 AI가 모드를 다시 묻지 않습니다(`SW`만 적으면 모드를 묻습니다). 정하지 않았으면 그 줄을 지워 AI가 1단계에서 묻게 합니다.
```bash
cat node_modules/@hm-design/ui/ai/AGENTS_SNIPPET.md >> AGENTS.md
```
+5 -5
View File
@@ -6,11 +6,11 @@
| 위치 | 역할 | 패키지 포함 |
|---|---|---|
| `docs/ai/AI_GUIDE.md` | 공통 진입점 원본(사용 유형 선택, 1~7단계, 패키지 분리, 예시 A~D, 소비 프로젝트 설정) | 사본으로 포함 |
| `docs/ai/AI_GUIDE.md` | 공통 진입점 원본(사용 유형 Web / SW 일반·뷰어 / OrgChart / 혼합 선택, 없는 컴포넌트 처리 3단계, 1~7단계, 패키지·SW 모드 분리, 예시 A~D, 소비 프로젝트 설정) | 사본으로 포함 |
| `docs/ai/AGENTS_SNIPPET.md` | 소비 프로젝트 루트 `AGENTS.md`에 붙일 연결 문구 원본 | 사본으로 포함 |
| `docs/ai/MAINTAINING.md` | 이 문서 | 미포함 |
| `packages/ui/ai/` | Web: `AI_USAGE`, `COMPONENT_CATALOG`, `DESIGN_RULES`, `COMPOSITION_PATTERNS` | 포함(`files`) |
| `packages/sw/ai/` | SW: 위 4종 + `examples/` | 포함 |
| `packages/sw/ai/` | SW: 위 4종(`AI_USAGE.md` §0 = SW 일반/뷰어 모드 선택) + 뷰어 모드 전용 `VIEWER.md` + `examples/`(A~F 일반 모드, H 뷰어 모드) | 포함 |
| `packages/org-chart/ai/` | OrgChart(Core + React 어댑터 API): 위 4종 | 포함 |
| `packages/org-chart-react/ai/` | `AI_USAGE`(Core `ai/` 안내) | 포함 |
| `scripts/ai-docs.mjs` | 동기화(`--sync`)·검사(`--check`) | — |
@@ -26,14 +26,14 @@
1. **공개 Export가 바뀌면** 해당 패키지 `ai/COMPONENT_CATALOG.md`에 이름·용도·HM Props(기본값)를 추가·수정·삭제합니다. 내부 전용 이름은 "공개하지 않은 것" 절에만 적습니다.
2. **Props·Variant 기본값·허용 조합이 바뀌면** 카탈로그 표와 `COMPOSITION_PATTERNS.md`의 예시 코드를 함께 고칩니다.
3. **토큰·CSS 값이 바뀌면** `DESIGN_RULES.md`의 표를 실제 CSS 선언과 맞춥니다(값은 CSS에서 복사, 추측 금지).
4. **새 화면 유형·조합 규칙이 생기면** `COMPOSITION_PATTERNS.md` §0 표에 행을 추가합니다.
5. 공통 규칙(유형 선택·혼합·보고 형식)이 바뀌면 `docs/ai/AI_GUIDE.md`만 고치고 `npm run sync:ai-docs`로 사본을 갱신합니다. 패키지 사본을 직접 고치지 않습니다.
4. **새 화면 유형·조합 규칙이 생기면** `COMPOSITION_PATTERNS.md` §0 표에 행을 추가합니다. SW 뷰어 모드 컴포넌트(`SWViewer*`)를 바꾸면 `VIEWER.md`와 카탈로그의 뷰어 절을 함께 고치고, 일반/뷰어 모드 구분이 바뀌면 `packages/sw/ai/AI_USAGE.md` §0과 공통 `AI_GUIDE.md` 1단계·5단계를 같이 맞춥니다.
5. 공통 규칙(유형·SW 모드 선택·혼합·보고 형식)이 바뀌면 `docs/ai/AI_GUIDE.md`만 고치고 `npm run sync:ai-docs`로 사본을 갱신합니다. 패키지 사본을 직접 고치지 않습니다.
6. `npm run check:ai-docs`를 실행해 PASS를 확인합니다.
7. 버전을 올리면 카탈로그 첫 줄의 기준 버전을 같이 바꿉니다.
## 3. `npm run check:ai-docs`가 검사하는 것
1. `docs/ai`의 공유 파일과 각 패키지 사본이 같은지
1. `docs/ai`의 공유 파일과 각 패키지 사본이 같은지(줄바꿈 CRLF/LF 차이는 무시 — `core.autocrlf=true`에서 `packages/sw`만 `.gitattributes`로 LF checkout)
2. 각 패키지 `package.json`의 `files`에 `ai`가 있는지
3. 공개 진입점(`src/index.ts` 등, `export *` 재귀 포함)의 **모든 Export 이름이 카탈로그에 나오는지**
4. 카탈로그에 Export처럼 보이지만(기존 Export 이름으로 시작) 실제로는 없는 이름이 없는지 — 예: `DialogFancyPanel`. "공개하지 않은 것"·"없는 것"·"지원하지 않는" 절은 제외
+36
View File
@@ -26,3 +26,39 @@
- Web CSS와 SW를 **한 문서**에서 함께 쓰는 경우의 시각 결과(문서에 NOT VERIFIED로 명시, 별도 entry 권장).
- 768px 화면, 실제 터치·스크린리더, Registry publish 후 설치.
- 문서의 Props 기본값·토큰 값 전부를 기계적으로 대조하지는 않았다(검사기는 Export 이름·링크·사본만 검사). 이번 작성은 소스를 직접 확인했다.
## 추가 검증 — SW 일반 / 뷰어 모드 구분 (2026-10-19)
범위: `feature/sw-viewer-header`(68fbcf6)를 merge(be7a04a)한 뒤, 사용 유형을 Web / SW(일반·뷰어) / OrgChart / 혼합으로 나누고 SW 모드 선택·혼합 금지·없는 컴포넌트 처리 3단계를 공통 가이드와 각 패키지 `ai/` 문서에 반영. 런타임 코드·CSS·Storybook·공개 API 변경 없음. 위 기록의 "SW 뷰어(SWHeader + SWToolGroup + SWPopup)"는 당시 명칭이며, 현재 기준으로는 **일반 모드 Header + 도구 막대** 구성이다(뷰어 모드 = `SWViewer*`).
| 항목 | 결과 |
|---|---|
| `npm run sync:ai-docs` → `npm run check:ai-docs` (뷰어 Export 33개 포함 카탈로그 ↔ 공개 Export) | PASS |
| `npm run build -w packages/sw` 후 `npm pack --ignore-scripts` 4종을 임시 소비 폴더 `node_modules/@hm-design/*`에 풀어 확인 | sw tarball에 `ai/VIEWER.md`·`examples/ExampleH-ViewerMode.tsx` 포함, `dist/index.d.ts`가 `sw-viewer`를 `export *` |
| 뷰어 문서(VIEWER.md, 카탈로그 §8, DESIGN_RULES §11, PATTERNS 7, AI_USAGE §0)의 Props·토큰 이름 ↔ `sw-viewer` 소스·`sw-viewer.css` | 일치(남은 차이는 예제 변수명과 "없는 Props" 목록뿐) |
| 설치 위치 기준 시나리오 정적 검사 124건: 공통(사본 동일·상대 링크), Web(설정 → `ui/ai`, 다른 영역 이관, 3단계), SW 미지정("HMDesign SW로 화면을 만들어 주세요" → 유형 확정 + 모드 질문만, 애매하면 추측 금지), SW 일반(설정 → 묻지 않음, `SWViewer*` 금지, 예제 B·F 명칭), SW 뷰어(설정·요청 근거 → `VIEWER.md`, `SWHeader`/`SWPopup` 재스타일 금지, 주요 8개 컴포넌트가 카탈로그와 설치 `.d.ts`에 존재), OrgChart(Chart Only / Full Page 질문 1회, 승인 디자인 유지), 혼합(SW 영역 모드, 보고 형식) | 124 PASS / 0 FAIL |
### Cold-start 검증(`be7a04a` 기준) 지적 사항 반영
| 지적 | 현재 작업본 |
|---|---|
| `check:ai-docs` FAIL — sw 사본 `AI_GUIDE.md`·`AGENTS_SNIPPET.md` 불일치 | 원인은 내용이 아니라 줄바꿈: `core.autocrlf=true`에서 `docs/ai`·ui·org-chart는 CRLF, `packages/sw`(`.gitattributes` `eol=lf`)는 LF로 checkout. `scripts/ai-docs.mjs` 사본 비교를 줄바꿈 무시로 변경. 작업본 스냅샷을 `git archive`(CRLF checkout 재현)로 풀어 검사 PASS, 실제 내용 차이를 넣으면 FAIL 검출 |
| `check:ai-docs` FAIL — SW 카탈로그에 `SWViewer*` 33개 누락 | 카탈로그 §8에 33개 모두 등재, 검사 PASS |
| 카탈로그 "표에 없는 이름은 공개 API 아님"과 VIEWER.md 충돌 | §8 등재로 해소, 머리말 "무엇을 쓸까"에 일반/뷰어 분기 |
| "도면 뷰어" 요청 시 예시 B(`SWHeader`+`SWPopup`)와 VIEWER.md가 다른 답 | 공통 1단계 4번·예시 B0/B1/B2, SW `AI_USAGE.md` §0(판단 순서·질문 문구·혼합 금지), 예제 B·F는 일반 모드로 명시 |
| `SWPopup` `anchorRef` 사용 시 열릴 때 Focus 미이동 | **이번 AI 지침 작업 범위 밖 — 별도 수정 대상.** 코드 수정하지 않음 |
### 추가 검증 — 코드 예제 (변경분만, 기존 PASS 재사용)
| 항목 | 결과 |
|---|---|
| 임시 소비 프로젝트(설치 tarball, React 19.3.0, TypeScript 7.0.2, Vite 8.3.0)에서 `COMPOSITION_PATTERNS.md` 7 코드 조각과 `VIEWER.md` §5 코드 조각을 **본문 그대로** 감싸고 자유 변수만 선언, 예제 H 포함 | `tsc --noEmit`(strict, skipLibCheck false) PASS, `vite build` PASS |
| 브라우저 1440px — PATTERNS 7 | 샘플 메뉴 열림·선택 → 파일명 표시, 도면 공간 탭 전환(`space=layout`), 설정 패널 열림 시 패널 안 Focus·Escape 닫힘·토글로 Focus 복귀, 정보 `modal` Focus·확인 닫힘, 가로 넘침 없음, 글꼴 Noto Sans KR, 콘솔 오류 0 |
| 브라우저 1440px — VIEWER.md §5 | 파일명 표시, 전체 보기 명령, 설정 패널 Focus, Switch 토글·Label 연결 |
| 800px 폭 | 항목이 More(⋯)로 이동(반응형 동작 확인, 세부 경계값 미측정) |
### NOT VERIFIED
- 독립 AI가 Cold-start로 이 문서를 읽고 실제로 모드를 묻거나 고르는지(행동 검증). 위 검사는 문서에 필요한 판단 문구가 읽는 경로에 있는지만 확인한다.
- 확정 Commit 기준 독립 Cold-start 재검증(별도 1회 예정).
- SW 일반/뷰어 모드 전환을 소비 프로젝트에서 실제로 구성한 화면, SW 화면 + 조직도 조합.