@simplysm/sd-claude 14.0.48 → 14.0.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,9 +50,9 @@ npm install @simplysm/sd-claude
50
50
 
51
51
  | API | Type | Description |
52
52
  |-----|------|-------------|
53
- | `claude/skills/` | asset directory | 16개 sd-* 스킬 디렉토리 (각 스킬은 `SKILL.md` + 선택적 `SKILL.eval.md`와 `references/` 포함) |
53
+ | `claude/skills/` | asset directory | 19개 sd-* 스킬 디렉토리 (각 스킬은 `SKILL.md` + 선택적 `SKILL.eval.md`와 `references/` 포함) |
54
54
  | `claude/rules/` | asset directory | Claude Code 규칙 파일 (`sd-claude-rules.md`, `sd-options.md`) |
55
- | `claude/references/` | asset directory | 스킬/규칙에서 참조하는 공유 문서 패키지 문서 디렉토리 |
55
+ | `claude/references/` | asset directory | 스킬/규칙에서 참조하는 공유 문서 (`sd-frontend-design.md`, `sd-testing.md`) |
56
56
 
57
57
  → See [docs/assets.md](./docs/assets.md) for details.
58
58
 
@@ -1,124 +1,44 @@
1
- # CRITICAL: 무단 진행·추측 금지
2
-
3
- - 어떠한 경우에도 지침을 무시하고 건너뛰지 않는다. 혼자만의 판단으로 무단 진행 절대(NEVER) 금지
4
- - 지침이 충돌등의 이유로 애매하면 사용자에게 질문한다.
5
- - 코드를 수정할 때, 왜 그 코드가 문제인지 근거를 먼저 확인하고 수정한다. "일단 바꿔보고 되면 넘어가자" 식의 추측성 시행착오를 절대(NEVER) 금지한다.
6
-
7
- # CRITICAL: 사실·지침 날조 금지
8
-
9
- **존재하지 않는 것을 지어내지 않는다(NEVER).**
10
-
11
- - 인용하는 파일·함수·API·라이브러리 시그니처는 반드시 Read/Grep으로 **직접 확인한 것**만 쓴다. 기억·일반 지식·추측 금지.
12
- - 사용자가 명시한 적 없는 지침/규칙을 "있는 것처럼" 만들어 따르지 않는다. 룰은 `.claude/rules/`, `CLAUDE.md`, 사용자 발화에만 존재한다. 본인이 추론한 베스트 프랙티스를 "규칙"으로 격상시키지 않는다.
13
- - 불확실하면 "확인 필요" 또는 "추측"이라 명시하고, 가능하면 도구로 검증한다. 모르면 모른다고 말한다.
14
- - 답변·코드·계획에 들어가는 모든 사실 주장은 **출처(파일경로:라인 / 도구 결과 / 사용자 발화)** 를 응답에 인라인으로 인용한다. 특히 조회로 얻은 존재·부재 단정은 조회 도구·대상·결과를 응답에 함께 표기한다 (예: "Grep `reverseBits` in `packages/core-common` → 결과 없음"). 출처를 댈 수 없는 주장은 하지 않는다.
15
-
16
- # CRITICAL: 변경사항 되돌리기 금지
17
-
18
- **git diff에 나타나는 변경사항을 임의로 되돌리지 않는다(NEVER).**
19
-
20
- - `git diff`에 보이는 변경은 사용자가 직접 수정한 것일 수 있다. subagent가 만든 변경인지, 사용자가 직접 한 변경인지 구분할 수 없으므로, 어떤 변경이든 되돌리기 전에 반드시 사용자에게 확인한다.
21
- - 특히 현재 작업 범위 밖의 파일 변경을 발견해도, "의도하지 않은 변경"이라고 단정짓지 않는다. 사용자가 별도로 수정한 코드일 수 있다.
22
- - 되돌려야 할 명확한 근거(사용자의 명시적 요청, 빌드/테스트 실패 등)가 없으면 절대 되돌리지 않는다.
23
-
24
- # Compaction Rules
25
-
26
- `/compact`수행 시, 항상 보존할 것:
27
-
28
- - 수정된 파일의 전체 경로 목록
29
- - 에러 메시지 원문
30
-
31
- # Python 인코딩
32
-
33
- - `python3 -c`로 유니코드 텍스트를 출력할 때, 반드시 `sys.stdout.reconfigure(encoding='utf-8')`을 사용한다. (Windows cp949 인코딩 에러 방지)
34
-
35
1
  # 금지 명령어
36
2
 
37
- - **GIT**: `git stash`, `git checkout`, `git restore`, `git reset`, `git clean` 사용 금지.
38
- - **CRITICAL: 폴더이동 금지**: `cd` 명령을 통한 타 폴더로의 이동 금지. 폴더이동시 hook 오류남!!
39
- - **타입체크 명령어**: `npx tsc` 사용 금지. 반드시 `pnpm typecheck [targets..]`등의 스크립트 사용
40
- - **Lint 명령어**: `npx eslint` 사용 금지. 반드시 `pnpm lint [targets..]`등의 스크립트 사용
41
-
42
- # 도구사용 규칙
43
-
44
- - Write: 이미 존재하는 파일에 Write 도구를 사용하지 않는다. 기존 파일 수정은 반드시 Edit 도구를 사용한다. (Write는 덮어쓰기때문에 위험함)
45
- - **CRITICAL: 파일을 읽으라는 지침이 있으면 Read tool로 반드시(MUST) 읽어라. 절대(NEVER) 무시하지 말것**
46
- - subagent 도구 사용시, 명시적으로 백그라운드 수행을 언급하지 않은경우, 굳이 백그라운드로 수행하지 않는다.
3
+ - `git stash`, `git checkout`, `git restore`, `git reset`, `git clean` 사용 금지.
4
+ - `cd` 명령을 통한 타 폴더로의 이동 금지.
5
+ - `npx tsc` 사용 금지. 반드시 `pnpm typecheck [targets..]`등의 스크립트 사용
6
+ - `npx eslint` 사용 금지. 반드시 `pnpm lint [targets..]`등의 스크립트 사용
47
7
 
48
8
  # 대화 규칙
49
9
 
