@simplysm/sd-claude 13.0.85 → 13.0.87
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 +160 -30
- package/claude/rules/sd-claude-rules.md +14 -11
- package/claude/rules/sd-library-issue.md +9 -4
- package/claude/rules/sd-readme.md +5 -0
- package/claude/skills/sd-audit/SKILL.md +133 -0
- package/claude/skills/sd-check/SKILL.md +111 -49
- package/claude/skills/sd-commit/SKILL.md +121 -32
- package/claude/skills/sd-debug/SKILL.md +96 -82
- package/claude/skills/sd-document/SKILL.md +64 -58
- package/claude/skills/sd-document/_common.py +1 -6
- package/claude/skills/sd-document/extract_docx.py +0 -1
- package/claude/skills/sd-document/extract_pdf.py +17 -25
- package/claude/skills/sd-document/extract_pptx.py +0 -1
- package/claude/skills/sd-document/extract_xlsx.py +2 -4
- package/claude/skills/sd-email-analyze/SKILL.md +33 -23
- package/claude/skills/sd-init/SKILL.md +99 -80
- package/claude/skills/sd-plan/SKILL.md +113 -119
- package/claude/skills/sd-plan-dev/SKILL.md +122 -0
- package/claude/skills/sd-readme/SKILL.md +147 -100
- package/claude/skills/sd-spec/SKILL.md +207 -0
- package/claude/skills/sd-spec/sections/api.md +85 -0
- package/claude/skills/sd-spec/sections/architecture.md +104 -0
- package/claude/skills/sd-spec/sections/db.md +99 -0
- package/claude/skills/sd-spec/sections/process.md +98 -0
- package/claude/skills/sd-spec/sections/ui.md +146 -0
- package/claude/skills/sd-test/SKILL.md +116 -0
- package/claude/skills/sd-use/SKILL.md +149 -0
- package/package.json +1 -1
- package/claude/rules/sd-simplysm-usage.md +0 -7
- package/claude/skills/sd-api-review/SKILL.md +0 -85
- package/claude/skills/sd-document/__pycache__/_common.cpython-313.pyc +0 -0
- package/claude/skills/sd-review/SKILL.md +0 -72
- package/claude/skills/sd-simplify/SKILL.md +0 -66
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Extract text, tables, and images from PDF files page by page."""
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import struct
|
|
5
|
+
import logging
|
|
5
6
|
from _common import (
|
|
6
7
|
setup_encoding, make_output_paths, print_header, save_image,
|
|
7
8
|
print_image_summary, run_cli, normalize_cell,
|
|
@@ -40,35 +41,26 @@ def extract(file_path):
|
|
|
40
41
|
print("| " + " | ".join(cells) + " |")
|
|
41
42
|
print()
|
|
42
43
|
|
|
43
|
-
# Image extraction (pypdf)
|
|
44
|
+
# Image extraction (pypdf page.images API)
|
|
45
|
+
logging.getLogger("pypdf").setLevel(logging.ERROR)
|
|
44
46
|
reader = PdfReader(file_path)
|
|
45
47
|
for page_num, page in enumerate(reader.pages, 1):
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if "/DCTDecode" in filter_str:
|
|
59
|
-
ext = "jpg"
|
|
60
|
-
elif "/JPXDecode" in filter_str:
|
|
61
|
-
ext = "jp2"
|
|
62
|
-
try:
|
|
63
|
-
img_path = save_image(out_dir, img_idx, obj.get_data(), ext)
|
|
64
|
-
except Exception as exc:
|
|
65
|
-
print(f"Warning: failed to decode image {img_idx}: {exc}", file=sys.stderr)
|
|
66
|
-
img_path = save_image(out_dir, img_idx, obj._data if hasattr(obj, "_data") else b"", "bin")
|
|
67
|
-
print(f"[IMG] (page={page_num}) {img_path}")
|
|
48
|
+
for img in page.images:
|
|
49
|
+
data = img.data
|
|
50
|
+
# Filter small mask/decorative images by checking PNG IHDR dimensions
|
|
51
|
+
if data[:4] == b'\x89PNG' and len(data) >= 24:
|
|
52
|
+
w = struct.unpack('>I', data[16:20])[0]
|
|
53
|
+
h = struct.unpack('>I', data[20:24])[0]
|
|
54
|
+
if w <= 4 or h <= 4:
|
|
55
|
+
continue
|
|
56
|
+
ext = img.name.rsplit('.', 1)[-1] if '.' in img.name else "png"
|
|
57
|
+
img_idx += 1
|
|
58
|
+
img_path = save_image(out_dir, img_idx, data, ext)
|
|
59
|
+
print(f"[IMG] (page={page_num}) {img_path}")
|
|
68
60
|
|
|
69
61
|
print()
|
|
70
62
|
print_image_summary(img_idx, out_dir)
|
|
71
63
|
|
|
72
64
|
|
|
73
65
|
if __name__ == "__main__":
|
|
74
|
-
run_cli(extract, "extract_pdf.py", {"pdfplumber": "pdfplumber", "pypdf": "pypdf"})
|
|
66
|
+
run_cli(extract, "extract_pdf.py", {"pdfplumber": "pdfplumber", "pypdf": "pypdf", "Pillow": "PIL"})
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Extract data and images from XLSX files with cell positions."""
|
|
3
3
|
|
|
4
|
-
import sys
|
|
5
4
|
from _common import (
|
|
6
5
|
setup_encoding, make_output_paths, print_header, save_image,
|
|
7
6
|
print_image_summary, run_cli,
|
|
@@ -24,12 +23,11 @@ def extract(file_path):
|
|
|
24
23
|
print(f"## Sheet: {sheet_name}\n")
|
|
25
24
|
|
|
26
25
|
# Data extraction
|
|
27
|
-
|
|
28
|
-
if not rows:
|
|
26
|
+
if ws.max_row is None or ws.max_row == 0:
|
|
29
27
|
print("(empty sheet)\n")
|
|
30
28
|
continue
|
|
31
29
|
|
|
32
|
-
for row in
|
|
30
|
+
for row in ws.iter_rows(values_only=False):
|
|
33
31
|
cells = []
|
|
34
32
|
for cell in row:
|
|
35
33
|
val = cell.value
|
|
@@ -1,44 +1,54 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sd-email-analyze
|
|
3
|
-
description:
|
|
3
|
+
description: 이메일 파일(.eml/.msg)을 분석하여 헤더, 본문, 인라인 이미지, 첨부파일을 추출. 사용자가 .eml/.msg 파일의 내용 확인이나 분석을 요청할 때 사용
|
|
4
|
+
argument-hint: "<이메일 파일 경로>"
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
#
|
|
7
|
+
# sd-email-analyze: 이메일 파일 분석 및 내용 추출
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
`.eml` 및 `.msg`(Outlook) 이메일 파일을 파싱하여 메일 헤더, 본문, 인라인 이미지, 첨부파일을 추출하고 분석한다.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
## 1. 인자 파싱
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
`$ARGUMENTS`에서 이메일 파일 경로를 추출한다.
|
|
14
|
+
- `$ARGUMENTS`가 비어있으면 현재 대화 맥락에서 이메일 파일 경로를 파악한다. 대화 맥락도 없으면 AskUserQuestion으로 파일 경로를 요청한다
|
|
15
|
+
- 지원 형식: `.eml`, `.msg`
|
|
16
|
+
- 파일이 존재하지 않거나 지원하지 않는 확장자이면 AskUserQuestion으로 올바른 경로를 요청한다
|
|
13
17
|
|
|
14
|
-
##
|
|
18
|
+
## 2. 이메일 파일 파싱
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
다음 명령을 실행하여 이메일 파일을 파싱한다:
|
|
17
21
|
|
|
18
22
|
```bash
|
|
19
|
-
python
|
|
23
|
+
python ${CLAUDE_SKILL_DIR}/email-analyzer.py <이메일_파일_경로>
|
|
20
24
|
```
|
|
21
25
|
|
|
22
|
-
-
|
|
23
|
-
-
|
|
26
|
+
- 최초 실행 시 `extract-msg` 패키지가 자동 설치된다
|
|
27
|
+
- 출력은 마크다운 리포트(stdout)이며, 추출된 파일은 `<이메일_파일명>_files/` 디렉토리에 저장된다
|
|
28
|
+
|
|
29
|
+
### 출력 구조
|
|
30
|
+
|
|
31
|
+
| 섹션 | 내용 |
|
|
32
|
+
|------|------|
|
|
33
|
+
| Email Info | Subject, From, To, CC, Date, 첨부파일 수 |
|
|
34
|
+
| Body | 본문 텍스트 (plain text 우선, 없으면 HTML 스트립) |
|
|
35
|
+
| Inline Images | 저장된 인라인 이미지 파일 경로 테이블 |
|
|
36
|
+
| Attachments | 저장된 첨부파일 경로 테이블 |
|
|
24
37
|
|
|
25
|
-
|
|
38
|
+
## 3. 추출 파일 분석
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
2. **Body Text**: Plain text (if plain text is unavailable, HTML tags are stripped)
|
|
29
|
-
3. **Inline Images**: Table of saved file paths
|
|
30
|
-
4. **Attachments**: Table of saved file paths
|
|
40
|
+
2단계 출력의 파일 경로를 확인하고 다음을 수행한다. 인라인 이미지 확인과 첨부파일 분석은 독립적이므로 가능한 한 병렬로 수행한다.
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
### 인라인 이미지
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
Read 도구로 각 저장 경로의 이미지를 확인한다.
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
2. **Attachments**: Use the **Read** tool (for images) or the **sd-document** skill script (for DOCX, XLSX, PPTX, PDF)
|
|
46
|
+
### 첨부파일
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
- 이미지 파일: Read 도구로 확인
|
|
49
|
+
- 문서 파일(DOCX, XLSX, PPTX, PDF): `/sd-document` 스킬로 분석
|
|
40
50
|
|
|
41
|
-
|
|
51
|
+
## 4. 완료 안내
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
2
|
|
53
|
+
분석이 완료되면 다음을 출력한다:
|
|
54
|
+
- 3단계에서 수행한 파일별 분석 결과 요약 (2단계에서 이미 출력된 이메일 기본 정보는 반복하지 않는다)
|
|
@@ -1,133 +1,152 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sd-init
|
|
3
|
-
description:
|
|
3
|
+
description: 프로젝트 설정 파일을 분석하여 CLAUDE.md를 자동 생성. 사용자가 CLAUDE.md 생성이나 갱신을 요청할 때 사용
|
|
4
|
+
argument-hint: ""
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
#
|
|
7
|
+
# sd-init: CLAUDE.md 자동 생성
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
프로젝트를 분석하여 CLAUDE.md를 생성한다. 기존 파일이 있으면 비교하여 병합한다.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
1~3단계는 독립적이므로 병렬로 수행할 수 있다.
|
|
11
12
|
|
|
12
|
-
##
|
|
13
|
+
## 1. 패키지 매니저 감지
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
프로젝트 루트의 lock 파일로 패키지 매니저를 판별한다:
|
|
15
16
|
|
|
16
17
|
1. `pnpm-lock.yaml` → pnpm
|
|
17
18
|
2. `yarn.lock` → yarn
|
|
18
|
-
3.
|
|
19
|
+
3. `bun.lock` 또는 `bun.lockb` → bun
|
|
20
|
+
4. 그 외 → npm
|
|
21
|
+
|
|
22
|
+
## 2. 스크립트 분석
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
`package.json`의 `scripts` 섹션을 Read하고, 각 스크립트가 실행하는 CLI 도구를 분석한다.
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
- 잘 알려진 도구(`tsc`, `vitest`, `eslint`, `prettier`, `playwright` 등)를 직접 실행하는 경우: 실행 내용을 그대로 기록
|
|
27
|
+
- 프로젝트 내부 CLI나 커스텀 스크립트(예: `tsx packages/.../cli.ts`)를 실행하는 경우: Bash로 `--help`를 붙여 실행(timeout 5초)하여 사용 가능한 서브커맨드와 주요 옵션을 파악. 실패하면 scripts 내용만 기록
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
이 단계에서는 정보 수집만 수행한다. 최종 포맷팅은 4단계에서 한다.
|
|
25
30
|
|
|
26
|
-
##
|
|
31
|
+
## 3. 코딩룰 분석
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
프로젝트 루트에서 다음 설정 파일을 찾아 존재하는 것만 Read한다:
|
|
29
34
|
|
|
30
|
-
- ESLint: `eslint.config.*`, `.eslintrc
|
|
35
|
+
- ESLint: 프로젝트 루트의 `eslint.config.*`, `.eslintrc.*`
|
|
31
36
|
- Prettier: `.prettierrc*`, `prettier.config.*`
|
|
32
37
|
- EditorConfig: `.editorconfig`
|
|
33
|
-
- TypeScript:
|
|
38
|
+
- TypeScript: 루트 `tsconfig.json`의 `compilerOptions`
|
|
34
39
|
- Stylelint: `.stylelintrc*`, `stylelint.config.*`
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
다음 기준으로 규칙을 선별하여 요약한다:
|
|
42
|
+
- 기본값과 다른 설정 (예: `verbatimModuleSyntax: true`)
|
|
43
|
+
- error 레벨의 비표준 규칙 (예: `no-console: error`)
|
|
44
|
+
- 특정 API 사용 금지/강제 규칙 (예: `Buffer` 금지 → `Uint8Array` 사용)
|
|
37
45
|
|
|
38
|
-
##
|
|
46
|
+
## 4. CLAUDE.md 생성
|
|
39
47
|
|
|
40
|
-
|
|
48
|
+
1~3단계에서 수집한 정보를 종합하여 CLAUDE.md 내용을 생성한다. 이미 읽은 파일은 다시 읽지 않는다.
|
|
41
49
|
|
|
42
|
-
|
|
43
|
-
- **PM**: Package manager detected in Step 1
|
|
44
|
-
- **Monorepo structure**: If a `workspaces` field or `pnpm-workspace.yaml` exists, briefly describe the workspace paths
|
|
45
|
-
- **Tech stack**: Identify key technologies (frameworks, bundlers, test tools, etc.) from `dependencies`/`devDependencies` and describe them very briefly
|
|
46
|
-
- **Commands**: Script usage organized in Step 2
|
|
47
|
-
- **Coding rules**: Rules from Step 3 that Claude should follow. Write as a `## Coding Rules` section
|
|
50
|
+
포함할 내용:
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
- **프로젝트 정보**: `package.json`의 `name`, `description`, 패키지 매니저
|
|
53
|
+
- **모노레포 구조**: `workspaces` 필드나 `pnpm-workspace.yaml`이 있으면 워크스페이스 경로를 간략히 기술
|
|
54
|
+
- **기술 스택**: `dependencies`/`devDependencies`에서 프레임워크, 번들러, 테스트 도구 등 주요 라이브러리를 나열 (최대 10개)
|
|
55
|
+
- **명령어**: 2단계에서 수집한 스크립트를 카테고리별로 bash 코드블록에 사용 예시로 포맷팅
|
|
56
|
+
- **코딩룰**: 3단계에서 선별한 규칙을 불릿 리스트로 작성
|
|
50
57
|
|
|
51
|
-
|
|
58
|
+
### 참고 예시
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
아래 예시의 **섹션 구성과 포맷팅 스타일**(bash 코드블록, 인라인 주석, 불릿 리스트)을 따르되, 내용은 대상 프로젝트에 맞게 작성한다. 예시에 없는 섹션을 추가하거나, 프로젝트에 해당하지 않는 섹션은 생략할 수 있다.
|
|
61
|
+
|
|
62
|
+
````markdown
|
|
54
63
|
# Simplysm
|
|
55
64
|
|
|
56
|
-
pnpm
|
|
65
|
+
pnpm 모노레포. 패키지 경로: `packages/*`, 테스트: `tests/*`
|
|
57
66
|
|
|
58
|
-
##
|
|
67
|
+
## 명령어
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
69
|
+
모든 명령어는 내부적으로 `pnpm sd-cli <command>`를 실행한다. `--debug` 플래그를 모든 명령어에 사용할 수 있다.
|
|
70
|
+
`[targets..]`를 지정하지 않으면 `sd.config.ts`에 정의된 모든 패키지가 대상이 된다.
|
|
71
|
+
대상은 패키지 경로로 지정한다 (예: `packages/core-common`, `tests/orm`).
|
|
63
72
|
|
|
64
|
-
###
|
|
73
|
+
### 개발
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
pnpm dev [targets..] #
|
|
68
|
-
pnpm dev packages/solid-demo #
|
|
69
|
-
pnpm dev -o key=value #
|
|
75
|
+
```bash
|
|
76
|
+
pnpm dev [targets..] # 클라이언트+서버 패키지를 개발 모드로 실행
|
|
77
|
+
pnpm dev packages/solid-demo # 특정 패키지만 개발 모드로 실행
|
|
78
|
+
pnpm dev -o key=value # sd.config.ts에 옵션 전달
|
|
70
79
|
|
|
71
|
-
pnpm watch [targets..] #
|
|
72
|
-
pnpm watch packages/core-common #
|
|
73
|
-
|
|
80
|
+
pnpm watch [targets..] # 라이브러리 패키지 빌드 watch 모드
|
|
81
|
+
pnpm watch packages/core-common # 특정 패키지만 watch
|
|
82
|
+
```
|
|
74
83
|
|
|
75
|
-
###
|
|
84
|
+
### 빌드 & 배포
|
|
76
85
|
|
|
77
|
-
|
|
78
|
-
pnpm build [targets..] #
|
|
79
|
-
pnpm build packages/solid #
|
|
86
|
+
```bash
|
|
87
|
+
pnpm build [targets..] # 프로덕션 빌드
|
|
88
|
+
pnpm build packages/solid # 특정 패키지만 빌드
|
|
80
89
|
|
|
81
|
-
pnpm pub [targets..] #
|
|
82
|
-
pnpm pub --no-build #
|
|
83
|
-
pnpm pub --dry-run #
|
|
84
|
-
|
|
90
|
+
pnpm pub [targets..] # 빌드 후 배포 (npm/sftp)
|
|
91
|
+
pnpm pub --no-build # 빌드 없이 배포만
|
|
92
|
+
pnpm pub --dry-run # 실제 배포 없이 시뮬레이션
|
|
93
|
+
```
|
|
85
94
|
|
|
86
|
-
###
|
|
95
|
+
### 코드 품질 검사
|
|
87
96
|
|
|
88
|
-
|
|
89
|
-
pnpm typecheck [targets..] # TypeScript
|
|
90
|
-
pnpm lint [targets..] #
|
|
91
|
-
pnpm lint:fix [targets..] #
|
|
92
|
-
pnpm check [targets..] #
|
|
93
|
-
pnpm vitest [targets..] # vitest watch
|
|
94
|
-
pnpm vitest run [targets..] #
|
|
95
|
-
|
|
97
|
+
```bash
|
|
98
|
+
pnpm typecheck [targets..] # TypeScript 타입 검사
|
|
99
|
+
pnpm lint [targets..] # ESLint + Stylelint 실행
|
|
100
|
+
pnpm lint:fix [targets..] # 린트 이슈 자동 수정 (--fix)
|
|
101
|
+
pnpm check [targets..] # 전체 검사 (타입 검사 + 린트 + 테스트 병렬 실행)
|
|
102
|
+
pnpm vitest [targets..] # vitest watch 모드
|
|
103
|
+
pnpm vitest run [targets..] # 테스트 1회 실행
|
|
104
|
+
```
|
|
96
105
|
|
|
97
|
-
##
|
|
106
|
+
## 아키텍처
|
|
98
107
|
|
|
99
|
-
|
|
108
|
+
의존 방향: 위 → 아래. `core-common`은 내부 의존성이 없는 리프 패키지이다.
|
|
100
109
|
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
```
|
|
111
|
+
앱: solid-demo (클라이언트) / solid-demo-server (서버)
|
|
103
112
|
UI: solid (SolidJS + Tailwind)
|
|
104
|
-
|
|
113
|
+
서비스: service-server (Fastify) / service-client / service-common
|
|
105
114
|
ORM: orm-node (MySQL/PostgreSQL/MSSQL) / orm-common
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
코어: core-common (중립) / core-browser / core-node
|
|
116
|
+
도구: sd-cli, lint, excel, storage, sd-claude, mcp-playwright
|
|
117
|
+
```
|
|
109
118
|
|
|
119
|
+
## 통합 테스트
|
|
110
120
|
|
|
111
|
-
|
|
121
|
+
`tests/` 폴더에 위치한다. `pnpm vitest run tests/orm` 등으로 실행한다.
|
|
112
122
|
|
|
113
|
-
|
|
123
|
+
- `tests/orm` — DB 연결, DbContext, escape 테스트 (MySQL, PostgreSQL, MSSQL). Docker 필요.
|
|
124
|
+
- `tests/service` — 서비스 클라이언트-서버 통신 테스트.
|
|
114
125
|
|
|
115
|
-
|
|
116
|
-
- `tests/service` — Service client-server communication tests.
|
|
126
|
+
## 코딩룰
|
|
117
127
|
|
|
118
|
-
|
|
128
|
+
- `import type` 필수 (`verbatimModuleSyntax`), `#private` 금지 → `private` 키워드 사용
|
|
129
|
+
- `console.*` 금지, `if (str)` 금지 → 명시적 비교 `str !== ""` 사용 (nullable boolean/object는 허용)
|
|
130
|
+
- `Buffer` 금지 → `Uint8Array`, `events` 금지 → `@simplysm/core-common`의 `EventEmitter` 사용
|
|
131
|
+
- SolidJS: props 구조분해 금지, `.map()` 대신 `<For>` 사용, `className` 대신 `class` 사용
|
|
132
|
+
- Prettier: 100자, 2칸 들여쓰기, 세미콜론, trailing comma, LF
|
|
133
|
+
````
|
|
119
134
|
|
|
120
|
-
|
|
121
|
-
- `console.*` forbidden, `if (str)` forbidden → use explicit comparison `str !== ""` (nullable boolean/object allowed)
|
|
122
|
-
- `Buffer` forbidden → `Uint8Array`, `events` forbidden → `EventEmitter` from `@simplysm/core-common`
|
|
123
|
-
- SolidJS: no props destructuring, use `<For>` instead of `.map()`, use `class` instead of `className`
|
|
124
|
-
- Prettier: 100 chars, 2-space indent, semicolons, trailing comma, LF
|
|
125
|
-
```
|
|
135
|
+
## 5. 기존 CLAUDE.md와 병합
|
|
126
136
|
|
|
127
|
-
|
|
137
|
+
- 기존 `CLAUDE.md`가 없으면 4단계의 결과를 그대로 저장한다
|
|
138
|
+
- 기존 `CLAUDE.md`가 있으면:
|
|
139
|
+
1. 기존 파일을 Read한다
|
|
140
|
+
2. 4단계에서 생성한 새 내용과 기존 내용을 섹션(`##` 헤딩) 단위로 비교한다
|
|
141
|
+
3. 병합 규칙:
|
|
142
|
+
- 4단계에서 생성한 섹션과 동일 주제의 기존 섹션이 있으면 → 새 내용으로 교체
|
|
143
|
+
- 기존에만 있고 4단계에서 생성하지 않은 섹션 → 그대로 보존
|
|
144
|
+
- 기존 섹션의 위치를 유지하되, 새로 추가된 섹션은 관련 섹션 근처에 배치
|
|
128
145
|
|
|
129
|
-
|
|
146
|
+
## 6. 완료 안내
|
|
130
147
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
148
|
+
저장이 완료되면 생성/업데이트된 파일 경로를 출력한다.
|
|
149
|
+
|
|
150
|
+
## 7. 커밋
|
|
151
|
+
|
|
152
|
+
수정된 파일이 있으면 `/sd-commit`을 실행하여 자동 커밋한다.
|