@kood/claude-code 0.1.16 → 0.2.1

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/dist/index.js CHANGED
@@ -159,26 +159,42 @@ var copyCommands = async (_templates, targetDir) => {
159
159
  }
160
160
  return counter;
161
161
  };
162
- var checkSkillsAndCommandsExist = async (_templates) => {
163
- const claudeDir = path.join(getTemplatesDir(), ".claude");
164
- const skillsSrc = path.join(claudeDir, "skills");
165
- const commandsSrc = path.join(claudeDir, "commands");
166
- const hasSkills = await fs.pathExists(skillsSrc);
167
- const hasCommands = await fs.pathExists(commandsSrc);
168
- return { hasSkills, hasCommands };
169
- };
170
162
  var checkExistingClaudeFiles = async (targetDir) => {
171
163
  const existingFiles = [];
172
164
  const skillsDir = path.join(targetDir, ".claude", "skills");
173
165
  const commandsDir = path.join(targetDir, ".claude", "commands");
166
+ const agentsDir = path.join(targetDir, ".claude", "agents");
174
167
  if (await fs.pathExists(skillsDir)) {
175
168
  existingFiles.push(".claude/skills/");
176
169
  }
177
170
  if (await fs.pathExists(commandsDir)) {
178
171
  existingFiles.push(".claude/commands/");
179
172
  }
173
+ if (await fs.pathExists(agentsDir)) {
174
+ existingFiles.push(".claude/agents/");
175
+ }
180
176
  return existingFiles;
181
177
  };
178
+ var copyAgents = async (_templates, targetDir) => {
179
+ const counter = { files: 0, directories: 0 };
180
+ const targetAgentsDir = path.join(targetDir, ".claude", "agents");
181
+ const agentsSrc = path.join(getTemplatesDir(), ".claude", "agents");
182
+ if (await fs.pathExists(agentsSrc)) {
183
+ await fs.ensureDir(targetAgentsDir);
184
+ await copyRecursive(agentsSrc, targetAgentsDir, counter);
185
+ }
186
+ return counter;
187
+ };
188
+ var checkAllExtrasExist = async (_templates) => {
189
+ const claudeDir = path.join(getTemplatesDir(), ".claude");
190
+ const skillsSrc = path.join(claudeDir, "skills");
191
+ const commandsSrc = path.join(claudeDir, "commands");
192
+ const agentsSrc = path.join(claudeDir, "agents");
193
+ const hasSkills = await fs.pathExists(skillsSrc);
194
+ const hasCommands = await fs.pathExists(commandsSrc);
195
+ const hasAgents = await fs.pathExists(agentsSrc);
196
+ return { hasSkills, hasCommands, hasAgents };
197
+ };
182
198
 
183
199
  // src/commands/init.ts
184
200
  var TEMPLATE_DESCRIPTIONS = {
@@ -270,17 +286,19 @@ var init = async (options) => {
270
286
  }
271
287
  logger.blank();
272
288
  logger.success(`Total: ${totalFiles} files, ${totalDirectories} directories`);
273
- const { hasSkills, hasCommands } = await checkSkillsAndCommandsExist(templates);
289
+ const { hasSkills, hasCommands, hasAgents } = await checkAllExtrasExist(templates);
274
290
  let installSkills = options.skills ?? false;
275
291
  let installCommands = options.commands ?? false;
276
- if (!options.skills && !options.commands && (hasSkills || hasCommands)) {
292
+ let installAgents = options.agents ?? false;
293
+ const noOptionsProvided = options.skills === void 0 && options.commands === void 0 && options.agents === void 0;
294
+ if (noOptionsProvided && (hasSkills || hasCommands || hasAgents)) {
277
295
  logger.blank();
278
296
  if (hasSkills) {
279
297
  const skillsResponse = await prompts({
280
298
  type: "confirm",
281
299
  name: "install",
282
300
  message: "Install skills to .claude/skills/?",
283
- initial: true
301
+ initial: false
284
302
  });
285
303
  installSkills = skillsResponse.install ?? false;
286
304
  }
@@ -289,12 +307,21 @@ var init = async (options) => {
289
307
  type: "confirm",
290
308
  name: "install",
291
309
  message: "Install commands to .claude/commands/?",
292
- initial: true
310
+ initial: false
293
311
  });
294
312
  installCommands = commandsResponse.install ?? false;
295
313
  }
314
+ if (hasAgents) {
315
+ const agentsResponse = await prompts({
316
+ type: "confirm",
317
+ name: "install",
318
+ message: "Install agents to .claude/agents/?",
319
+ initial: false
320
+ });
321
+ installAgents = agentsResponse.install ?? false;
322
+ }
296
323
  }