50
- - 사용자의 질문에 답변만 하라. 절대 지침 없이 임의로 다음단계(특히, 코드변경)로 넘어가지 않는다(NEVER). 답변만 하고 사용자의 명시적 요청을 기다린다.
51
- - 사용자의 질문은 동의를 구하는것이 아니다. 무조건적 동의하려하지 말고, 비판적으로 사고하여 답변한다.
52
- - 사용자 요청의 의도가 불명확할 때는 `/sd-inner-clarify` 스킬을 호출하여 명확화한다. 단순 정보 조회처럼 의도가 명확한 질문에는 위 "답변만 하라" 규칙을 따른다. (절대 추측하지 않는다.)
53
- - **CRITICAL: 맥락에 맞는 언어로 말한다**. 지금 대화의 층위가 무엇인지 먼저 파악하고 그 층위의 용어로 말한다.
10
+ - 응답 항상 thinking 것.
11
+ - 내장 도구 적극 활용 (Read/Grep/Glob/Bash/WebFetch/WebSearch/Skill/TaskCreate 등)
12
+ - 사용자가 명시하지 않은 사항 추측으로 행동 금지. 추측한것이 맞는지 `AskUserQuestion` tool로 물어볼 것.
13
+ - 사용자 요청의 의도가 불명확할 때는 `/sd-inner-clarify` 스킬을 호출하여 명확화.
14
+ - 맥락에 맞는 용어 사용
54
15
  - 업무 기능·요구사항 논의 → 업무 용어 (사용자가 화면에서 뭘 하는지)
55
16
  - DB 스키마 설계 → 테이블·컬럼명
56
17
  - 코드 구현 → 함수·클래스명
57
- - 층위를 섞지 않는다. 업무 결정을 하면서 DB 컬럼명부터 던지거나, 스키마 설계를 하면서 업무 용어만 쓰지 않는다.
58
- - **한국 개발 현장 통용 용어 우선**: 한국 개발 현장에서 일반적으로 통용되는 용어를 우선 사용한다. 그런 용어가 없거나 불확실할 때는 한글 음차("시딩") 대신 영어 원문("seeding")을 그대로 쓰고, 처음 쓸 때 한 줄로 풀어 설명한다.
59
- - 사용자가 "무슨 소린지 모르겠다"는 취지로 되물으면, 같은 말을 반복하지 말고 **한 층위 위**(구현→스키마→업무)로 올라가서 다시 설명한다.
18
+ - 한국 개발 현장 통용 용어 사용
60
19
 
61
20
  # Playwright
62
21
 
63
- - playwright 사용시, 사용자가 접속주소를 알려주지 않았다면, 반드시 사용자에게 접속주소를 요청할것. (절대 서버를 강제로 임의 실행하지 말것)
22
+ - 사용자가 접속주소를 알려주지 않았다면, 반드시 사용자에게 접속주소를 요청할것. (서버 강제 실행 금지)
64
23
  - /playwright-cli 스킬을 사용할 것
65
24
 
66
- # 코딩
67
-
68
- - `@simplysm/*` 패키지를 사용할 때 아래 `# @simplysm 패키지 참조` 섹션을 따른다.
69
- - `@angular/*` 패키지를 사용할 때 `angular-cli` mcp를 활용하여, 표준 사용법을 확인하여 따른다.
70
- - 테스트 작성 시 `.claude/references/sd-testing.md`를 읽고 따른다.
71
- - 프론트엔드 UI 코드 작성·수정 시 `.claude/references/sd-frontend-design.md`를 읽고 따른다.
72
- - 디버깅 시 `/sd-inner-debug` 스킬을 호출한다.
73
- - **CRITICAL: 코딩·코드예제 출력 시, 반드시 Grep/Glob/Read로 코드베이스의 유사 코드를 먼저 검색·확인한 뒤 동일 패턴으로 작성한다.** "이미 알고 있다", "일반적인 패턴이다" 등의 이유로 검색을 생략하는 것은 위반이다.
74
- - 코드를 수정할 경우 수정에 의한 사이드이펙트를 항상 고려한다. (예, html구조가 바뀌면 css의 selector도 바뀌어야함)
75
- - 함수 작성 혹은 함수내 기능 추가시 단일 책임 원칙을 따른다. (함수가 이름에서 드러나지 않는 일을 몰래 해선 안됨)
76
- - `src/`에는 프로덕션 코드만 둔다. 테스트에서만 사용하는 파일(타입 선언, 헬퍼 등)은 `tests/`에 위치시킨다.
77
- - **barrel export 금지**: `src/` 루트의 `index.ts`를 제외하고, 하위 폴더에 re-export 전용 `index.ts`를 만들지 않는다. 패키지 루트 `index.ts`에서 개별 파일 경로를 직접 export한다.
78
- - 다른 패키지의 타입등 re-export 금지.
79
- - **dynamic import (`import()`) 사용 금지**: 조건부 peer dependency 로딩, 외부 ts 파일 읽기 등 정적 import가 불가능한 경우를 제외하고 `import()` 사용 금지. 정적 `import` 문을 사용한다.
80
- - **CRITICAL: 구조화된 문법 처리 시 파서 사용 필수**: TypeScript/JavaScript, HTML, CSS, JSON, YAML 등 **문법 구조가 정의된 텍스트**를 분석·변환할 때는 반드시 해당 언어의 **공식 파서/AST**(예: TypeScript Compiler API, `@angular/compiler`, `postcss`, `parse5`, `JSON.parse` 등)를 사용한다. 정규식·문자열 치환으로 **우회 금지(NEVER)**. 정규식은 주석·문자열·중첩 구조·이스케이프 등 엣지 케이스에서 반드시 깨진다. 파서 사용이 어렵거나 오버헤드가 크다고 판단되면 **사용자에게 먼저 질문**한다.
81
- - **null/undefined 비교 규칙**: `===`/`!==` 사용이 기본이지만 **null/undefined 비교만 예외**이다. 일반 값 비교는 `===`/`!==`, null/undefined 검사는 `== null`/`!= null`을 사용한다. `=== null`, `!== null`, `=== undefined`, `!== undefined`는 lint 에러이다.
82
- - `value === "hello"` ○ (일반 값 비교 → `===`)
83
- - `value == null` ○ (null/undefined 검사 → `==`)
84
- - `value === null` ✕ (lint 에러)
85
- - `value === undefined` ✕ (lint 에러)
86
-
87
- ## 자주 하는 실수
88
-
89
- - **import 경로에 `.js` 확장자 금지**: 내부 모듈 import 시 `.js` 확장자를 붙이지 않는다. `from "./foo"` ○, `from "./foo.js"` ✕. 이 프로젝트는 번들러(esbuild/Vite)가 확장자를 해석하므로 `.js`를 붙이면 안 된다.
90
- - **`as any[]` 캐스팅 후 `??` 방어**: `value as any[]`로 캐스팅하면 TypeScript는 nullable이 아니라고 판단하여 `?? []`에 lint 에러 발생. `value as any[] | undefined`로 캐스팅해야 한다
91
- - **타입 추론 해제 금지**: 타입 추론을 해제하는 방식의 수정은 절대 금지한다.
92
- - **불필요한 `as` 캐스팅**: 가드(`target !== "client"` 등)로 타입이 좁혀진 후에는 `as SdClientPackageConfig` 같은 캐스팅 불필요. lint 에러 `no-unnecessary-type-assertion` 발생
93
- - **타입 정의 확인 필수**: 인터페이스에 없는 프로퍼티를 추측으로 넣지 않는다. 반드시 실제 타입 정의를 읽고 작성한다
94
- - **클래스 필드 vs prototype**: `Object.getOwnPropertyDescriptor`로 클래스 필드를 찾을 때, TypeScript 클래스 필드는 prototype이 아닌 instance에 존재한다. prototype에서 찾으면 `undefined` 반환
95
- - **요청하지 않은 기능 추가 금지**: 원본 코드에 없고 사용자가 요청하지 않은 기능을 임의로 추가하지 않는다. 기존 코드의 이벤트/패턴을 그대로 유지하고, 요청된 변경만 수행한다.
96
- - **프로젝트 구조 이해 필수**: 코드를 배치하기 전에 해당 디렉토리가 빌드 산출물인지, 영구 소스인지 반드시 확인한다. 모르면 사용자에게 질문한다.
97
- - `eslint-disable @typescript-eslint/require-await` 금지
98
-
99
- # @simplysm 패키지 참조
25
+ # 사용법 참조
100
26
 
