@kood/claude-code 0.7.10 → 0.7.11

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
@@ -327,6 +327,7 @@ var copyCommands = createExtrasCopier("commands");
327
327
  var copyAgents = createExtrasCopier("agents");
328
328
  var copyInstructions = createExtrasCopier("instructions");
329
329
  var copyScripts = createExtrasCopier("scripts");
330
+ var copyHooks = createExtrasCopier("hooks");
330
331
  var getSkillsToInstall = async (skillsSrc, templates) => {
331
332
  const metadataMap = await loadAllSkillMetadata(skillsSrc);
332
333
  const isNonUITemplate = templates.some((t) => NON_UI_TEMPLATES.includes(t));
@@ -372,6 +373,7 @@ var checkExistingClaudeFiles = async (targetDir) => {
372
373
  const agentsDir = path8.join(targetDir, ".claude", "agents");
373
374
  const instructionsDir = path8.join(targetDir, ".claude", "instructions");
374
375
  const scriptsDir = path8.join(targetDir, ".claude", "scripts");
376
+ const hooksDir = path8.join(targetDir, ".claude", "hooks");
375
377
  if (await fs6.pathExists(skillsDir)) {
376
378
  existingFiles.push(".claude/skills/");
377
379
  }
@@ -387,6 +389,9 @@ var checkExistingClaudeFiles = async (targetDir) => {
387
389
  if (await fs6.pathExists(scriptsDir)) {
388
390
  existingFiles.push(".claude/scripts/");
389
391
  }
392
+ if (await fs6.pathExists(hooksDir)) {
393
+ existingFiles.push(".claude/hooks/");
394
+ }
390
395
  return existingFiles;
391
396
  };
392
397
  var checkAllExtrasExist = async (_templates) => {
@@ -396,12 +401,21 @@ var checkAllExtrasExist = async (_templates) => {
396
401
  const agentsSrc = path8.join(claudeDir, "agents");
397
402
  const instructionsSrc = path8.join(claudeDir, "instructions");
398
403
  const scriptsSrc = path8.join(claudeDir, "scripts");
404
+ const hooksSrc = path8.join(claudeDir, "hooks");
399
405
  const hasSkills = await hasFiles(skillsSrc);
400
406
  const hasCommands = await hasFiles(commandsSrc);
401
407
  const hasAgents = await hasFiles(agentsSrc);
402
408
  const hasInstructions = await hasFiles(instructionsSrc);
403
409
  const hasScripts = await hasFiles(scriptsSrc);
404
- return { hasSkills, hasCommands, hasAgents, hasInstructions, hasScripts };
410
+ const hasHooks = await hasFiles(hooksSrc);
411
+ return {
412
+ hasSkills,
413
+ hasCommands,
414
+ hasAgents,
415
+ hasInstructions,
416
+ hasScripts,
417
+ hasHooks
418
+ };
405
419
  };
406
420
 
407
421
  // src/features/extras/extras-installer.ts
@@ -475,6 +489,22 @@ async function installScriptsIfNeeded(templates, targetDir, shouldInstall, hasSc
475
489
  );
476
490
  return scriptsResult;
477
491
  }
492
+ async function installHooksIfNeeded(templates, targetDir, shouldInstall, hasHooks) {
493
+ if (!shouldInstall) {
494
+ return { files: 0, directories: 0 };
495
+ }
496
+ if (!hasHooks) {
497
+ logger.warn("No hooks found in selected templates.");
498
+ return { files: 0, directories: 0 };
499
+ }
500
+ logger.blank();
501
+ logger.info("Installing hooks...");
502
+ const hooksResult = await copyHooks(templates, targetDir);
503
+ logger.success(
504
+ `Hooks: ${hooksResult.files} files, ${hooksResult.directories} directories`
505
+ );
506
+ return hooksResult;
507
+ }
478
508
  async function installInstructionsIfNeeded(templates, targetDir, shouldInstall, hasInstructions) {
479
509
  if (!shouldInstall) {
480
510
  return { files: 0, directories: 0 };
@@ -497,9 +527,10 @@ async function installExtras(templates, targetDir, flags, availability) {
497
527
  installCommands,
498
528
  installAgents,
499
529
  installInstructions,
500
- installScripts
530
+ installScripts,
531
+ installHooks
501
532
  } = flags;
502
- if (!installSkills && !installCommands && !installAgents && !installInstructions && !installScripts) {
533
+ if (!installSkills && !installCommands && !installAgents && !installInstructions && !installScripts && !installHooks) {
503
534
  return { files: 0, directories: 0 };
504
535
  }
505
536
  const existingClaudeFiles = await checkExistingClaudeFiles(targetDir);
@@ -534,8 +565,14 @@ async function installExtras(templates, targetDir, flags, availability) {
534
565
  installScripts,
535
566
  availability.hasScripts
536
567
  );
537
- const totalFiles = skillsResult.files + commandsResult.files + agentsResult.files + instructionsResult.files + scriptsResult.files;
538
- const totalDirectories = skillsResult.directories + commandsResult.directories + agentsResult.directories + instructionsResult.directories + scriptsResult.directories;
568
+ const hooksResult = await installHooksIfNeeded(
569
+ templates,
570
+ targetDir,
571
+ installHooks,
572
+ availability.hasHooks
573
+ );
574
+ const totalFiles = skillsResult.files + commandsResult.files + agentsResult.files + instructionsResult.files + scriptsResult.files + hooksResult.files;
575
+ const totalDirectories = skillsResult.directories + commandsResult.directories + agentsResult.directories + instructionsResult.directories + scriptsResult.directories + hooksResult.directories;
539
576
  return { files: totalFiles, directories: totalDirectories };
540
577
  }
541
578
 
@@ -620,19 +657,22 @@ async function promptExtrasSelection(options) {
620
657
  agents,
621
658
  instructions,
622
659
  scripts,
660
+ hooks,
623
661
  hasSkills,
624
662
  hasCommands,
625
663
  hasAgents,
626
664
  hasInstructions,
627
- hasScripts
665
+ hasScripts,
666
+ hasHooks
628
667
  } = options;
629
668
  let installSkills = skills ?? false;
630
669
  let installCommands = commands ?? false;
631
670
  const installAgents = agents ?? hasAgents;
632
671
  const installInstructions = instructions ?? hasInstructions;
633
672
  const installScripts = scripts ?? hasScripts;
634
- const noOptionsProvided = skills === void 0 && commands === void 0 && agents === void 0 && instructions === void 0 && scripts === void 0;
635
- if (noOptionsProvided && (hasSkills || hasCommands || hasAgents || hasInstructions || hasScripts)) {
673
+ const installHooks = hooks ?? hasHooks;
674
+ const noOptionsProvided = skills === void 0 && commands === void 0 && agents === void 0 && instructions === void 0 && scripts === void 0 && hooks === void 0;
675
+ if (noOptionsProvided && (hasSkills || hasCommands || hasAgents || hasInstructions || hasScripts || hasHooks)) {
636
676
  logger.blank();
637
677
  if (hasSkills) {
638
678
  const result = await promptConfirm(
@@ -654,7 +694,8 @@ async function promptExtrasSelection(options) {
654
694
  installCommands,
655
695
  installAgents,
656
696
  installInstructions,
657
- installScripts
697
+ installScripts,
698
+ installHooks
658
699
  };
659
700
  }
660
701
  async function promptScopeSelection(options) {
@@ -1420,29 +1461,32 @@ async function installTemplates(templates, targetDir) {
1420
1461
  logger.success(`Total: ${totalFiles} files, ${totalDirectories} directories`);
1421
1462
  return { files: totalFiles, directories: totalDirectories };
1422
1463
  }
1423
- async function promptForExtrasInstallation(options, hasSkills, hasCommands, hasAgents, hasInstructions, hasScripts) {
1464
+ async function promptForExtrasInstallation(options, hasSkills, hasCommands, hasAgents, hasInstructions, hasScripts, hasHooks) {
1424
1465
  return await promptExtrasSelection({
1425
1466
  skills: options.skills,
1426
1467
  commands: options.commands,
1427
1468
  agents: options.agents,
1428
1469
  instructions: options.instructions,
1429
1470
  scripts: options.scripts,
1471
+ hooks: options.hooks,
1430
1472
  hasSkills,
1431
1473
  hasCommands,
1432
1474
  hasAgents,
1433
1475
  hasInstructions,
1434
- hasScripts
1476
+ hasScripts,
1477
+ hasHooks
1435
1478
  });
1436
1479
  }
1437
- function showInstallationSummary(templates, flags, hasSkills, hasCommands, hasAgents, hasInstructions, hasScripts, scope) {
1480
+ function showInstallationSummary(templates, flags, hasSkills, hasCommands, hasAgents, hasInstructions, hasScripts, hasHooks, scope) {
1438
1481
  const {
1439
1482
  installSkills,
1440
1483
  installCommands,
1441
1484
  installAgents,
1442
1485
  installInstructions,
1443
- installScripts
1486
+ installScripts,
1487
+ installHooks
1444
1488
  } = flags;
1445
- const hasExtrasInstalled = installSkills && hasSkills || installCommands && hasCommands || installAgents && hasAgents || installInstructions && hasInstructions || installScripts && hasScripts;
1489
+ const hasExtrasInstalled = installSkills && hasSkills || installCommands && hasCommands || installAgents && hasAgents || installInstructions && hasInstructions || installScripts && hasScripts || installHooks && hasHooks;
1446
1490
  if (templates.length === 0 && !hasExtrasInstalled) {
1447
1491
  logger.blank();
1448
1492
  logger.info("No templates or extras installed.");
@@ -1475,6 +1519,9 @@ function showInstallationSummary(templates, flags, hasSkills, hasCommands, hasAg
1475
1519
  if (installScripts && hasScripts) {
1476
1520
  logger.step("Scripts \u2192 .claude/scripts/");
1477
1521
  }
1522
+ if (installHooks && hasHooks) {
1523
+ logger.step("Hooks \u2192 .claude/hooks/");
1524
+ }
1478
1525
  }
1479
1526
  logger.blank();
1480
1527
  logger.info("Next steps:");
@@ -1513,21 +1560,30 @@ var init = async (options) => {
1513
1560
  }
1514
1561
  }
1515
1562
  const templatesToCheck = templates.length > 0 ? templates : availableTemplates;
1516
- const { hasSkills, hasCommands, hasAgents, hasInstructions, hasScripts } = await checkAllExtrasExist(templatesToCheck);
1563
+ const {
1564
+ hasSkills,
1565
+ hasCommands,
1566
+ hasAgents,
1567
+ hasInstructions,
1568
+ hasScripts,
1569
+ hasHooks
1570
+ } = await checkAllExtrasExist(templatesToCheck);
1517
1571
  const flags = await promptForExtrasInstallation(
1518
1572
  options,
1519
1573
  hasSkills,
1520
1574
  hasCommands,
1521
1575
  hasAgents,
1522
1576
  hasInstructions,
1523
- hasScripts
1577
+ hasScripts,
1578
+ hasHooks
1524
1579
  );
1525
1580
  await installExtras(templatesToCheck, targetDir, flags, {
1526
1581
  hasSkills,
1527
1582
  hasCommands,
1528
1583
  hasAgents,
1529
1584
  hasInstructions,
1530
- hasScripts
1585
+ hasScripts,
1586
+ hasHooks
1531
1587
  });
1532
1588
  showInstallationSummary(
1533
1589
  templates,
@@ -1537,6 +1593,7 @@ var init = async (options) => {
1537
1593
  hasAgents,
1538
1594
  hasInstructions,
1539
1595
  hasScripts,
1596
+ hasHooks,
1540
1597
  scope
1541
1598
  );
1542
1599
  const codexSyncPath = path11.join(targetDir, ".codex");
@@ -1602,7 +1659,7 @@ var init = async (options) => {
1602
1659
 
1603
1660
  // src/index.ts
1604
1661
  var program = new Command();
1605
- program.name("claude-code").description("Claude Code documentation installer for projects").version("0.7.10");
1662
+ program.name("claude-code").description("Claude Code documentation installer for projects").version("0.7.11");
1606
1663
  program.option(
1607
1664
  "-t, --template <names>",
1608
1665
  "template names (comma-separated: tanstack-start,hono)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kood/claude-code",
3
- "version": "0.7.10",
3
+ "version": "0.7.11",
4
4
  "description": "Claude Code documentation installer for projects",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: codex
3
3
  description: OpenAI Codex MCP 연동 에이전트. 꼼꼼한 구현, 코드 리뷰, 엣지케이스 검증 담당. Agent Teams에서 Team Lead 역할 우선.
4
- tools: Read, Write, Edit, Grep, Glob, Bash, mcp__codex__codex, mcp__codex__review
4
+ tools: Read, Write, Edit, Grep, Glob, Bash, mcp__codex__codex, mcp__codex__codex_reply
5
5
  model: sonnet
6
6
  permissionMode: default
7
7
  maxTurns: 50
@@ -15,56 +15,29 @@ maxTurns: 50
15
15
 
16
16
  # Codex Agent
17
17
 
18
- OpenAI Codex MCP를 통해 Claude와 페어 프로그래밍하는 에이전트.
18
+ codex-mcp 서버로 OpenAI Responses API 호출. Claude와 페어 프로그래밍.
19
19
 
20
- **역할:**
21
- - **Agent Teams Team Lead** (기본)
22
- - 꼼꼼한 코드 구현 (엣지케이스, 타입 안정성)
23
- - 코드 리뷰 (버그, 보안, 성능)
24
- - 테스트 작성 및 검증
25
- - Claude 설계 구현 및 검증
20
+ **역할:** Agent Teams **Team Lead** (기본), 구현, 리뷰, 테스트, 디버깅
26
21
 
27
22
  ---
28
23
 
29
24
  <team_lead>
30
25
 
31
- ## Team Lead 역할
32
-
33
- > **Agent Teams 모드에서 Codex가 Team Lead를 맡는 것이 기본**
26
+ ## Team Lead
34
27
 
35
28
  | 역할 | 이유 |
36
29
  |------|------|
37
- | **태스크 분해** | 꼼꼼한 작업 분할, 누락 방지 |
38
- | **품질 게이트** | 코드 품질/테스트 통과 검증 |
39
- | **진행 관리** | 팀원 진척 추적, 병목 감지 |
40
- | **충돌 조율** | 파일 충돌 사전 방지 |
41
-
42
- ### Team Lead 워크플로우
30
+ | 태스크 분해 | 꼼꼼한 분할, 누락 방지 |
31
+ | 품질 게이트 | 코드 품질/테스트 검증 |
32
+ | 진행 관리 | 병목 감지 |
33
+ | 충돌 조율 | 파일 충돌 방지 |
43
34
 
44
35
  ```typescript
45
- // 1. 생성 (Codex Lead)
46
- TeamCreate({
47
- team_name: "project-team",
48
- description: "작업 설명",
49
- agent_type: "codex"
50
- })
51
-
52
- // 2. Claude 팀원 스폰
53
- Task({
54
- subagent_type: 'implementation-executor',
55
- team_name: 'project-team',
56
- name: 'claude-impl',
57
- prompt: '창의적 설계 + 구현'
58
- })
59
-
60
- // 3. 태스크 관리
61
- TaskCreate({ subject: "API 구현", ... })
62
- TaskUpdate({ id: "task-1", status: "completed" })
63
-
64
- // 4. 품질 검증
65
- mcp__codex__review({ target: "uncommitted" })
66
-
67
- // 5. 팀 정리
36
+ TeamCreate({ team_name: "project", agent_type: "codex" })
37
+ Task({ subagent_type: 'implementation-executor', team_name: 'project', name: 'claude-impl', prompt: '...' })
38
+ // 품질 검증
39
+ mcp__codex__codex_reply({ thread_id: "...", prompt: "코드 리뷰: 보안, 성능, 엣지케이스" })
40
+ // 정리
68
41
  SendMessage({ type: 'shutdown_request', recipient: 'claude-impl' })
69
42
  TeamDelete()
70
43
  ```
@@ -75,51 +48,41 @@ TeamDelete()
75
48
 
76
49
  <codex_mcp_usage>
77
50
 
78
- ## Codex MCP 도구 사용
51
+ ## MCP 도구
79
52
 
80
- ### 코드 생성/수정
53
+ **인증:** Codex CLI OAuth (`~/.codex/auth.json`), 토큰 자동 갱신
54
+
55
+ ### 새 태스크
81
56
 
82
57
  ```typescript
83
58
  mcp__codex__codex({
84
- prompt: `
85
- 구현 요구사항:
86
- - [상세 요구사항]
87
-
88
- 품질 기준:
89
- - 모든 엣지케이스 처리
90
- - 타입 안정성 보장
91
- - 에러 핸들링 포함
92
- `,
93
- working_directory: "/path/to/project"
59
+ prompt: "구현 요구사항 + 품질 기준",
60
+ working_directory: "/path/to/project",
61
+ model: "gpt-5.3-codex high" // 선택 (세션에 저장, 생략 시 Codex CLI 기본값)
94
62
  })
63
+ // → JSON { thread_id, result }
95
64
  ```
96
65
 
97
- ### 코드 리뷰
66
+ **에이전트 루프:** `read_file`, `write_file`, `list_files`, `shell_exec` 자율 호출
67
+
68
+ ### 세션 이어가기
98
69
 
99
70
  ```typescript
100
- mcp__codex__review({
101
- target: "uncommitted", // 또는 "branch:feature", "commit:abc123"
102
- focus: ["security", "performance", "bugs", "edge-cases"]
71
+ mcp__codex__codex_reply({
72
+ thread_id: "이전 thread_id",
73
+ prompt: "후속 지시"
103
74
  })
75
+ // 세션 모델 자동 유지, 이전 컨텍스트 보존
104
76
  ```
105
77
 
106
- </codex_mcp_usage>
107
-
108
- ---
109
-
110
- <strengths>
111
-
112
- ## 강점 영역
78
+ ### 리뷰 패턴
113
79
 
114
- | 영역 | 활용 |
115
- |------|------|
116
- | **정밀 구현** | 복잡한 알고리즘, 비즈니스 로직 |
117
- | **엣지케이스** | null, undefined, 빈 배열, 경계값 |
118
- | **코드 리뷰** | 버그, 보안 취약점, 성능 이슈 |
119
- | **테스트** | 단위 테스트, 통합 테스트, 엣지케이스 테스트 |
120
- | **디버깅** | 버그 원인 분석, 재현, 수정 |
80
+ ```typescript
81
+ const r = mcp__codex__codex({ prompt: "src/auth/ 분석", working_directory: cwd })
82
+ mcp__codex__codex_reply({ thread_id: r.thread_id, prompt: "보안, 엣지케이스, 성능 리뷰" })
83
+ ```
121
84
 
122
- </strengths>
85
+ </codex_mcp_usage>
123
86
 
124
87
  ---
125
88
 
@@ -127,207 +90,54 @@ mcp__codex__review({
127
90
 
128
91
  ## 작업 흐름
129
92
 
130
- ### 1. 구현 작업
93
+ **구현:** Read(파일 파악) → codex(구현) → Bash(테스트) → Edit(미세 조정)
131
94
 
132
- ```bash
133
- # 요구사항 분석
134
- Read: 관련 파일 파악
95
+ **리뷰:** Bash(git diff) → codex(diff 분석) → codex_reply(리뷰) → 치명적/경고/제안 분류
135
96
 
136
- # Codex MCP로 구현
137
- mcp__codex__codex:
138
- prompt: "구현 요구사항 + 품질 기준"
139
-
140
- # 결과 검증
141
- Bash: npm test
142
- Read: 생성된 코드 확인
143
-
144
- # 필요 시 수정
145
- Edit: 미세 조정
146
- ```
147
-
148
- ### 2. 리뷰 작업
149
-
150
- ```bash
151
- # 변경사항 확인
152
- Bash: git diff
153
-
154
- # Codex 리뷰
155
- mcp__codex__review:
156
- target: "uncommitted"
157
- focus: ["security", "bugs", "edge-cases"]
158
-
159
- # 리뷰 결과 정리
160
- → 치명적/경고/제안 분류
161
- → 구체적 수정 방법 제시
162
- ```
163
-
164
- ### 3. Claude 설계 구현
165
-
166
- ```bash
167
- # Claude 설계 문서 확인
168
- Read: 설계 문서/인터페이스 정의
169
-
170
- # 설계 기반 구현
171
- mcp__codex__codex:
172
- prompt: `
173
- Claude 설계 기반 구현:
174
- [설계 내용]
175
-
176
- 구현 요구사항:
177
- - 인터페이스 준수
178
- - 타입 안정성
179
- - 테스트 포함
180
- `
181
-
182
- # 구현 결과 검증
183
- Bash: npm run typecheck && npm test
184
- ```
97
+ **설계 구현:** Read(설계 문서) → codex(설계 기반 구현) → Bash(typecheck + test)
185
98
 
186
99
  </workflow>
187
100
 
188
101
  ---
189
102
 
190
- <output_format>
191
-
192
- ## 출력 형식
193
-
194
- ### 구현 완료
195
-
196
- ```markdown
197
- ## 구현 완료
198
-
199
- **생성/수정 파일:**
200
- - src/auth/AuthService.ts (신규)
201
- - src/auth/TokenManager.ts (신규)
202
- - tests/auth.test.ts (신규)
203
-
204
- **주요 구현:**
205
- - JWT 토큰 생성/검증
206
- - 리프레시 토큰 로직
207
- - 에러 핸들링
208
-
209
- **엣지케이스 처리:**
210
- - 만료된 토큰 → 자동 갱신 시도
211
- - 잘못된 토큰 → 401 반환
212
- - 리프레시 토큰 만료 → 재로그인 유도
213
-
214
- **테스트 결과:**
215
- ✅ 15 tests passed
216
- ```
217
-
218
- ### 리뷰 완료
219
-
220
- ```markdown
221
- ## 코드 리뷰 결과
222
-
223
- **검토 파일:**
224
- - src/api/users.ts
225
- - src/components/UserForm.tsx
226
-
227
- ### 치명적 (필수 수정)
228
-
229
- #### 1. src/api/users.ts:15 - SQL Injection 취약점
230
- **문제:** 사용자 입력 직접 쿼리에 삽입
231
- **수정:** Prepared statement 사용
232
- ```typescript
233
- // Before
234
- const query = `SELECT * FROM users WHERE id = ${userId}`
235
-
236
- // After
237
- const query = `SELECT * FROM users WHERE id = ?`
238
- await db.query(query, [userId])
239
- ```
240
-
241
- ### 경고 (권장)
242
-
243
- #### 2. src/components/UserForm.tsx:28 - Null 체크 누락
244
- ...
245
-
246
- ### 제안 (선택)
247
- ...
248
-
249
- **요약:** 치명적 1개, 경고 2개, 제안 1개
250
- ```
251
-
252
- </output_format>
253
-
254
- ---
255
-
256
103
  <collaboration>
257
104
 
258
- ## Claude 협업
105
+ ## Claude 협업
259
106
 
260
107
  | 상황 | Codex 역할 |
261
- |------|------------|
262
- | **Claude 설계 후** | 설계 기반 구현, 엣지케이스 추가 |
263
- | **Claude 구현 후** | 코드 리뷰, 개선점 제안 |
264
- | **병렬 작업** | 백엔드/테스트/리뷰 담당 |
265
- | **의견 분기** | 꼼꼼한 관점에서 의견 제시 |
266
-
267
- ### 협업 시 주의사항
268
-
269
- - Claude 설계 의도 존중
270
- - 변경 시 이유 명확히 설명
271
- - 충돌 발생 시 양쪽 장단점 제시
272
- - 최종 결정은 사용자에게 위임
108
+ |------|-----------|
109
+ | Claude 설계 | 구현 + 엣지케이스 추가 |
110
+ | Claude 구현 | 리뷰 + 개선 제안 |
111
+ | 병렬 작업 | 백엔드/테스트/리뷰 |
112
+ | 의견 분기 | 꼼꼼한 관점 제시, 최종 결정은 사용자 |
273
113
 
274
114
  </collaboration>
275
115
 
276
116
  ---
277
117
 
278
- <forbidden>
279
-
280
- ## 금지 사항
281
-
282
- | 분류 | 금지 |
283
- |------|------|
284
- | **MCP** | MCP 없이 Codex 기능 시뮬레이션 |
285
- | **범위** | Claude 담당 영역 침범 |
286
- | **결정** | 충돌 시 임의 결정 (사용자 선택 유도) |
287
- | **검증** | 테스트 없이 구현 완료 선언 |
288
-
289
- </forbidden>
290
-
291
- ---
292
-
293
- <required>
118
+ <rules>
294
119
 
295
- ## 필수 사항
120
+ ## 필수 / 금지
296
121
 
297
- | 분류 | 필수 |
122
+ | 필수 | 금지 |
298
123
  |------|------|
299
- | **MCP** | mcp__codex__codex 또는 review 사용 |
300
- | **검증** | 구현 후 테스트/타입체크 실행 |
301
- | **엣지케이스** | 모든 경계 조건 처리 |
302
- | **출력** | 구조화된 결과 보고 |
124
+ | codex 또는 codex_reply 사용 | MCP 없이 시뮬레이션 |
125
+ | 구현 후 테스트 실행 | 테스트 없이 완료 선언 |
126
+ | 모든 경계 조건 처리 | Claude 영역 침범 |
127
+ | 구조화된 결과 보고 | 충돌 시 임의 결정 |
303
128
 
304
- </required>
129
+ </rules>
305
130
 
306
131
  ---
307
132
 
308
133
  <error_handling>
309
134
 
310
- ## 에러 처리
311
-
312
- | 에러 | 원인 | 대응 |
313
- |------|------|------|
314
- | MCP 연결 실패 | Codex 서버 미설정 | 설정 안내 메시지 반환 |
315
- | API 타임아웃 | 네트워크/부하 | 재시도 (최대 2회) |
316
- | 구현 실패 | 요구사항 불명확 | 명확화 요청 |
317
-
318
- ### MCP 미설정 시 응답
319
-
320
- ```markdown
321
- ## Codex MCP 연결 필요
322
-
323
- Codex MCP가 설정되지 않았습니다.
324
-
325
- **설정 방법:**
326
- ```bash
327
- claude mcp add codex -- codex mcp-server
328
- ```
329
-
330
- 설정 후 다시 시도해주세요.
331
- ```
135
+ | 에러 | 대응 |
136
+ |------|------|
137
+ | MCP 연결 실패 | 설정 → OpenAI/Codex 등록 안내 |
138
+ | 401 | `codex auth login` 안내 |
139
+ | 타임아웃 | 재시도 |
140
+ | 세션 not found | codex 세션 |
141
+ | 동시 요청 에러 | 이전 요청 완료 대기 |
332
142
 
333
143
  </error_handling>
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: "Cancel active Ralph Loop"
3
+ allowed-tools: ["Bash(test -f .claude/ralph-loop.local.md:*)", "Bash(rm .claude/ralph-loop.local.md)", "Read(.claude/ralph-loop.local.md)"]
4
+ hide-from-slash-command-tool: "true"
5
+ ---
6
+
7
+ # Cancel Ralph
8
+
9
+ To cancel the Ralph loop:
10
+
11
+ 1. Check if `.claude/ralph-loop.local.md` exists using Bash: `test -f .claude/ralph-loop.local.md && echo "EXISTS" || echo "NOT_FOUND"`
12
+
13
+ 2. **If NOT_FOUND**: Say "No active Ralph loop found."
14
+
15
+ 3. **If EXISTS**:
16
+ - Read `.claude/ralph-loop.local.md` to get the current iteration number from the `iteration:` field
17
+ - Remove the file using Bash: `rm .claude/ralph-loop.local.md`
18
+ - Report: "Cancelled Ralph loop (was at iteration N)" where N is the iteration value