@simplysm/sd-claude 14.0.46 → 14.0.47
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/claude/references/sd-simplysm14/angular/docs/providers.md +9 -0
- package/claude/references/sd-simplysm14/angular/docs/ui-navigation.md +34 -2
- package/claude/references/sd-simplysm14/excel/docs/core-classes.md +10 -0
- package/claude/references/sd-simplysm14/excel/docs/types.md +5 -1
- package/claude/references/sd-simplysm14/sd-claude/docs/assets.md +1 -1
- package/claude/references/sd-simplysm14.md +20 -20
- package/claude/rules/sd-claude-rules.md +6 -3
- package/claude/skills/sd-claude-docs/SKILL.md +2 -3
- package/claude/skills/sd-commit/SKILL.md +1 -1
- package/claude/skills/sd-deliverable/SKILL.md +1 -2
- package/claude/skills/sd-doc-extract/SKILL.md +1 -1
- package/claude/skills/sd-issue/SKILL.md +1 -1
- package/claude/skills/sd-outlook/SKILL.md +1 -1
- package/claude/skills/sd-prompt/SKILL.md +29 -29
- package/claude/skills/sd-prompt/references/eval-runner.md +2 -3
- package/claude/skills/sd-tdd/SKILL.md +6 -0
- package/claude/skills/sd-use/SKILL.md +1 -1
- package/claude/skills/sd-wbs/SKILL.md +1 -0
- package/package.json +1 -1
|
@@ -219,6 +219,15 @@ abstract class SdSharedDataProvider<T extends Record<string, SharedDataBase<stri
|
|
|
219
219
|
| `emitAsync(name, changeKeys?)` | 변경 이벤트 발행. 내부에서 `client.getEvent<typeof SdSharedDataChangeEvent>("SdSharedDataChange").emit(...)` 호출 |
|
|
220
220
|
| `wait()` | 모든 로딩 완료까지 대기 |
|
|
221
221
|
|
|
222
|
+
### 로딩 전략 (Lazy Loading)
|
|
223
|
+
|
|
224
|
+
**`register()`는 메타정보만 등록하고 실제 데이터를 가져오지 않는다.** 타입별 데이터는 해당 타입의 `getHandle(name)`이 **처음 호출되는 시점**에 `info.getter()`를 실행하여 로딩된다. 즉 `initialize()`에서 여러 타입을 `register()` 해도 앱 시작 시 전체가 일괄 로딩되지 않으며, 실제로 사용되는 타입만 온디맨드로 로딩된다.
|
|
225
|
+
|
|
226
|
+
- 첫 `getHandle()` 호출 → `getter()` 실행 + `SdSharedDataChange` 리스너 등록
|
|
227
|
+
- 이후 같은 타입의 `getHandle()` 호출은 캐시된 `itemsSignal`을 재사용
|
|
228
|
+
- 이후 갱신은 서버에서 `emitAsync()`로 발행된 `SdSharedDataChange` 이벤트 수신 시에만 발생 (`changeKeys`가 있으면 부분 업데이트, 없으면 전체 리로드)
|
|
229
|
+
- `register()`를 동일 `name`으로 재호출하면 `generation`이 증가하고 `needsReload=true`로 표시되어, 다음 `getHandle()` 호출 시 재로딩된다
|
|
230
|
+
|
|
222
231
|
## `SdSharedDataChangeEvent`
|
|
223
232
|
|
|
224
233
|
공유 데이터 변경 이벤트 정의. `defineEvent`로 생성되며, 이벤트 이름 문자열 `"SdSharedDataChange"`를 인자로 받는다.
|
|
@@ -36,9 +36,14 @@ class SdCollapseIcon {
|
|
|
36
36
|
|
|
37
37
|
## Tab
|
|
38
38
|
|
|
39
|
+
> **CRITICAL — 역할 범위**
|
|
40
|
+
> `sd-tab`/`sd-tab-item`은 **상단의 탭 선택 UI만** 담당한다. 내부 뷰(패널) 전환 기능은 **없다**.
|
|
41
|
+
> `sd-tab-item`의 `<ng-content>`는 **탭 라벨 전용**이다. 이 안에 시트/폼/상세 등 뷰 콘텐츠를 넣지 않는다.
|
|
42
|
+
> 뷰 콘텐츠는 `sd-tab` **바깥**에서 선택된 `value`를 기준으로 `@if` / `@switch`로 제어한다.
|
|
43
|
+
|
|
39
44
|
### `SdTab`
|
|
40
45
|
|
|
41
|
-
탭 컨테이너 컴포넌트.
|
|
46
|
+
탭 컨테이너 컴포넌트. 선택된 값을 `value` model로 보관한다.
|
|
42
47
|
|
|
43
48
|
```typescript
|
|
44
49
|
@Component({ selector: "sd-tab" })
|
|
@@ -49,7 +54,7 @@ class SdTab<T> {
|
|
|
49
54
|
|
|
50
55
|
### `SdTabItem`
|
|
51
56
|
|
|
52
|
-
탭 항목 컴포넌트.
|
|
57
|
+
탭 항목 컴포넌트. 자신의 `value`가 부모 `SdTab.value`와 같으면 선택 상태가 된다. 클릭 시 부모 `value`를 자신의 `value`로 세팅한다.
|
|
53
58
|
|
|
54
59
|
```typescript
|
|
55
60
|
@Component({ selector: "sd-tab-item" })
|
|
@@ -58,6 +63,33 @@ class SdTabItem<T> {
|
|
|
58
63
|
}
|
|
59
64
|
```
|
|
60
65
|
|
|
66
|
+
### 사용 예시
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<!-- ✅ 올바른 사용: 탭은 선택 UI, 뷰는 @if로 제어 -->
|
|
70
|
+
<sd-tab [(value)]="tab">
|
|
71
|
+
<sd-tab-item [value]="'list'">목록</sd-tab-item>
|
|
72
|
+
<sd-tab-item [value]="'detail'">상세</sd-tab-item>
|
|
73
|
+
</sd-tab>
|
|
74
|
+
|
|
75
|
+
@if (tab() === "list") {
|
|
76
|
+
<sd-sheet ...></sd-sheet>
|
|
77
|
+
}
|
|
78
|
+
@if (tab() === "detail") {
|
|
79
|
+
<app-detail ...></app-detail>
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<!-- ❌ 잘못된 사용: sd-tab-item 안에 뷰 콘텐츠를 넣음 -->
|
|
85
|
+
<sd-tab [(value)]="tab">
|
|
86
|
+
<sd-tab-item [value]="'list'">
|
|
87
|
+
목록
|
|
88
|
+
<sd-sheet ...></sd-sheet> <!-- 금지: 라벨 영역에 뷰를 넣지 않는다 -->
|
|
89
|
+
</sd-tab-item>
|
|
90
|
+
</sd-tab>
|
|
91
|
+
```
|
|
92
|
+
|
|
61
93
|
## Pagination
|
|
62
94
|
|
|
63
95
|
### `SdPagination`
|
|
@@ -371,6 +371,16 @@ export class ExcelCell {
|
|
|
371
371
|
|
|
372
372
|
셀 스타일을 설정한다. 기존 스타일이 있으면 클론 후 병합한다.
|
|
373
373
|
|
|
374
|
+
커스텀 Excel formatCode를 지정하려면 `numberFormatCode`를 사용한다:
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
await cell.setStyle({ numberFormatCode: "0.000000" }); // 소수점 6자리
|
|
378
|
+
await cell.setStyle({ numberFormatCode: "#,##0.00" }); // 천 단위 구분 + 2자리
|
|
379
|
+
await cell.setStyle({ numberFormatCode: "0.00%" }); // 퍼센트
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
`numberFormat`(프리셋)과 `numberFormatCode`(커스텀)가 동시에 지정되면 `numberFormatCode`가 우선 적용된다.
|
|
383
|
+
|
|
374
384
|
| Parameter | Type | Description |
|
|
375
385
|
|-----------|------|-------------|
|
|
376
386
|
| `opts` | `ExcelStyleOptions` | 스타일 옵션 (배경색, 테두리, 정렬, 숫자 형식) |
|
|
@@ -82,6 +82,7 @@ export interface ExcelStyleOptions {
|
|
|
82
82
|
horizontalAlign?: ExcelHorizontalAlign;
|
|
83
83
|
verticalAlign?: ExcelVerticalAlign;
|
|
84
84
|
numberFormat?: ExcelNumberFormat;
|
|
85
|
+
numberFormatCode?: string;
|
|
85
86
|
}
|
|
86
87
|
```
|
|
87
88
|
|
|
@@ -91,7 +92,10 @@ export interface ExcelStyleOptions {
|
|
|
91
92
|
| `border` | `ExcelBorderPosition[] \| undefined` | 테두리 위치 배열 |
|
|
92
93
|
| `horizontalAlign` | `ExcelHorizontalAlign \| undefined` | 가로 정렬 |
|
|
93
94
|
| `verticalAlign` | `ExcelVerticalAlign \| undefined` | 세로 정렬 |
|
|
94
|
-
| `numberFormat` | `ExcelNumberFormat \| undefined` | 숫자 형식 |
|
|
95
|
+
| `numberFormat` | `ExcelNumberFormat \| undefined` | 숫자 형식 프리셋 |
|
|
96
|
+
| `numberFormatCode` | `string \| undefined` | 커스텀 Excel formatCode 문자열 (예: `"0.000000"`, `"#,##0.00"`, `"0.00%"`) |
|
|
97
|
+
|
|
98
|
+
**우선순위:** `numberFormatCode`가 지정되면 `numberFormat`보다 우선 적용된다. 동일한 formatCode는 `numFmts`에 중복 등록되지 않는다.
|
|
95
99
|
|
|
96
100
|
### `ExcelBorderPosition`
|
|
97
101
|
|
|
@@ -13,23 +13,23 @@ import type { ServiceMethods } from "@simplysm/service-server";
|
|
|
13
13
|
|
|
14
14
|
## 패키지별 상세 문서
|
|
15
15
|
|
|
16
|
-
| 패키지 | 문서
|
|
17
|
-
| -------------------------------------- |
|
|
18
|
-
| @simplysm/angular | [usage.md](
|
|
19
|
-
| @simplysm/capacitor-plugin-auto-update | [usage.md](
|
|
20
|
-
| @simplysm/capacitor-plugin-file-system | [usage.md](
|
|
21
|
-
| @simplysm/capacitor-plugin-intent | [usage.md](
|
|
22
|
-
| @simplysm/capacitor-plugin-usb-storage | [usage.md](
|
|
23
|
-
| @simplysm/core-browser | [usage.md](
|
|
24
|
-
| @simplysm/core-common | [usage.md](
|
|
25
|
-
| @simplysm/core-node | [usage.md](
|
|
26
|
-
| @simplysm/excel | [usage.md](
|
|
27
|
-
| @simplysm/lint | [usage.md](
|
|
28
|
-
| @simplysm/orm-common | [usage.md](
|
|
29
|
-
| @simplysm/orm-node | [usage.md](
|
|
30
|
-
| @simplysm/sd-claude | [usage.md](
|
|
31
|
-
| @simplysm/sd-cli | [usage.md](
|
|
32
|
-
| @simplysm/service-client | [usage.md](
|
|
33
|
-
| @simplysm/service-common | [usage.md](
|
|
34
|
-
| @simplysm/service-server | [usage.md](
|
|
35
|
-
| @simplysm/storage | [usage.md](
|
|
16
|
+
| 패키지 | 문서 |
|
|
17
|
+
| -------------------------------------- | ----------------------------------------------------------------- |
|
|
18
|
+
| @simplysm/angular | [usage.md](./sd-simplysm14/angular/usage.md) |
|
|
19
|
+
| @simplysm/capacitor-plugin-auto-update | [usage.md](./sd-simplysm14/capacitor-plugin-auto-update/usage.md) |
|
|
20
|
+
| @simplysm/capacitor-plugin-file-system | [usage.md](./sd-simplysm14/capacitor-plugin-file-system/usage.md) |
|
|
21
|
+
| @simplysm/capacitor-plugin-intent | [usage.md](./sd-simplysm14/capacitor-plugin-intent/usage.md) |
|
|
22
|
+
| @simplysm/capacitor-plugin-usb-storage | [usage.md](./sd-simplysm14/capacitor-plugin-usb-storage/usage.md) |
|
|
23
|
+
| @simplysm/core-browser | [usage.md](./sd-simplysm14/core-browser/usage.md) |
|
|
24
|
+
| @simplysm/core-common | [usage.md](./sd-simplysm14/core-common/usage.md) |
|
|
25
|
+
| @simplysm/core-node | [usage.md](./sd-simplysm14/core-node/usage.md) |
|
|
26
|
+
| @simplysm/excel | [usage.md](./sd-simplysm14/excel/usage.md) |
|
|
27
|
+
| @simplysm/lint | [usage.md](./sd-simplysm14/lint/usage.md) |
|
|
28
|
+
| @simplysm/orm-common | [usage.md](./sd-simplysm14/orm-common/usage.md) |
|
|
29
|
+
| @simplysm/orm-node | [usage.md](./sd-simplysm14/orm-node/usage.md) |
|
|
30
|
+
| @simplysm/sd-claude | [usage.md](./sd-simplysm14/sd-claude/usage.md) |
|
|
31
|
+
| @simplysm/sd-cli | [usage.md](./sd-simplysm14/sd-cli/usage.md) |
|
|
32
|
+
| @simplysm/service-client | [usage.md](./sd-simplysm14/service-client/usage.md) |
|
|
33
|
+
| @simplysm/service-common | [usage.md](./sd-simplysm14/service-common/usage.md) |
|
|
34
|
+
| @simplysm/service-server | [usage.md](./sd-simplysm14/service-server/usage.md) |
|
|
35
|
+
| @simplysm/storage | [usage.md](./sd-simplysm14/storage/usage.md) |
|
|
@@ -79,12 +79,15 @@
|
|
|
79
79
|
- **클래스 필드 vs prototype**: `Object.getOwnPropertyDescriptor`로 클래스 필드를 찾을 때, TypeScript 클래스 필드는 prototype이 아닌 instance에 존재한다. prototype에서 찾으면 `undefined` 반환
|
|
80
80
|
- **요청하지 않은 기능 추가 금지**: 원본 코드에 없고 사용자가 요청하지 않은 기능을 임의로 추가하지 않는다. 기존 코드의 이벤트/패턴을 그대로 유지하고, 요청된 변경만 수행한다.
|
|
81
81
|
- **프로젝트 구조 이해 필수**: 코드를 배치하기 전에 해당 디렉토리가 빌드 산출물인지, 영구 소스인지 반드시 확인한다. 모르면 사용자에게 질문한다.
|
|
82
|
+
- `eslint-disable @typescript-eslint/require-await` 금지
|
|
82
83
|
|
|
83
84
|
# @simplysm 패키지 참조
|
|
84
85
|
|
|
85
|
-
- `@simplysm/*` 패키지 사용 시,
|
|
86
|
-
-
|
|
87
|
-
-
|
|
86
|
+
- `@simplysm/*` 패키지 사용 시, 해당 참조문서를 읽고 해당 패키지의 문서 경로를 찾아 읽는다.
|
|
87
|
+
- v14: `.claude/references/sd-simplysm14.md`
|
|
88
|
+
- v12: `.claude/references/sd-simplysm12.md`
|
|
89
|
+
- 해당 문서에는 지침 및 사용법이 기록되어 있다.
|
|
90
|
+
- 주의사항: 해당 패키지의 `CLAUDE.md`를 읽는것이 아니다.
|
|
88
91
|
- simplysm 패키지의 경우 context7은 구버전일 수 있으니 사용을 지양한다.
|
|
89
92
|
|
|
90
93
|
# 프로젝트 경계
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sd-claude-docs
|
|
3
3
|
description: 프로젝트 분석을 통해 CLAUDE.md와 LLM용 usage 문서를 동시 생성하는 스킬. "init", "CLAUDE.md 생성", "usage 문서 생성", "LLM 문서 만들어줘", "패키지 문서 생성" 등을 요청할 때 사용한다.
|
|
4
|
-
model: sonnet
|
|
5
|
-
effort: low
|
|
4
|
+
model: claude-sonnet-4-5
|
|
6
5
|
---
|
|
7
6
|
|
|
8
7
|
# sd-claude-docs: CLAUDE.md + usage 문서 통합 생성
|
|
@@ -91,7 +90,7 @@ root 문서는 생성·변경하지 않는다.
|
|
|
91
90
|
|
|
92
91
|
## Step 3: 패키지별 문서 생성 (모노레포)
|
|
93
92
|
|
|
94
|
-
각 패키지에 대해 **Agent 도구로 subagent(model: `sonnet
|
|
93
|
+
각 패키지에 대해 **Agent 도구로 subagent(model: `claude-sonnet-4-5`)를 병렬 실행**한다.
|
|
95
94
|
하나의 메시지에서 모든 패키지의 Agent 호출을 동시에 보낸다.
|
|
96
95
|
|
|
97
96
|
### subagent 프롬프트
|
|
@@ -33,7 +33,14 @@ description: 스킬/프롬프트 파일의 작성·개선을 위한 EDD 스킬.
|
|
|
33
33
|
|
|
34
34
|
## Step 2: Eval 시나리오 정의
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Eval은 스킬/프롬프트가 큰 틀에서 작동하는지 보는 **스모크 테스트**이다. 세부 지시를 하나하나 검증하지 않으므로, 가볍고 빠르게 돈다.
|
|
37
|
+
|
|
38
|
+
### 시나리오 구성 원칙
|
|
39
|
+
|
|
40
|
+
- **시나리오**: 최소 성공 시나리오 1~2개 및 회귀 테스트 시나리오
|
|
41
|
+
- **happy-path 중심**: 대표적 성공 케이스 1개는 프롬프트 작성 전에 먼저 작성한다. 실사용에서 실패가 관찰되면 회귀 테스트로 추가한다
|
|
42
|
+
- **사전 조건 최소화**: 긴 파일 세팅·복잡한 디렉토리 구성 요구 지양
|
|
43
|
+
- **빠른 실행**: 수분 내 종료되는 단순 입력으로 구성한다
|
|
37
44
|
|
|
38
45
|
### Eval 유형
|
|
39
46
|
|
|
@@ -46,48 +53,44 @@ description: 스킬/프롬프트 파일의 작성·개선을 위한 EDD 스킬.
|
|
|
46
53
|
|
|
47
54
|
Judge의 정확도는 체크리스트의 품질에 달려있다. 다음 원칙을 따른다:
|
|
48
55
|
|
|
49
|
-
#### 1)
|
|
56
|
+
#### 1) 산출물 중심 — 과정이 아닌 결과를 본다
|
|
57
|
+
|
|
58
|
+
체크리스트는 **스킬/프롬프트가 만들어낸 산출물이 목적을 달성했는가**를 본다. 중간 과정·도구 사용·질문 여부는 체크하지 않는다.
|
|
50
59
|
|
|
51
|
-
특정 도구에 의존하면 환경에 따라 판정이 달라진다. "무엇을 했는가"를 기술한다:
|
|
52
|
-
특히 AskUserQuestion의 경우 Eval환경에서는 질문하지 않고 답을 스스로 도출하므로, 이에 유의한다.
|
|
53
60
|
```
|
|
54
|
-
(X) "불명확한 부분에 대해
|
|
55
|
-
(
|
|
61
|
+
(X) "불명확한 부분에 대해 사용자에게 질문했다" — 프로세스
|
|
62
|
+
(X) "Read 도구로 파일을 읽었다" — 도구 사용
|
|
63
|
+
(X) "FAIL 원인을 분석하고 개선안을 제시했다" — 프로세스
|
|
56
64
|
|
|
57
|
-
(
|
|
58
|
-
(O) "
|
|
65
|
+
(O) "Impact Mapping 트리(Goal→Actor→Impact→Deliverable)가 산출되었다"
|
|
66
|
+
(O) "모든 Feature가 Goal까지 역추적 가능하다"
|
|
67
|
+
(O) "SKILL.md에 프론트매터(name, description)가 포함되었다"
|
|
68
|
+
```
|
|
59
69
|
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
#### 2) 상황 의존 금지 — 구조·구현 세부에 종속되지 않는다
|
|
71
|
+
|
|
72
|
+
SKILL.md의 Step 구조·도구명·파일 형식 같은 구현 세부에 종속된 항목은 배제한다. 구조가 바뀌면 체크도 깨지기 때문이다.
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
(X) "Eval 파일이 프롬프트보다 먼저 작성되었다" — Step 순서에 종속
|
|
76
|
+
(X) "격리된 workspace(.tmp/)에서 claude -p가 실행되었다" — 실행 환경 세부
|
|
77
|
+
(O) "신규 스킬 요청에 대해 SKILL.md가 생성되었다" — 스킬 목적 자체
|
|
62
78
|
```
|
|
63
79
|
|
|
64
|
-
####
|
|
80
|
+
#### 3) 객관적 기준 — 주관적 표현을 제거한다
|
|
65
81
|
|
|
66
82
|
```
|
|
67
83
|
(X) "프롬프트 내용이 좋은가"
|
|
68
84
|
(O) "모호한 표현('적절한', '필요시', '경우에 따라' 등)이 없는가"
|
|
69
85
|
```
|
|
70
86
|
|
|
71
|
-
####
|
|
87
|
+
#### 4) 단일 기준 — 하나의 항목은 하나만 평가한다
|
|
72
88
|
|
|
73
89
|
```
|
|
74
90
|
(X) "파일을 읽고 올바른 분석을 출력했다"
|
|
75
|
-
(O) "해당 파일을 읽었다."
|
|
76
91
|
(O) "분석 결과가 사실에 부합한다"
|
|
77
92
|
```
|
|
78
93
|
|
|
79
|
-
#### 4) 프로세스 중심 — 추론 결과가 아닌 규칙 적용 여부를 평가한다
|
|
80
|
-
|
|
81
|
-
LLM이 특정 형태의 결과를 출력했는지가 아니라, 프로세스/규칙을 따랐는지를 기준으로 작성한다:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
(X) "기존 스킬/룰 목록이 출력에 포함되었다" — 특정 출력 형태를 기대
|
|
85
|
-
(O) "기존 스킬/룰과의 충돌·중복 여부를 확인했다" — 규칙 적용 여부를 평가
|
|
86
|
-
|
|
87
|
-
(X) "3개의 개선안이 출력에 포함되었다" — 추론 결과의 수량을 기대
|
|
88
|
-
(O) "FAIL 원인을 분석하고 개선안을 제시했다" — 프로세스 수행 여부를 평가
|
|
89
|
-
```
|
|
90
|
-
|
|
91
94
|
### Eval 파일 형식
|
|
92
95
|
|
|
93
96
|
#### 입력 작성 원칙
|
|
@@ -137,7 +140,6 @@ LLM이 특정 형태의 결과를 출력했는지가 아니라, 프로세스/규
|
|
|
137
140
|
- **강한 규칙에 키워드를 구분한다** — `MUST`, `NEVER`, `ALWAYS`, `CRITICAL`, `IMPORTANT`, `required`, `prohibited`. IMPORTANT/CRITICAL은 진짜 중요한 규칙에만 사용한다.
|
|
138
141
|
- **모호한 표현을 제거한다** — "적절하게", "필요시", "경우에 따라" 등은 LLM이 추측하게 만든다. 구체적인 조건과 행동으로 바꾸거나 AskUserQuestion을 활용한다.
|
|
139
142
|
- **간결하게 유지한다** — SKILL.md는 200줄 이하를 목표로 한다. 200줄이 넘을 경우 "Progressive Disclosure" 원칙에 따라 파일을 분리한다.
|
|
140
|
-
- **과적합을 방지한다** — 특정 Eval 시나리오에만 맞추지 말고, 일반적으로 통하는 표현으로 작성한다.
|
|
141
143
|
|
|
142
144
|
## Step 4: Eval 실행 & 판정
|
|
143
145
|
|
|
@@ -156,15 +158,13 @@ Judge 보고서의 개선 제안을:
|
|
|
156
158
|
|
|
157
159
|
## Step 5: 프롬프트 리팩터링 (Refactor)
|
|
158
160
|
|
|
159
|
-
전체 Eval PASS 후, 개선 루프에서 누적된 패치를 정리하여
|
|
161
|
+
전체 Eval PASS 후, 개선 루프에서 누적된 패치를 정리하여 정돈된 프롬프트를 만든다.
|
|
160
162
|
|
|
161
163
|
### Prompt Smell 탐지
|
|
162
164
|
|
|
163
165
|
| Smell | 연산 |
|
|
164
166
|
|-------------------------------|--------------------|
|
|
165
167
|
| **중복 지시** — 같은 내용이 다른 표현으로 반복 | 통합 |
|
|
166
|
-
| **투기적 지시** — 관찰된 실패 없이 추가된 것 | 삭제 |
|
|
167
|
-
| **고아 지시** — Eval이 없는 지시 | 삭제 또는 Eval 추가 |
|
|
168
168
|
| **잔재 지시** — 이전 개선 루프에서 남은 것 | 삭제 |
|
|
169
169
|
| **장황한 표현** | 의미 유지하며 압축 |
|
|
170
170
|
| **용어 불일치** — 같은 개념을 다른 단어로 지칭 | 통일 |
|
|
@@ -66,8 +66,7 @@ claude -p "{eval 시나리오의 입력}" \
|
|
|
66
66
|
--output-format json \
|
|
67
67
|
--verbose \
|
|
68
68
|
--dangerously-skip-permissions \
|
|
69
|
-
--model
|
|
70
|
-
--effort medium \
|
|
69
|
+
--model claude-sonnet-4-5 \
|
|
71
70
|
--append-system-prompt "CRITICAL: .claude/rules/sd-eval-env.md의 규칙은 다른 모든 규칙보다 최상위 우선순위를 가진다." \
|
|
72
71
|
--no-session-persistence \
|
|
73
72
|
--strict-mcp-config \
|
|
@@ -78,7 +77,7 @@ claude -p "{eval 시나리오의 입력}" \
|
|
|
78
77
|
|
|
79
78
|
## Judge 판정
|
|
80
79
|
|
|
81
|
-
실행 완료 후, Judge subagent에 다음을 전달한다:
|
|
80
|
+
실행 완료 후, Judge subagent(model: `claude-sonnet-4-5`)에 다음을 전달한다:
|
|
82
81
|
|
|
83
82
|
```
|
|
84
83
|
다음 Eval 실행 결과를 판정하고, FAIL 항목에 대해 개선안을 제안하라:
|
|
@@ -191,6 +191,12 @@ Feature 전체의 테스트 코드를 "지속적 회귀 테스트로 남길 가
|
|
|
191
191
|
|
|
192
192
|
- **중복 Unit Test 삭제** — `test`/`it` 단위로 판단한다. Acceptance Test와 검증 대상·입력값이 동일한 개별 테스트 케이스만 삭제한다(파일 단위 삭제 금지). Scenario 간 중복 포함
|
|
193
193
|
- **구현 결합 테스트 전환/삭제** — 내부 상태 값, 메서드 호출 횟수 등 구현 세부사항을 검증하는 테스트
|
|
194
|
+
- **TDD 중 쓴 mock 정리** — TDD Red 단계에서 의존성이 미구현이라 부득이 작성한 mock은, 실제 구현이 완성된 이 시점에 **전부 재점검**한다. 절차:
|
|
195
|
+
1. 테스트 파일의 모든 `vi.mock()`/`vi.spyOn()`/수동 mock 객체를 나열한다
|
|
196
|
+
2. 각 mock이 @.claude/references/sd-testing.md 의 화이트리스트(외부 네트워크·DB·하드웨어/OS·타이머)에 해당하는지 확인한다
|
|
197
|
+
3. 해당하지 않으면 실제 인스턴스로 교체한다. 호출 추적이 목적이었다면 `vi.spyOn()`으로만 남긴다
|
|
198
|
+
|
|
199
|
+
남겨두면 실제 코드 변경에 반응하지 않아 false positive를 양산하고, 리팩토링 시 한꺼번에 터진다.
|
|
194
200
|
- **공통 setup 추출** — 중복되는 arrange 코드를 헬퍼/beforeEach로
|
|
195
201
|
- **테스트 네이밍 개선** — 검증하는 동작을 문장처럼 읽히게
|
|
196
202
|
|
|
@@ -74,6 +74,7 @@ Feature는 독립적으로 설계·개발·검증할 수 있는 최소 기능
|
|
|
74
74
|
묶지 않음)
|
|
75
75
|
- 범주는 Epic, 개별 기능이 Feature (예: "알림" Epic → 토스트 알림, 모달 알림, 이메일 알림 각각이 Feature)
|
|
76
76
|
- 가능한한 의존성 순서로 정렬
|
|
77
|
+
- **테스트 작성을 별도 Feature로 분리하지 않는다(NEVER).** 각 Feature는 `sd-tdd`로 구현될 때 테스트와 프로덕션 코드를 함께 작성한다.
|
|
77
78
|
|
|
78
79
|
### Feature 작성 규칙
|
|
79
80
|
|