101
- - `@simplysm/*` 패키지 사용 시, 해당 패키지의 `README.md` 및 `docs/` 문서를 읽는다.
102
- - v14: `node_modules/@simplysm/{패키지명}/README.md` (분량이 많은 항목은 `node_modules/@simplysm/{패키지명}/docs/*.md`)
103
- - v12: `.claude/references/sd-simplysm12.md`
104
- - 해당 문서에는 사용법 및 지침이 기록되어 있다.
105
- - 주의사항: 해당 패키지의 `CLAUDE.md`는 모노레포 **내부 개발자용 컨텍스트**이므로 소비앱에서 이를 읽지 않는다. 소비앱은 `README.md`와 `docs/`만 참조한다.
106
- - simplysm 패키지의 경우 context7은 구버전일 수 있으니 사용을 지양한다.
27
+ - 프론트엔드: `.claude/references/sd-frontend-design.md`
28
+ - `@angular/*`: `angular-cli` mcp를 활용
29
+ - `@simplysm/*`: 해당 패키지의 `README.md`
107
30
 
108
- # 프로젝트 경계
109
-
110
- **CRITICAL: 프로젝트 루트 외부의 파일을 절대 생성/수정/삭제하지 않는다.**
111
-
112
- - 다른 모노레포(`../simplysm/` 등)에 파일을 만드는 것은 절대 금지.
113
-
114
- # 빌드 산출물 디렉토리
115
-
116
- **CRITICAL: `.capacitor/`, `.electron/` 디렉토리는 빌드 시 삭제 후 재생성되는 산출물이다.**
117
-
118
- - 이 디렉토리 안에 직접 파일을 생성/수정하면 빌드 시 전부 사라진다.
31
+ # 코딩
119
32
 
120
- # Feature 범위 준수
33
+ - barrel export 금지: `src/` 루트의 `index.ts`외, 하위 폴더 re-export `index.ts` 금지
34
+ - 다른 패키지에 대한 re-export 금지
35
+ - 정적 import가 불가능한 경우를 제외하고 `import()` 사용 금지
36
+ - 구조화된 문법 처리 시 파서 사용 필수. 정규식·문자열 치환으로 우회 금지
37
+ - null/undefined 비교 규칙: 일반 값 비교는 `===`/`!==`, null/undefined 검사는 `== null`/`!= null`을 사용.
38
+ - 내부 모듈 import 시 `.js` 확장자를 붙이지 않는다. (번들러가 확장자 해석)
39
+ - 타입 추론을 해제하는 방식의 수정 금지
40
+ - 불필요한 `as` 캐스팅 금지
121
41
 
122
- **CRITICAL: Feature 문서에 명시되지 않은 작업을 임의로 수행하지 않는다.**
42
+ ## 주의사항
123
43
 
124
- - 구현 추가 작업이 필요하다고 판단되면, 먼저 사용자에게 확인한다.
44
+ - 프로젝트 루트 외부 파일 생성/수정/삭제 금지
@@ -1,42 +1,49 @@
1
1
  # sd-options: 선택지 제시 규칙
2
2
 
3
- 사용자에게 질문, 제안등 선택지를 제시하는 **모든 상황**에서 아래 규칙을 따른다.
3
+ ## 적용 대상 (예외 없음)
4
4
 
5
- - 선택지에 대해 **장단점/트레이드오프/10점 만점 점수**를 포함한다
6
- - **"수행 안 함"** 선택지를 반드시 포함한다 — 수정/변경을 하지 않는 경우에도 동일하게 장단점과 점수를 매긴다
7
- - **결정 대상**을 먼저 명시한 뒤, 선택지 정보를 아래 **근거 제시 규칙**에 따라 출력하고, `---` 구분선을 출력한다.
8
- - **CRITICAL**: 선택지 출력 후에는 반드시 `AskUserQuestion` tool을 즉시 호출하여 사용자에게 선택을 요구한다
9
- - 텍스트로 "진행할까요?", "어떤 걸로 할까요?", "선택해주세요" 등을 묻고 사용자 응답을 기다리는 것은 **위반**이다
5
+ 사용자에게 질문·제안·확인 응답이 필요한 모든 출력에 적용한다.
10
6
 
11
- ## 결정 대상 명시 규칙
7
+ - "이 정도 질문은 과하다", "단순 확인이니 생략"은 위반이다
8
+ - 단일 경로만 합리적이라 느껴질 때도, "수행 안 함"을 포함한 선택지 구조로 제시한다
9
+ - 가벼운 사안은 경량 모드로 오버헤드를 낮추되, 선택지 구조와 `AskUserQuestion` 호출은 생략 불가
12
10
 
13
- 선택지를 나열하기 **전에**, 이 결정이 **어디의 무엇**에 대한 것인지 한 줄로 명시한다.
11
+ ## 공통 규칙
14
12
 