297
- if (installSkills || installCommands) {
324
+ if (installSkills || installCommands || installAgents) {
298
325
  const existingClaudeFiles = await checkExistingClaudeFiles(targetDir);
299
326
  if (existingClaudeFiles.length > 0 && !options.force) {
300
327
  logger.warn("The following .claude files/folders already exist:");
@@ -307,9 +334,10 @@ var init = async (options) => {
307
334
  initial: false
308
335
  });
309
336
  if (!response.overwrite) {
310
- logger.info("Skipping skills/commands installation.");
337
+ logger.info("Skipping extras installation.");
311
338
  installSkills = false;
312
339
  installCommands = false;
340
+ installAgents = false;
313
341
  }
314
342
  }
315
343
  if (installSkills && hasSkills) {
@@ -336,13 +364,25 @@ var init = async (options) => {
336
364
  } else if (installCommands && !hasCommands) {
337
365
  logger.warn("No commands found in selected templates.");
338
366
  }
367
+ if (installAgents && hasAgents) {
368
+ logger.blank();
369
+ logger.info("Installing agents...");
370
+ const agentsResult = await copyAgents(templates, targetDir);
371
+ totalFiles += agentsResult.files;
372
+ totalDirectories += agentsResult.directories;
373
+ logger.success(
374
+ `Agents: ${agentsResult.files} files, ${agentsResult.directories} directories`
375
+ );
376
+ } else if (installAgents && !hasAgents) {
377
+ logger.warn("No agents found in selected templates.");
378
+ }
339
379
  }
340
380
  logger.blank();
341
381
  logger.success("Claude Code documentation installed!");
342
382
  logger.blank();
343
383
  logger.info("Installed templates:");
344
384
  templates.forEach((t) => logger.step(t));
345
- if (installSkills || installCommands) {
385
+ if (installSkills || installCommands || installAgents) {
346
386
  logger.blank();
347
387
  logger.info("Installed extras:");
348
388
  if (installSkills) {
@@ -351,6 +391,9 @@ var init = async (options) => {
351
391
  if (installCommands) {
352
392
  logger.step("Commands \u2192 .claude/commands/");
353
393
  }
394
+ if (installAgents) {
395
+ logger.step("Agents \u2192 .claude/agents/");
396
+ }
354
397
  }
355
398
  logger.blank();
356
399
  logger.info("Next steps:");
@@ -361,11 +404,11 @@ var init = async (options) => {
361
404
 
362
405
  // src/index.ts
363
406
  var program = new Command();
364
- program.name("claude-code").description("Claude Code documentation installer for projects").version("0.1.16");
407
+ program.name("claude-code").description("Claude Code documentation installer for projects").version("0.2.1");
365
408
  program.option(
366
409
  "-t, --template <names>",
367
410
  "template names (comma-separated: tanstack-start,hono)"
368
- ).option("-f, --force", "overwrite existing files without prompting").option("--cwd <path>", "target directory (default: current directory)").option("--list", "list available templates").option("-s, --skills", "install skills to .claude/skills/").option("-c, --commands", "install commands to .claude/commands/").action(async (options) => {
411
+ ).option("-f, --force", "overwrite existing files without prompting").option("--cwd <path>", "target directory (default: current directory)").option("--list", "list available templates").option("-s, --skills", "install skills to .claude/skills/").option("-c, --commands", "install commands to .claude/commands/").option("-a, --agents", "install agents to .claude/agents/").action(async (options) => {
369
412
  banner();
370
413
  if (options.list) {
371
414
  const templates = await listAvailableTemplates();
@@ -379,7 +422,8 @@ program.option(
379
422
  force: options.force,
380
423
  cwd: options.cwd,
381
424
  skills: options.skills,
382
- commands: options.commands
425
+ commands: options.commands,
426
+ agents: options.agents
383
427
  });
384
428
  });
385
429
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kood/claude-code",
3
- "version": "0.1.16",
3
+ "version": "0.2.1",
4
4
  "description": "Claude Code documentation installer for projects",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: code-reviewer
3
+ description: 코드 리뷰. git diff 분석, 버그/보안/품질 이슈 탐지. "리뷰해줘", "코드 봐줘" 요청 시 사용.
4
+ model: inherit
5
+ color: red
6
+ tools: ["Read", "Grep", "Bash"]
7
+ ---
8
+
9
+ You are an expert code reviewer.
10
+
11
+ ## Responsibilities
12
+
13
+ 1. 버그 탐지 - 로직 오류, null/undefined, 레이스 컨디션
14
+ 2. 보안 검토 - 인젝션, XSS, 민감 데이터 노출
15
+ 3. 품질 확인 - 중복, 에러 핸들링, CLAUDE.md 규칙 준수
16
+
17
+ ## Process
18
+
19
+ 1. `git diff` 또는 지정 파일 분석
20
+ 2. 이슈 심각도 분류 (Critical/Important)
21
+ 3. 구체적 수정안 제시
22
+
23
+ ## Confidence
24
+
25
+ 80점 이상만 보고:
26
+ - 75+ : 확실한 이슈
27
+ - 100 : 반드시 수정
28
+
29
+ ## Output
30
+
31
+ Critical → Important 순으로 `[파일:라인]` + 이슈 + 수정안 제시.
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: debug-detective
3
+ description: 디버깅 전문가. 버그 원인 분석 및 수정안 제시. "에러", "버그", "안돼" 요청 시 사용.
4
+ model: inherit
5
+ color: yellow
6
+ tools: ["Read", "Grep", "Glob", "Bash"]
7
+ ---
8
+
9
+ You are a debugging specialist.
10
+
11
+ ## Responsibilities
12
+
13
+ 1. 에러 분석 - 스택 트레이스, 로그, 재현 조건
14
+ 2. 원인 추적 - 코드 흐름 따라 근본 원인 탐지
15
+ 3. 수정안 제시 - 최소 변경으로 해결
16
+
17
+ ## Process
18
+
19
+ 1. 증상 파악 (에러 메시지, 재현 단계)
20
+ 2. 가설 수립 (가능한 원인 목록)
21
+ 3. 코드 분석으로 가설 검증
22
+ 4. 근본 원인 수정
23
+
24
+ ## Common Patterns
25
+
26
+ | 패턴 | 증상 | 확인 |
27
+ |------|------|------|
28
+ | Null Reference | TypeError | 옵셔널 체이닝 |
29
+ | Race Condition | 간헐적 실패 | async/await |
30
+ | Off-by-One | 잘못된 인덱스 | 반복문 경계 |
31
+ | State Mutation | 예상외 변경 | 불변성 |
32
+
33
+ ## Rules
34
+
35
+ - 추측 금지, 코드 근거 필수
36
+ - 최소 변경 원칙
37
+ - Before/After 코드 제시
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: refactor-advisor
3
+ description: 리팩토링 조언. 코드 개선점 분석 및 계획 수립. "리팩토링", "정리", "개선" 요청 시 사용.
4
+ model: inherit
5
+ color: cyan
6
+ tools: ["Read", "Grep", "Glob"]
7
+ ---
8
+
9
+ You are a refactoring specialist.
10
+
11
+ ## Responsibilities
12
+
13
+ 1. 코드 스멜 탐지 - 중복, 긴 함수, 복잡한 조건문
14
+ 2. 구조 개선 - 모듈화, 관심사 분리
15
+ 3. 안전한 계획 - 단계별 실행, 테스트 보장
16
+
17
+ ## Process
18
+
19
+ 1. 현재 코드 구조 파악
20
+ 2. 문제점/개선점 식별
21
+ 3. 우선순위 결정
22
+ 4. 단계별 계획 수립
23
+
24
+ ## Code Smells
25
+
26
+ | 카테고리 | 예시 |
27
+ |----------|------|
28
+ | Bloaters | 긴 메서드, 큰 클래스 |
29
+ | Couplers | 과도한 의존성 |
30
+ | Dispensables | 중복, 죽은 코드 |
31
+
32
+ ## Techniques
33
+
34
+ | 기법 | 상황 |
35
+ |------|------|
36
+ | Extract Function | 긴 함수, 중복 |
37
+ | Extract Component | 복잡한 UI |
38
+ | Replace Conditional | 복잡한 if/switch |
39
+
40
+ ## Rules
41
+
42
+ - 한 번에 하나의 리팩토링
43
+ - 각 단계 후 테스트
44
+ - 기능 변경 없이 구조만 개선
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: test-writer
3
+ description: 테스트 작성. 함수/컴포넌트 테스트 생성. "테스트 추가", "테스트 작성" 요청 시 사용.
4
+ model: inherit
5
+ color: green
6
+ tools: ["Read", "Write", "Grep", "Glob"]
7
+ ---
8
+
9
+ You are a testing specialist.
10
+
11
+ ## Responsibilities
12
+
13
+ 1. 유닛 테스트 - 함수, 클래스 단위
14
+ 2. 통합 테스트 - API, 서비스 상호작용
15
+ 3. 엣지 케이스 - 경계값, 에러, 빈 입력
16
+
17
+ ## Process
18
+
19
+ 1. 대상 코드 분석 (입력/출력, 의존성)
20
+ 2. 테스트 케이스 도출 (정상, 엣지, 에러)
21
+ 3. 프로젝트 테스트 패턴 확인
22
+ 4. 테스트 코드 작성
23
+
24
+ ## Coverage Priority
25
+
26
+ | 우선순위 | 케이스 |
27
+ |----------|--------|
28
+ | 필수 | happy path |
29
+ | 필수 | 에러 핸들링 |
30
+ | 권장 | 경계값 |
31
+ | 권장 | null/undefined |
32
+
33
+ ## Structure
34
+
35
+ ```typescript
36
+ describe('[대상]', () => {
37
+ it('should [동작] when [조건]', () => {
38
+ // Arrange → Act → Assert
39
+ });
40
+ });
41
+ ```
@@ -0,0 +1,281 @@
1
+ ---
2
+ description: 계획 실행 또는 간단한 작업 수행. ultrathink + sequential thinking 2-5 + TodoWrite 필수.
3
+ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, Task, TodoWrite, mcp__sequential-thinking__sequentialthinking
4
+ argument-hint: <실행할 작업 또는 계획 파일명>
5
+ ---
6
+
7
+ # Execute Command
8
+
9
+ 계획 문서를 기반으로 실행하거나, 간단한 작업을 바로 수행하는 커맨드.
10
+
11
+ ## CRITICAL: 필수 요구사항
12
+
13
+ | 요구사항 | 설명 |
14
+ |----------|------|
15
+ | **ARGUMENT 필수** | 작업 내용 없이 실행 시 되물음 |
16
+ | **Ultrathink** | 깊은 사고로 작업 분석 |
17
+ | **Sequential Thinking 2-5** | 복잡도에 따라 조정 |
18
+ | **TodoWrite** | 진행 상황 추적 필수 |
19
+
20
+ ## ARGUMENT 확인
21
+
22
+ ```
23
+ $ARGUMENTS 없음 → 즉시 질문:
24
+ "무엇을 실행할까요?
25
+ - 계획 파일명 (예: session-auth)
26
+ - 또는 구체적인 작업 설명"
27
+
28
+ $ARGUMENTS 있음 → 실행 모드 판별
29
+ ```
30
+
31
+ **실행 대상**: $ARGUMENTS
32
+
33
+ ## 실행 모드 판별
34
+
35
+ ```
36
+ ARGUMENT 분석:
37
+ ├─ .claude/plans/*.md 존재? → 계획 기반 실행
38
+ ├─ 구체적 작업 설명? → 직접 실행
39
+ └─ 모호함? → 되물음
40
+ ```
41
+
42
+ **모드 판별 예시:**
43
+
44
+ | ARGUMENT | 모드 |
45
+ |----------|------|
46
+ | `session-auth` | 계획 기반 (.claude/plans/session-auth.md) |
47
+ | `버튼 색상을 파란색으로 변경` | 직접 실행 |
48
+ | `인증 개선` | 되물음 (계획? 직접?) |
49
+
50
+ ## 계획 기반 실행
51
+
52
+ ### 실행 흐름
53
+
54
+ ```
55
+ 1. .claude/plans/$ARGUMENTS.md 읽기
56
+ 2. Sequential Thinking으로 단계 파악
57
+ 3. TodoWrite로 체크리스트 생성
58
+ 4. 단계별 실행:
59
+ a. 현재 단계 in_progress 표시
60
+ b. 코드 수정
61
+ c. 테스트 실행 (있다면)
62
+ d. 완료 표시
63
+ 5. 전체 완료 후 git commit
64
+ ```
65
+
66
+ ### 계획 문서 읽기
67
+
68
+ ```
69
+ 파일 위치: .claude/plans/[기능명].md
70
+
71
+ 읽을 내용:
72
+ - 선택된 접근 방식
73
+ - 구현 단계 및 체크리스트
74
+ - 변경 파일 목록
75
+ - 고려사항/리스크
76
+ ```
77
+
78
+ ### TodoWrite 연동
79
+
80
+ ```
81
+ 계획의 체크리스트 → TodoWrite로 변환:
82
+
83
+ 계획 문서:
84
+ ### 1단계: 컴포넌트 생성
85
+ - [ ] Button 컴포넌트 생성
86
+ - [ ] 스타일 적용
87
+
88
+ → TodoWrite:
89
+ - "Button 컴포넌트 생성" (pending)
90
+ - "스타일 적용" (pending)
91
+ ```
92
+
93
+ ## 직접 실행
94
+
95
+ ### 실행 흐름
96
+
97
+ ```
98
+ 1. ARGUMENT 확인 (작업 설명)
99
+ 2. Sequential Thinking으로 분석 (2-5단계)
100
+ 3. 필요시 Task로 코드 탐색
101
+ 4. TodoWrite로 작업 목록 생성
102
+ 5. 코드 수정
103
+ 6. 테스트 실행 (있다면)
104
+ 7. git commit
105
+ ```
106
+
107
+ ### 복잡도 판단
108
+
109
+ | 복잡도 | 사고 횟수 | 예시 | 권장 |
110
+ |--------|----------|------|------|
111
+ | 간단 | 2 | 오타 수정, 색상 변경 | 직접 실행 |
112
+ | 보통 | 3-4 | 함수 추가, 컴포넌트 수정 | 직접 실행 |
113
+ | 복잡 | 5 | 다중 파일 변경 | 직접 실행 |
114
+ | 매우 복잡 | - | 아키텍처 변경 | /plan 먼저 |
115
+
116
+ **복잡도가 높으면:**
117
+
118
+ ```
119
+ "이 작업은 복잡해 보입니다.
120
+ /plan 커맨드로 먼저 계획을 세우시겠습니까? (Y/N)"
121
+
122
+ Y → /plan 안내
123
+ N → Sequential Thinking 5단계로 진행
124
+ ```
125
+
126
+ ## Sequential Thinking 가이드
127
+
128
+ **간단 (2단계):**
129
+
130
+ ```
131
+ thought 1: 작업 내용 파악 및 대상 파일 확인
132
+ thought 2: 수정 방안 및 영향 확인
133
+ ```
134
+
135
+ **보통 (3-4단계):**
136
+
137
+ ```
138
+ thought 1: 작업 분석 및 범위 파악
139
+ thought 2: 관련 코드 구조 이해
140
+ thought 3: 수정 계획 수립
141
+ thought 4: 테스트 방안 (필요시)
142
+ ```
143
+
144
+ **복잡 (5단계):**
145
+
146
+ ```
147
+ thought 1: 작업 분석 및 복잡도 판단
148
+ thought 2: 코드베이스 탐색 전략
149
+ thought 3: 의존성 및 영향 범위 파악
150
+ thought 4: 단계별 수정 계획
151
+ thought 5: 검증 및 롤백 계획
152
+ ```
153
+
154
+ ## Task Subagent 활용
155
+
156
+ | subagent_type | 용도 |
157
+ |---------------|------|
158
+ | `Explore` | 관련 파일 탐색, 패턴 파악 |
159
+ | `general-purpose` | 복잡한 로직 분석 |
160
+
161
+ **Task 호출 시점:**
162
+
163
+ ```
164
+ - 수정 대상 파일 불명확
165
+ - 영향 범위 파악 필요
166
+ - 기존 패턴 확인 필요
167
+ ```
168
+
169
+ ## 진행 상황 추적
170
+
171
+ **TodoWrite 필수 사용:**
172
+
173
+ ```
174
+ 작업 시작 시:
175
+ 1. 전체 작업 목록 TodoWrite로 생성
176
+ 2. 현재 작업 in_progress
177
+ 3. 완료 시 즉시 completed 표시
178
+ 4. 다음 작업으로 이동
179
+ ```
180
+
181
+ **예시:**
182
+
183
+ ```
184
+ TodoWrite:
185
+ - [completed] 파일 구조 분석
186
+ - [in_progress] Button 컴포넌트 수정
187
+ - [pending] 테스트 실행
188
+ - [pending] git commit
189
+ ```
190
+
191
+ ## Git 커밋 규칙
192
+
193
+ **수정 완료 후 커밋:**
194
+
195
+ ```bash
196
+ # 수정한 파일만 add
197
+ git add <수정된 파일>
198
+
199
+ # 커밋 (한 줄, prefix 필수, 마침표 없음)
200
+ git commit -m "<prefix>: <설명>"
201
+ ```
202
+
203
+ **Prefix:**
204
+
205
+ | Prefix | 용도 |
206
+ |--------|------|
207
+ | feat | 새 기능 |
208
+ | fix | 버그 수정 |
209
+ | refactor | 리팩토링 |
210
+ | style | UI/스타일 변경 |
211
+ | perf | 성능 개선 |
212
+ | test | 테스트 추가 |
213
+ | docs | 문서 수정 |
214
+ | chore | 설정/빌드 |
215
+
216
+ ## 예시 워크플로우
217
+
218
+ ### 계획 기반 실행
219
+
220
+ ```
221
+ 1. 사용자: /execute session-auth
222
+
223
+ 2. .claude/plans/session-auth.md 읽기
224
+
225
+ 3. TodoWrite 생성:
226
+ - 세션 스토어 설정 (pending)
227
+ - 미들웨어 구현 (pending)
228
+ - API 엔드포인트 수정 (pending)
229
+ - 테스트 작성 (pending)
230
+
231
+ 4. 단계별 실행 및 완료 표시
232
+
233
+ 5. git commit -m "feat: 세션 기반 인증 구현"
234
+ ```
235
+
236
+ ### 직접 실행
237
+
238
+ ```
239
+ 1. 사용자: /execute 로그인 버튼 색상을 파란색으로 변경
240
+
241
+ 2. Sequential Thinking (2단계):
242
+ thought 1: "로그인 버튼 → LoginButton 컴포넌트 찾기"
243
+ thought 2: "색상 변경 위치 확인, CSS/Tailwind 스타일"
244
+
245
+ 3. TodoWrite:
246
+ - LoginButton 컴포넌트 수정 (in_progress)
247
+ - 변경 확인 (pending)
248
+
249
+ 4. Edit으로 수정
250
+
251
+ 5. git commit -m "style: 로그인 버튼 색상 파란색으로 변경"
252
+ ```
253
+
254
+ ## 테스트 실행
255
+
256
+ **코드 수정 후 테스트:**
257
+
258
+ ```
259
+ 테스트 파일 존재 시:
260
+ 1. 관련 테스트 실행
261
+ 2. 실패 시 수정
262
+ 3. 전체 테스트 통과 확인
263
+
264
+ 테스트 파일 없을 시:
265
+ - 수동 확인 안내
266
+ - 또는 테스트 작성 제안
267
+ ```
268
+
269
+ ## CRITICAL: 절대 금지
270
+
271
+ | 금지 항목 |
272
+ |----------|
273
+ | ARGUMENT 없이 실행 시작 |
274
+ | TodoWrite 없이 작업 진행 |
275
+ | Sequential Thinking 없이 수정 |
276
+ | 테스트 실패 상태로 커밋 |
277
+ | "Generated with Claude Code" 포함 |
278
+ | "Co-Authored-By:" 헤더 |
279
+ | 여러 줄 커밋 메시지 |
280
+ | 커밋 메시지에 마침표(.) |
281
+ | 매우 복잡한 작업을 /plan 없이 진행 |