@simplysm/sd-claude 13.0.93 → 13.0.96

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
@@ -101,12 +101,14 @@ INIT_CWD 환경변수 → node_modules 경로에서 역추적 → process.cwd()
101
101
  | 파일 | 설명 |
102
102
  |---|---|
103
103
  | `sd-claude-rules.md` | 질문 응답/문제해결 원칙 (편법 금지, 근본 원인 추적) |
104
+ | `sd-library-issue.md` | `@simplysm/*` 라이브러리 버그 발견 시 이슈 리포트 작성 규칙 |
104
105
  | `sd-readme.md` | `@simplysm/*` 패키지 사용 시 README.md 참조 규칙 |
105
106
 
106
107
  **Skills (`.claude/skills/`):**
107
108
 
108
109
  | 스킬 | 설명 |
109
110
  |---|---|
111
+ | `sd-apk-decompile` | APK 디컴파일 (JADX + Apktool + dex2jar/CFR) |
110
112
  | `sd-audit` | 코드베이스 점검 및 개선 사항 도출 |
111
113
  | `sd-check` | typecheck + lint(fix) + 단위test 순차 수행 및 자동 수정 |
112
114
  | `sd-commit` | `[type] scope` 형식의 커밋 메시지 생성 및 커밋 |
@@ -114,9 +116,12 @@ INIT_CWD 환경변수 → node_modules 경로에서 역추적 → process.cwd()
114
116
  | `sd-document` | `.docx/.xlsx/.pptx/.pdf` 파일 분석 및 생성 |
115
117
  | `sd-email-analyze` | `.eml/.msg` 이메일 파일 분석 (헤더/본문/첨부파일 추출) |
116
118
  | `sd-init` | 프로젝트 설정 분석 후 `CLAUDE.md` 자동 생성 |
119
+ | `sd-migration` | 원본/현재 코드베이스 비교 분석 후 마이그레이션 대상 목록 생성 |
117
120
  | `sd-plan` | 요구분석서/점검 결과 기반 TDD 구현계획서 작성 |
118
121
  | `sd-plan-dev` | 구현계획서 기반 TDD 방식 실제 구현 수행 |
119
122
  | `sd-readme` | LLM 인덱싱용 `README.md` 및 `docs/` 생성 |
123
+ | `sd-review` | spec/plan 문서와 구현 비교하여 완성도 검증 |
124
+ | `sd-simplify` | 수정된 코드를 reuse/quality/efficiency 관점으로 검토 및 개선 |
120
125
  | `sd-spec` | 사용자 요청과 코드베이스 분석 후 요구분석서 작성 |
121
126
  | `sd-test` | TDD 테스트 작성 및 실행 |
122
127
  | `sd-use` | 요청 내용에 적합한 `sd-*` 스킬 자동 매칭 및 실행 |
@@ -1,7 +1,8 @@
1
1
  # 사용자의 질문
2
2
 
3
3
  - 사용자가 선택에 대한 고민을 물어보면, 각 선택에 대해 10점만점의 점수를 매겨 사용자에게 판단을 돕는다.
4
- - 사용자의 질문을 바로 수정하지 않는다. 질문에 대한 답을 하고 사용자의 명시적 수정요청을 기다린다.
4
+ - 사용자의 질문에 대해 바로 코드수정을 하지 않는다. 질문에 대한 답을 하고 사용자의 명시적 수정요청을 기다린다.
5
+ - 사용자의 질문이 명확하지 않으면 AskUserQuestion을 활용하여 명확화 한다. (절대 추측하지 않는다.)
5
6
 
6
7
  # 문제해결
7
8
 
@@ -6,7 +6,27 @@
6
6
 
7
7
  ## 규칙
8
8
 
9
- - 사실만 보고한다. 수정 방안이나 코드 위치 힌트를 포함하지 않는다.
10
9
  - 이슈를 자동 제출하지 않는다. 텍스트만 표시한다.
11
- - 라이브러리 내부 분석(클래스명, 변수명, 상속 체인 등)을 포함하지 않는다. 사용자가 관찰 가능한 증상만 기술한다.
12
10
  - 이슈 리포트는 대화에서 사용 중인 언어로 작성한다.
