@planningo/duul 1.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/LICENSE +21 -0
- package/README.ko.md +438 -0
- package/README.md +463 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +18 -0
- package/build/prompts/code-review-system.d.ts +9 -0
- package/build/prompts/code-review-system.js +116 -0
- package/build/prompts/execution-partition-system.d.ts +11 -0
- package/build/prompts/execution-partition-system.js +76 -0
- package/build/prompts/plan-review-system.d.ts +29 -0
- package/build/prompts/plan-review-system.js +175 -0
- package/build/schemas/code-review.d.ts +514 -0
- package/build/schemas/code-review.js +175 -0
- package/build/schemas/common.d.ts +118 -0
- package/build/schemas/common.js +64 -0
- package/build/schemas/execution-partition.d.ts +597 -0
- package/build/schemas/execution-partition.js +107 -0
- package/build/schemas/plan-review.d.ts +523 -0
- package/build/schemas/plan-review.js +175 -0
- package/build/services/filesystem-tools.d.ts +6 -0
- package/build/services/filesystem-tools.js +39 -0
- package/build/services/filesystem.d.ts +69 -0
- package/build/services/filesystem.js +609 -0
- package/build/services/pricing.d.ts +8 -0
- package/build/services/pricing.js +105 -0
- package/build/services/providers/anthropic.d.ts +28 -0
- package/build/services/providers/anthropic.js +431 -0
- package/build/services/providers/google.d.ts +28 -0
- package/build/services/providers/google.js +358 -0
- package/build/services/providers/openai.d.ts +22 -0
- package/build/services/providers/openai.js +395 -0
- package/build/services/providers/types.d.ts +82 -0
- package/build/services/providers/types.js +1 -0
- package/build/services/review-gates.d.ts +83 -0
- package/build/services/review-gates.js +200 -0
- package/build/services/review-limits.d.ts +36 -0
- package/build/services/review-limits.js +65 -0
- package/build/services/reviewer.d.ts +30 -0
- package/build/services/reviewer.js +243 -0
- package/build/services/usage-logger.d.ts +2 -0
- package/build/services/usage-logger.js +42 -0
- package/build/tools/code-review.d.ts +2 -0
- package/build/tools/code-review.js +178 -0
- package/build/tools/execution-partition.d.ts +2 -0
- package/build/tools/execution-partition.js +146 -0
- package/build/tools/plan-review.d.ts +2 -0
- package/build/tools/plan-review.js +183 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Planningo
|
|
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,438 @@
|
|
|
1
|
+
# DUUL
|
|
2
|
+
|
|
3
|
+
**D**ual-phase **U**pfront-plan & **U**nit-verify **L**oop — LLM을 개발 계획 및 코드의 리뷰어로 활용하는 MCP 서버. OpenAI, Anthropic, Google, OpenRouter 및 OpenAI 호환 프로바이더를 지원합니다.
|
|
4
|
+
|
|
5
|
+
> [English README](./README.md)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 개요
|
|
10
|
+
|
|
11
|
+
DUUL은 [Model Context Protocol](https://modelcontextprotocol.io/) 서버로, MCP 클라이언트(Claude Desktop, Claude Code 등)가 외부 LLM에 구조화된 리뷰를 요청할 수 있게 합니다. **2단계 리뷰 루프**를 구현합니다:
|
|
12
|
+
|
|
13
|
+
1. **Upfront-plan 리뷰** -- 시니어 아키텍트 페르소나가 코드 작성 전에 구현 계획을 검토합니다.
|
|
14
|
+
2. **Unit-verify 리뷰** -- 엄격한 QA 엔지니어 페르소나가 승인된 계획 대비 코드를 검토합니다.
|
|
15
|
+
|
|
16
|
+
호출 에이전트는 각 단계에서 `APPROVE` 판정을 받을 때까지 리뷰어와 반복하고, 이후 다음 단계로 진행합니다. 이를 통해 한 LLM이 다른 LLM의 작업을 검증하는 크로스 모델 리뷰 워크플로우를 만듭니다.
|
|
17
|
+
|
|
18
|
+
**토큰 효율 설계:** 1단계(계획 작성)는 Sonnet급 서브에이전트에 위임합니다 — 리뷰어가 계획의 문제를 잡아주므로 충분합니다. 2단계(코드 구현)는 최대 코드 품질을 위해 Opus에서 실행됩니다. 이를 통해 1단계 토큰 비용이 약 80% 절감됩니다.
|
|
19
|
+
|
|
20
|
+
리뷰어는 **워크스페이스 인식 파일 탐색** 기능을 갖추고 있어, `workspace_root`가 주어지면 7개의 내장 도구(파일 읽기, 코드 검색, 디렉토리 목록 등)를 사용하여 정보에 기반한 리뷰 결정을 내립니다.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 설치
|
|
25
|
+
|
|
26
|
+
### 사전 요구 사항
|
|
27
|
+
|
|
28
|
+
- **Node.js 20+**
|
|
29
|
+
- 지원되는 프로바이더 중 하나 이상의 API 키 (OpenAI, Anthropic, Google 또는 OpenRouter)
|
|
30
|
+
- **권장: [ripgrep](https://github.com/BurntSushi/ripgrep) (`rg`)** — 리뷰어의 워크스페이스 탐색 시 더 빠른 코드 검색을 위해. 미설치 시 `git grep` 또는 `grep`으로 폴백되며, 대규모 코드베이스에서 상당히 느려집니다.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# macOS
|
|
34
|
+
brew install ripgrep
|
|
35
|
+
|
|
36
|
+
# Ubuntu / Debian
|
|
37
|
+
sudo apt install ripgrep
|
|
38
|
+
|
|
39
|
+
# Windows (scoop)
|
|
40
|
+
scoop install ripgrep
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### npm에서 설치 (권장)
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
claude mcp add duul \
|
|
47
|
+
-e OPENAI_API_KEY=sk-... \
|
|
48
|
+
-- npx -y @planningo/duul
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
또는 프로젝트 레벨 `.mcp.json` 파일에 수동으로 추가합니다:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"mcpServers": {
|
|
56
|
+
"duul": {
|
|
57
|
+
"command": "npx",
|
|
58
|
+
"args": ["-y", "@planningo/duul"],
|
|
59
|
+
"env": {
|
|
60
|
+
"OPENAI_API_KEY": "sk-..."
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Claude Desktop에서 설정
|
|
68
|
+
|
|
69
|
+
`claude_desktop_config.json`에 다음을 추가합니다:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"duul": {
|
|
75
|
+
"command": "npx",
|
|
76
|
+
"args": ["-y", "@planningo/duul"],
|
|
77
|
+
"env": {
|
|
78
|
+
"OPENAI_API_KEY": "sk-...",
|
|
79
|
+
"REVIEW_PROVIDER": "openai"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 소스에서 빌드 (개발용)
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
git clone https://github.com/Planningo/duul.git
|
|
90
|
+
cd duul
|
|
91
|
+
npm install
|
|
92
|
+
npm run build
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
그런 다음 MCP 설정에서 `npx -y @planningo/duul` 대신 `node /absolute/path/to/duul/build/index.js`를 사용하세요.
|
|
96
|
+
|
|
97
|
+
설치 후, 자연어로 요청하면 됩니다: **"DUUL로 개발 진행해줘"** 또는 **"run DUUL"**.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 설정
|
|
102
|
+
|
|
103
|
+
### 환경 변수
|
|
104
|
+
|
|
105
|
+
모든 설정은 MCP `env` 블록을 통해 전달합니다 (`.env` 파일이 아님).
|
|
106
|
+
|
|
107
|
+
#### 프로바이더 & 모델
|
|
108
|
+
|
|
109
|
+
| 변수 | 필수 | 기본값 | 설명 |
|
|
110
|
+
|------|------|--------|------|
|
|
111
|
+
| `REVIEW_PROVIDER` | 아니오 | `openai` | 프로바이더: `openai`, `anthropic`, `google`, `openrouter`, `compatible` |
|
|
112
|
+
| `REVIEW_MODEL` | 아니오 | 프로바이더 기본값 | 모델 ID (예: `gpt-5.4`, `claude-opus-4-20250514`, `gemini-3.1-pro-preview`) |
|
|
113
|
+
| `OPENAI_API_KEY` | 조건부 | -- | `openai` 또는 `compatible` 프로바이더 사용 시 필수 |
|
|
114
|
+
| `ANTHROPIC_API_KEY` | 조건부 | -- | `anthropic` 프로바이더 사용 시 필수 |
|
|
115
|
+
| `GOOGLE_API_KEY` | 조건부 | -- | `google` 프로바이더 사용 시 필수 |
|
|
116
|
+
| `OPENROUTER_API_KEY` | 조건부 | -- | `openrouter` 프로바이더 사용 시 필수 |
|
|
117
|
+
| `REVIEW_API_KEY` | 아니오 | -- | `compatible` 프로바이더용 API 키 (`OPENAI_API_KEY`로 폴백) |
|
|
118
|
+
|
|
119
|
+
프로바이더별 기본 모델:
|
|
120
|
+
- **OpenAI:** `gpt-5.4`
|
|
121
|
+
- **Anthropic:** `claude-opus-4-20250514`
|
|
122
|
+
- **Google:** `gemini-3.1-pro-preview`
|
|
123
|
+
|
|
124
|
+
#### 반복 제한
|
|
125
|
+
|
|
126
|
+
각 단계에는 최대 리뷰 반복 횟수가 있습니다. 초과하면 서버가 `requires_human_review: true`를 반환하여 사람에게 에스컬레이션합니다.
|
|
127
|
+
|
|
128
|
+
| 변수 | 기본값 | 설명 |
|
|
129
|
+
|------|--------|------|
|
|
130
|
+
| `MAX_PLAN_REVIEW_ITERATIONS` | `7` | 사람 개입 전 최대 계획 리뷰 횟수 |
|
|
131
|
+
| `MAX_CODE_REVIEW_ITERATIONS` | `7` | 사람 개입 전 최대 코드 리뷰 횟수 |
|
|
132
|
+
| `MAX_PARTITION_ITERATIONS` | `5` | 사람 개입 전 최대 실행 분할 횟수 |
|
|
133
|
+
|
|
134
|
+
**예시: 복잡한 프로젝트를 위한 넉넉한 제한**
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"mcpServers": {
|
|
139
|
+
"duul": {
|
|
140
|
+
"command": "node",
|
|
141
|
+
"args": ["/absolute/path/to/duul/build/index.js"],
|
|
142
|
+
"env": {
|
|
143
|
+
"OPENAI_API_KEY": "sk-...",
|
|
144
|
+
"MAX_PLAN_REVIEW_ITERATIONS": "10",
|
|
145
|
+
"MAX_CODE_REVIEW_ITERATIONS": "10",
|
|
146
|
+
"MAX_PARTITION_ITERATIONS": "7"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**예시: 빠른 작업을 위한 타이트한 제한**
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"env": {
|
|
158
|
+
"MAX_PLAN_REVIEW_ITERATIONS": "3",
|
|
159
|
+
"MAX_CODE_REVIEW_ITERATIONS": "3"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### 요청별 오버라이드
|
|
165
|
+
|
|
166
|
+
개별 리뷰 호출에서 `max_review_iterations` 입력 파라미터로 반복 제한을 오버라이드할 수 있습니다 (범위: 1–20). 환경 변수보다 우선합니다.
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"plan": "...",
|
|
171
|
+
"max_review_iterations": 3,
|
|
172
|
+
"iteration_count": 1
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**우선순위:** 요청별 `max_review_iterations` > 환경 변수 > 기본값.
|
|
177
|
+
|
|
178
|
+
### 요청별 리뷰어 설정
|
|
179
|
+
|
|
180
|
+
각 리뷰 요청에 `reviewer_config` 객체를 포함하여 프로바이더와 모델을 오버라이드할 수 있습니다:
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"reviewer_config": {
|
|
185
|
+
"provider": "anthropic",
|
|
186
|
+
"model": "claude-opus-4-20250514",
|
|
187
|
+
"temperature": 0.3,
|
|
188
|
+
"top_p": 0.2
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
| 필드 | 타입 | 기본값 | 설명 |
|
|
194
|
+
|------|------|--------|------|
|
|
195
|
+
| `provider` | `string` | env / `openai` | `openai`, `anthropic`, `google`, `openrouter`, `compatible` |
|
|
196
|
+
| `model` | `string` | env / 프로바이더 기본값 | 모델 식별자 |
|
|
197
|
+
| `base_url` | `string` | -- | 커스텀 API 엔드포인트 (`compatible` 또는 자체 호스팅용) |
|
|
198
|
+
| `api_key` | `string` | -- | 요청별 API 키 (환경 변수 오버라이드) |
|
|
199
|
+
| `temperature` | `number` | `0.2` | 샘플링 온도 (0–2) |
|
|
200
|
+
| `top_p` | `number` | `0.1` | 핵 샘플링 (0–1) |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 작동 방식
|
|
205
|
+
|
|
206
|
+
### 전체 리뷰 루프
|
|
207
|
+
|
|
208
|
+
```mermaid
|
|
209
|
+
flowchart TD
|
|
210
|
+
Start(["사용자: 'DUUL로 개발 진행해줘'"]):::trigger --> Plan["구현 계획 작성\n(Sonnet 서브에이전트)"]:::sonnet
|
|
211
|
+
|
|
212
|
+
subgraph Phase1["1단계: 계획 핑퐁 — Sonnet (최대 7회 반복)"]
|
|
213
|
+
Plan --> PR["request_plan_review"]
|
|
214
|
+
PR --> IterCheck1{반복\n제한?}
|
|
215
|
+
IterCheck1 -- "초과" --> Human1["⏸ requires_human_review: true"]
|
|
216
|
+
IterCheck1 -- "제한 내" --> Review1[/"LLM 리뷰어\n(시니어 아키텍트)"/]
|
|
217
|
+
Review1 --> Status1{review_status?}
|
|
218
|
+
Status1 -- "incomplete" --> Narrow1["범위 축소 후 재시도\n(artifact_refs 줄이기)"]
|
|
219
|
+
Narrow1 --> PR
|
|
220
|
+
Status1 -- "completed" --> Verdict1{verdict?}
|
|
221
|
+
Verdict1 -- "REVISE" --> Fix1["blocking_issues 기반\n계획 수정"]
|
|
222
|
+
Fix1 --> PR
|
|
223
|
+
Verdict1 -- "APPROVE" --> PlanOK(["계획 승인 ✓"]):::approved
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
PlanOK --> Impl["코드 구현\n(실제 파일 작성)"]:::opus
|
|
227
|
+
|
|
228
|
+
subgraph Phase2["2단계: 코드 핑퐁 — Opus (최대 7회 반복)"]
|
|
229
|
+
Impl --> CR["request_code_review\n+ approved_plan"]
|
|
230
|
+
CR --> IterCheck2{반복\n제한?}
|
|
231
|
+
IterCheck2 -- "초과" --> Human2["⏸ requires_human_review: true"]
|
|
232
|
+
IterCheck2 -- "제한 내" --> Review2[/"LLM 리뷰어\n(엄격한 QA 엔지니어)"/]
|
|
233
|
+
Review2 --> Status2{review_status?}
|
|
234
|
+
Status2 -- "incomplete" --> Narrow2["범위 축소 후 재시도"]
|
|
235
|
+
Narrow2 --> CR
|
|
236
|
+
Status2 -- "completed" --> Verdict2{verdict?}
|
|
237
|
+
Verdict2 -- "REVISE" --> Fix2["blocking_issues +\nvulnerabilities 기반 코드 수정"]
|
|
238
|
+
Fix2 --> CR
|
|
239
|
+
Verdict2 -- "APPROVE" --> CodeOK(["코드 승인 ✓"]):::approved
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
CodeOK --> Done(["완료: 계획 승인 & 코드 리뷰 통과"]):::done
|
|
243
|
+
|
|
244
|
+
classDef trigger fill:#e1f5fe,stroke:#0288d1,color:#01579b
|
|
245
|
+
classDef approved fill:#e8f5e9,stroke:#388e3c,color:#1b5e20
|
|
246
|
+
classDef done fill:#c8e6c9,stroke:#2e7d32,color:#1b5e20,stroke-width:2px
|
|
247
|
+
classDef sonnet fill:#fff3e0,stroke:#f57c00,color:#e65100
|
|
248
|
+
classDef opus fill:#ede7f6,stroke:#7b1fa2,color:#4a148c
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 선택: 실행 파티션 (멀티 에이전트)
|
|
252
|
+
|
|
253
|
+
1단계 승인 후, 대규모 계획은 2단계 전에 병렬화 가능한 서브태스크로 분할할 수 있습니다:
|
|
254
|
+
|
|
255
|
+
```mermaid
|
|
256
|
+
flowchart LR
|
|
257
|
+
PlanOK(["계획 승인"]) --> EP["request_execution_partition"]
|
|
258
|
+
EP --> Mode{execution_mode?}
|
|
259
|
+
Mode -- "serial" --> Serial["단일 에이전트\n전체 실행"]
|
|
260
|
+
Mode -- "parallel" --> Parallel["N개 에이전트 생성\n(새 워크스페이스)"]
|
|
261
|
+
Mode -- "hybrid" --> Hybrid["혼합: 병렬 그룹\n+ 직렬 체크포인트"]
|
|
262
|
+
Serial --> Phase2["서브태스크별 2단계"]
|
|
263
|
+
Parallel --> Phase2
|
|
264
|
+
Hybrid --> Phase2
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### DUUL 트리거 방법
|
|
268
|
+
|
|
269
|
+
대화 중에 **"DUUL"** (또는 **"두울"**)을 언급하면 활성화됩니다.
|
|
270
|
+
|
|
271
|
+
**트리거 예시:**
|
|
272
|
+
- "DUUL로 개발 진행해줘", "두울 돌려줘", "DUUL로 해줘"
|
|
273
|
+
- "run DUUL", "use DUUL for this", "start DUUL"
|
|
274
|
+
|
|
275
|
+
**트리거가 아닌 것** (에이전트가 직접 처리하는 일반 요청):
|
|
276
|
+
- "코드 리뷰해줘", "이거 확인해봐", "내 계획 봐줘"
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## 도구
|
|
281
|
+
|
|
282
|
+
### `request_plan_review` -- The Architect
|
|
283
|
+
|
|
284
|
+
DUUL 1단계: LLM 시니어 소프트웨어 아키텍트에게 개발 계획의 리뷰를 요청합니다.
|
|
285
|
+
|
|
286
|
+
**입력 스키마:**
|
|
287
|
+
|
|
288
|
+
| 필드 | 타입 | 필수 | 설명 |
|
|
289
|
+
|------|------|------|------|
|
|
290
|
+
| `plan` | `string` | 예 | 상세한 구현 계획 |
|
|
291
|
+
| `project_context` | `object` | 아니오 | 구조화된 프로젝트 컨텍스트 |
|
|
292
|
+
| `constraints` | `string[]` | 아니오 | 특수 제약 조건: 성능, 메모리, 보안 등 |
|
|
293
|
+
| `notes_to_reviewer` | `string` | 아니오 | 리뷰어에게 전달할 컨텍스트 또는 반박 |
|
|
294
|
+
| `workspace_root` | `string` | 아니오 | 워크스페이스 루트 절대 경로 (파일 탐색 활성화) |
|
|
295
|
+
| `working_directories` | `string[]` | 아니오 | 파일 접근을 제한할 하위 디렉토리 |
|
|
296
|
+
| `linked_roots` | `string[]` | 아니오 | 읽기 전용 외부 워크스페이스 루트 (최대 5개) |
|
|
297
|
+
| `artifact_refs` | `Array<{ path, reason, priority }>` | 아니오 | 우선순위가 있는 중요 파일 참조 (최대 30개) |
|
|
298
|
+
| `tracked_only` | `boolean` | 아니오 | git 추적 파일만 접근 허용 |
|
|
299
|
+
| `previous_review_id` | `string` | 아니오 | 이전 리뷰 호출의 응답 ID |
|
|
300
|
+
| `iteration_count` | `number` | 아니오 | 현재 반복 횟수 |
|
|
301
|
+
| `max_review_iterations` | `number` | 아니오 | 반복 제한 오버라이드 (1–20) |
|
|
302
|
+
| `reviewer_config` | `object` | 아니오 | 요청별 리뷰어 설정 |
|
|
303
|
+
|
|
304
|
+
**출력 스키마:**
|
|
305
|
+
|
|
306
|
+
| 필드 | 타입 | 설명 |
|
|
307
|
+
|------|------|------|
|
|
308
|
+
| `verdict` | `"APPROVE" \| "REVISE"` | 최종 판정 |
|
|
309
|
+
| `review_status` | `"completed" \| "incomplete"` | 리뷰 완료 여부 |
|
|
310
|
+
| `confidence` | `number` (0-1) | 판정에 대한 신뢰도, 참고용 |
|
|
311
|
+
| `requires_human_review` | `boolean` | 사람의 검토가 필요한지 여부 |
|
|
312
|
+
| `architectural_analysis` | `string` | 구조적 장단점 분석 |
|
|
313
|
+
| `blocking_issues` | `Array<{ description, suggestion }>` | 진행 전 반드시 수정해야 하는 이슈 |
|
|
314
|
+
| `non_blocking_suggestions` | `string[]` | 선택적 개선 제안 |
|
|
315
|
+
| `edge_cases` | `string[]` | 고려되지 않은 엣지 케이스 |
|
|
316
|
+
| `checklist_for_implementation` | `string[]` | 구현 시 반드시 따라야 할 체크리스트 |
|
|
317
|
+
| `review_id` | `string` | 라운드 간 컨텍스트 유지를 위한 응답 ID |
|
|
318
|
+
| `iteration_count` | `number` | 현재 반복 횟수 |
|
|
319
|
+
| `iteration_limit` | `number` | 이 단계의 유효 반복 제한 |
|
|
320
|
+
| `iteration_limit_reached` | `boolean` | 반복 제한에 도달했는지 여부 |
|
|
321
|
+
|
|
322
|
+
### `request_code_review` -- The Debugger
|
|
323
|
+
|
|
324
|
+
DUUL 2단계: LLM 엄격한 QA 엔지니어에게 코드 리뷰를 요청합니다. 이전에 승인된 계획이 필요합니다.
|
|
325
|
+
|
|
326
|
+
**입력 스키마:**
|
|
327
|
+
|
|
328
|
+
| 필드 | 타입 | 필수 | 설명 |
|
|
329
|
+
|------|------|------|------|
|
|
330
|
+
| `code` | `string` | 예 | 리뷰할 코드 |
|
|
331
|
+
| `approved_plan` | `string` | 예 | 이 코드가 구현하는 승인된 계획 |
|
|
332
|
+
| `file_path` | `string` | 아니오 | 맥락에 맞는 피드백을 위한 파일 경로 |
|
|
333
|
+
| `dependencies` | `object` | 아니오 | 관련 라이브러리 버전 정보 |
|
|
334
|
+
| `relevant_code` | `Array<{ file_path, code }>` | 아니오 | 관련 코드 스니펫 |
|
|
335
|
+
| `notes_to_reviewer` | `string` | 아니오 | 리뷰어에게 전달할 컨텍스트 또는 반박 |
|
|
336
|
+
| `workspace_root` | `string` | 아니오 | 워크스페이스 루트 절대 경로 |
|
|
337
|
+
| `working_directories` | `string[]` | 아니오 | 파일 접근을 제한할 하위 디렉토리 |
|
|
338
|
+
| `artifact_refs` | `Array<{ path, reason, priority }>` | 아니오 | 중요 파일 참조 (최대 30개) |
|
|
339
|
+
| `previous_review_id` | `string` | 아니오 | 이전 리뷰 호출의 응답 ID |
|
|
340
|
+
| `iteration_count` | `number` | 아니오 | 현재 반복 횟수 |
|
|
341
|
+
| `max_review_iterations` | `number` | 아니오 | 반복 제한 오버라이드 (1–20) |
|
|
342
|
+
| `reviewer_config` | `object` | 아니오 | 요청별 리뷰어 설정 |
|
|
343
|
+
|
|
344
|
+
**출력 스키마:**
|
|
345
|
+
|
|
346
|
+
| 필드 | 타입 | 설명 |
|
|
347
|
+
|------|------|------|
|
|
348
|
+
| `verdict` | `"APPROVE" \| "REVISE"` | 최종 판정 |
|
|
349
|
+
| `review_status` | `"completed" \| "incomplete"` | 리뷰 완료 여부 |
|
|
350
|
+
| `confidence` | `number` (0-1) | 판정에 대한 신뢰도, 참고용 |
|
|
351
|
+
| `requires_human_review` | `boolean` | 사람의 검토가 필요한지 여부 |
|
|
352
|
+
| `logic_validation` | `string` | 코드가 승인된 계획을 얼마나 정확히 구현하는지 |
|
|
353
|
+
| `blocking_issues` | `Array<{ description, suggestion }>` | 진행 전 반드시 수정해야 하는 이슈 |
|
|
354
|
+
| `non_blocking_suggestions` | `string[]` | 선택적 개선 제안 |
|
|
355
|
+
| `vulnerabilities` | `Array<{ type, description, severity }>` | 보안/성능 취약점 |
|
|
356
|
+
| `optimized_snippet` | `string \| null` | 최적화된 코드 블록 |
|
|
357
|
+
| `review_id` | `string` | 라운드 간 컨텍스트 유지를 위한 응답 ID |
|
|
358
|
+
| `iteration_count` | `number` | 현재 반복 횟수 |
|
|
359
|
+
| `iteration_limit` | `number` | 이 단계의 유효 반복 제한 |
|
|
360
|
+
| `iteration_limit_reached` | `boolean` | 반복 제한에 도달했는지 여부 |
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 워크스페이스 범위
|
|
365
|
+
|
|
366
|
+
`workspace_root`가 제공되면 리뷰어는 7개의 파일 탐색 도구에 접근할 수 있습니다:
|
|
367
|
+
|
|
368
|
+
| 도구 | 설명 |
|
|
369
|
+
|------|------|
|
|
370
|
+
| `read_file` | 전체 파일 내용 읽기 (50KB 초과 시 경고) |
|
|
371
|
+
| `list_directory` | 파일 및 디렉토리 목록 |
|
|
372
|
+
| `search_in_files` | 파일 전체에서 정규식 검색 (`rg` > `git grep` > `grep`) |
|
|
373
|
+
| `read_file_range` | 특정 줄 범위 읽기 (최대 200줄) |
|
|
374
|
+
| `stat_file` | 파일 크기, 수정 시간, 타입 조회 |
|
|
375
|
+
| `read_json` | JSON 파일 읽기 (선택적 JSON 포인터) |
|
|
376
|
+
| `list_tracked_files` | git 추적 파일 목록 (선택적 접두사 필터) |
|
|
377
|
+
|
|
378
|
+
### 보안
|
|
379
|
+
|
|
380
|
+
- 차단 경로: `.git/`, `build/`, `dist/`, `*.log`
|
|
381
|
+
- `linked_roots`는 읽기 전용
|
|
382
|
+
- `tracked_only: true` 시 git 추적 파일만 접근 가능
|
|
383
|
+
- 심볼릭 링크 탈출 방지
|
|
384
|
+
- 시스템 디렉토리 및 얕은 경로 (깊이 3 미만) 거부
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## 프로바이더 기능 매트릭스
|
|
389
|
+
|
|
390
|
+
| 프로바이더 | 구조화된 출력 | 도구 호출 | 이전 응답 ID | JSON 스키마 엄격 |
|
|
391
|
+
|-----------|-------------|---------|------------|----------------|
|
|
392
|
+
| **OpenAI** | 예 | 예 | 예 | 예 |
|
|
393
|
+
| **Anthropic** | 아니오 (JSON 프롬프트 + zod) | 아니오 | 아니오 | 아니오 |
|
|
394
|
+
| **Google** | 아니오 (JSON 모드 + zod) | 아니오 | 아니오 | 아니오 |
|
|
395
|
+
| **OpenRouter** | 예 (OpenAI API 경유) | 예 | 예 | 예 |
|
|
396
|
+
| **Compatible** | 예 (OpenAI API 경유) | 예 | 예 | 예 |
|
|
397
|
+
|
|
398
|
+
**성능 저하 동작:**
|
|
399
|
+
- **구조화된 출력 미지원:** JSON 프롬프팅 + zod 검증 폴백.
|
|
400
|
+
- **도구 호출 미지원:** 리뷰어가 워크스페이스를 탐색할 수 없음. `relevant_code`와 `artifact_refs`로 보완.
|
|
401
|
+
- **이전 응답 ID 미지원:** 각 리뷰 호출이 독립적 (대화 기억 없음).
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## 아키텍처
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
src/
|
|
409
|
+
index.ts 진입점. MCP 서버 + stdio 트랜스포트.
|
|
410
|
+
schemas/
|
|
411
|
+
common.ts 공유 스키마 (ArtifactRef, ReviewerConfig, IterationMeta).
|
|
412
|
+
plan-review.ts 계획 리뷰 입출력 스키마.
|
|
413
|
+
code-review.ts 코드 리뷰 입출력 스키마.
|
|
414
|
+
execution-partition.ts 실행 분할 입출력 스키마.
|
|
415
|
+
prompts/
|
|
416
|
+
plan-review-system.ts 시니어 아키텍트 시스템 프롬프트.
|
|
417
|
+
code-review-system.ts 엄격한 QA 엔지니어 시스템 프롬프트.
|
|
418
|
+
execution-partition-system.ts 프로젝트 매니저 시스템 프롬프트.
|
|
419
|
+
services/
|
|
420
|
+
reviewer.ts 프로바이더 팩토리 + callReview() 디스패처.
|
|
421
|
+
review-limits.ts 반복 제한 해석 및 적용.
|
|
422
|
+
filesystem.ts 워크스페이스 범위 파일 작업 + 보안.
|
|
423
|
+
providers/
|
|
424
|
+
types.ts ReviewerProvider 인터페이스 + 기능 선언.
|
|
425
|
+
openai.ts OpenAI: 구조화된 출력 + 도구 루프.
|
|
426
|
+
anthropic.ts Anthropic: JSON 프롬프트 + zod.
|
|
427
|
+
google.ts Google: JSON 모드 + zod.
|
|
428
|
+
tools/
|
|
429
|
+
plan-review.ts request_plan_review MCP 도구.
|
|
430
|
+
code-review.ts request_code_review MCP 도구.
|
|
431
|
+
execution-partition.ts request_execution_partition MCP 도구.
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## 라이선스
|
|
437
|
+
|
|
438
|
+
MIT
|