@tuzi-ince/hi-loop 0.4.0 → 0.4.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/README.md +20 -2
- package/docs/DESIGN.md +1 -1
- package/docs/SPEC.md +1 -1
- package/docs/guide.md +27 -13
- package/package.json +1 -1
- package/skills/flow/SKILL.md +25 -21
- package/src/mcp-server.js +13 -0
package/README.md
CHANGED
|
@@ -174,7 +174,9 @@ CI·배포 설정, 빌드·러너 설정, 환경 변수. "테스트는 통과했
|
|
|
174
174
|
사람이 놓치지 않게 한다.
|
|
175
175
|
|
|
176
176
|
**(b) 조건부 검사 — 바뀐 파일에 따라 게이트를 켠다.** 무거운 검사(e2e 등)를 매 회차 돌리는
|
|
177
|
-
대신, 특정
|
|
177
|
+
대신, 특정 경로에 변경이 있을 때만 돌린다. `--when` 은 `git status`(HEAD 대비 워킹트리 변경)로
|
|
178
|
+
매칭한다 — 즉 "그 경로를 건드린 그 회차만"이 아니라 **커밋 전 변경분에 그 경로가 있는 한 이후
|
|
179
|
+
회차마다** 검사가 돈다(2회차에 e2e 가 사라지지 않게 하려는 의도).
|
|
178
180
|
|
|
179
181
|
```bash
|
|
180
182
|
hi-loop run --goal "..." \
|
|
@@ -188,6 +190,22 @@ hi-loop run --goal "..." \
|
|
|
188
190
|
- `--when` 글롭에 안 맞은 검사는 **건너뜀으로 기록**된다 — 안 돌린 것이 통과처럼 보이지 않게
|
|
189
191
|
Gaps에 남는다.
|
|
190
192
|
|
|
193
|
+
**MCP 에서도 같은 걸 쓴다 — "UI 변경 회차에만 e2e"를 엔진이 강제한다.** `hiloop_run` 이 `checks`
|
|
194
|
+
인자를 받는다(CLI `--check/--when` 의 MCP 노출):
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
"checks": [
|
|
198
|
+
{ "cmd": "npm test" },
|
|
199
|
+
{ "cmd": "npx playwright test", "when": "src/**/*.tsx" }
|
|
200
|
+
]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
- e2e 를 "스킬이 사람에게 기억해서 실행"(제안)이 아니라 **엔진이 결정론적으로 강제**(메커니즘)하는 길이다.
|
|
204
|
+
UI 파일이 바뀐 회차마다 엔진이 e2e 를 돌리고 통과해야 pass 로 인정한다 — 조용히 빠지지 않는다.
|
|
205
|
+
- e2e 는 **셸 명령**이어야 한다. 엔진은 Playwright **MCP 도구**를 부를 수 없으므로, MCP 만 있는
|
|
206
|
+
프로젝트는 `flow` 스킬이 루프 통과 후 MCP 로 돌린다(폴백). 셸 e2e 명령도 없으면 스킵.
|
|
207
|
+
- `flow` 스킬이 UI 작업을 감지하면 사용자에게 물은 뒤 이 `checks` 를 자동 구성해 `hiloop_run` 에 넘긴다.
|
|
208
|
+
|
|
191
209
|
**diff만 리뷰하고 싶다면** — 지금 워킹트리 변경분을 정확성·보안·YAGNI 축으로 심판:
|
|
192
210
|
|
|
193
211
|
```bash
|
|
@@ -275,7 +293,7 @@ hi-loop run --goal "..." --start-from BUILD --stop-after CODE_REVIEW
|
|
|
275
293
|
|
|
276
294
|
| 사용자가 이렇게 말하면 | LLM이 하는 일 |
|
|
277
295
|
|---|---|
|
|
278
|
-
| `/hi-loop 로그인 폼 만들어줘` (슬래시 스킬) |
|
|
296
|
+
| `/hi-loop:flow 로그인 폼 만들어줘` (슬래시 스킬) | `flow` 스킬 기동 → `hiloop_run(full=true)` 실행 (bare `/hi-loop` 은 명령이지 이 스킬이 아님) |
|
|
279
297
|
| "hiloop_run 도구로 결제 버그 고쳐줘" | 지목된 MCP 도구를 로드해 바로 호출 |
|
|
280
298
|
| 터미널에서 `hi-loop run --goal "..." --full` | 엔진을 CLI로 직접 구동(LLM 개입 없음) |
|
|
281
299
|
|
package/docs/DESIGN.md
CHANGED
|
@@ -571,7 +571,7 @@ try/catch 로 감싼다. **텔레그램 장애로 빌드가 죽는 것은 설계
|
|
|
571
571
|
|
|
572
572
|
| 항목 | 상태 | 근거 |
|
|
573
573
|
|---|---|---|
|
|
574
|
-
| 단위/수용 테스트
|
|
574
|
+
| 단위/수용 테스트 343개 | ✅ 통과 | `npm test` (네트워크·실제 LLM 없이) |
|
|
575
575
|
| **설치본(tarball) 실행** | ✅ 실측 | `npm pack` → `npm install -g --prefix /tmp/lev-prefix ./tgz` → **심링크 bin 경유** 실행 및 전체 루프 E2E 통과. §4.5 버그를 잡아낸 경로 |
|
|
576
576
|
| CLI 루프 E2E (가짜 에이전트) | ✅ 실측 | PLAN→실패→DO→통과→exit 0, 2회차 프롬프트에 실제 AssertionError 주입 확인 |
|
|
577
577
|
| MCP 서버 (도구 왕복) | ✅ 실측 | stdio 로 initialize → tools/list(3종) → tools/call |
|
package/docs/SPEC.md
CHANGED
|
@@ -222,7 +222,7 @@ runLoop({
|
|
|
222
222
|
- FR-4.3 노출 도구:
|
|
223
223
|
| tool | input | 동작 |
|
|
224
224
|
|---|---|---|
|
|
225
|
-
| `hiloop_run` | `goal`(필수), `testCommand?`, `maxLoops?`, `verifySpec?`, `spec?`, `reconcile?`, `cwd?` | 루프 실행 후 결과 텍스트 반환. `budgetUsd`·`stagnation`은 노출 안 함(CLI 전용) |
|
|
225
|
+
| `hiloop_run` | `goal`(필수), `testCommand?`, `maxLoops?`, `verifySpec?`, `spec?`, `reconcile?`, `reconcileSpec?`, `checks?`, `cwd?` | 루프 실행 후 결과 텍스트 반환. `budgetUsd`·`stagnation`은 노출 안 함(CLI 전용). `checks`=`[{cmd,when?}]` 조건부 검사(CLI `--check/--when` 의 MCP 노출) — UI 변경 회차에만 e2e 같은 게이트를 **엔진이 강제**한다 |
|
|
226
226
|
| `hiloop_status` | `cwd?` | 현재 `.hi-loop/STATE.json` 요약 반환 |
|
|
227
227
|
| `hiloop_reset` | `cwd?` | 상태 파일 삭제 |
|
|
228
228
|
- FR-4.4 도구 오류는 예외를 던지지 않고 `isError: true` + 메시지로 반환한다.
|
package/docs/guide.md
CHANGED
|
@@ -33,8 +33,9 @@ hi-loop run --goal "add 함수를 만들어라" --test "npm test" # 사람이
|
|
|
33
33
|
| Git | 선택 (롤백/리뷰용) | `git --version` |
|
|
34
34
|
|
|
35
35
|
> ⚠️ **`npm install -g handoff` 를 하지 마라.** 무스코프 `handoff` 는 이 프로젝트와
|
|
36
|
-
> 무관한 **제3자의 redis lua 래퍼 패키지**(v0.1.3)다. 이
|
|
37
|
-
>
|
|
36
|
+
> 무관한 **제3자의 redis lua 래퍼 패키지**(v0.1.3)다. 이 프로젝트는 **스코프 이름
|
|
37
|
+
> `@tuzi-ince/hi-loop`** 으로 npm 레지스트리에 게시돼 있다(현재 0.4.0). 스코프를 반드시 붙여라.
|
|
38
|
+
> 최신 소스(0.4.1+)로 개발·검증하려면 아래 §2 의 로컬 설치를 쓴다.
|
|
38
39
|
|
|
39
40
|
---
|
|
40
41
|
|
|
@@ -45,9 +46,9 @@ hi-loop run --goal "add 함수를 만들어라" --test "npm test" # 사람이
|
|
|
45
46
|
```bash
|
|
46
47
|
git clone <이 저장소> hi-loop && cd hi-loop
|
|
47
48
|
npm install # @modelcontextprotocol/sdk, zod
|
|
48
|
-
npm test #
|
|
49
|
+
npm test # 전부 통과 확인
|
|
49
50
|
npm link # 전역에 hi-loop / hi-loop-setup 심볼릭 링크
|
|
50
|
-
hi-loop --version # 0.1
|
|
51
|
+
hi-loop --version # 0.4.1
|
|
51
52
|
```
|
|
52
53
|
|
|
53
54
|
해제: `npm unlink -g @tuzi-ince/hi-loop`
|
|
@@ -62,10 +63,10 @@ npm install -g /absolute/path/to/hi-loop
|
|
|
62
63
|
|
|
63
64
|
```bash
|
|
64
65
|
# 보내는 쪽
|
|
65
|
-
npm pack # tuzi-ince-hi-loop-0.1.
|
|
66
|
+
npm pack # tuzi-ince-hi-loop-0.4.1.tgz 생성 (~26kB)
|
|
66
67
|
|
|
67
68
|
# 받는 쪽
|
|
68
|
-
npm install -g ./tuzi-ince-hi-loop-0.1.
|
|
69
|
+
npm install -g ./tuzi-ince-hi-loop-0.4.1.tgz
|
|
69
70
|
```
|
|
70
71
|
|
|
71
72
|
### 2-D. 설치 없이 직접 실행
|
|
@@ -259,7 +260,7 @@ hi-loop rollback --cwd . # 작업 대상 지정
|
|
|
259
260
|
|
|
260
261
|
| 도구 | 인자 | 용도 |
|
|
261
262
|
|---|---|---|
|
|
262
|
-
| `hiloop_run` | `goal`(필수), `testCommand`, `maxLoops`, `verifySpec`, `full`, `ship`, `watch`, `stopAfter`, `spec`, `reconcile`, `reconcileSpec`, `cwd` | 자가 치유(+전과정) 루프 실행 |
|
|
263
|
+
| `hiloop_run` | `goal`(필수), `testCommand`, `maxLoops`, `verifySpec`, `full`, `ship`, `watch`, `stopAfter`, `spec`, `reconcile`, `reconcileSpec`, `checks`, `cwd` | 자가 치유(+전과정) 루프 실행 |
|
|
263
264
|
| `hiloop_answer` | `choice`, `note`, `cwd` | 대기 중인 질문에 답하고 재개 가능 상태로 되돌림 |
|
|
264
265
|
| `hiloop_status` | `cwd` | 진행 상태 조회 (장시간 루프를 들여다보는 창) |
|
|
265
266
|
| `hiloop_rollback` | `to`, `cwd` | 체크포인트로 파일 복원 |
|
|
@@ -269,6 +270,18 @@ hi-loop rollback --cwd . # 작업 대상 지정
|
|
|
269
270
|
> MCP `hiloop_run`은 CLI와 달리 `--budget-usd`·`--stagnation`을 노출하지 않는다.
|
|
270
271
|
> 예산 상한이 필요하면 CLI(`hi-loop run`)를 쓴다. 정체 감지는 기본값(3회)으로 동작한다.
|
|
271
272
|
|
|
273
|
+
> **UI 변경 회차에만 e2e 를 엔진이 강제하기 (`checks`).** `checks: [{cmd, when?}]` 를 주면
|
|
274
|
+
> `testCommand` 대신 이 배열이 판정 기준이 되고, `when` 글롭에 맞는 파일이 바뀐 회차에만 그 검사를
|
|
275
|
+
> 돌린다. e2e 를 스킬의 자연어 지시(사람이 기억해서 실행)가 아니라 **엔진이 결정론적으로 강제**하는 길이다:
|
|
276
|
+
> ```json
|
|
277
|
+
> "checks": [
|
|
278
|
+
> { "cmd": "npm test" },
|
|
279
|
+
> { "cmd": "npx playwright test", "when": "src/**/*.tsx" }
|
|
280
|
+
> ]
|
|
281
|
+
> ```
|
|
282
|
+
> e2e 는 **셸 명령**이어야 한다(엔진은 Playwright MCP 도구를 부를 수 없다 — 그 경우는 스킬이 루프 후
|
|
283
|
+
> MCP 로 돌린다). `flow` 스킬이 UI 작업을 감지하면 이 `checks` 를 자동으로 구성해 넘긴다.
|
|
284
|
+
|
|
272
285
|
> **cwd 기본값은 `CLAUDE_PROJECT_DIR || process.cwd()`.** MCP 는 호스트(클로드코드/커서)가 서버를
|
|
273
286
|
> 띄우는 경로라, "어느 프로젝트인가"의 정답은 호스트가 주입하는 `CLAUDE_PROJECT_DIR` 다. 각 도구에
|
|
274
287
|
> `cwd` 를 명시하면 그것이 최우선. (CLI 는 반대로 순수 `process.cwd()` — 터미널에서 cd 한 곳이 의도다.)
|
|
@@ -346,7 +359,7 @@ hi-loop 의 CHECK 단계는 **에이전트가 "다 됐다"고 말해도 믿지
|
|
|
346
359
|
npm version patch --no-git-tag-version # 0.1.0 -> 0.1.1
|
|
347
360
|
|
|
348
361
|
# ── CHECK 1: 소스에서 테스트
|
|
349
|
-
npm test #
|
|
362
|
+
npm test # 343개
|
|
350
363
|
|
|
351
364
|
# ── CHECK 2: 아티팩트로 만든다 (레지스트리 안 건드림)
|
|
352
365
|
npm pack # tuzi-ince-hi-loop-0.1.1.tgz
|
|
@@ -372,7 +385,7 @@ rm -rf /tmp/lev-prefix # 정리
|
|
|
372
385
|
|
|
373
386
|
### 이 루프가 실제로 잡아낸 버그
|
|
374
387
|
|
|
375
|
-
이 절차는 이론이 아니다. **소스에서는
|
|
388
|
+
이 절차는 이론이 아니다. **소스에서는 343개 테스트가 다 통과하는데 설치본에서는
|
|
376
389
|
모든 명령이 아무 일도 안 하고 조용히 `exit 0` 으로 끝나는** 버그를 이 루프가 잡았다.
|
|
377
390
|
|
|
378
391
|
원인: `bin/*.js` 의 "직접 실행인가?" 판정이
|
|
@@ -431,7 +444,7 @@ npm install -g @tuzi-ince/hi-loop # 명령 이름은 그대로 hi-loop / hi-l
|
|
|
431
444
|
|
|
432
445
|
배포 전 체크리스트:
|
|
433
446
|
|
|
434
|
-
- [ ] `npm test` 통과 (
|
|
447
|
+
- [ ] `npm test` 통과 (343개)
|
|
435
448
|
- [ ] **§7 의 실제 에이전트 스모크 테스트 통과** ← 아직 안 된 항목. **이게 통과하기 전엔 배포하지 마라**
|
|
436
449
|
- [ ] `npm pack --dry-run` 으로 포함 파일 확인 (bin, src, docs, README)
|
|
437
450
|
- [ ] `version` 갱신
|
|
@@ -468,11 +481,11 @@ cat .hi-loop/STATE.json | jq '{status, phase, iteration, sessionId, sessionSeria
|
|
|
468
481
|
|
|
469
482
|
**실제로 실행해 확인함**
|
|
470
483
|
|
|
471
|
-
- `npm test`
|
|
484
|
+
- `npm test` 전부 통과
|
|
472
485
|
- `npm pack` → tarball 생성 (bin/src/docs/README 포함)
|
|
473
486
|
- **`npm install -g --prefix /tmp/lev-prefix ./tarball` 로 진짜 설치 → 설치본 실행 확인**
|
|
474
487
|
- `bin/hi-loop` 가 심링크로 생성됨을 `ls -l` 로 확인
|
|
475
|
-
- **심링크 bin 경유** `hi-loop --version` → `0.1
|
|
488
|
+
- **심링크 bin 경유** `hi-loop --version` → `0.4.1`, `run`(goal 없음) → exit 2
|
|
476
489
|
- 설치본으로 전체 루프 E2E: PLAN→실패→DO→통과→exit 0
|
|
477
490
|
- 설치본 `hi-loop-setup` → `.mcp.json` 이 설치 위치를 정확히 가리킴
|
|
478
491
|
- `hi-loop-setup` 멱등, `--dry-run` 무기록
|
|
@@ -507,7 +520,8 @@ cat .hi-loop/STATE.json | jq '{status, phase, iteration, sessionId, sessionSeria
|
|
|
507
520
|
- **MCP 모드에서 실제 에이전트 spawn** — 도구 왕복(initialize/tools/call)만 확인
|
|
508
521
|
- 장시간(10회) 실제 루프
|
|
509
522
|
- 텔레그램 실제 발송
|
|
510
|
-
-
|
|
523
|
+
- 레지스트리에는 **0.4.0** 이 게시돼 있다 — 이번 세션의 변경(0.4.1: `.hi-loop/` 상태·대문자 규약·
|
|
524
|
+
MCP `checks`)을 레지스트리로 받으려면 **0.4.1 재게시**가 필요하다. 그전까지 최신은 로컬 설치(§2)로만.
|
|
511
525
|
|
|
512
526
|
**재현 절차**
|
|
513
527
|
|
package/package.json
CHANGED
package/skills/flow/SKILL.md
CHANGED
|
@@ -46,6 +46,19 @@ user-invocable: true
|
|
|
46
46
|
- `full: true` — 발굴·설계리뷰·코드리뷰를 포함한 전체 라이프사이클
|
|
47
47
|
- `testCommand`: 프로젝트의 테스트 명령(기본 `npm test`)
|
|
48
48
|
- 필요 시 `maxLoops`, `ship`, `watch`
|
|
49
|
+
- **UI 작업이면 e2e 를 엔진 게이트로 넣는다(권장 — LLM 기억에 의존하지 않는 결정론적 강제).**
|
|
50
|
+
goal 이 UI(화면·컴포넌트·라우팅·스타일)를 건드릴 것 같고 프로젝트에 **셸 e2e 명령**
|
|
51
|
+
(package.json `test:e2e` 스크립트, 또는 `playwright.config.*` → `npx playwright test`)이 있으면,
|
|
52
|
+
**먼저 사용자에게 e2e 게이트 여부를 묻고**, 켜기로 하면 `checks` 로 넘긴다:
|
|
53
|
+
```json
|
|
54
|
+
"checks": [
|
|
55
|
+
{ "cmd": "<기본 테스트, 예: npm test>" },
|
|
56
|
+
{ "cmd": "<e2e 셸 명령>", "when": "<UI 글롭, 예: src/**/*.tsx>" }
|
|
57
|
+
]
|
|
58
|
+
```
|
|
59
|
+
→ 엔진이 **UI 변경이 (커밋 전) 워킹트리에 있는 회차마다** e2e 를 돌리고, 통과해야 pass 로 인정한다(조용히 빠지지 않는다).
|
|
60
|
+
- 셸 e2e 명령이 없고 **Playwright MCP 만** 있으면 `checks` 를 쓰지 않는다(엔진은 MCP 도구를 못 부른다)
|
|
61
|
+
— 루프 통과 후 7단계에서 MCP 로 돌린다. **둘 다 없으면** e2e 는 스킵한다(도구를 임의 설치하지 않는다).
|
|
49
62
|
|
|
50
63
|
5. **사용자 선택 처리.** 응답이 `⏸ 사용자의 선택이 필요합니다` 로 오면,
|
|
51
64
|
그 질문을 **그대로 사용자에게 제시**하고 답을 받는다. 답을 `hiloop_answer`
|
|
@@ -54,27 +67,18 @@ user-invocable: true
|
|
|
54
67
|
6. **결과 보고.** `✅ 통과` / `❌ 실패` 와 반복 횟수, 그리고 함께 온 Gaps(검증 한계)를
|
|
55
68
|
사용자에게 전한다. false green(테스트만 초록이고 실제 미완)을 통과로 포장하지 않는다.
|
|
56
69
|
|
|
57
|
-
7. **
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
수백 MB다. 사용자에게 상황을 알리고 선택지를 준다: (a) 설치 후 진행, (b) 이미 있는 다른
|
|
70
|
-
도구 사용, (c) 건너뛰기. 어느 쪽도 강요하지 않고, **이 게이트를 "스킵"으로 기록**한다.
|
|
71
|
-
|
|
72
|
-
- e2e를 실제로 실행하기로 했으면 **결과 화면(스크린샷) 저장 여부도 사용자에게 묻는다**.
|
|
73
|
-
스크린샷은 **브라우저를 구동하는 도구(1·2)가 있을 때만** 가능하다 — 없으면 저장할 화면이
|
|
74
|
-
없음을 밝힌다.
|
|
75
|
-
- 완료되면 **테스트 결과서와 스크린샷을 프로젝트의 test 폴더에 저장**한다
|
|
76
|
-
(예: 리포트 `tests/e2e/report-<날짜시각>.md`, 스크린샷 `tests/e2e/screenshots/`).
|
|
77
|
-
날짜·시각은 실제 값으로 채운다. 저장 경로를 사용자에게 알린다.
|
|
70
|
+
7. **e2e 후처리 (스크린샷·리포트, MCP 폴백).** 루프가 통과(✅)한 뒤, 4단계에서 정한 e2e 전략에 따라:
|
|
71
|
+
- **엔진 `checks` 로 돌린 경우**: e2e 는 이미 게이트로 통과했다(엔진이 강제). 결과 화면(스크린샷)
|
|
72
|
+
저장이 필요하면 사용자에게 물어 저장한다. **여기서 다시 e2e 를 돌릴 필요는 없다.**
|
|
73
|
+
- **Playwright MCP 폴백 경우**(셸 e2e 명령이 없어 4단계에서 checks 를 못 건 경우): 사용자에게
|
|
74
|
+
"UI 변경이 있었습니다. 지금 Playwright MCP 로 e2e 를 돌릴까요?" 물어, 승인 시 MCP 로 실행한다.
|
|
75
|
+
- **스킵된 경우**(도구 없음): e2e 도구가 없어 스킵했음을 밝힌다 — 통과한 루프를 실패로 만들지 않는다.
|
|
76
|
+
- 실행한 경우 **결과서·스크린샷을 test 폴더에 저장**한다(예: 리포트 `tests/e2e/report-<날짜시각>.md`,
|
|
77
|
+
스크린샷 `tests/e2e/screenshots/`). 날짜·시각은 실제 값으로 채우고 저장 경로를 알린다.
|
|
78
|
+
스크린샷은 브라우저를 구동하는 도구(Playwright MCP/셸)가 있을 때만 가능하다.
|
|
79
|
+
|
|
80
|
+
> 왜 이렇게 나누나: e2e "실행"은 결정론적 게이트라 **엔진(`checks`)**에 맡기는 게 최신 정설이다
|
|
81
|
+
> (프롬프트 지시는 "제안"이지 "강제"가 아니다). 엔진이 못 부르는 Playwright MCP 만 LLM 이 후처리한다.
|
|
78
82
|
|
|
79
83
|
8. **커밋 게이트 (git 워크플로).** 테스트가 통과(✅)하고 e2e 게이트까지 끝나면 `commitPolicy` 대로
|
|
80
84
|
**로컬** 커밋한다. **push/PR 은 하지 않는다.** git 저장소가 아니면 건너뛴다.
|
package/src/mcp-server.js
CHANGED
|
@@ -43,6 +43,7 @@ export const tools = {
|
|
|
43
43
|
spec,
|
|
44
44
|
reconcile,
|
|
45
45
|
reconcileSpec,
|
|
46
|
+
checks,
|
|
46
47
|
cwd = defaultCwd(),
|
|
47
48
|
}) => {
|
|
48
49
|
if (!goal) return fail('goal 은 필수입니다.');
|
|
@@ -62,6 +63,9 @@ export const tools = {
|
|
|
62
63
|
specPath: spec || null,
|
|
63
64
|
reconcile: reconcile === undefined ? null : Boolean(reconcile),
|
|
64
65
|
reconcileSpec: reconcileSpec || null,
|
|
66
|
+
// 조건부 검사(--check/--when 의 MCP 노출): 주면 testCommand 대신 이 배열이 판정 기준이 된다.
|
|
67
|
+
// when 글롭에 맞는 파일이 바뀐 회차에만 그 검사를 돌린다(UI 변경 회차에만 e2e 등).
|
|
68
|
+
checks: Array.isArray(checks) && checks.length ? checks : null,
|
|
65
69
|
cwd,
|
|
66
70
|
logger: log,
|
|
67
71
|
});
|
|
@@ -204,6 +208,15 @@ export async function startMcpServer({ version = '0.1.0' } = {}) {
|
|
|
204
208
|
.string()
|
|
205
209
|
.optional()
|
|
206
210
|
.describe('정합 게이트가 대조할 표준 문서 경로(기본 docs/DESIGN.md). 예: docs/DESIGN.md. 지정하면 게이트가 켜진다.'),
|
|
211
|
+
checks: z
|
|
212
|
+
.array(z.object({ cmd: z.string(), when: z.string().optional() }))
|
|
213
|
+
.optional()
|
|
214
|
+
.describe(
|
|
215
|
+
'조건부 판정 검사. 주면 testCommand 대신 이 배열이 판정 기준이 된다(첫 항목에 기본 테스트를 넣을 것). ' +
|
|
216
|
+
'when 글롭(예: "src/**/*.tsx")이 있으면 그 경로가 바뀐 회차에만 그 검사를 돌린다 — ' +
|
|
217
|
+
'"UI 를 고친 회차에만 e2e" 를 엔진이 강제하는 용도. e2e 는 셸 명령이어야 한다(예: {cmd:"npx playwright test", when:"src/**/*.tsx"}). ' +
|
|
218
|
+
'short-circuit 하지 않아 유닛이 깨져도 e2e 결과를 같은 회차에 함께 본다.',
|
|
219
|
+
),
|
|
207
220
|
cwd: cwdSchema,
|
|
208
221
|
},
|
|
209
222
|
},
|