11
+
12
+ ## 이슈 리포트 작성 금지사항 (엄격히 준수)
13
+
14
+ 이슈 리포트는 **사용자가 관찰한 현상만** 기술한다. 아래 항목은 절대 포함하지 않는다:
15
+
16
+ - **원인 분석/추측 금지**: "~때문에 발생", "~가 원인", "검증이 과도하게 제한적" 등 원인을 단정하거나 추측하는 문장
17
+ - **내부 구현 언급 금지**: 파일 경로, 라인 번호, 클래스명, 변수명, 정규식 패턴, 상속 체인 등 라이브러리 내부 코드 정보
18
+ - **수정 방안 금지**: 해결 방법, 대안, 워크어라운드, 코드 변경 제안
19
+ - **점수/비교표 금지**: 선택지에 점수를 매기거나 비교하는 표
20
+
21
+ ## 이슈 리포트 형식
22
+
23
+ ```
24
+ **제목:** [사용자가 관찰한 현상을 한 줄로 요약]
25
+
26
+ **재현 절차:**
27
+ 1. [사용자가 수행한 설정/조작 단계]
28
+
29
+ **기대 동작:** [사용자가 기대한 결과]
30
+
31
+ **실제 동작:** [에러 메시지 원문 등 사용자가 실제로 관찰한 결과]
32
+ ```
@@ -0,0 +1,279 @@
1
+ ---
2
+ name: sd-apk-decompile
3
+ description: APK 파일을 디컴파일하여 Java 소스, 리소스, 웹 에셋을 추출. 사용자가 APK 분석이나 디컴파일을 요청할 때 사용
4
+ argument-hint: "<APK 파일 경로> [--quick]"
5
+ ---
6
+
7
+ # sd-apk-decompile: APK 디컴파일
8
+
9
+ Android APK 파일을 디컴파일하여 Java 소스, 리소스, 웹 에셋, 네이티브 라이브러리 정보를 추출한다.
10
+
11
+ - **기본 모드**: JADX + Apktool + dex2jar/CFR 전체 파이프라인 (Phase 2, 3은 병렬 실행)
12
+ - **--quick 모드**: JADX만 사용 (Phase 2, 4 스킵)
13
+ - Phase 5(웹 에셋), Phase 6(네이티브)은 두 모드 모두에서 해당 시 실행한다
14
+
15
+ **에러 처리 원칙:** 개별 Phase가 실패해도 에러를 기록하고 다음 Phase를 계속 진행한다. 최종 요약에서 실패한 Phase를 보고한다.
16
+
17
+ ## 1. 인자 파싱
18
+
19
+ `$ARGUMENTS`에서 APK 파일 경로와 옵션을 파싱한다.
20
+
21
+ - 첫 번째 인자: APK 파일 경로 (필수)
22
+ - `--quick`: JADX만 사용하는 빠른 모드 (선택)
23
+ - `$ARGUMENTS`가 비어있으면 AskUserQuestion으로 APK 파일 경로를 요청한다
24
+
25
+ 파싱 후 Bash로 파일을 검증한다:
26
+
27
+ ```bash
28
+ test -f "<apk_path>"
29
+ ```
30
+
31
+ - 파일이 없으면 "파일을 찾을 수 없습니다: {경로}"를 출력하고 종료한다
32
+ - `.apk` 확장자가 아니면 "APK 파일이 아닙니다: {경로}"를 출력하고 종료한다
33
+
34
+ 출력 디렉토리를 결정한다:
35
+ - APK 파일과 동일 디렉토리에 `<APK파일명(확장자 제외)>_decompiled/`
36
+ - 이미 존재하면 덮어쓴다 (기존 결과를 갱신)
37
+
38
+ ## 2. 도구 의존성 검사
39
+
40
+ Bash로 모든 도구의 설치 여부를 **병렬로** 확인한다.
41
+
42
+ **필수 도구 (항상 검사):**
43
+
44
+ ```bash
45
+ java -version 2>&1
46
+ jadx --version 2>&1
47
+ ```
48
+
49
+ **추가 도구 (--quick이 아닐 때만 검사):**
50
+
51
+ ```bash
52
+ apktool --version 2>&1
53
+ d2j-dex2jar.bat --help 2>&1 || d2j-dex2jar.sh --help 2>&1
54
+ ```
55
+
56
+ CFR 검사 — JAR 파일이므로 다음 순서로 탐색:
57
+ 1. 환경변수 `CFR_JAR`가 설정되어 있으면 `test -f "$CFR_JAR"` 확인
58
+ 2. 없으면 미설치로 판단
59
+
60
+ **미설치 도구가 있으면** 다음 테이블을 출력하고 **스킬 실행을 중단**한다:
61
+
62
+ ```
63
+ ## 미설치 도구
64
+
65
+ | 도구 | 설치 방법 |
66
+ |------|----------|
67
+ | Java | Android SDK에 포함. JAVA_HOME 환경변수 확인 |
68
+ | JADX | choco install jadx 또는 https://github.com/skylot/jadx/releases |
69
+ | Apktool | https://apktool.org/docs/install/ |
70
+ | dex2jar | https://github.com/pxb1988/dex2jar/releases |
71
+ | CFR | https://github.com/leibnitz27/cfr/releases → CFR_JAR 환경변수에 경로 설정 |
72
+
73
+ 도구 설치 후 다시 실행하세요.
74
+ ```
75
+
76
+ ## 3. Phase 1: 기본 정보 추출
77
+
78
+ 출력 디렉토리를 생성하고, APK 내부 구조를 파악한다.
79
+
80
+ ```bash
81
+ mkdir -p "<output>"
82
+ unzip -l "<apk_path>" | grep -E "(classes.*\.dex|\.so|assets/public/|assets/www/)"
83
+ ```
84
+
85
+ `unzip -l`이 실패하면 "APK 파일을 읽을 수 없습니다 (파일이 손상되었을 수 있음)"를 출력하고 종료한다.
86
+
87
+ grep 출력에서 다음을 확인한다:
88
+ - `classes*.dex` 파일 수 카운트 → **dex_count**
89
+ - `lib/` 하위에 `.so` 파일 존재 여부 → **has_native_libs** 플래그
90
+ - `assets/public/` 존재 여부 → **is_capacitor** 플래그
91
+ - `assets/www/` 존재 여부 → **is_cordova** 플래그
92
+
93
+ **dex_count가 0이면**: "DEX 파일이 없습니다. 리소스만 추출합니다." 경고를 출력하고, Phase 3(JADX)과 Phase 4(dex2jar+CFR)를 스킵한다.
94
+
95
+ 확인 결과를 텍스트로 출력한다:
96
+
97
+ ```
98
+ ## APK 구조 분석
99
+
100
+ - DEX 파일: N개
101
+ - 네이티브 라이브러리: 있음/없음
102
+ - Capacitor 앱: Yes/No
103
+ - Cordova 앱: Yes/No
104
+ ```
105
+
106
+ ## 4. Phase 2+3: 리소스 디코딩 + Java 소스 복원
107
+
108
+ ### Phase 2: Apktool (--quick 시 스킵)
109
+
110
+ **`--quick` 모드이면 Phase 2를 건너뛴다.**
111
+
112
+ **비-quick 모드에서 Phase 2(Apktool)와 Phase 3(JADX)은 독립 작업이므로 병렬로 실행한다** (각각 별도 Bash 호출).
113
+
114
+ Apktool로 리소스를 디코딩하고 smali를 추출한다:
115
+
116
+ ```bash
117
+ apktool d "<apk_path>" -o "<output>/apktool" -f
118
+ ```
119
+
120
+ 완료 후 필요한 파일을 정리한다:
121
+
122
+ ```bash
123
+ cp "<output>/apktool/AndroidManifest.xml" "<output>/AndroidManifest.xml"
124
+ cp -r "<output>/apktool/res" "<output>/res"
125
+ mkdir -p "<output>/smali"
126
+ cp -r "<output>"/apktool/smali*/* "<output>/smali/" 2>/dev/null
127
+ ```
128
+
129
+ ### Phase 3: JADX
130
+
131
+ 핵심 단계. JADX로 DEX를 Java 소스로 디컴파일한다. 대형 APK는 시간이 오래 걸릴 수 있으므로 **Bash timeout을 600초(10분)로 설정**한다:
132
+
133
+ ```bash
134
+ jadx -d "<output>/src" --deobf --show-bad-code "<apk_path>"
135
+ ```
136
+
137
+ - `--deobf`: 난독화된 클래스/메서드명을 가독성 있는 이름으로 변환
138
+ - `--show-bad-code`: 디컴파일 실패한 코드도 주석 형태로 포함
139
+
140
+ JADX의 stderr 출력에서 디컴파일 통계를 파싱한다 (예: `INFO - Finished, ... classes, ... error`):
141
+ - 처리된 클래스 수
142
+ - 에러 발생 클래스 수
143
+
144
+ **`--quick` 모드에서만** (Apktool이 AndroidManifest.xml을 생성하지 않았을 때) JADX 리소스에서 복사한다:
145
+
146
+ ```bash
147
+ cp "<output>/src/resources/AndroidManifest.xml" "<output>/AndroidManifest.xml" 2>/dev/null
148
+ ```
149
+
150
+ ## 5. Phase 4: 교차 검증 (dex2jar + CFR)
151
+
152
+ **`--quick` 모드이면 이 단계를 건너뛴다.**
153
+
154
+ JADX와 다른 알고리즘으로 디컴파일하여 보완한다.
155
+
156
+ 임시 디렉토리를 만들고 DEX를 추출한다:
157
+
158
+ ```bash
159
+ _WORKDIR=$(mktemp -d)
160
+ unzip -o "<apk_path>" "classes*.dex" -d "$_WORKDIR"
161
+ ```
162
+
163
+ 각 DEX 파일을 JAR로 변환하고 CFR로 디컴파일한다:
164
+
165
+ ```bash
166
+ for dex in "$_WORKDIR"/classes*.dex; do
167
+ jar_name="${dex%.dex}.jar"
168
+ d2j-dex2jar.bat "$dex" -o "$jar_name" --force 2>&1 || d2j-dex2jar.sh "$dex" -o "$jar_name" --force 2>&1
169
+ done
170
+
171
+ for jar in "$_WORKDIR"/classes*.jar; do
172
+ java -jar "$CFR_JAR" "$jar" --outputdir "<output>/src-cfr" 2>&1
173
+ done
174
+
175
+ rm -rf "$_WORKDIR"
176
+ ```
177
+
178
+ ## 6. Phase 5: 웹 에셋 추출
179
+
180
+ Phase 1에서 **is_capacitor** 또는 **is_cordova** 플래그가 설정된 경우에만 실행한다.
181
+ 둘 다 아니면 이 단계를 건너뛴다.
182
+
183
+ Capacitor 앱인 경우:
184
+ ```bash
185
+ unzip -o "<apk_path>" "assets/public/*" -d "<output>/web"
186
+ mv "<output>/web/assets/public/"* "<output>/web/" 2>/dev/null
187
+ rm -rf "<output>/web/assets"
188
+ ```
189
+
190
+ Cordova 앱인 경우:
191
+ ```bash
192
+ unzip -o "<apk_path>" "assets/www/*" -d "<output>/web"
193
+ mv "<output>/web/assets/www/"* "<output>/web/" 2>/dev/null
194
+ rm -rf "<output>/web/assets"
195
+ ```
196
+
197
+ ## 7. Phase 6: 네이티브 라이브러리 분석
198
+
199
+ Phase 1에서 **has_native_libs** 플래그가 설정된 경우에만 실행한다.
200
+ 플래그가 없으면 이 단계를 건너뛴다.
201
+
202
+ APK에서 네이티브 라이브러리를 추출한다:
203
+
204
+ ```bash
205
+ unzip -o "<apk_path>" "lib/*" -d "<output>"
206
+ ```
207
+
208
+ 각 `.so` 파일의 심볼을 추출한다 (`nm`이 없으면 이 단계를 건너뛴다):
209
+
210
+ ```bash
211
+ find "<output>/lib" -name "*.so" -exec sh -c '
212
+ nm -D "$1" > "$1.symbols.txt" 2>&1
213
+ grep "Java_" "$1.symbols.txt" > "$1.jni.txt" 2>/dev/null
214
+ ' _ {} \;
215
+ ```
216
+
217
+ - `*.symbols.txt`: 전체 exported 심볼
218
+ - `*.jni.txt`: JNI 메서드만 필터링 (`Java_` 접두사)
219
+
220
+ ## 8. 결과 요약 출력
221
+
222
+ `<output>/AndroidManifest.xml`이 존재하면 Read하여 앱 정보를 파싱한다. 없으면 "AndroidManifest.xml을 추출하지 못했습니다"를 출력하고 가능한 정보만으로 요약한다.
223
+
224
+ 파싱할 항목:
225
+ - `package` 속성 → 패키지명
226
+ - `android:versionName` → 버전
227
+ - `uses-sdk android:targetSdkVersion` → 타겟 SDK
228
+ - `uses-permission android:name` → 퍼미션 목록
229
+ - `activity android:name` → Activity 목록
230
+ - `service android:name` → Service 목록
231
+ - `receiver android:name` → BroadcastReceiver 목록
232
+ - `provider android:name` → ContentProvider 목록
233
+
234
+ `src/` 하위 디렉토리 구조에서 사용된 라이브러리/SDK를 추정한다 (예: `com.google.firebase`, `androidx`, `org.apache` 등).
235
+
236
+ 다음 형식으로 콘솔에 출력한다:
237
+
238
+ ```
239
+ ## 디컴파일 결과
240
+
241
+ ### 앱 정보
242
+ - 패키지명: {package}
243
+ - 버전: {versionName}
244
+ - 타겟 SDK: {targetSdkVersion}
245
+
246
+ ### 퍼미션
247
+ - {permission 1}
248
+ - {permission 2}
249
+ - ...
250
+
251
+ ### 컴포넌트
252
+ - Activity: N개
253
+ - Service: N개
254
+ - BroadcastReceiver: N개
255
+ - ContentProvider: N개
256
+
257
+ ### 앱 유형
258
+ - Capacitor: Yes/No
259
+ - Cordova: Yes/No
260
+
261
+ ### 사용된 라이브러리 (추정)
262
+ - {library 1}
263
+ - {library 2}
264
+
265
+ ### 네이티브 라이브러리
266
+ - {abi}/{name}.so (JNI 메서드: N개)
267
+
268
+ ### 디컴파일 통계
269
+ - JADX: {처리 클래스}개 처리, {에러 클래스}개 에러
270
+ - CFR: 실행됨/스킵됨
271
+
272
+ ### 실패한 Phase (있는 경우)
273
+ - Phase N: {에러 메시지}
274
+
275
+ ### 출력 디렉토리
276
+ {output 절대 경로}
277
+ ```
278
+
279
+ 동일 내용을 `<output>/info.txt`에 Write한다.
@@ -16,17 +16,10 @@ argument-hint: "<문제 현상 설명>"
16
16
  - 특수문자(`#`, `/`, `\`, `(`, `)`, `.` 등)는 제거하거나 `-`로 치환한다 (예: "ORM 쿼리 오류 (v2.0)" → `orm-query-error-v2-0`)
17
17
  - 이미 kebab-case이면 그대로 사용한다
18
18
 
19
- ## 2. 코드베이스 분석
19
+ ## 2. 근본 원인 분석 및 해결책 제시
20
20
 
21
- 문제 현상과 관련된 코드베이스를 분석한다.
22
- - Agent tool (subagent_type: Explore)을 활용하여 관련 파일, 패키지, 의존성을 탐색한다
23
- - 에러 메시지, 스택 트레이스, 코드 경로 등을 기반으로 관련 코드를 파악한다
24
- - 필요에 따라 Glob, Grep, Read 등을 직접 사용할 수도 있다
25
- - 분석 결과로 현재 상태, 관련 코드/패키지, 기존 구현 방식을 파악한다
26
-
27
- ## 3. 근본 원인 분석 및 해결책 제시
28
-
29
- 코드베이스 분석 결과를 바탕으로 문제의 근본 원인을 깊이 파고들어 분석하고, 각 원인별 해결책을 방안으로 제시한다.
21
+ 문제의 근본 원인을 깊이 파고들어 분석하고, 각 원인별 해결책을 방안으로 제시한다.
22
+ 필요시 코드베이스를 자유롭게 탐색한다.
30
23
 
31
24
  **핵심 원칙 — 편법/우회방법 절대 금지:**
32
25
  - 증상을 숨기는 해결이 아닌, 원인 자체를 제거하는 방향으로 분석한다
@@ -63,7 +56,7 @@ argument-hint: "<문제 현상 설명>"
63
56
  - 점수 기준: 높을수록 해당 선택이 적절함을 의미한다
64
57
  - 모든 방안은 편법/우회가 아닌 근원적 해결책이어야 한다
65
58
 
66
- ## 4. 결과 표시 및 선택
59
+ ## 3. 결과 표시 및 선택
67
60
 
68
61
  근본 원인 분석 결과 방안이 하나도 도출되지 않은 경우 "분석 결과 코드베이스에서 근본 원인을 식별할 수 없습니다."를 출력하고 문서 저장 없이 종료한다.
69
62
 
@@ -89,7 +82,7 @@ argument-hint: "<문제 현상 설명>"
89
82
  - 모든 선택지의 점수가 0이면 → "분석 결과 유효한 해결책을 도출할 수 없습니다."를 출력하고 종료한다
90
83
  - 가장 높은 점수가 동점이면 → 자동 결정 불가 → AskUserQuestion으로 사용자에게 질문
91
84
 
92
- ## 5. 결과 문서 저장
85
+ ## 4. 결과 문서 저장
93
86
 
94
87
  채택된 방안을 debug.md로 저장한다.
95
88
 
@@ -111,7 +104,7 @@ argument-hint: "<문제 현상 설명>"
111
104
 
112
105
  ## 현재 상태
113
106
 
114
- {코드베이스 분석 결과 - 관련 기존 코드/패키지, 현재 구현 방식, 관련 의존성}
107
+ {관련 코드/패키지, 현재 구현 방식, 관련 의존성}
115
108
 
116
109
  ## 요구사항
117
110
 
@@ -128,7 +121,7 @@ argument-hint: "<문제 현상 설명>"
128
121
 
129
122
  - "안함"이 선택된 경우 debug.md를 저장하지 않고 "채택된 해결책이 없어 문서를 저장하지 않습니다."를 출력한다
130
123
 
131
- ## 6. 완료 안내
124
+ ## 5. 완료 안내
132
125
 
133
126
  문서 작성이 완료되면 다음을 출력한다:
134
127
  - 완성된 문서의 파일 경로
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: sd-migration
3
+ description: 원본 코드베이스와 현재 코드베이스를 비교 분석하여 마이그레이션 대상 목록을 생성. 사용자가 코드 마이그레이션 분석을 요청할 때 사용
4
+ argument-hint: "<원본 코드베이스 경로>"
5
+ ---
6
+
7
+ # sd-migration: 마이그레이션 분석
8
+
9
+ 원본 코드베이스와 현재 코드베이스를 비교 분석하여, 마이그레이션 대상 목록을 migration.md로 저장한다.
10
+
11
+ **마이그레이션 목표:** API/사용법은 원본과 동일하게 유지한다. 내부 구현은 현재 코드베이스의 패턴에 맞게 조정하되, 외부 동작(엔드포인트, 파라미터, 응답 형식, 화면 흐름)은 원본과 일치해야 한다.
12
+
13
+ ## 1. 인자 파싱
14
+
15
+ `$ARGUMENTS`에서 원본 코드베이스의 로컬 파일시스템 경로를 추출한다.
16
+ - `$ARGUMENTS`가 비어있으면 AskUserQuestion으로 원본 코드베이스 경로를 요청한다
17
+ - Bash `ls`로 해당 디렉토리가 존재하는지 검증한다
18
+ - 예시: `/sd-migration /d/projects/old-app`
19
+
20
+ ## 2. 코드베이스 탐색
21
+
22
+ Agent tool (subagent_type: Explore)을 **2개 동시에** (하나의 메시지에서 병렬로) 호출하여 양쪽 코드베이스를 탐색한다.
23
+
24
+ **Agent A — 원본 코드베이스 탐색:**
25
+ - 파일 트리 구조
26
+ - package.json (dependencies, devDependencies, scripts)
27
+ - 설정 파일 (tsconfig, vite, webpack, eslint 등)
28
+ - 소스 구조 (디렉토리 구성, 진입점)
29
+ - 라우트/페이지 목록
30
+ - API 엔드포인트
31
+ - DB 스키마/모델
32
+ - UI 컴포넌트
33
+ - 유틸리티/헬퍼
34
+ - 테스트
35
+ - 정적 자산
36
+ - 환경변수
37
+ - 외부 서비스 연동
38
+
39
+ **Agent B — 현재 코드베이스 탐색:**
40
+ - 위와 동일한 항목들을 현재 코드베이스에서 탐색
41
+
42
+ 각 Agent는 구조화된 결과를 반환해야 한다: 기술 스택, 파일 트리 요약, 체크리스트 항목별 상태.
43
+
44
+ ## 3. 기술스택 감지 및 분석 전략 선택
45
+
46
+ 양쪽의 package.json, 설정 파일, import 패턴을 비교하여 기술 스택을 감지하고, 분석 전략을 자동 선택한다.
47
+
48
+ | 스택 유형 | 분석 방법 | 비교 단위 |
49
+ |----------|----------|----------|
50
+ | 동일 스택 | 파일/모듈 구조 직접 비교 | 파일, 디렉토리, 패키지, 의존성, 설정 |
51
+ | 이기종 스택 | 기능/역할 기반 매핑 | 기능, 컴포넌트, API, 데이터 모델, 비즈니스 로직 |
52
+
53
+ ## 4. 비교 분석
54
+
55
+ 선택된 전략에 따라 원본과 현재를 비교한다.
56
+
57
+ **마이그레이션 목표 재확인:** API/사용법은 원본과 동일하게 유지한다. 내부 구현은 현재 코드베이스의 패턴에 맞게 조정하되, 외부 동작(엔드포인트, 파라미터, 응답 형식, 화면 흐름)은 원본과 일치해야 한다.
58
+
59
+ **전수 체크리스트** — 아래 항목을 빠짐없이 순회한다:
60
+
61
+ 코드 포팅:
62
+ - [ ] 소스 디렉토리 전체 파일 트리 비교
63
+ - [ ] package.json 의존성 비교 (dependencies, devDependencies)
64
+ - [ ] 라우트/페이지/화면 목록 비교
65
+ - [ ] API 엔드포인트 비교 (경로, 메서드, 파라미터, 응답 형식)
66
+ - [ ] DB 모델/스키마/마이그레이션 비교
67
+ - [ ] UI 컴포넌트 인벤토리 비교
68
+ - [ ] 유틸리티/헬퍼/공통 모듈 비교
69
+ - [ ] 테스트 파일 비교
70
+ - [ ] 정적 자산 비교 (이미지, 폰트, 아이콘)
71
+ - [ ] 미들웨어/가드/인터셉터 비교
72
+ - [ ] 인증/인가 로직 비교
73
+ - [ ] 에러 처리 패턴 비교
74
+ - [ ] 국제화/지역화(i18n) 비교
75
+
76
+ 환경/인프라:
77
+ - [ ] DB 종류·버전 차이 (예: MySQL→PostgreSQL, MSSQL→MySQL)
78
+ - [ ] 외부 서비스 연동 정보 차이 (URL, 인증 방식, SDK 버전)
79
+ - [ ] 환경변수 매핑 (원본의 환경변수가 현재에서 어떻게 대응되는지)
80
+ - [ ] 빌드/배포 설정 차이 (빌드 도구, CI/CD, Docker)
81
+ - [ ] 런타임 환경 차이 (Node.js 버전, 패키지 매니저)
82
+
83
+ **비교 결과를 3가지로 분류한다:**
84
+ - **원본에만 존재** → 마이그레이션 대상에 포함 (묻지 않음)
85
+ - **양쪽 동일** → 제외 (묻지 않음)
86
+ - **양쪽 다르게 구현** → 모호한 항목으로 분류하여 5단계에서 처리
87
+
88
+ ## 5. 명확화 질문
89
+
90
+ 4단계에서 "양쪽 다르게 구현"으로 분류된 항목에 대해 하나씩 다음 프로세스를 반복한다.
91
+
92
+ 1. 원본과 현재의 구현 차이를 상세히 설명한다
93
+ 2. AskUserQuestion을 **1개만** 호출하여 마이그레이션 대상에 포함할지 여부를 묻는다
94
+ 3. 답변을 반영한 뒤, 모호한 항목이 남아있으면 1로 돌아간다
95
+
96
+ 모호한 항목이 없으면 이 단계를 건너뛴다.
97
+
98
+ ## 6. migration.md 작성
99
+
100
+ 확정된 마이그레이션 대상을 다음 형식으로 작성한다:
101
+
102
+ ```markdown
103
+ # 마이그레이션 분석 결과
104
+
105
+ **원본:** `{원본 경로}`
106
+ **현재:** `{현재 코드베이스 경로}`
107
+ **원본 스택:** {감지된 기술스택}
108
+ **현재 스택:** {감지된 기술스택}
109
+ **분석 방식:** {동일 스택 / 이기종 스택}
110
+
111
+ ## 요약
112
+
113
+ | 카테고리 | 원본 | 현재 | 마이그레이션 대상 |
114
+ |---------|------|------|-----------------|
115
+ | {카테고리} | {개수} | {개수} | {개수} |
116
+
117
+ ## 마이그레이션 대상
118
+
119
+ ### {카테고리}
120
+
121
+ #### M1. {항목 제목}
122
+
123
+ - **유형:** {파일 / 기능 / 환경}
124
+ - **원본 위치:** `{원본 파일 경로 또는 기능 위치}`
125
+ - **현재 대응:** {없음 / 부분 구현 (`{경로}`) / 패턴 상이 (`{경로}`)}
126
+ - **설명:** {마이그레이션에 필요한 작업 설명}
127
+
128
+ #### M2. {항목 제목}
129
+
130
+ ...
131
+
132
+ ### {카테고리}
133
+
134
+ #### M3. {항목 제목}
135
+
136
+ ...
137
+ ```
138
+
139
+ **M 번호 규칙:**
140
+ - M1, M2, ... 모든 카테고리에 걸쳐 순차 번호 (카테고리마다 초기화하지 않음)
141
+ - 카테고리는 `###` 레벨, 각 M 항목은 `####` 레벨로 카테고리 아래에 배치
142
+ - 각 M 항목은 **파일 단위 또는 기능 단위** 수준의 세밀한 단위로 작성 ("UI 전체 마이그레이션"처럼 뭉뚱그리지 않음)
143
+ - 사용자가 `/sd-spec`에 여러 M 번호를 전달하여 관련 항목을 결합할 수 있음
144
+
145
+ ## 7. 파일 저장
146
+
147
+ - 디렉토리: `.tasks/{yyMMddHHmmss}_{topic}/`
148
+ - `{topic}`: 원본 프로젝트 디렉토리명에서 추출, kebab-case + `-migration` 접미사
149
+ - `{yyMMddHHmmss}`: Bash `date +%y%m%d%H%M%S`로 생성
150
+ - 예시: 원본 `/d/projects/my-app` → topic `my-app-migration`
151
+ - 파일명: `migration.md`
152
+ - 디렉토리가 없으면 먼저 생성한다
153
+
154
+ ## 8. 완료 안내
155
+
156
+ 문서 작성이 완료되면 다음을 출력한다:
157
+ - 완성된 문서의 파일 경로
158
+ - 사용자에게 직접 migration.md를 확인할 것을 권장
159
+ - 다음 단계 안내:
160
+ ```
161
+ /sd-spec {migration.md경로} M3 # M3 항목의 요구분석서 작성
162
+ /sd-spec {migration.md경로} M1 M5 # 여러 항목을 하나의 요구분석서로 작성
163
+ ```
@@ -68,11 +68,13 @@ argument-hint: "<입력 문서 경로 [R번호]> 또는 <간단한 요구사항>
68
68
  | 비코드 작업 (LLM용 문서) | subagent를 통한 테스트 방안 계획 (sd-plan-dev에서 `_test.md` 작성) |
69
69
  | 비코드 작업 (일반 문서) | 테스트 생략 가능 |
70
70
 
71
+ **복수 유형 혼합 시:** 한 작업이 여러 유형에 걸치면 (예: LLM용 문서 신규 작성 + 기존 문서 텍스트 변경), 가장 엄격한 테스트 전략을 적용한다.
72
+
71
73
  **테스트 시나리오 작성 원칙:**
72
74
 
73
75
  - 테스트는 **상태(정적)가 아닌 동작**을 검증한다
74
76
  - 상태 (X): "파일에 특정 텍스트가 적혀있는지 확인" → 정적 검사에 불과
75
- - 현상 (O): "실행했을 때 기대한 동작이 나타나는지 확인" → 실제 동작 검증
77
+ - 동작 (O): "실행했을 때 기대한 동작이 나타나는지 확인" → 실제 동작 검증
76
78
  - 예: LLM용 문서 테스트 시 "SKILL.md에 '테스트 재실행' 문구가 있는지"가 아니라 "LLM이 SKILL.md를 따라 실행했을 때 실제로 테스트를 재실행하는지"를
77
79
  검증한다
78
80
 
@@ -125,7 +127,7 @@ argument-hint: "<입력 문서 경로 [R번호]> 또는 <간단한 요구사항>
125
127
 
126
128
  ### Refactor Phase
127
129
 
128
- `/simplify 완료 보고는 생략하고, 작업을 멈추지 않는다. 부모 프로세스를 계속 진행한다.` 하여 품질 개선 → 테스트 재실행하여 통과 확인
130
+ `/sd-simplify` 하여 코드 리팩터링 완료 멈추지 말고 즉시 테스트 재실행하여 통과 확인
129
131
  ```
130
132
 
131
133
  **참조 문서 표기 규칙:**
@@ -170,5 +172,4 @@ argument-hint: "<입력 문서 경로 [R번호]> 또는 <간단한 요구사항>
170
172
  - 다음 단계 안내:
171
173
  ```
172
174
  /sd-plan-dev {plan경로}
173
- /sd-plan-dev {plan경로} --worktree # 별도 worktree에서 격리 실행
174
175
  ```
@@ -1,16 +1,16 @@
1
1
  ---
2
2
  name: sd-plan-dev
3
3
  description: 구현계획서를 기반으로 TDD 방식의 실제 구현을 수행. 사용자가 구현계획서 기반의 코드 구현을 요청할 때 사용
4
- argument-hint: "<plan 파일 경로> [--worktree]"
4
+ argument-hint: "<plan 파일 경로>"
5
5
  ---
6
6
 
7
7
  # sd-plan-dev: 구현 실행
8
8
 
9
- 구현계획서(plan)를 기반으로 TDD 사이클(RED → GREEN → Refactor)을 실행하여 실제 구현을 수행한다.
9
+ 구현계획서(plan)를 기반으로 TDD 사이클(RED → GREEN → Refactor → Commit)을 실행하여 실제 구현을 수행한다.
10
10
 
11
11
  ## 1. 인자 파싱
12
12
 
13
- `$ARGUMENTS`를 분석하여 plan 옵션을 결정한다.
13
+ `$ARGUMENTS`를 분석하여 plan 결정한다.
14
14
 
15
15
  ### 1-1. plan 파일 경로
16
16
 
@@ -19,20 +19,14 @@ argument-hint: "<plan 파일 경로> [--worktree]"
19
19
 
20
20
  ### 1-2. 인자 없음
21
21
 
22
- `$ARGUMENTS`가 비어있으면 (옵션 플래그 제외):
22
+ `$ARGUMENTS`가 비어있으면:
23
23
  - 현재 대화 맥락에서 plan 내용을 파악한다
24
24
  - 대화에도 plan이 없으면 다음을 출력하고 종료한다:
25
25
  > 구현계획서가 없습니다. 먼저 `/sd-plan`을 실행하여 계획을 수립하세요.
26
26
 
27
- ### 1-3. `--worktree` 옵션
28
-
29
- `$ARGUMENTS`에 `--worktree`가 포함된 경우 worktree 모드를 활성화한다.
30
- - 기본값: 비활성 (현행 동작)
31
- - 활성 시: 2단계에서 worktree 격리 실행 전략을 적용한다
32
-
33
27
  ## 참조 문서 수정 (전 단계 공통)
34
28
 
35
- 2~5단계 진행 중 참조 plan 또는 spec 문서에 누락, 오류, 실제 코드와의 불일치를 발견하면 다음 프로세스를 따른다:
29
+ 2~4단계 진행 중 참조 plan 또는 spec 문서에 누락, 오류, 실제 코드와의 불일치를 발견하면 다음 프로세스를 따른다:
36
30
 
37
31
  1. 발견된 이슈와 제안하는 수정 내용을 텍스트로 설명한다
38
32
  2. AskUserQuestion으로 수정 승인을 요청한다
@@ -45,10 +39,6 @@ argument-hint: "<plan 파일 경로> [--worktree]"
45
39
  - 기존 문서의 구조와 다른 항목은 유지한다
46
40
  - 한 번에 하나의 이슈만 처리한다 (여러 이슈 발견 시 순차 처리)
47
41
 
48
- **worktree subagent 제약:**
49
- - worktree subagent 내에서는 상위 문서(plan/spec)를 직접 수정하지 않는다
50
- - subagent는 발견한 이슈를 반환 결과에 포함하고, 메인 에이전트가 이 섹션의 프로세스에 따라 수정을 처리한다
51
-
52
42
  ## 2. 작업 파악 및 실행 전략
53
43
 
54
44
  plan에서 작업 목록을 파악하고 스케줄링을 결정한다.
@@ -60,24 +50,11 @@ plan에서 작업 목록을 파악하고 스케줄링을 결정한다.
60
50
  - 의존 작업: 의존 순서대로 순차 실행
61
51
  - 혼합: 독립 작업끼리는 병렬, 의존 체인은 순차로 조합
62
52
 
63
- ### `--worktree` 미사용 시
64
-
65
53
  결정된 스케줄링에 따라 실행한다:
66
54
  - 단일 작업: 바로 3단계(TDD 사이클)로 진행
67
- - 병렬 실행: Agent tool로 각 작업을 별도 subagent에 위임하여 동시에 TDD 사이클 수행
55
+ - 병렬 실행: Agent tool로 각 작업을 별도 subagent에 위임하여 동시에 TDD 사이클(RED → GREEN → Refactor → Commit) 수행
68
56
  - 순차 실행: 선행 작업 완료 후 후행 작업 시작
69
57
 
70
- ### `--worktree` 사용 시
71
-
72
- 결정된 스케줄링에 따라 `isolation: "worktree"` Agent tool로 실행한다:
73
- - 단일 작업: worktree subagent 1개 생성 → 완료 후 4단계(merge)
74
- - 병렬 실행: 각 작업별 worktree subagent 병렬 생성 → 모든 subagent 완료 후 4단계에서 순차 merge
75
- - 순차 실행: 첫 작업 worktree subagent 생성 → 완료 후 4단계에서 merge → 현재 branch(merge 완료된 상태)를 base로 다음 작업 worktree subagent 생성 → 반복
76
-
77
- **worktree 불가 제약**: subagent 테스트(`_test.md` 기반)가 필요한 작업은 worktree subagent 안에서 Agent tool을 사용할 수 없으므로 worktree 적용 불가. 해당 작업은 worktree 없이 3단계로 직접 수행한다.
78
-
79
- **혼합 케이스** (worktree 가능 + 불가 작업 공존): worktree 가능한 작업끼리 스케줄링에 따라 worktree subagent로 실행하고, worktree 불가 작업은 모든 worktree merge 완료 후 순차 단일 수행한다. 단, 의존성에 의해 순서가 정해진 경우 그 순서를 우선한다.
80
-
81
58
  ## 3. TDD 사이클 실행
82
59
 
83
60
  2단계에서 결정한 스케줄링에 따라 **모든 작업**에 대해 아래 TDD 사이클을 수행한다.
@@ -88,14 +65,24 @@ plan의 RED Phase에 명시된 테스트 전략에 따라 분기한다:
88
65
 
89
66
  **vitest 테스트인 경우:**
90
67
  - plan의 테스트 시나리오에 따라 vitest 테스트 파일을 작성한다
68
+ - 프로젝트의 기존 테스트 파일 패턴을 탐색하여 (`*.test.ts`, `*.spec.ts`, `__tests__/` 등) 동일한 패턴으로 생성한다
69
+ - 기존 패턴이 없으면 `{대상파일명}.test.{확장자}`로 대상 파일과 동일 디렉토리에 생성한다
91
70
  - Bash로 `vitest run {테스트 파일}` 실행하여 실패를 확인한다
92
71
 
93
72
  **subagent 테스트인 경우 (LLM용 문서, 테스트 환경 없는 코드 등):**
94
73
  - plan의 테스트 시나리오에 따라 `_test.md` 파일을 작성한다
95
74
  - plan 파일 기반: plan 파일과 동일 디렉토리. plan이 `{R번호}_plan.md`이면 `{R번호}_test.md`, `plan.md`이면 `test.md`
96
75
  - 현재 대화 기반 (파일 경로 없음): plan에 참조 spec 경로가 있으면 해당 디렉토리에 저장. 없으면 `.tasks/` 하위에 새 디렉토리 생성
97
- - 형식: 테스트별 입력/기대출력 쌍
98
- - Agent tool로 subagent를 생성하여 테스트를 실행하고 실패를 확인한다
76
+ - 형식:
77
+ ```markdown
78
+ ## 테스트 1: {테스트 제목}
79
+ **입력:** {subagent에게 실행시킬 지시}
80
+ **기대 결과:** {검증 기준}
81
+ ```
82
+ - Agent tool로 **테스트별 독립 subagent**를 병렬로 생성하여 실행하고 실패를 확인한다
83
+ - 각 테스트(`## 테스트 N`)마다 별도 subagent를 호출한다 (단일 메시지에서 병렬 호출)
84
+ - subagent에게 전달할 내용: 대상 파일 경로, 해당 테스트 1건의 입력과 기대 결과, "테스트를 실행하고 PASS/FAIL을 판정하라"는 지시
85
+ - 하나의 subagent에 여러 테스트를 전달하지 않는다 (컨텍스트 격리)
99
86
 
100
87
  **테스트 생략인 경우:**
101
88
  - RED Phase를 건너뛰고 GREEN Phase로 바로 진행한다
@@ -105,7 +92,7 @@ plan의 RED Phase에 명시된 테스트 전략에 따라 분기한다:
105
92
  plan의 GREEN Phase에 명시된 구현 계획에 따라 최소한의 구현을 수행한다 (YAGNI 원칙).
106
93
  - 구현 후 테스트를 재실행하여 통과를 확인한다
107
94
  - vitest: Bash로 재실행
108
- - subagent 테스트: Agent tool로 재실행
95
+ - subagent 테스트: Agent tool로 테스트별 독립 subagent를 병렬로 재실행
109
96
  - 테스트 생략인 경우: 구현만 수행
110
97
 
111
98
  **구현 중 불확실한 부분 처리:**
@@ -118,40 +105,24 @@ plan의 GREEN Phase에 명시된 구현 계획에 따라 최소한의 구현을
118
105
 
119
106
  > plan/spec 문서 자체에 오류·누락이 있는 경우는 이 지침이 아닌 "참조 문서 수정" 프로세스를 따른다.
120
107
 
121
- **worktree subagent 내:** 불확실한 부분을 반환 결과에 포함하고, 메인 에이전트가 사용자에게 확인 후 해당 부분을 처리한다.
122
-
123
108
  ### Refactor Phase
124
109
 
125
- `/simplify 완료 보고는 생략하고, 작업을 멈추지 않는다. 부모 프로세스를 계속 진행한다. 다음 파일만 리뷰: {수정한 파일 목록}` 하여 품질을 개선한다.
110
+ `/sd-simplify` 하여 코드를 리팩터링한다. 완료 멈추지 말고 즉시 다음 단계로 진행한다.
126
111
  - 완료 후 테스트를 재실행하여 통과를 확인한다
127
112
  - 리팩터링으로 테스트가 깨지면 수정 후 재확인한다
128
113
 
129
114
  ### Commit Phase
130
115
 
131
- TDD 사이클(RED → GREEN → Refactor) 완료 1회 commit한다.
132
- - 작업 하나 = commit 하나
133
- - `--worktree` 사용 여부와 관계없이 동일하게 적용한다
134
-
135
- ### 다음 작업 전이
116
+ **각 작업의 TDD 사이클(RED → GREEN → Refactor) 완료 직후, 다음 작업으로 넘어가기 전에 반드시 커밋한다.**
136
117
 
137
- Commit 완료 후, 스케줄링에 따라 남은 작업이 있으면 해당 작업의 TDD 사이클(RED → GREEN → Refactor → Commit)을 반복한다. 모든 작업이 완료되면 5단계로 진행한다.
118
+ - `/sd-commit`을 실행하여 해당 작업에서 수정한 내용을 커밋한다
119
+ - 작업 하나 = commit 하나. 여러 작업을 몰아서 한번에 커밋하지 않는다
138
120
 
139
- ## 4. worktree merge (`--worktree` 활성 시)
140
-
141
- worktree subagent 완료 후 반환된 branch를 순차적으로 merge한다.
142
-
143
- **정상 흐름:**
144
- 1. `git merge {branch}` 실행
145
- 2. merge 완료 후 worktree를 정리한다
146
- 3. 성공 시 다음 branch merge (또는 5단계로 진행하여 자가검토 수행)
121
+ ### 다음 작업 전이
147
122
 
148
- **conflict 발생 시:**
149
- 1. `git merge --abort` 실행하여 working directory를 깨끗한 상태로 복원
150
- 2. conflict 발생한 worktree 경로와 branch명을 출력
151
- 3. AskUserQuestion으로 "직접 merge하세요" 안내 + "완료" 옵션 제시
152
- 4. 사용자가 "완료" 선택 시 worktree를 정리하고 다음 branch merge 계속
123
+ Commit 완료 후, 스케줄링에 따라 남은 작업이 있으면 해당 작업의 TDD 사이클(RED → GREEN → Refactor → Commit)을 반복한다. 모든 작업이 완료되면 4단계로 진행한다.
153
124
 
154
- ## 5. 자가검토
125
+ ## 4. 자가검토
155
126
 
156
127
  모든 작업의 TDD 사이클이 완료되면 plan 원문과 실제 구현 결과를 대조한다.
157
128
 
@@ -163,9 +134,9 @@ worktree subagent 완료 후 반환된 branch를 순차적으로 merge한다.
163
134
  - 누락 항목에 대해 3단계 TDD 사이클(RED → GREEN → Refactor → Commit)을 수행한다
164
135
  - 1번으로 돌아가 다시 대조한다
165
136
  4. 2회 반복 후에도 누락이 남아있으면 남은 항목을 사용자에게 보고한다
166
- 5. 모든 항목이 충족되면 6단계로 진행한다
137
+ 5. 모든 항목이 충족되면 5단계로 진행한다
167
138
 
168
- ## 6. 완료 안내
139
+ ## 5. 완료 안내
169
140
 
170
141
  모든 작업의 TDD 사이클과 자가검토가 완료되면 다음을 출력한다:
171
142
  - 전체 작업의 구현 결과 요약 (작업별 상태)
@@ -100,11 +100,15 @@ Agent tool (subagent_type: Explore)로 각 검증 항목의 구현 여부를 판
100
100
 
101
101
  ### 4-2. 파일 저장 (미충족 항목이 있을 때만)
102
102
 
103
- 미충족 항목이 하나라도 있으면 `review.md`를 생성한다. 동일 위치에 기존 review.md가 있으면 덮어쓴다.
103
+ 미충족 항목이 하나라도 있으면 `review.md`를 생성한다.
104
104
 
105
- **저장 위치:**
106
- - 디렉토리 입력 해당 디렉토리
107
- - 파일 나열 번째 파일의 디렉토리
105
+ **저장 위치:** `.tasks/{yyMMddHHmmss}_{topic}/review.md`
106
+ - `yyMMddHHmmss`는 현재 시간 (Bash `date +%y%m%d%H%M%S`로 생성)
107
+ - topic 추출: 입력 문서의 task 디렉토리 이름에서 타임스탬프 접두사(`yyMMddHHmmss_`)를 제외한 부분에 `-review` 접미사를 붙인다
108
+ - 예: 입력이 `.tasks/260315120000_feature/spec.md`이면 topic은 `feature-review`
109
+ - 예: 입력이 `.tasks/260315120000_db-migration/`이면 topic은 `db-migration-review`
110
+ - 입력이 `.tasks/` 하위가 아닌 경우: 입력 경로의 마지막 디렉토리명에 `-review`를 붙인다
111
+ - 디렉토리가 없으면 먼저 생성한다
108
112
 
109
113
  **review.md 구조:**
110
114
 
@@ -124,13 +128,10 @@ Agent tool (subagent_type: Explore)로 각 검증 항목의 구현 여부를 판
124
128
 
125
129
  ## 다음 단계
126
130
 
127
- - `/sd-plan-dev {plan경로}` — {plan있는 미충족 항목 설명}
128
- - `/sd-plan {spec경로} R번호` — {plan이 없는 미충족 항목 설명}
131
+ `/sd-plan {이 review.md의 경로}`
129
132
  ```
130
133
 
131
134
  ### 4-3. 완료 안내
132
135
 
133
136
  - **전체 충족**: 전체 통과 메시지를 출력한다
134
- - **미충족 존재**: review.md 경로를 안내하고, 사용자에게 직접 문서를 확인할 것을 권장하며, 다음 단계를 출력한다:
135
- - plan이 있는 미충족 항목: `/sd-plan-dev {plan경로}`
136
- - plan이 없는 미충족 항목: `/sd-plan {spec경로} R번호`
137
+ - **미충족 존재**: review.md 경로를 안내하고, 사용자에게 직접 문서를 확인할 것을 권장하며, 다음 단계를 출력한다: `/sd-plan {review.md경로}`
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: sd-simplify
3
+ description: 외부 동작을 유지하면서 코드의 내부 구조를 개선. 사용자가 코드 리팩터링을 요청할 때 사용
4
+ argument-hint: "<파일 경로 목록>"
5
+ ---
6
+
7
+ # sd-simplify: 코드 리팩터링
8
+
9
+ 외부 동작을 그대로 유지하면서 내부 구조를 개선한다. 새로운 기능을 추가하지 않는다.
10
+
11
+ ## 1. 대상 파일 결정
12
+
13
+ `$ARGUMENTS`를 분석한다:
14
+ - 파일 경로가 있으면 해당 파일을 대상으로 한다
15
+ - 비어있으면 현재 대화에서 수정된 파일을 대상으로 한다
16
+ - 대상을 파악할 수 없으면 AskUserQuestion으로 요청한다
17
+
18
+ ## 2. 리팩터링 수행
19
+
20
+ 대상 파일을 읽고 다음 항목을 순서대로 점검하여 해당 사항이 있으면 수정한다.
21
+
22
+ - **중복 제거**: 복붙이나 비슷한 로직이 있으면 공통 함수/메서드로 추출
23
+ - **네이밍 개선**: 의도가 불명확한 변수명/함수명/클래스명을 명확하게 변경
24
+ - **구조 분리**: 하나의 함수가 너무 많은 일을 하면 책임 단위로 분리 (Extract Method, Extract Class)
25
+ - **매직 넘버/하드코딩 제거**: `if (x === 3)` 같은 코드를 의미 있는 상수나 파라미터로 변환
26
+ - **테스트 코드 리팩터링**: 테스트 간 중복 setup을 beforeEach로 묶기, 테스트 헬퍼 추출, 테스트 이름 명확화
27
+
28
+ ## 3. 완료
29
+
30
+ - 수정한 경우: 수정된 파일 목록과 변경 내용을 간략히 출력한다
31
+ - 수정할 것이 없는 경우: "리팩터링 대상 없음"을 출력한다
32
+ - 완료 후 절대 멈추지 않는다. 호출한 스킬의 다음 단계로 즉시 진행한다.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: sd-spec
3
3
  description: 사용자 요청과 코드베이스를 분석하여 요구분석서를 작성. 사용자가 요구분석/spec 작성을 요청할 때 사용
4
- argument-hint: "<topic> 또는 <spec 경로 R번호> 또는 <R번호>"
4
+ argument-hint: "<topic> 또는 <spec 경로 R번호> 또는 <R번호> 또는 <migration.md 경로 [M번호...]>"
5
5
  ---
6
6
 
7
7
  # sd-spec: 요구분석서 작성
@@ -26,7 +26,20 @@ argument-hint: "<topic> 또는 <spec 경로 R번호> 또는 <R번호>"
26
26
  - 대화에도 spec이 없으면 AskUserQuestion으로 spec 파일 경로를 요청한다
27
27
  - 해당 spec을 Read하고 R항목의 내용을 추출한다. 해당 R번호가 존재하지 않으면 AskUserQuestion으로 올바른 R번호를 확인한다
28
28
 
29
- ### 1-3. topic (신규 spec 모드)
29
+ ### 1-3. migration.md 경로 (+ 선택적 M번호) (마이그레이션 spec 모드)
30
+
31
+ `$ARGUMENTS`에 `migration.md`로 끝나는 경로가 포함된 경우:
32
+ - 해당 migration.md를 Read한다
33
+ - 경로 뒤에 `M숫자` 패턴이 있으면 해당 M항목만 대상으로 한다 (여러 M번호 지정 가능)
34
+ - 경로만 있으면 (M번호 미지정) 문서 내 모든 M항목을 대상으로 한다
35
+ - 대상 M항목(`#### M{숫자}. {제목}`)의 내용을 추출한다
36
+ - M항목의 "유형", "원본 위치", "현재 대응", "설명" 정보를 기반으로 요구분석서를 작성한다
37
+ - 해당 M번호가 존재하지 않으면 AskUserQuestion으로 올바른 M번호를 확인한다
38
+ - 예: `/sd-spec .tasks/260316_my-app-migration/migration.md` → 모든 M항목 대상
39
+ - 예: `/sd-spec .tasks/260316_my-app-migration/migration.md M3`
40
+ - 예: `/sd-spec .tasks/260316_my-app-migration/migration.md M1 M5`
41
+
42
+ ### 1-4. topic (신규 spec 모드)
30
43
 
31
44
  위 조건에 해당하지 않으면 기존 신규 spec 작성 모드로 진입한다:
32
45
  - `$ARGUMENTS`가 비어있으면 현재 대화 맥락에서 topic을 파악한다. 대화 맥락도 없으면 AskUserQuestion으로 topic을 요청한다
@@ -89,6 +102,16 @@ argument-hint: "<topic> 또는 <spec 경로 R번호> 또는 <R번호>"
89
102
 
90
103
  이하 섹션 구조(개요, 현재 상태, 요구사항, 영향 범위)는 신규 spec 모드와 동일하다.
91
104
 
105
+ **마이그레이션 spec 모드**에서는 문서 상단에 참조 문서를 추가한다:
106
+
107
+ ```markdown
108
+ # 요구분석서: {M항목 제목들의 종합 설명}
109
+
110
+ **참조 문서:** `{migration.md 경로}` {M번호들}
111
+ ```
112
+
113
+ 이하 섹션 구조(개요, 현재 상태, 요구사항, 영향 범위)는 신규 spec 모드와 동일하다.
114
+
92
115
  **신규 spec 모드**에서는 참조 문서 없이 시작한다:
93
116
 
94
117
  ```markdown
@@ -190,6 +213,19 @@ argument-hint: "<topic> 또는 <spec 경로 R번호> 또는 <R번호>"
190
213
  - 예: 상위 spec이 `.tasks/260315_example/spec.md`이고 R1이면 → `.tasks/260315_example/R1/spec.md`
191
214
  - 디렉토리가 없으면 먼저 생성한다
192
215
 
216
+ ### 마이그레이션 spec 모드
217
+
218
+ - 특정 M번호 지정 시: migration.md와 동일 디렉토리 하위에 `{M번호}/` (복수 M이면 `{M번호}_{M번호}/`)
219
+ - M번호 미지정 시 (전체): migration.md와 동일 디렉토리에 `spec.md`
220
+ - 파일명: `spec.md`
221
+ - 전체 경로:
222
+ - 특정 M: `{migration.md 디렉토리}/{M번호}/spec.md`
223
+ - 전체: `{migration.md 디렉토리}/spec.md`
224
+ - 예: migration.md가 `.tasks/260316_my-app-migration/migration.md`이고 M번호 미지정이면 → `.tasks/260316_my-app-migration/spec.md`
225
+ - 예: M3이면 → `.tasks/260316_my-app-migration/M3/spec.md`
226
+ - 예: M1과 M5이면 → `.tasks/260316_my-app-migration/M1_M5/spec.md`
227
+ - 디렉토리가 없으면 먼저 생성한다
228
+
193
229
  **저장 구조 예시:**
194
230
  ```
195
231
  .tasks/260315_example/
@@ -82,18 +82,34 @@ sd-plan의 테스트 전략 결정과 sd-plan-dev의 TDD 사이클 실행을 통
82
82
  **입력:** {subagent에게 실행시킬 지시}
83
83
  **기대 결과:** {검증 기준}
84
84
  ```
85
- 3. Agent tool로 subagent 생성하여 테스트를 실행한다
86
- - subagent에게 전달할 내용: 대상 파일 경로, test.md 경로, "test.md의 테스트를 실행하고 PASS/FAIL을 판정하라"는 지시
85
+ 3. Agent tool로 **테스트별 독립 subagent**를 병렬로 생성하여 실행한다
86
+ - 테스트(`## 테스트 N`)마다 별도 subagent를 호출한다 (단일 메시지에서 병렬 호출)
87
+ - subagent에게 전달할 내용: 대상 파일 경로, 해당 테스트 1건의 입력과 기대 결과, "테스트를 실행하고 PASS/FAIL을 판정하라"는 지시
88
+ - 하나의 subagent에 여러 테스트를 전달하지 않는다 (컨텍스트 격리)
87
89
 
88
90
  **이미 모든 테스트가 통과하면 (vitest/subagent 공통):**
91
+
92
+ 추가 컨텍스트 또는 대화 맥락이 문제/버그/이슈를 설명하고 있는지 판단한다.
93
+
94
+ **문제 제기가 아닌 경우 (단순 테스트 요청):**
89
95
  - "모든 테스트가 이미 통과합니다. 수정이 필요하지 않습니다."를 출력하고 종료한다
90
96
 
97
+ **문제 제기인 경우:**
98
+ 1. 현재 테스트가 문제를 재현하지 못한 것으로 판단한다
99
+ 2. 이전 테스트가 왜 통과했는지(어떤 관점을 놓쳤는지) 분석한다
100
+ 3. 문제를 재현할 수 있는 다른 관점에서 테스트 시나리오를 재작성한다
101
+ 4. 재작성한 테스트를 실행한다
102
+ 5. 여전히 통과하면 2~4를 반복한다 (최대 3회)
103
+ 6. 3회 시도 후에도 모든 테스트가 통과하면:
104
+ - 시도한 테스트 시나리오 목록을 정리하여 사용자에게 보고한다
105
+ - "문제를 재현하는 테스트를 작성하지 못했습니다. 문제 상황을 더 구체적으로 설명해주세요."를 출력하고 중단한다
106
+
91
107
  ## 6. GREEN Phase: 대상 수정 및 재테스트
92
108
 
93
109
  테스트 실패 항목에 대해 대상 파일을 수정한다.
94
110
  - 수정 후 테스트를 재실행한다
95
111
  - vitest: Bash로 `vitest run {테스트 파일}` 재실행
96
- - subagent: Agent tool로 subagent 재실행
112
+ - subagent: Agent tool로 테스트별 독립 subagent 병렬로 재실행
97
113
  - 여전히 실패하면 다시 수정 → 재테스트를 반복한다
98
114
  - 최대 3회 반복한다. 3회 시도 후에도 실패하면 실패 원인을 분석하여 사용자에게 보고하고 중단한다
99
115
 
@@ -101,7 +117,7 @@ sd-plan의 테스트 전략 결정과 sd-plan-dev의 TDD 사이클 실행을 통
101
117
 
102
118
  GREEN Phase에서 대상 파일을 수정한 경우에만 수행한다.
103
119
 
104
- `/simplify 완료 보고는 생략하고, 작업을 멈추지 않는다. 부모 프로세스를 계속 진행한다. 다음 파일만 리뷰: {수정한 파일 목록}` 하여 품질을 개선한다.
120
+ `/sd-simplify` 하여 코드를 리팩터링한다. 완료 멈추지 말고 즉시 다음 단계로 진행한다.
105
121
  - 완료 후 테스트를 재실행하여 통과를 확인한다
106
122
  - 리팩터링으로 테스트가 깨지면 수정 후 재확인한다
107
123
 
@@ -33,7 +33,10 @@ argument-hint: "<요청 내용> | --help"
33
33
  | sd-check | typecheck, lint(fix), 단위test를 순차 수행하고 에러를 자동 수정 | 품질 검사, check, typecheck, lint, 코드 검사, 자동 수정 |
34
34
  | sd-test | 테스트 대상에 대해 작업 유형별 TDD 테스트를 독립 수행 | 테스트, 테스트 작성, 유닛 테스트 |
35
35
  | sd-review | spec/plan 문서와 구현을 비교하여 완성도를 검증 | 리뷰, review, 검증, 충족, 완성도, 구현 검토 |
36
+ | sd-simplify | 외부 동작을 유지하면서 코드의 내부 구조를 개선 | 리팩터링, simplify, 중복 제거, 구조 개선 |
36
37
  | sd-commit | 변경사항을 분석하여 [type] scope 형식의 커밋 메시지를 생성하고 커밋 | 커밋, commit, 변경사항 저장, git commit |
38
+ | sd-apk-decompile | APK 파일을 디컴파일하여 Java 소스, 리소스, 웹 에셋을 추출 | APK, 디컴파일, decompile, 안드로이드 분석 |
39
+ | sd-migration | 원본 코드베이스와 현재 코드베이스를 비교 분석하여 마이그레이션 대상 목록을 생성 | 마이그레이션, migration, 코드 이전, 포팅 |
37
40
 
38
41
  키워드 힌트는 참고용이며, 최종 판단은 요청의 전체 맥락과 의도를 기준으로 한다.
39
42
 
@@ -122,12 +125,21 @@ argument-hint: "<요청 내용> | --help"
122
125
 
123
126
  /sd-document ──────> .docx/.xlsx/.pptx/.pdf 읽기/쓰기
124
127
 
128
+ /sd-simplify ─────> 코드 리팩터링 (중복 제거, 네이밍 개선, 구조 분리)
129
+
125
130
  /sd-commit ────────> 변경사항 분석 + [type] scope 커밋 메시지 생성 + 커밋
126
131
 
127
132
  /sd-email-analyze ─> .eml/.msg 분석 > 첨부파일 추출
128
133
  |
129
134
  v
130
135
  /sd-document (문서 첨부파일)
136
+
137
+ /sd-apk-decompile ─> APK 디컴파일 (JADX + Apktool + dex2jar/CFR)
138
+
139
+ /sd-migration ────> 원본↔현재 코드베이스 비교 > migration.md 생성
140
+ |
141
+ v
142
+ /sd-spec (M 항목별 요구분석서 작성)
131
143
  ```
132
144
 
133
145
  ### 라우터
@@ -153,6 +165,9 @@ argument-hint: "<요청 내용> | --help"
153
165
  | `/sd-commit` | 커밋 메시지 생성 + 커밋 | `/sd-commit` |
154
166
  | `/sd-document` | 문서 읽기/쓰기 | `/sd-document report.xlsx` |
155
167
  | `/sd-email-analyze` | 이메일 분석 | `/sd-email-analyze mail.eml` |
168
+ | `/sd-simplify` | 코드 리팩터링 | `/sd-simplify src/utils.ts` |
169
+ | `/sd-apk-decompile` | APK 디컴파일 | `/sd-apk-decompile app.apk` |
170
+ | `/sd-migration` | 마이그레이션 분석 | `/sd-migration /d/projects/old-app` |
156
171
  | `/sd-use` | 자동 스킬 매칭 | `/sd-use 로그인 버그 좀 봐줘` |
157
172
  | `/sd-use --help` | 이 가이드 표시 | `/sd-use --help` |
158
173
  ````
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/sd-claude",
3
- "version": "13.0.93",
3
+ "version": "13.0.96",
4
4
  "description": "Simplysm Claude Code asset installer",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",