@graypark/loophaus 2.0.0
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-plugin/plugin.json +11 -0
- package/LICENSE +21 -0
- package/README.ko.md +358 -0
- package/README.md +282 -0
- package/bin/install.mjs +10 -0
- package/bin/loophaus.mjs +192 -0
- package/bin/uninstall.mjs +233 -0
- package/codex/commands/cancel-ralph.md +30 -0
- package/codex/commands/ralph-loop.md +73 -0
- package/commands/cancel-ralph.md +23 -0
- package/commands/help.md +96 -0
- package/commands/loop-plan.md +55 -0
- package/commands/loop-pulse.md +38 -0
- package/commands/loop-stop.md +29 -0
- package/commands/loop.md +17 -0
- package/commands/ralph-loop.md +18 -0
- package/core/engine.mjs +84 -0
- package/core/event-logger.mjs +37 -0
- package/core/loop.schema.json +29 -0
- package/hooks/hooks.json +15 -0
- package/hooks/stop-hook.mjs +79 -0
- package/lib/paths.mjs +91 -0
- package/lib/state.mjs +46 -0
- package/lib/stop-hook-core.mjs +162 -0
- package/package.json +57 -0
- package/platforms/claude-code/adapter.mjs +20 -0
- package/platforms/claude-code/installer.mjs +165 -0
- package/platforms/codex-cli/adapter.mjs +20 -0
- package/platforms/codex-cli/installer.mjs +131 -0
- package/platforms/kiro-cli/adapter.mjs +21 -0
- package/platforms/kiro-cli/installer.mjs +115 -0
- package/scripts/setup-ralph-loop.sh +145 -0
- package/skills/ralph-claude-cancel/SKILL.md +23 -0
- package/skills/ralph-claude-interview/SKILL.md +178 -0
- package/skills/ralph-claude-loop/SKILL.md +101 -0
- package/skills/ralph-claude-orchestrator/SKILL.md +129 -0
- package/skills/ralph-interview/SKILL.md +275 -0
- package/skills/ralph-orchestrator/SKILL.md +254 -0
- package/store/state-store.mjs +80 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "loophaus",
|
|
3
|
+
"description": "loophaus — Control plane for coding agents",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "graypark",
|
|
7
|
+
"email": "vcz.graypark@gmail.com"
|
|
8
|
+
},
|
|
9
|
+
"skills": "./skills/",
|
|
10
|
+
"keywords": ["loophaus", "loop", "control-plane", "agents"]
|
|
11
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Viewcommz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
[English](README.md) | [한국어](README.ko.md)
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/vcz-Gray/loophaus/main/assets/loophaus-banner.svg" alt="loophaus" width="600" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@graypark/loophaus"><img src="https://img.shields.io/npm/v/@graypark/loophaus.svg?style=flat-square&color=blue" alt="npm version" /></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@graypark/loophaus"><img src="https://img.shields.io/npm/dm/@graypark/loophaus.svg?style=flat-square&color=green" alt="npm downloads" /></a>
|
|
10
|
+
<a href="https://github.com/vcz-Gray/loophaus/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="license" /></a>
|
|
11
|
+
<img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg?style=flat-square" alt="node version" />
|
|
12
|
+
<img src="https://img.shields.io/badge/platform-Claude%20Code%20%7C%20Codex%20CLI%20%7C%20Kiro%20CLI-purple.svg?style=flat-square" alt="platform" />
|
|
13
|
+
<img src="https://img.shields.io/badge/tests-36%20passing-brightgreen.svg?style=flat-square" alt="tests" />
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<b>코딩 에이전트를 위한 컨트롤 플레인 — Claude Code, Codex CLI, Kiro CLI에서 동작하는 반복형 개발 루프.</b>
|
|
18
|
+
<br/>
|
|
19
|
+
<sub><a href="https://ghuntley.com/ralph/">Geoffrey Huntley의 Ralph Wiggum 기법</a> 기반</sub>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 왜 loophaus인가?
|
|
25
|
+
|
|
26
|
+
AI 코딩 에이전트는 다음과 같은 문제를 겪습니다:
|
|
27
|
+
|
|
28
|
+
| 문제 | 현상 |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| **컨텍스트 부패** | 긴 대화가 노이즈를 축적, 에이전트가 혼란에 빠짐 |
|
|
31
|
+
| **체크포인트 없음** | 전부 아니면 전무 — 중단 후 재개 불가 |
|
|
32
|
+
| **학습 손실** | 이전 반복의 인사이트가 새 컨텍스트에 덮어쓰임 |
|
|
33
|
+
| **완료 모호성** | 에이전트가 "완료"라 하지만 테스트는 실패 |
|
|
34
|
+
|
|
35
|
+
loophaus는 이렇게 해결합니다:
|
|
36
|
+
|
|
37
|
+
- **반복마다 신선한 컨텍스트** — 매 사이클마다 디스크에서 PRD + 진행 상황을 읽어, 품질 저하 없음
|
|
38
|
+
- **Git 기반 안전장치** — 스토리별 원자적 커밋, 언제든 롤백 가능
|
|
39
|
+
- **추가 전용 학습** — `progress.txt`가 반복을 거듭하며 지식을 축적
|
|
40
|
+
- **테스트 검증 완료** — `<promise>COMPLETE</promise>`가 실제로 참일 때만 종료 가능
|
|
41
|
+
|
|
42
|
+
## 동작 원리
|
|
43
|
+
|
|
44
|
+
AI 에이전트가 연속 루프에서 태스크를 수행합니다. 매 반복은 **신선한 컨텍스트**로 시작합니다 — PRD와 진행 파일을 읽어 다음 할 일을 결정합니다. 에이전트는 하나의 스토리를 구현하고, 커밋하고, 진행 상황을 업데이트하고, 종료합니다. Stop hook이 종료를 가로채 프롬프트를 다시 주입합니다. 모든 스토리가 통과할 때까지 반복합니다.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
┌──────────────────────┐
|
|
48
|
+
│ /loop-plan │
|
|
49
|
+
│ 태스크 설명 │
|
|
50
|
+
└──────────┬───────────┘
|
|
51
|
+
│
|
|
52
|
+
┌──────────▼───────────┐
|
|
53
|
+
│ prd.json 생성 │
|
|
54
|
+
│ + progress.txt │
|
|
55
|
+
└──────────┬───────────┘
|
|
56
|
+
│
|
|
57
|
+
┌────────────────▼────────────────┐
|
|
58
|
+
│ 루프 실행 │
|
|
59
|
+
│ │
|
|
60
|
+
│ 1. prd.json + progress 읽기 │
|
|
61
|
+
│ 2. 다음 스토리 선택 (passes=false)│
|
|
62
|
+
│ 3. 구현 + 검증 │
|
|
63
|
+
│ 4. 커밋 + progress 업데이트 │
|
|
64
|
+
│ 5. 종료 시도 │
|
|
65
|
+
│ │ │
|
|
66
|
+
│ Stop Hook이 가로채기 │
|
|
67
|
+
│ 프롬프트 재주입 │
|
|
68
|
+
│ │ │
|
|
69
|
+
│ 1단계로 복귀 ────────────────┘
|
|
70
|
+
│ │
|
|
71
|
+
│ 모든 스토리 통과? │
|
|
72
|
+
│ → <promise>COMPLETE</promise> │
|
|
73
|
+
└─────────────────────────────────┘
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 빠른 시작
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx @graypark/loophaus install
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
이후 AI 코딩 세션에서:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
/loop-plan JWT, bcrypt, 로그인 UI를 포함한 사용자 인증 추가
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
그게 전부입니다. 인터뷰가 PRD를 생성하고, 루프를 활성화하고, 스토리별로 구현을 시작합니다.
|
|
89
|
+
|
|
90
|
+
## 커맨드
|
|
91
|
+
|
|
92
|
+
> **Bauhaus** — 형태는 기능을 따른다.
|
|
93
|
+
|
|
94
|
+
| 커맨드 | 설명 |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `/loop-plan` | 인터뷰 → PRD 생성 → 루프 시작 |
|
|
97
|
+
| `/loop` | 반복 실행 |
|
|
98
|
+
| `/loop-stop` | 루프 중단 |
|
|
99
|
+
| `/loop-pulse` | 상태 확인 |
|
|
100
|
+
|
|
101
|
+
### `/loop-plan` — 메인 진입점
|
|
102
|
+
|
|
103
|
+
태스크에 대해 인터뷰하고, 적절한 크기의 스토리로 PRD를 생성하고, 루프를 활성화한 다음 즉시 작업을 시작합니다.
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
/loop-plan 프론트엔드와 백엔드에 걸친 인증 모듈 리팩토링
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**동작 과정:**
|
|
110
|
+
|
|
111
|
+
1. 3~5개의 타겟 질문 (범위, 검증, 병렬성 등)
|
|
112
|
+
2. 적절한 크기와 순서의 스토리가 포함된 `prd.json` 생성
|
|
113
|
+
3. 반복 추적을 위한 `progress.txt` 작성
|
|
114
|
+
4. Stop hook 활성화 및 US-001 구현 시작
|
|
115
|
+
|
|
116
|
+
**즉시 실행** — "준비됐나요?" 프롬프트 생략:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
/loop-plan 사용자 API에 페이지네이션 추가, 바로 실행
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### `/loop` — 직접 루프
|
|
123
|
+
|
|
124
|
+
이미 PRD가 있거나 직접 프롬프트를 작성하고 싶을 때:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
/loop "prd.json 읽기, 다음 스토리 선택, 구현, 검증, 커밋" --max-iterations 20 --completion-promise "COMPLETE"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### `/loop-stop` — 중단
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
/loop-stop
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `/loop-pulse` — 상태 확인
|
|
137
|
+
|
|
138
|
+
현재 루프의 진행 상황, 완료된 스토리 수, 남은 반복 수를 확인합니다.
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
/loop-pulse
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## 플랫폼 지원
|
|
145
|
+
|
|
146
|
+
loophaus는 세 개의 주요 코딩 에이전트 플랫폼을 지원합니다:
|
|
147
|
+
|
|
148
|
+
| 기능 | Claude Code | Codex CLI | Kiro CLI |
|
|
149
|
+
| --- | --- | --- | --- |
|
|
150
|
+
| 자동 감지 설치 | `~/.claude/` | `~/.codex/` | `~/.kiro/` |
|
|
151
|
+
| Stop hook | bash 기반 | Node.js 기반 | bash 기반 |
|
|
152
|
+
| 루프 실행 | Skill tool | 네이티브 커맨드 | 네이티브 커맨드 |
|
|
153
|
+
| 멀티 에이전트 | Agent tool | 서브에이전트 | 서브에이전트 |
|
|
154
|
+
| 상태 파일 | `.claude/ralph-loop.local.md` | `progress.txt` | `progress.txt` |
|
|
155
|
+
|
|
156
|
+
## 설치
|
|
157
|
+
|
|
158
|
+
### 자동 감지 설치 (권장)
|
|
159
|
+
|
|
160
|
+
설치된 호스트를 자동으로 감지하여 설치합니다:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
npx @graypark/loophaus install
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### 호스트별 설치
|
|
167
|
+
|
|
168
|
+
특정 호스트만 대상으로 설치:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
npx @graypark/loophaus install --claude # Claude Code만
|
|
172
|
+
npx @graypark/loophaus install --host codex-cli # Codex CLI만
|
|
173
|
+
npx @graypark/loophaus install --kiro # Kiro CLI만
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
| 플래그 | 설명 |
|
|
177
|
+
| --- | --- |
|
|
178
|
+
| `--host <name>` | 특정 호스트 대상 지정 |
|
|
179
|
+
| `--claude` | `--host claude-code` 축약형 |
|
|
180
|
+
| `--kiro` | `--host kiro-cli` 축약형 |
|
|
181
|
+
| `--local` | 프로젝트 로컬 `.codex/`에 설치 (Codex만) |
|
|
182
|
+
| `--dry-run` | 변경 없이 미리보기 |
|
|
183
|
+
| `--force` | 기존 파일 덮어쓰기 |
|
|
184
|
+
|
|
185
|
+
<details>
|
|
186
|
+
<summary>설치되는 항목</summary>
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
~/.codex/ # (또는 ~/.claude/, ~/.kiro/)
|
|
190
|
+
├── plugins/loophaus/ # 핵심 플러그인 파일
|
|
191
|
+
├── hooks.json # Stop hook (기존 설정과 병합)
|
|
192
|
+
└── skills/
|
|
193
|
+
├── loop/ # /loop — 루프 실행
|
|
194
|
+
├── loop-plan/ # /loop-plan — PRD 생성 + 루프 시작
|
|
195
|
+
├── loop-stop/ # /loop-stop — 루프 중단
|
|
196
|
+
└── loop-pulse/ # /loop-pulse — 상태 확인
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
</details>
|
|
200
|
+
|
|
201
|
+
## CLI
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx @graypark/loophaus install # 자동 감지 설치
|
|
205
|
+
npx @graypark/loophaus status # 설치 상태 확인
|
|
206
|
+
npx @graypark/loophaus stats # 루프 실행 통계
|
|
207
|
+
npx @graypark/loophaus uninstall # 제거
|
|
208
|
+
npx @graypark/loophaus --version # 버전 확인
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 아키텍처
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
loophaus/
|
|
215
|
+
├── .claude-plugin/plugin.json # Claude Code 마켓플레이스 매니페스트
|
|
216
|
+
├── bin/
|
|
217
|
+
│ ├── loophaus.mjs # CLI 진입점
|
|
218
|
+
│ ├── install.mjs # 크로스 플랫폼 설치기
|
|
219
|
+
│ └── uninstall.mjs # 제거기
|
|
220
|
+
├── hooks/
|
|
221
|
+
│ └── stop-hook.mjs # 핵심 루프 엔진 (Node.js)
|
|
222
|
+
├── commands/
|
|
223
|
+
│ ├── loop.md # /loop 커맨드
|
|
224
|
+
│ ├── loop-plan.md # /loop-plan 커맨드
|
|
225
|
+
│ ├── loop-stop.md # /loop-stop 커맨드
|
|
226
|
+
│ ├── loop-pulse.md # /loop-pulse 커맨드
|
|
227
|
+
│ └── help.md # /help 커맨드
|
|
228
|
+
├── platforms/ # 호스트별 어댑터
|
|
229
|
+
├── store/ # 상태 저장소
|
|
230
|
+
├── core/ # 핵심 로직
|
|
231
|
+
├── skills/
|
|
232
|
+
│ ├── ralph-interview/SKILL.md # Codex: 인터랙티브 커맨드 생성기
|
|
233
|
+
│ ├── ralph-orchestrator/SKILL.md # Codex: 멀티 에이전트 패턴
|
|
234
|
+
│ ├── ralph-claude-interview/SKILL.md # Claude: 인터뷰 + Skill tool 호출
|
|
235
|
+
│ ├── ralph-claude-loop/SKILL.md # Claude: PRD 기반 루프
|
|
236
|
+
│ ├── ralph-claude-cancel/SKILL.md # Claude: 루프 취소
|
|
237
|
+
│ └── ralph-claude-orchestrator/SKILL.md # Claude: Agent tool 패턴
|
|
238
|
+
├── lib/
|
|
239
|
+
│ ├── paths.mjs # 크로스 플랫폼 경로
|
|
240
|
+
│ ├── state.mjs # 루프 상태 관리
|
|
241
|
+
│ └── stop-hook-core.mjs # 테스트 가능한 hook 로직
|
|
242
|
+
└── tests/ # 36개 테스트 케이스 (vitest)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## PRD 포맷
|
|
246
|
+
|
|
247
|
+
loophaus는 **ralph-skills 호환** `prd.json` 포맷을 사용합니다:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"project": "MyApp",
|
|
252
|
+
"branchName": "ralph/auth-system",
|
|
253
|
+
"description": "JWT 인증 시스템과 로그인 UI",
|
|
254
|
+
"userStories": [
|
|
255
|
+
{
|
|
256
|
+
"id": "US-001",
|
|
257
|
+
"title": "password hash를 포함한 users 테이블 추가",
|
|
258
|
+
"description": "개발자로서, 인증을 위한 사용자 저장소가 필요합니다",
|
|
259
|
+
"acceptanceCriteria": [
|
|
260
|
+
"email, password_hash 컬럼이 있는 Users 테이블",
|
|
261
|
+
"마이그레이션 정상 실행",
|
|
262
|
+
"타입 체크 통과"
|
|
263
|
+
],
|
|
264
|
+
"priority": 1,
|
|
265
|
+
"passes": false,
|
|
266
|
+
"notes": ""
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
각 스토리는 **한 번의 반복**(하나의 컨텍스트 윈도우)에서 완료할 수 있는 크기입니다. 의존성은 priority 순으로 정렬됩니다.
|
|
273
|
+
|
|
274
|
+
## ralph-codex에서 마이그레이션
|
|
275
|
+
|
|
276
|
+
기존에 `ralph-codex`를 사용하고 있었다면, loophaus가 자동으로 마이그레이션을 처리합니다:
|
|
277
|
+
|
|
278
|
+
- **상태 파일 호환** — 기존 `prd.json`과 `progress.txt`를 그대로 사용 가능
|
|
279
|
+
- **자동 감지** — 설치 시 기존 ralph-codex 설정을 감지하고 loophaus 포맷으로 업그레이드
|
|
280
|
+
- **커맨드 매핑** — 기존 `/ralph-interview` → `/loop-plan`, `/ralph-loop` → `/loop`, `/cancel-ralph` → `/loop-stop`
|
|
281
|
+
|
|
282
|
+
마이그레이션 방법:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
# 기존 ralph-codex 제거
|
|
286
|
+
npx @graypark/ralph-codex uninstall
|
|
287
|
+
|
|
288
|
+
# loophaus 설치 (기존 상태 파일 자동 인식)
|
|
289
|
+
npx @graypark/loophaus install
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
기존 PRD 파일은 수정 없이 그대로 동작합니다. `progress.txt`에 축적된 학습 내용도 보존됩니다.
|
|
293
|
+
|
|
294
|
+
## 생태계 호환성
|
|
295
|
+
|
|
296
|
+
loophaus는 기존 Ralph 도구들과 호환됩니다:
|
|
297
|
+
|
|
298
|
+
| 도구 | 호환성 |
|
|
299
|
+
| --- | --- |
|
|
300
|
+
| `ralph-skills:prd` | 동일한 `prd.json` 포맷 — 거기서 PRD를 생성하고 여기서 루프 실행 |
|
|
301
|
+
| `ralph-skills:ralph` | 동일한 `progress.txt`, `passes` 추적, `COMPLETE` promise |
|
|
302
|
+
| 공식 `ralph-loop` 플러그인 | PRD 파일이 양쪽 stop hook에서 동작 |
|
|
303
|
+
| `snarktank/ralph` | 호환되는 PRD 구조 및 반복 패턴 |
|
|
304
|
+
|
|
305
|
+
## 멀티 에이전트 오케스트레이션
|
|
306
|
+
|
|
307
|
+
여러 서비스에 걸치거나 광범위한 탐색이 필요한 태스크에 사용합니다:
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
Phase 1 — 병렬 스캔 (3 에이전트):
|
|
311
|
+
├── 에이전트 "fe-scan": frontend/** 인증 취약점 탐색
|
|
312
|
+
├── 에이전트 "be-scan": backend/** 인증 취약점 탐색
|
|
313
|
+
└── 에이전트 "db-scan": 스키마의 누락된 제약조건 검토
|
|
314
|
+
|
|
315
|
+
Phase 2 — 순차 수정 (루프):
|
|
316
|
+
└── 병합된 발견사항 읽기 → 스토리별로 수정 구현
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
인터뷰 과정에서 병렬성 잠재력을 점수 매트릭스로 자동 평가합니다.
|
|
320
|
+
|
|
321
|
+
5가지 오케스트레이션 패턴:
|
|
322
|
+
|
|
323
|
+
| 패턴 | 사용 시점 |
|
|
324
|
+
| --- | --- |
|
|
325
|
+
| 병렬 탐색 → 순차 구현 | 대규모 코드베이스 조사 후 수정 |
|
|
326
|
+
| 소유권 분할 | 멀티 서비스 변경 (fe + be + auth) |
|
|
327
|
+
| Fan-Out / Fan-In | 병렬 감사 (보안 + 성능 + 접근성) |
|
|
328
|
+
| 정찰 후 실행 | 익숙하지 않은 코드베이스 |
|
|
329
|
+
| 체크포인트가 있는 파이프라인 | 다단계 변환 |
|
|
330
|
+
|
|
331
|
+
## 업데이트
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
npx @graypark/loophaus install --force
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## 제거
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
npx @graypark/loophaus uninstall
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## 개발
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
npm install && npm test # 36개 테스트
|
|
347
|
+
npx vitest # watch 모드
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## 라이선스
|
|
351
|
+
|
|
352
|
+
MIT
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
<p align="center">
|
|
357
|
+
<a href="https://docs.anthropic.com/en/docs/claude-code">Claude Code</a>, <a href="https://github.com/openai/codex">Codex CLI</a>, <a href="https://kiro.dev">Kiro CLI</a>를 위해 만들어졌습니다
|
|
358
|
+
</p>
|
package/README.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
[English](README.md) | [한국어](README.ko.md)
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/vcz-Gray/loophaus/main/assets/loophaus-banner.svg" alt="loophaus" width="600" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@graypark/loophaus"><img src="https://img.shields.io/npm/v/@graypark/loophaus.svg?style=flat-square&color=blue" alt="npm version" /></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@graypark/loophaus"><img src="https://img.shields.io/npm/dm/@graypark/loophaus.svg?style=flat-square&color=green" alt="npm downloads" /></a>
|
|
10
|
+
<a href="https://github.com/vcz-Gray/loophaus/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="license" /></a>
|
|
11
|
+
<img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg?style=flat-square" alt="node version" />
|
|
12
|
+
<img src="https://img.shields.io/badge/platform-Claude%20Code%20%7C%20Codex%20CLI%20%7C%20Kiro%20CLI-purple.svg?style=flat-square" alt="platform" />
|
|
13
|
+
<img src="https://img.shields.io/badge/tests-36%20passing-brightgreen.svg?style=flat-square" alt="tests" />
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<h3 align="center">Control plane for coding agents — iterative dev loops across Claude Code, Codex CLI, and Kiro CLI.</h3>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<sub>Based on <a href="https://ghuntley.com/ralph/">Geoffrey Huntley's Ralph Wiggum technique</a></sub>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Why loophaus?
|
|
25
|
+
|
|
26
|
+
AI coding agents struggle with fundamental problems that get worse over long sessions:
|
|
27
|
+
|
|
28
|
+
| Problem | What happens |
|
|
29
|
+
|---------|-------------|
|
|
30
|
+
| **Context rot** | Long conversations accumulate noise, the agent gets confused |
|
|
31
|
+
| **No checkpoints** | All-or-nothing execution — can't resume after interruption |
|
|
32
|
+
| **Lost learnings** | Previous iterations' insights overwritten by new context |
|
|
33
|
+
| **Completion ambiguity** | Agent says "done" but tests still fail |
|
|
34
|
+
| **Platform lock-in** | Techniques that work in one agent don't transfer to others |
|
|
35
|
+
|
|
36
|
+
loophaus solves this:
|
|
37
|
+
|
|
38
|
+
- **Fresh context per iteration** — Each cycle reads PRD + progress from disk, zero degradation
|
|
39
|
+
- **Git-enforced safety** — Atomic commits per story, rollback at any point
|
|
40
|
+
- **Append-only learnings** — `progress.txt` accumulates knowledge across iterations
|
|
41
|
+
- **Test-verified completion** — Agent can only exit when `<promise>COMPLETE</promise>` is genuinely true
|
|
42
|
+
- **Universal stop hook** — One Node.js hook works across Claude Code, Codex CLI, and Kiro CLI
|
|
43
|
+
|
|
44
|
+
## How it works
|
|
45
|
+
|
|
46
|
+
An AI agent works on a task in a continuous loop. Each iteration starts with fresh context — reading the PRD and progress files to decide what to do next. The agent implements one story, commits, updates progress, and exits. The stop hook intercepts the exit and re-injects the prompt. Repeat until all stories pass.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
┌──────────────────────┐
|
|
50
|
+
│ /loop-plan │
|
|
51
|
+
│ Describe your task │
|
|
52
|
+
└──────────┬───────────┘
|
|
53
|
+
│
|
|
54
|
+
┌──────────▼───────────┐
|
|
55
|
+
│ Generate prd.json │
|
|
56
|
+
│ + progress.txt │
|
|
57
|
+
└──────────┬───────────┘
|
|
58
|
+
│
|
|
59
|
+
┌────────────────▼────────────────┐
|
|
60
|
+
│ /loop │
|
|
61
|
+
│ │
|
|
62
|
+
│ 1. Read prd.json + progress │
|
|
63
|
+
│ 2. Pick next story (passes=false)│
|
|
64
|
+
│ 3. Implement + verify │
|
|
65
|
+
│ 4. Commit + update progress │
|
|
66
|
+
│ 5. Exit attempt │
|
|
67
|
+
│ │ │
|
|
68
|
+
│ Stop Hook intercepts │
|
|
69
|
+
│ Re-injects prompt │
|
|
70
|
+
│ │ │
|
|
71
|
+
│ Back to step 1 ──────────────┘
|
|
72
|
+
│ │
|
|
73
|
+
│ All stories pass? │
|
|
74
|
+
│ → <promise>COMPLETE</promise> │
|
|
75
|
+
│ │
|
|
76
|
+
│ /loop-pulse → check status │
|
|
77
|
+
│ /loop-stop → cancel anytime │
|
|
78
|
+
└─────────────────────────────────┘
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Quick Start
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx @graypark/loophaus install
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The installer auto-detects your host (Claude Code, Codex CLI, or Kiro CLI) and sets up everything — stop hook, commands, and skills.
|
|
88
|
+
|
|
89
|
+
Then in your AI coding session:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
/loop-plan Add user authentication with JWT, bcrypt, and login UI
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
That's it. The interview generates a PRD, activates the loop, and starts implementing story by story.
|
|
96
|
+
|
|
97
|
+
## Commands
|
|
98
|
+
|
|
99
|
+
| Command | Description |
|
|
100
|
+
|---------|-------------|
|
|
101
|
+
| `/loop-plan` | Interactive interview — asks targeted questions, generates PRD, activates loop |
|
|
102
|
+
| `/loop` | Start iterative dev loop directly (when you already have a PRD or custom prompt) |
|
|
103
|
+
| `/loop-stop` | Stop the active loop immediately |
|
|
104
|
+
| `/loop-pulse` | Check current loop status, iteration count, and progress |
|
|
105
|
+
|
|
106
|
+
## Platform Support
|
|
107
|
+
|
|
108
|
+
| | Claude Code | Codex CLI | Kiro CLI |
|
|
109
|
+
|---|---|---|---|
|
|
110
|
+
| **Stop Hook** | Node.js | Node.js | Node.js |
|
|
111
|
+
| **Install target** | Plugin cache | `hooks.json` | `agents/` + `steering/` |
|
|
112
|
+
| **Commands** | `/reload-plugins` | native | steering manual mode |
|
|
113
|
+
| **Multi-agent** | Agent tool | subprocesses | steering agents |
|
|
114
|
+
|
|
115
|
+
All three platforms share the same core engine (`core/engine.mjs`) and state store (`store/state-store.mjs`). Platform-specific adapters handle the differences.
|
|
116
|
+
|
|
117
|
+
## Installation
|
|
118
|
+
|
|
119
|
+
### Auto-detect (recommended)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx @graypark/loophaus install
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Specify host
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npx @graypark/loophaus install --host claude-code
|
|
129
|
+
npx @graypark/loophaus install --host codex-cli
|
|
130
|
+
npx @graypark/loophaus install --host kiro-cli
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Flags
|
|
134
|
+
|
|
135
|
+
| Flag | Description |
|
|
136
|
+
|------|-------------|
|
|
137
|
+
| `--force` | Overwrite existing installation |
|
|
138
|
+
| `--dry-run` | Preview changes without writing files |
|
|
139
|
+
| `--local` | Install to project directory instead of global (Codex CLI only) |
|
|
140
|
+
|
|
141
|
+
## CLI
|
|
142
|
+
|
|
143
|
+
loophaus ships a standalone CLI for management tasks:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
loophaus install # Install to detected host
|
|
147
|
+
loophaus status # Show current loop state and active host
|
|
148
|
+
loophaus stats # Iteration history and completion metrics
|
|
149
|
+
loophaus uninstall # Clean removal from all hosts
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Or via npx:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npx @graypark/loophaus install
|
|
156
|
+
npx @graypark/loophaus status
|
|
157
|
+
npx @graypark/loophaus stats
|
|
158
|
+
npx @graypark/loophaus uninstall
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Architecture
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
loophaus/
|
|
165
|
+
├── bin/
|
|
166
|
+
│ ├── loophaus.mjs # CLI entry point
|
|
167
|
+
│ ├── install.mjs # Cross-platform installer
|
|
168
|
+
│ └── uninstall.mjs # Clean uninstaller
|
|
169
|
+
├── core/
|
|
170
|
+
│ ├── engine.mjs # Core loop engine (shared)
|
|
171
|
+
│ ├── event-logger.mjs # Iteration event tracking
|
|
172
|
+
│ └── loop.schema.json # PRD validation schema
|
|
173
|
+
├── store/
|
|
174
|
+
│ └── state-store.mjs # Loop state persistence
|
|
175
|
+
├── platforms/
|
|
176
|
+
│ ├── claude-code/
|
|
177
|
+
│ │ ├── adapter.mjs # Claude Code platform adapter
|
|
178
|
+
│ │ └── installer.mjs # Plugin cache installer
|
|
179
|
+
│ ├── codex-cli/
|
|
180
|
+
│ │ ├── adapter.mjs # Codex CLI platform adapter
|
|
181
|
+
│ │ └── installer.mjs # hooks.json installer
|
|
182
|
+
│ └── kiro-cli/
|
|
183
|
+
│ ├── adapter.mjs # Kiro CLI platform adapter
|
|
184
|
+
│ └── installer.mjs # agents/ + steering/ installer
|
|
185
|
+
├── hooks/
|
|
186
|
+
│ ├── stop-hook.mjs # Universal stop hook (Node.js)
|
|
187
|
+
│ └── hooks.json # Hook configuration template
|
|
188
|
+
├── commands/
|
|
189
|
+
│ ├── loop-plan.md # /loop-plan command definition
|
|
190
|
+
│ ├── loop.md # /loop command definition
|
|
191
|
+
│ ├── loop-stop.md # /loop-stop command definition
|
|
192
|
+
│ ├── loop-pulse.md # /loop-pulse command definition
|
|
193
|
+
│ └── help.md # /help command definition
|
|
194
|
+
├── skills/
|
|
195
|
+
│ ├── ralph-interview/ # Interactive PRD generator
|
|
196
|
+
│ ├── ralph-orchestrator/ # Multi-agent patterns
|
|
197
|
+
│ ├── ralph-claude-interview/ # Claude Code interview + Skill tool
|
|
198
|
+
│ ├── ralph-claude-loop/ # Claude Code PRD-driven loop
|
|
199
|
+
│ ├── ralph-claude-cancel/ # Claude Code cancel
|
|
200
|
+
│ └── ralph-claude-orchestrator/# Claude Code Agent tool patterns
|
|
201
|
+
├── lib/
|
|
202
|
+
│ ├── paths.mjs # Cross-platform path resolution
|
|
203
|
+
│ ├── state.mjs # Legacy state management
|
|
204
|
+
│ └── stop-hook-core.mjs # Testable hook logic
|
|
205
|
+
├── .claude-plugin/
|
|
206
|
+
│ └── plugin.json # Claude Code marketplace manifest
|
|
207
|
+
└── tests/ # 36 test cases (vitest)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## PRD Format
|
|
211
|
+
|
|
212
|
+
loophaus uses a `prd.json` format compatible with the ralph-skills ecosystem:
|
|
213
|
+
|
|
214
|
+
```json
|
|
215
|
+
{
|
|
216
|
+
"project": "MyApp",
|
|
217
|
+
"branchName": "loop/auth-system",
|
|
218
|
+
"description": "JWT authentication with login UI",
|
|
219
|
+
"userStories": [
|
|
220
|
+
{
|
|
221
|
+
"id": "US-001",
|
|
222
|
+
"title": "Add users table with password hash",
|
|
223
|
+
"description": "As a developer, I need user storage for auth",
|
|
224
|
+
"acceptanceCriteria": [
|
|
225
|
+
"Users table with email, password_hash columns",
|
|
226
|
+
"Migration runs successfully",
|
|
227
|
+
"Typecheck passes"
|
|
228
|
+
],
|
|
229
|
+
"priority": 1,
|
|
230
|
+
"passes": false,
|
|
231
|
+
"notes": ""
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Each story is sized to complete in one iteration (one context window). Dependencies are ordered by priority. The loop engine picks the next story where `passes` is `false` and works on it until verification succeeds.
|
|
238
|
+
|
|
239
|
+
## Migrating from ralph-codex
|
|
240
|
+
|
|
241
|
+
`@graypark/ralph-codex` has been deprecated in favor of `@graypark/loophaus`. The migration is straightforward:
|
|
242
|
+
|
|
243
|
+
1. **Install loophaus** — it replaces ralph-codex entirely:
|
|
244
|
+
```bash
|
|
245
|
+
npx @graypark/loophaus install --force
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
2. **State files auto-migrate** — Existing `prd.json` and `progress.txt` files are fully compatible. No changes needed.
|
|
249
|
+
|
|
250
|
+
3. **Command mapping:**
|
|
251
|
+
|
|
252
|
+
| ralph-codex | loophaus |
|
|
253
|
+
|-------------|----------|
|
|
254
|
+
| `/ralph-interview` | `/loop-plan` |
|
|
255
|
+
| `/ralph-loop` | `/loop` |
|
|
256
|
+
| `/cancel-ralph` | `/loop-stop` |
|
|
257
|
+
| (none) | `/loop-pulse` |
|
|
258
|
+
|
|
259
|
+
4. **Uninstall the old package** (optional):
|
|
260
|
+
```bash
|
|
261
|
+
npx @graypark/ralph-codex uninstall
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Development
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
git clone https://github.com/vcz-Gray/loophaus.git
|
|
268
|
+
cd loophaus
|
|
269
|
+
npm install
|
|
270
|
+
npm test # 36 test cases
|
|
271
|
+
npx vitest # watch mode
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
<p align="center">
|
|
281
|
+
Built for <a href="https://docs.anthropic.com/en/docs/claude-code">Claude Code</a>, <a href="https://github.com/openai/codex">Codex CLI</a>, and <a href="https://kiro.dev">Kiro CLI</a>
|
|
282
|
+
</p>
|
package/bin/install.mjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Backward-compat wrapper — delegates to bin/loophaus.mjs
|
|
3
|
+
|
|
4
|
+
import { resolve, dirname } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const loophausCli = resolve(dirname(__filename), "loophaus.mjs");
|
|
9
|
+
|
|
10
|
+
await import(loophausCli);
|