15
- - 형식: `**결정 대상:** {파일경로:라인번호} {대상 설명}` (대상이 여러 라인이어도 대표 라인/범위를 반드시 명시)
16
- - 예시 (단일 라인): `**결정 대상:** packages/angular/src/controls/input/sd-textfield.ts:45 — validate() 메서드의 에러 처리 방식`
17
- - 예시 (복수 라인): `**결정 대상:** .claude/rules/sd-options.md:8,31 CRITICAL 키워드 사용 방식`
18
- - 예시 (범위): `**결정 대상:** .claude/skills/sd-use/SKILL.md:43-68 스킬 카탈로그 섹션`
13
+ - 결정 대상 명시: 선택지 전에 한 줄로 `결정 대상: {파일경로:라인}` 출력 (예: `결정 대상: packages/foo.ts:45`)
14
+ - 하나의 선택지를 추천하고 사유 요약
15
+ - 복수 결정사항: 응답에 건만. 다음 건은 응답에서. 남은 건수 표시 (예: "1/3건 완료")
16
+ - 도구 호출 의무: 선택지 출력 즉시 `AskUserQuestion` tool을 호출하여 응답을 종료한다. 텍스트로 "진행할까요?" 묻고 응답 대기하면 위반.
17
+ - `AskUserQuestion`이 deferred tool로 표시되어 있으면 먼저 `ToolSearch query="select:AskUserQuestion"`로 스키마를 로드한 뒤 호출한다.
19
18
 
20
- ## 근거 제시 규칙
19
+ ## 티어 선택
21
20
 
22
- 사용자가 선택지를 판단하려면 **구체적 근거**가 필요하다. 추상적 설명만 나열하지 말고, 아래 항목을 반드시 포함한다.
21
+ 사안의 무게에 따라 경량 모드와 전체 모드 하나를 선택한다.
23
22
 
24
- - **현재 상태 인용**: 선택의 대상이 되는 코드·설정·구조를 인용할 때, **파일경로:라인번호를 반드시 포함**한다. 코드블록을 사용할 경우에도 해당 코드가 위치한 파일경로:라인번호를 함께 명시한다
25
- - **변경 후 모습**: 각 선택지를 적용하면 실제로 어떻게 바뀌는지 코드블록·구조도·시그니처 등으로 보여준다
26
- - **차이점 대비**: 선택지 간 차이가 드러나도록 동일한 관점에서 나란히 비교한다 (예: 같은 코드 조각이 A안/B안에서 각각 어떻게 되는지)
27
- - **영향 범위**: 변경이 파급되는 파일·모듈·API를 명시한다
23
+ ### 경량 모드 적용 대상 가벼운 결정
28
24
 
29
- > 원칙: 사용자가 **코드나 원문을 직접 찾아보지 않아도** 출력만으로 판단할 있어야 한다.
25
+ 조건: 영향 범위가 단일 파일·수 이내이고, 선택지의 차이가 한눈에 명확할 때.
30
26
 
31
- ## 복수 결정사항 처리
27
+ 필수 항목:
28
+ - 결정 대상 한 줄
29
+ - 2~4개 선택지 + "수행 안 함"
30
+ - 각 선택지: 한 줄 요약 + 한 줄 트레이드오프 + 10점 만점 단일 점수
31
+ - 추천 한 줄
32
+ - `AskUserQuestion` 호출
32
33
 
33
- - **CRITICAL: 결정사항이 여러 개일 경우, 반드시 번에 하나의 결정사항만 제시하고, 사용자 선택 후 다음으로 넘어간다.**
34
- - 선택지 제시 후 `AskUserQuestion` 호출로 **응답을 완전히 종료**한다. 다음 결정사항은 **새 응답**에서 제시한다 (같은 응답 내 연속 제시 금지)
35
- - 이전 선택 결과에 따라 후속 결정사항이 변경·추가·삭제될 수 있으므로, 매 단계마다 남은 결정사항을 재평가한다
36
- - 남은 결정사항이 몇 건인지 알려준다 (예: "1/3건 완료")
34
+ ### 전체 모드 적용 대상 무거운 결정
37
35
 
38
- ## 점수 기준
36
+ 조건: 설계·아키텍처·공개 API·규칙/설정 파일·복수 파일 영향·되돌리기 어려운 변경.
37
+
38
+ 필수 항목 (공통 규칙 + 아래):
39
+
40
+ - 근거 제시
41
+ - 현재 상태 인용: 파일경로:라인번호 필수. 코드블록 사용 시에도 경로:라인 병기
42
+ - 변경 후 모습: 코드블록·구조도·시그니처로 제시
43
+ - 차이점 대비: 동일 관점에서 선택지 나란히 비교
44
+ - 영향 범위: 파급되는 파일·모듈·API 명시
45
+ - 원칙: 사용자가 원문을 찾지 않아도 이 출력만으로 판단 가능해야 한다
46
+ - 축별 점수
47
+ - 맥락에 맞는 관점(축) 3개 이상 선정
48
+ - 축별 점수를 반드시 노출한 뒤 평균을 10점 만점으로 병기 (최종 점수만 쓰는 것 금지)
39
49
 
40
- - 모든 점수는 **10점 만점**이다
41
- - LLM이 맥락에 맞는 관점(축)을 3개 이상 선정하여 관점별 점수를 매기고, **축별 점수를 반드시 노출한 뒤 평균을 10점 만점으로 함께 표시**한다 (최종 점수만 쓰는 것 금지)
42
- - **하나의 선택지를 명시적으로 추천** — 추천 사유를 한 줄로 요약
@@ -0,0 +1,18 @@
1
+ import hashlib, json, os, sys
2
+
3
+ data = json.load(sys.stdin)
4
+ tool_input = data["tool_input"]
5
+ file_path = tool_input.get("file_path", "")
6
+ session_id = data.get("session_id", "unknown")
7
+
8
+ if not file_path or not os.path.isfile(file_path):
9
+ sys.exit(0)
10
+
11
+ file_hash = hashlib.sha256(open(file_path, "rb").read()).hexdigest()
12
+ path_hash = hashlib.sha256(os.path.normpath(file_path).encode()).hexdigest()
13
+
14
+ cache_dir = os.path.join(".tmp", "read_hash", session_id)
15
+ os.makedirs(cache_dir, exist_ok=True)
16
+
17
+ with open(os.path.join(cache_dir, path_hash), "w") as f:
18
+ f.write(file_hash)
@@ -1,7 +1,19 @@
1
- import json, os, sys
1
+ import hashlib, json, os, sys
2
2
 
3
3
  data = json.load(sys.stdin)
4
4
  file_path = data["tool_input"]["file_path"]
5
+ session_id = data.get("session_id", "unknown")
6
+
5
7
  if os.path.isfile(file_path):
6
- print(f"CRITICAL: This file already exists. NEVER delete/rm the file and retry with Write. You MUST use the Edit tool instead: {file_path}", file=sys.stderr)
7
- sys.exit(2)
8
+ path_hash = hashlib.sha256(os.path.normpath(file_path).encode()).hexdigest()
9
+ cache_file = os.path.join(".tmp", "read_hash", session_id, path_hash)
10
+
11
+ cached_hash = ""
12
+ if os.path.isfile(cache_file):
13
+ cached_hash = open(cache_file, "r").read().strip()
14
+
15
+ current_hash = hashlib.sha256(open(file_path, "rb").read()).hexdigest()
16
+
17
+ if cached_hash != current_hash:
18
+ print(f"CRITICAL: File content has changed or was never Read. You MUST Read the file first, then MUST REVISE your Write content based on the current file content before retrying: {file_path}", file=sys.stderr)
19
+ sys.exit(2)
@@ -29,6 +29,17 @@
29
29
  ]
30
30
  }
31
31
  ],
32
+ "PostToolUse": [
33
+ {
34
+ "matcher": "Read",
35
+ "hooks": [
36
+ {
37
+ "type": "command",
38
+ "command": "python .claude/sd-cache-read-hash.py"
39
+ }
40
+ ]
41
+ }
42
+ ],
32
43
  "SubagentStart": [
33
44
  {
34
45
  "hooks": [
@@ -16,9 +16,9 @@ description: typecheck, lint, test를 실행하고 에러 발생시 사용자
16
16
  발견된 에러가 **수정 대상**인지 판단하는 기준:
17
17
 
18
18
  - **sd-check 단독 실행 (이 대화에서 sd-check 호출 전 Claude의 코드 수정이 없음)**: 발견된 **모든 에러**가 수정 대상. "수정 대상 외"로 판단하여 스킵 금지(NEVER).
19
- - **직전 대화 내 코드 수정이 있음**: 해당 수정과 **관련된 에러만** 수정 대상. 무관한 에러는 조용히 스킵하되, 사용자에게 **보고하지 않는다** (그냥 넘어간다).
19
+ - **대화세션내 코드 수정이 있음**: 해당 수정과 **관련된 에러만** 수정 대상. 무관한 에러는 조용히 스킵하되, 사용자에게 **보고하지 않는다** (그냥 넘어간다).
20
20
 
21
- 판단 제외 — "직전 수정"에 해당하지 않는 것:
21
+ 판단 제외 — "대화세션내 수정"에 해당하지 않는 것:
22
22
  - git status의 미커밋 변경, 과거 커밋 변경
23
23
  - sd-check 내부(typecheck/lint/test 단계)에서 발생한 수정
24
24
 
@@ -81,7 +81,7 @@ Bash 출력이 길면 잘리므로 **반드시 파일로 리다이렉트**한
81
81
  탐지된 check 스크립트:
82
82
  1. typecheck → pnpm run typecheck
83
83
  2. lint → pnpm run lint
84
- 3. test → pnpm vitest run
84
+ 3. test → pnpm vitest run --reporter=dot --silent=passed-only
85
85
  ```
86
86
 
87
87
  탐지된 스크립트가 없으면 오류 메시지를 출력하고 종료한다.
@@ -108,4 +108,4 @@ typecheck 명령어를 실행한다. (`출력 캡처 규칙`에 따라 파일로
108
108
 
109
109
  ## Step 5: 반복 혹은 완료
110
110
 
111
- typecheck, lint, test 수행하는 동안 코드 수정이 있었으면 `typecheck`부터 다시 시작한다. 수정이 없었으면 완료.
111
+ typecheck, lint, test 수행 코드 수정이 있었으면 `typecheck`부터 다시 시작한다. 수정이 없었으면 완료.
@@ -6,13 +6,12 @@ effort: low
6
6
 
7
7
  # sd-claude-docs: CLAUDE.md + README.md/docs 통합 생성
8
8
 
9
- 프로젝트를 분석하여 CLAUDE.md(내부 개발 컨텍스트)와 README.md/docs/(소비자용 API 문서)를 한 번에 생성한다.
10
- 설정 파일, 스크립트, 소스 코드에서 검증 가능한 사실만 추출한다. 기존 문서가 있으면 섹션 단위로 병합한다.
9
+ 프로젝트를 분석하여 **CLAUDE.md**(모노레포 내부 개발자용 컨텍스트)와 **README.md + docs/**(패키지 소비자용 API 문서)를 한 번에 생성·갱신한다. 설정 파일·스크립트·소스 코드에서 검증 가능한 사실만 추출하며, 기존 문서는 섹션 단위로 병합한다.
11
10
 
12
- - **라이브러리 프로젝트** (`private: true`가 아닌 패키지가 1개 이상): CLAUDE.md + 각 패키지 `README.md`(+ 필요 시 `docs/`)
11
+ - **라이브러리 프로젝트** (`private: true`가 아닌 패키지 1개 이상 존재): CLAUDE.md + 각 패키지 `README.md` (+ 분량 조건에 해당 시 `docs/{category}/{entry}.md` 트리)
13
12
  - **소비앱** (모든 패키지가 `private: true`): CLAUDE.md만 생성
14
13
 
15
- CLAUDE.md는 모노레포 **내부 개발자(LLM 포함)** 용 컨텍스트이고, README.md + docs/는 **패키지 소비자** API/사용 지침 문서다. 문서는 독립적으로 유지한다. 패키지 CLAUDE.md 최상단에는 README.md 참조하도록 안내 문구를 삽입한다(Step 3에서 규정).
14
+ **두 문서의 독립성.** CLAUDE.md는 **모노레포 내부 개발자(LLM 포함)**용, README.md + docs/는 **패키지 소비자**용이다. 대상·관점이 달라 중복되지 않는다. README.md + docs/는 **wiki 스타일**로 구성한다 — 각 export된 class/component(Entry)는 자체 md 파일로 분리되어, 소비자(특히 LLM)가 필요한 Entry 하나만 조회할 수 있게 한다. README.md 인덱스, 상세는 Entry 파일에 둔다.
16
15
 
17
16
  ## 사용법
18
17
 
@@ -21,7 +20,33 @@ CLAUDE.md는 모노레포 **내부 개발자(LLM 포함)** 용 컨텍스트이
21
20
  /sd-claude-docs angular ← packages/angular 만
22
21
  ```
23
22
 
24
- ## Step 1: 프로젝트 설정 분석
23
+ ## 공통 규칙
24
+
25
+ ### 작성 언어
26
+
27
+ 모든 문서는 **대화언어**로 작성한다. "적절히", "필요에 따라", "상황에 따라" 같은 모호한 표현을 사용하지 않는다.
28
+
29
+ ### 문서 병합 규칙
30
+
31
+ 기존 문서가 있으면 섹션(`##` 제목) 단위로 비교한다.
32
+
33
+ 1. 동일 주제의 기존 섹션 → 새 콘텐츠로 **대체**
34
+ 2. 대응 섹션이 없는 기존 섹션 → 그대로 **보존**
35
+ 3. 기존 섹션 위치를 유지하고, 새로 생성된 섹션은 마지막 기존 섹션 **뒤에** 추가
36
+
37
+ ### 출력 경로 규칙
38
+
39
+ 라이브러리 프로젝트에서 패키지 소비자용 문서는 **해당 패키지 루트**에 위치한다.
40
+
41
+ | 구분 | CLAUDE.md | README.md | docs/ |
42
+ |------|-----------|-----------|-------|
43
+ | 모노레포 (각 패키지) | `{패키지 경로}/CLAUDE.md` | `{패키지 경로}/README.md` | `{패키지 경로}/docs/{category}/{entry}.md` |
44
+ | 모노레포 루트 | `./CLAUDE.md` | — | — |
45
+ | 단일 패키지 (루트=패키지) | `./CLAUDE.md` | `./README.md` | `./docs/{category}/{entry}.md` |
46
+
47
+ `private: true` 패키지는 README.md / docs/를 생성하지 않는다 (CLAUDE.md만).
48
+
49
+ ## Step 1: 사전 분석
25
50
 
26
51
  ### 1-1. 패키지 매니저 감지
27
52
 
@@ -37,11 +62,11 @@ CLAUDE.md는 모노레포 **내부 개발자(LLM 포함)** 용 컨텍스트이
37
62
  루트 `package.json`의 `scripts` 섹션을 읽고 각 스크립트의 CLI 도구를 분석한다.
38
63
 
39
64
  - **잘 알려진 도구** (`tsc`, `vitest`, `eslint`, `prettier`, `playwright` 등): 명령어를 그대로 기록
40
- - **커스텀 CLI 또는 프로젝트 내부 스크립트** (예: `tsx packages/.../cli.ts`): Bash에서 `--help`를 먼저 실행한다(5초 타임아웃). `--help`로 하위 명령어와 주요 옵션을 파악할 수 있으면 그 결과를 사용한다. `--help`가 실패하거나 유용한 정보가 없을 때에만 소스 코드를 Read로 분석한다
65
+ - **커스텀 CLI** (예: `tsx packages/.../cli.ts`): Bash에서 `--help`를 먼저 실행한다 (5초 타임아웃). 유용한 정보가 있으면 그 결과를 사용한다. `--help`가 실패하거나 정보가 부족할 때만 소스 코드를 Read로 분석한다.
41
66
 
42
67
  ### 1-3. 코딩 규칙 추출
43
68
 
44
- 프로젝트 루트에서 아래 설정 파일을 찾아 읽는다 (없는 파일은 건너뛴다):
69
+ 아래 설정 파일을 찾아 읽는다 (없는 파일은 건너뛴다):
45
70
 
46
71
  - ESLint: `eslint.config.*`, `.eslintrc.*`
47
72
  - Prettier: `.prettierrc*`, `prettier.config.*`
@@ -49,113 +74,99 @@ CLAUDE.md는 모노레포 **내부 개발자(LLM 포함)** 용 컨텍스트이
49
74
  - TypeScript: `tsconfig.json` → `compilerOptions`
50
75
  - Stylelint: `.stylelintrc*`, `stylelint.config.*`
51
76
 
52
- 아래 기준으로 규칙을 선별한다:
77
+ 선별 기준:
53
78
 
54
- - 도구의 기본값과 다른 설정 (예: TypeScript `verbatimModuleSyntax: true`, Prettier `printWidth: 100`)
79
+ - 도구 기본값과 다른 설정 (예: TypeScript `verbatimModuleSyntax: true`, Prettier `printWidth: 100`)
55
80
  - error 수준의 비표준 규칙 (예: `no-console: error`)
56
81
  - 특정 API를 금지하거나 요구하는 규칙 (예: `Buffer` 금지 → `Uint8Array` 사용)
57
82
 
58
- ### 1-4. .claude/rules/ 스캔
83
+ ### 1-4. `.claude/rules/` 스캔
59
84
 
60
- `.claude/rules/` 디렉토리가 존재하면 모든 `.md` 파일을 읽는다. 이미 다루고 있는 주제를 목록화한다. 해당 주제는 **CLAUDE.md에서 제외**한다 — 파일 간 규칙 중복은 LLM이 고유한 지침 대신 중복 컨텍스트를 처리하게 되어 지침의 효과를 약화시킨다.
85
+ 디렉토리가 존재하면 모든 `.md` 파일을 읽어 이미 다루고 있는 주제를 목록화한다. 해당 주제는 **CLAUDE.md에서 제외**한다 — 파일 간 규칙 중복은 LLM이 고유 지침 대신 중복 컨텍스트를 처리하게 되어 지침의 효과를 약화시킨다.
61
86
 
62
87
  ### 1-5. 프로젝트 유형 감지
63
88
 
64
- 모노레포인 경우 모든 패키지의 `package.json`을, 단일 패키지인 경우 루트 `package.json`을 확인한다.
89
+ 모노레포면 모든 패키지의 `package.json`을, 단일 패키지면 루트 `package.json`을 확인한다.
65
90
 
66
- - **라이브러리 프로젝트**: `private: true`가 아닌 패키지가 1개 이상 존재
91
+ - **라이브러리 프로젝트**: `private: true`가 아닌 패키지가 1개 이상
67
92
  - **소비앱**: 모든 패키지가 `private: true`
68
93
 
69
- 라이브러리 프로젝트인 경우 소비자용 문서의 출력 경로는 **해당 패키지 루트**다:
70
- - `README.md` → `{패키지 경로}/README.md`
71
- - 분량이 많은 경우 `{패키지 경로}/docs/*.md`
72
- - 단일 패키지 프로젝트면 루트가 곧 패키지 경로다 (`./README.md`, `./docs/`)
73
-
74
- `private: true` 패키지는 README.md / docs/를 생성하지 않는다 (CLAUDE.md만).
94
+ ## Step 2: 처리 대상 결정
75
95
 
76
- ## Step 2: 분기
96
+ 인자 유무와 워크스페이스 구성으로 **처리 대상 패키지 경로 목록**을 확정한다. 단일 패키지 프로젝트는 루트를 "가상 패키지"로 취급하여 동일 프로세스를 적용한다 (자기참조 없음).
77
97
 
78
- ### 패키지명 지정
98
+ | 경우 | 처리 대상 | Step 4 수행 |
99
+ |------|-----------|-------------|
100
+ | 인자 있음 | `packages/{인자}/package.json`이 존재하면 해당 1개 경로. 없으면 사용자에게 알리고 종료. | 건너뜀 |
101
+ | 인자 없음 + 모노레포 | `packages/` 하위 모든 패키지 경로 | 수행 |
102
+ | 인자 없음 + 단일 패키지 | 루트 경로 1개 (루트 = 패키지) | 건너뜀 |
79
103
 
80
- `packages/{패키지명}/package.json`이 존재하는지 확인한다. 없으면 사용자에게 알린다.
81
- 존재하면 해당 패키지에 대해 subagent 1개를 실행한다 (3단계의 subagent 프롬프트와 동일).
82
- root 문서는 생성·변경하지 않는다.
104
+ ## Step 3: 패키지 처리
83
105
 
84
- ### 전체 실행 — 단일 패키지 프로젝트
106
+ ### 3-1. 소스 병합
85
107
 
86
- `workspaces` 필드가 없고 `pnpm-workspace.yaml`도 없으면 단일 패키지다.
87
- 패키지별 CLAUDE.md는 생성하지 않는다. 바로 4단계로 진행하여 root 문서를 생성한다.
88
- 라이브러리 프로젝트인 경우 `package-doc-gen.md`의 Step 2~4를 root에 직접 적용하여 루트의 `README.md` (+ 분량이 많으면 `docs/*.md`)를 생성한다.
108
+ subagent가 개별 파일을 하나씩 Read하는 대신 병합 파일 1회 Read로 전체 소스를 파악할 수 있게 한다. 컨텍스트 소비를 대폭 줄이는 핵심 단계이다.
89
109
 
90
- ### 전체 실행 모노레포
110
+ 패키지에 대해 Bash로 실행 (여러 패키지면 병렬):
91
111
 
92
- `packages/` 하위의 모든 패키지를 탐색하여 전체를 처리 대상으로 한다. 3단계로 진행한다.
112
+ ```bash
113
+ bash .claude/skills/sd-claude-docs/merge-source.sh {패키지경로} ./tmp/{패키지명}-source.txt
114
+ ```
93
115
 
94
- ## Step 3: 패키지별 문서 생성 (모노레포)
116
+ ### 3-2. subagent 병렬 실행
95
117
 
96
- 패키지에 대해 **Agent 도구로 subagent(effort: `low`)를 병렬 실행**한다.
97
- 하나의 메시지에서 모든 패키지의 Agent 호출을 동시에 보낸다.
118
+ 처리 대상 목록의 경로에 대해 **Agent 도구로 subagent(effort: `low`)를 병렬 실행**한다. 하나의 메시지에서 모든 Agent 호출을 동시에 보낸다.
98
119
 
99
- ### subagent 프롬프트
120
+ #### subagent 프롬프트
100
121
 
101
122
  ```
102
- {패키지 경로}의 CLAUDE.md와 README.md/docs를 생성한다.
123
+ {패키지 경로}의 CLAUDE.md와 README.md/docs를 생성·갱신한다.
103
124
 
104
- ## CLAUDE.md 생성 (`{패키지 경로}/CLAUDE.md`)
125
+ `.claude/skills/sd-claude-docs/references/package-docs.md`를 읽고 지침을 따른다.
105
126
 
106
- `.claude/skills/sd-claude-docs/references/package-claudemd.md`를 읽고 그 지침을 따른다.
107
-
108
- 루트 수준 설정 (이 내용과 동일한 정보는 패키지 CLAUDE.md에 반복하지 않는다):
109
- {1단계에서 추출한 코딩 규칙 컴파일러 설정 목록}
110
-
111
- ## README.md / docs/ 생성 {`private: true` 패키지이면 이 섹션 전체 생략}
112
-
113
- `.claude/skills/sd-claude-docs/references/package-doc-gen.md`를 읽고 그 지침을 따른다.
114
- 출력 경로: `{패키지 경로}/` (README.md는 항상, docs/는 분량 분기 조건에 해당될 때)
127
+ 전달 사항:
128
+ - 패키지 경로: {패키지 경로}
129
+ - 소스 병합 파일: {./tmp/{패키지명}-source.txt의 절대 경로}
130
+ - 루트 수준 설정 (이 내용과 중복되는 정보는 패키지 CLAUDE.md에 반복하지 않는다):
131
+ {Step 1에서 추출한 코딩 규칙·컴파일러 설정 목록}
115
132
  ```
116
133
 
117
- 각 subagent는 소스 코드를 한 번 분석하여 CLAUDE.md(Key Patterns)와 README.md/docs(API 문서) 모두에 활용한다.
134
+ 각 subagent는 소스 병합 파일을 한 번 Read하여 CLAUDE.md(Key Patterns)와 README.md/docs(API 문서) 모두에 활용한다.
118
135
 
119
136
  ### subagent 반환 정보
120
137
 
121
- - CLAUDE.md 생성 여부
122
- - README.md 생성 여부 + 문서 구조 (README 단독 / README + docs/)
123
- - API 항목
138
+ - 패키지 경로
139
+ - CLAUDE.md 생성/갱신/건너뜀 여부
140
+ - README.md 생성/갱신/건너뜀 여부 + 구조 (README 단독 / README + docs 트리)
141
+ - Entry 수 / 총 API 항목 수
124
142
  - 생성된 파일 목록
125
143
 
126
- ## Step 4: root 문서 생성
144
+ ## Step 4: 루트 CLAUDE.md 생성
127
145
 
128
- ### root CLAUDE.md
146
+ Step 2의 "Step 4 수행" 열이 "수행"인 경우에만 진행한다.
129
147
 
130
- 1단계의 정보를 조합하여 루트 CLAUDE.md 콘텐츠를 생성한다. `.claude/rules/`에서 이미 다루고 있는 주제(1-4단계에서 감지)는 제외한다.
148
+ ### 4-1. 콘텐츠 구성
131
149
 
132
- **모노레포인 경우**: 3단계에서 생성된 패키지의 `CLAUDE.md`를 Read하여 참고한다. 패키지별 CLAUDE.md에 이미 기술된 상세 내용(아키텍처, 패턴 등) 루트에 중복 기술하지 않고, 아키텍처 섹션에서 패키지 간 의존 관계와 역할 요약만 포함한다.
150
+ Step 1 결과와 Step 3패키지 CLAUDE.md 조합하여 루트 CLAUDE.md를 생성한다. `.claude/rules/`에서 이미 다루는 주제(1-4에서 감지)는 **제외**한다. 패키지 CLAUDE.md에 기술된 상세(아키텍처, 패턴 등) 루트에 중복하지 않고, 아키텍처 섹션에서 패키지 간 의존 관계와 역할 요약만 포함한다.
133
151
 
134
152
  #### 포함할 섹션
135
153
 
136
- - **프로젝트 정보**: `package.json`의 `name`과 `description`, 패키지 매니저
137
- - **모노레포 구조**: `workspaces` 필드 또는 `pnpm-workspace.yaml`이 있으면 워크스페이스 경로를 나열하고패키지를 간략히 설명 (패키지당 10단어 이내)
138
- - **기술 스택**: `dependencies`/`devDependencies`의 주요 라이브러리 — 프레임워크, 번들러, 테스트 도구 (최대 10개)
139
- - **명령어**: 1-2단계의 스크립트를 bash 코드 블록으로 포매팅하고 인라인 주석 추가, 카테고리별 그룹화
140
- - **아키텍처**: 모노레포인 경우 패키지별 CLAUDE.md에서 역할을 읽어 패키지 간 의존 관계를 요약한다
141
- - **코딩 규칙**: 1-3단계에서 선별한 규칙을 불릿 리스트로 포매팅
154
+ - **프로젝트 정보**: 루트 `package.json`의 `name`/`description`, 패키지 매니저
155
+ - **모노레포 구조**: 워크스페이스 경로 나열,패키지 10단어 이내 요약
156
+ - **기술 스택**: 주요 프레임워크·번들러·테스트 도구 (최대 10개)
157
+ - **명령어**: 1-2 스크립트를 카테고리별 bash 코드 블록으로 포매팅, 인라인 주석 추가
158
+ - **아키텍처**: 패키지 간 의존 관계 및 역할 요약
159
+ - **코딩 규칙**: 1-3에서 선별한 규칙을 불릿 리스트로 포매팅
142
160
 
143
- 실질적 내용이 없는 섹션은 생략한다. 프로젝트에 필요하면목록에 없는 섹션도 추가한다 (예: 통합 테스트).
161
+ 실질적 내용이 없는 섹션은 생략한다. 필요 섹션도 추가한다 (예: 통합 테스트).
144
162
 
145
- #### 병합
163
+ ### 4-2. 병합
146
164
 
147
- - **기존 파일이 없는 경우**: 바로 저장
148
- - **기존 파일이 있는 경우**:
149
- 1. 기존 파일을 읽는다
150
- 2. 새 콘텐츠와 기존 콘텐츠를 섹션(`##` 제목) 단위로 비교한다
151
- 3. 병합 규칙:
152
- - 생성된 섹션과 동일한 주제의 기존 섹션 → 새 콘텐츠로 **대체**
153
- - 생성된 대응 섹션이 없는 기존 섹션 → 그대로 **보존**
154
- - 기존 섹션의 위치를 보존한다. 새로 생성된 섹션은 반드시 마지막 기존 섹션 뒤에 추가한다
165
+ 공통 규칙의 "문서 병합 규칙"을 적용한다.
155
166
 
156
- #### 참고 예시
167
+ ### 참고 예시
157
168
 
158
- 아래의 **섹션 구조와 포매팅 스타일**을 따른다. **CLAUDE.md는 반드시 대화언어로 작성한다.**
169
+ 아래 **섹션 구조와 포매팅 스타일**을 따른다.
159
170
 
160
171
  ````markdown
161
172
  # Simplysm
@@ -164,8 +175,6 @@ pnpm 모노레포. 패키지 경로: `packages/*`, 테스트: `tests/*`
164
175
 
165
176
  ## 명령어
166
177
 
167
- 모든 명령어는 내부적으로 `pnpm sd-cli <command>`를 실행한다.
168
-
169
178
  ### 개발
170
179
 
171
180
  ```bash
@@ -176,7 +185,7 @@ pnpm watch [targets..] # 라이브러리 패키지를 watch
176
185
  ### 코드 품질
177
186
 
178
187
  ```bash
179
- pnpm check [targets..] # 전체 검사 (typecheck + lint 병렬)
188
+ pnpm check [targets..] # 전체 검사
180
189
  pnpm typecheck [targets..] # TypeScript 타입 체크
181
190
  ```
182
191
 
@@ -186,7 +195,7 @@ pnpm typecheck [targets..] # TypeScript 타입 체크
186
195
 
187
196
  ```
188
197
  UI: angular (Angular)
189
- 서비스: service-server (Fastify) / service-client / service-common
198
+ 서비스: service-server / service-client / service-common
190
199
  코어: core-common (중립) / core-browser / core-node
191
200
  ```
192
201
 
@@ -201,20 +210,20 @@ UI: angular (Angular)
201
210
  ```markdown
202
211
  ## sd-claude-docs 결과
203
212
 
204
- | 패키지 | CLAUDE.md | README.md | 구조 | API 항목 |
213
+ | 패키지 | CLAUDE.md | README.md | 구조 | Entry / API |
205
214
  |--------|-----------|-----------|------|-------------|
206
215
  | root | 생성 | — | — | — |
207
- | @simplysm/core-common | 갱신 | 갱신 | README 단독 | 35 |
208
- | @simplysm/angular | 갱신 | 갱신 | README + docs/ | 126 |
209
- | @simplysm/storage | 생성 | 생성 | README 단독 | 8 |
216
+ | @simplysm/core-common | 갱신 | 갱신 | README 단독 | 8 / 35 |
217
+ | @simplysm/angular | 갱신 | 갱신 | README + docs 트리 | 72 / 126 |
210
218
  | @simplysm/internal | 생성 | — (private) | — | — |
211
219
 
212
220
  ### 생성된 파일 목록
213
221
  - CLAUDE.md (root)
214
222
  - packages/core-common/CLAUDE.md
215
223
  - packages/core-common/README.md
224
+ - packages/core-common/docs/utils/string-utils.md
216
225
  - packages/angular/CLAUDE.md
217
226
  - packages/angular/README.md
218
- - packages/angular/docs/types.md
227
+ - packages/angular/docs/{category}/{entry}.md
219
228
  - ...
220
229
  ```