@walwal-harness/cli 5.5.1 → 5.5.3
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 +208 -63
- package/bin/init.js +24 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,141 @@
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## Run Book — 0 → 첫 스프린트 완주
|
|
13
|
+
|
|
14
|
+
> 프로젝트 루트에서 `npm i @walwal-harness/cli` 를 마치고 Claude Code 를 재시작한 뒤 아래 순서 그대로 진행합니다.
|
|
15
|
+
|
|
16
|
+
### Step 1. Dispatcher — 들어오자마자
|
|
17
|
+
|
|
18
|
+
Claude Code 세션을 연 뒤 첫 메시지로:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
하네스 엔지니어링 시작
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Dispatcher 가:
|
|
25
|
+
- 요청을 분류 (기능 요청 / 실수 지적 / 메타 질문)
|
|
26
|
+
- `FULLSTACK` / `FE-ONLY` / `BE-ONLY` 파이프라인 결정 → `actions/pipeline.json`
|
|
27
|
+
- 신규/재플래닝이면 "Brainstormer 를 거칠지" 한 번 묻고 `next_agent` 설정 후 STOP
|
|
28
|
+
|
|
29
|
+
완료되면 **새 세션을 열기만 하면** SessionStart 훅이 다음 에이전트(`planner` 또는 `brainstorming`)를 안내합니다.
|
|
30
|
+
|
|
31
|
+
### Step 2. Planner
|
|
32
|
+
|
|
33
|
+
새 세션에서:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
/harness-planner
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Planner 가 `plan.md` + `feature-list.json` + `api-contract.json` 을 생성합니다. AC(Acceptance Criteria)는 반드시 **Executable** 포맷으로 기술됩니다.
|
|
40
|
+
|
|
41
|
+
### Step 3. Solo / Team 모드 선택
|
|
42
|
+
|
|
43
|
+
Planner 완료 후 두 갈래 중 하나.
|
|
44
|
+
|
|
45
|
+
| 선택 | 명령 | 언제 |
|
|
46
|
+
|------|------|------|
|
|
47
|
+
| **Solo** | 프롬프트로 `/harness-generator-backend` → `/harness-generator-frontend` → `/harness-evaluator-*` 순차 호출 | 학습 목적 · feature 3개 이하 · 레이아웃이 좁음 |
|
|
48
|
+
| **Team** | `/harness-team` | feature 4개 이상 · 병렬로 확 밀고 싶을 때 |
|
|
49
|
+
|
|
50
|
+
### Step 4. Team 모드 — Dashboard 띄우기
|
|
51
|
+
|
|
52
|
+
Team 모드는 tmux 통합 Studio 레이아웃을 제공합니다:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Claude Code 내에서
|
|
56
|
+
> /harness-team
|
|
57
|
+
|
|
58
|
+
# 또는 외부 터미널에서
|
|
59
|
+
npx walwal-harness team
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
첫 실행 시 자동으로:
|
|
63
|
+
1. `feature-queue.json` 초기화 (의존성 topological sort)
|
|
64
|
+
2. tmux (또는 iTerm2 native split) 레이아웃 구축
|
|
65
|
+
3. 3개 팀 worker 가 Gen → Eval 루프를 병렬 실행
|
|
66
|
+
4. 팀이 feature 완료 시 자동 dequeue
|
|
67
|
+
5. 5회 초과 실패하면 사용자 개입 요청
|
|
68
|
+
|
|
69
|
+
#### 대시보드 구성
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
┌────────────────────┬──────────────────────────┬───────────┐
|
|
73
|
+
│ Dashboard │ Gotcha & Memory │ TEAM 1 │
|
|
74
|
+
│ - pipeline/sprint │ - 활성 에이전트 gotcha │ Gen|Eval │
|
|
75
|
+
│ - feature 진행도 │ - 나머지 에이전트 요약 ├───────────┤
|
|
76
|
+
│ - queue 상태 │ - SHARED MEMORY │ TEAM 2 │
|
|
77
|
+
│ │ (memory.md 최근 N) │ Gen|Eval │
|
|
78
|
+
├────────────────────┤ ├───────────┤
|
|
79
|
+
│ Archive Prompt │ │ TEAM 3 │
|
|
80
|
+
│ (완료 feature 요약)│ │ Gen|Eval │
|
|
81
|
+
└────────────────────┴──────────────────────────┴───────────┘
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
| 패널 | 내용 | 소스 |
|
|
85
|
+
|------|------|------|
|
|
86
|
+
| **Dashboard** | Pipeline · Sprint · Feature passes (●/◐/○/◌/✗) · Queue R:B:P · Retry | `harness-dashboard.sh` |
|
|
87
|
+
| **Gotcha & Memory** | 활성 에이전트의 누적 실수 + 나머지 요약 + 공유 메모리 | `harness-gotcha-memory.sh` |
|
|
88
|
+
| **TEAM 1–3** | 각 워커의 현재 feature · phase(Gen/Eval) · 실시간 stdout | `harness-queue-manager.sh` worker loop |
|
|
89
|
+
| **Archive Prompt** | 직전 완료 feature 요약 (다음 팀 컨텍스트 주입용) | archive 디렉토리 |
|
|
90
|
+
|
|
91
|
+
- 새로고침 주기: `HARNESS_REFRESH=5` (초). 환경변수로 조정.
|
|
92
|
+
- 단축키: `tmux prefix + 방향키` 로 패널 이동, `prefix + z` 로 확대/축소.
|
|
93
|
+
- 종료: `npx walwal-harness team --kill`.
|
|
94
|
+
|
|
95
|
+
### Step 5. Gotcha 등록 — 같은 실수 반복 막기
|
|
96
|
+
|
|
97
|
+
사용자가 에이전트의 실수를 지적하면 Dispatcher 가 해당 에이전트의 `.harness/gotchas/<agent>.md` 에 자동 append. 다음 세션부터 그 에이전트는 세션 시작 시 자기 gotcha 파일을 읽고 같은 실수를 피합니다.
|
|
98
|
+
|
|
99
|
+
#### 예제 — 실수 지적
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
아니 그렇게 하면 안 되지. Generator-Backend 가 MockServer 를 무시하고
|
|
103
|
+
실제 DB 에 붙으려고 하는데, npm run dev 에서 MockServer 가 concurrent 로
|
|
104
|
+
기동되어 있으니 그걸 먼저 확인하고 써.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Dispatcher 는 자동으로 분류:
|
|
108
|
+
- **대상 에이전트**: `generator-backend`
|
|
109
|
+
- **저장 위치**: `.harness/gotchas/generator-backend.md`
|
|
110
|
+
- **ID 할당**: `[G-002]` (기존 항목 다음 번호)
|
|
111
|
+
|
|
112
|
+
#### 기록 포맷 (Dispatcher 가 자동 작성)
|
|
113
|
+
|
|
114
|
+
```markdown
|
|
115
|
+
### [G-002] MockServer + npm run dev 자동 기동 + OpenAPI 동기화
|
|
116
|
+
- **Date**: 2026-04-22
|
|
117
|
+
- **Severity**: HIGH
|
|
118
|
+
- **Occurrences**: 1
|
|
119
|
+
- **Symptom**: 실제 DB 연결 시도 → 연결 실패로 스프린트 중단
|
|
120
|
+
- **Rule**: `npm run dev` 는 MockServer 를 concurrent 로 기동한다.
|
|
121
|
+
API 호출 전 `http://localhost:3001/health` 를 확인할 것.
|
|
122
|
+
- **Applies to**: generator-backend
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### 공유 메모리 (프로젝트 전체 규칙)
|
|
126
|
+
|
|
127
|
+
한 에이전트 실수가 아니라 **모든 에이전트에 적용할 구조적 교훈** 이면 `.harness/memory.md` 로 승격:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
이건 특정 Generator 실수가 아니라 이 프로젝트 공통 규칙이야 —
|
|
131
|
+
모든 테스트는 MockServer seed data 기반이어야 한다는 걸
|
|
132
|
+
메모리에 올려줘.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
→ Dispatcher 가 `memory.md` 에 `### [M-NNN] ...` 로 기록. Planner 리뷰 후 `unverified → verified` 로 승격.
|
|
136
|
+
|
|
137
|
+
#### 주의 — 데이터 보존
|
|
138
|
+
|
|
139
|
+
v5.5.2 부터 `npm install` postinstall 이 `### [G-NNN]` 엔트리가 있는 gotcha 파일을 **절대 덮어쓰지 않습니다**. 그 이전 버전에서는 업데이트 시 누적 기록이 템플릿으로 초기화되는 버그가 있었습니다 — 반드시 `5.5.2+` 를 사용하세요.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Detail Architecture
|
|
144
|
+
|
|
145
|
+
여기부터는 어떻게 구성되어 있는지, 왜 그렇게 설계했는지에 대한 상세 문서입니다.
|
|
146
|
+
|
|
12
147
|
## 두 가지 모드
|
|
13
148
|
|
|
14
149
|
| 모드 | 설명 | 실행 방법 |
|
|
@@ -31,7 +166,7 @@ npm install @walwal-harness/cli
|
|
|
31
166
|
|
|
32
167
|
`postinstall`이 자동으로:
|
|
33
168
|
1. `.harness/` 디렉토리 스캐폴딩
|
|
34
|
-
2. `.claude/skills/` 에 에이전트 스킬 설치 (
|
|
169
|
+
2. `.claude/skills/` 에 에이전트 스킬 설치 (8개)
|
|
35
170
|
3. `.claude/commands/` 에 모드 제어 커맨드 설치 (3개)
|
|
36
171
|
4. `scripts/` 에 오케스트레이션 스크립트 설치
|
|
37
172
|
5. SessionStart / UserPromptSubmit 훅 등록
|
|
@@ -45,8 +180,7 @@ npm install @walwal-harness/cli
|
|
|
45
180
|
npm update @walwal-harness/cli
|
|
46
181
|
```
|
|
47
182
|
|
|
48
|
-
npm update 시 모든 시스템 파일(scripts, skills, commands)이 **자동으로 교체**됩니다.
|
|
49
|
-
사용자 데이터(progress.json, progress.log, gotchas 커스텀 항목, archive)는 보존됩니다.
|
|
183
|
+
npm update 시 모든 시스템 파일(scripts, skills, commands, config 템플릿)이 **자동으로 교체**됩니다. 사용자 데이터(progress.json, progress.log, **gotchas 누적 엔트리**, memory.md, archive)는 보존됩니다.
|
|
50
184
|
|
|
51
185
|
### CLI 명령어
|
|
52
186
|
|
|
@@ -60,40 +194,67 @@ npx walwal-harness --help # 도움말
|
|
|
60
194
|
|
|
61
195
|
---
|
|
62
196
|
|
|
63
|
-
##
|
|
197
|
+
## 에이전트 구성
|
|
64
198
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
199
|
+
| 에이전트 | 역할 | 모델 |
|
|
200
|
+
|----------|------|------|
|
|
201
|
+
| **Dispatcher** | 요청 분석 → 파이프라인 결정 · gotcha 관리 | opus |
|
|
202
|
+
| **Brainstormer** | 러프한 요구사항 → 구조화된 spec | opus |
|
|
203
|
+
| **Planner** | 제품 사양 + API 계약서 + 서비스 분할 | opus |
|
|
204
|
+
| **Generator-Backend** | NestJS MSA 서비스 구현 | sonnet |
|
|
205
|
+
| **Generator-Frontend** | React/Next.js UI 구현 | sonnet |
|
|
206
|
+
| **Evaluator-Code-Quality** | 코드 유지보수성/아키텍처/Best Practice (BE/FE/libs 공통, 브라우저 없음) | opus |
|
|
207
|
+
| **Evaluator-Functional** | Playwright E2E 기능 검증 · API 계약 준수 | opus |
|
|
208
|
+
| **Evaluator-Visual** | 레이아웃/접근성/AI슬롭 검증 | opus |
|
|
68
209
|
|
|
69
|
-
|
|
70
|
-
claude # (또는 codex)
|
|
210
|
+
### Evaluator Chain (v5.5+)
|
|
71
211
|
|
|
72
|
-
|
|
73
|
-
> 하네스 엔지니어링 시작
|
|
212
|
+
Generator 이후는 **3-Evaluator 직렬 체인 + 조기 종료** 로 동작:
|
|
74
213
|
|
|
75
|
-
# 4. Dispatcher → Planner 순서로 자동 진행
|
|
76
|
-
# 5. Generator, Evaluator를 프롬프트로 순차 호출
|
|
77
214
|
```
|
|
215
|
+
Generator
|
|
216
|
+
→ Evaluator-Code-Quality (정적 · 저비용 · 브라우저 없음)
|
|
217
|
+
→ Evaluator-Functional (동작 · 중비용 · Playwright/curl)
|
|
218
|
+
→ Evaluator-Visual (렌더 · 고비용 · 스크린샷)
|
|
219
|
+
→ Archive
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
앞단 FAIL 시 뒤 평가자는 실행하지 않고 바로 Generator 재작업으로 리라우팅. BE-ONLY 파이프라인에서는 Visual 이 체인에서 제외됩니다.
|
|
223
|
+
|
|
224
|
+
| 단계 | 채점 축 | Weight | 도구 |
|
|
225
|
+
|------|---------|--------|------|
|
|
226
|
+
| Code-Quality | C1 Layer · C2 Readability · C3 DRY · C4 Type/Error · C5 Test | 25/15/20/25/15 | Read/Grep + tsc/eslint |
|
|
227
|
+
| Functional | R1 Contract · R2 AC · R3 Negative · R4 E2E · R5 Error | 25/25/20/15/15 | Playwright 또는 curl |
|
|
228
|
+
| Visual | V1 Layout · V2 Responsive · V3 A11y · V4 Consistency · V5 Interaction | 20×5 | Playwright 스크린샷 |
|
|
229
|
+
|
|
230
|
+
### Evaluation 기준
|
|
231
|
+
- PASS: Weighted Score ≥ 2.80 / 3.00
|
|
232
|
+
- AC 100% 충족 필수 (부분 통과 = FAIL)
|
|
233
|
+
- Regression 실패 1건+ = FAIL (이전 Sprint PASS 기능 재검증)
|
|
234
|
+
- Evidence 없는 Score = 0점 강제 재계산
|
|
235
|
+
- Cross-Validation 불일치 1건+ = CONDITIONAL FAIL
|
|
236
|
+
- Team Mode: 최대 5회 재시도 후 사용자 개입 요청
|
|
78
237
|
|
|
79
|
-
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 솔로 파이프라인 상세
|
|
80
241
|
|
|
81
242
|
```
|
|
82
243
|
사용자 요청 → Dispatcher → (Brainstormer) → Planner
|
|
83
244
|
→ Generator-Backend → Generator-Frontend
|
|
84
|
-
→ Evaluator-Functional → Evaluator-Visual
|
|
245
|
+
→ Evaluator-Code-Quality → Evaluator-Functional → Evaluator-Visual
|
|
85
246
|
→ PASS: 다음 Sprint | FAIL: Generator로 재시도 (최대 5회)
|
|
86
247
|
```
|
|
87
248
|
|
|
88
|
-
|
|
249
|
+
각 에이전트는 **독립 Claude Code 세션** 에서 실행됩니다. Session Boundary Protocol 이 On Start / On Complete / On Fail 훅으로 progress.json 을 갱신하고 STOP. 다음 세션을 열면 SessionStart 훅이 자동으로 다음 에이전트를 안내합니다.
|
|
89
250
|
|
|
90
|
-
##
|
|
251
|
+
## 팀 파이프라인 상세
|
|
91
252
|
|
|
92
253
|
```bash
|
|
93
|
-
# Planner 완료
|
|
254
|
+
# Planner 완료 후
|
|
94
255
|
> /harness-team
|
|
95
256
|
|
|
96
|
-
#
|
|
257
|
+
# 자동 실행 흐름:
|
|
97
258
|
# 1. feature-queue.json 초기화 (의존성 topological sort)
|
|
98
259
|
# 2. tmux Studio 레이아웃 구축
|
|
99
260
|
# 3. 3개 팀이 병렬로 Gen→Eval 루프 자동 실행
|
|
@@ -101,23 +262,7 @@ claude # (또는 codex)
|
|
|
101
262
|
# 5. 5회 초과 실패 시 사용자 개입 요청
|
|
102
263
|
```
|
|
103
264
|
|
|
104
|
-
###
|
|
105
|
-
|
|
106
|
-
```
|
|
107
|
-
┌──────────────┬──────────────┬──────────────┐
|
|
108
|
-
│ Prompt │ Dashboard │ TEAM 1 │
|
|
109
|
-
│ History │ (queue + │ Gen | Eval │
|
|
110
|
-
│ │ status) ├──────────────┤
|
|
111
|
-
├──────────────┤ │ TEAM 2 │
|
|
112
|
-
│ Controller │ │ Gen | Eval │
|
|
113
|
-
│ (Claude / │ ├──────────────┤
|
|
114
|
-
│ Codex) │ │ TEAM 3 │
|
|
115
|
-
└──────────────┴──────────────┴──────────────┘
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## 모드 전환
|
|
265
|
+
### 모드 전환
|
|
121
266
|
|
|
122
267
|
| 명령 | 설명 |
|
|
123
268
|
|------|------|
|
|
@@ -133,27 +278,6 @@ Team 실행 중 → /harness-stop → /harness-solo → 프롬프트로 계속
|
|
|
133
278
|
|
|
134
279
|
---
|
|
135
280
|
|
|
136
|
-
## 에이전트 구성
|
|
137
|
-
|
|
138
|
-
| 에이전트 | 역할 | 모델 |
|
|
139
|
-
|----------|------|------|
|
|
140
|
-
| **Dispatcher** | 요청 분석 → 파이프라인 결정 | opus |
|
|
141
|
-
| **Brainstormer** | 러프한 요구사항 → 구조화된 spec | opus |
|
|
142
|
-
| **Planner** | 제품 사양 + API 계약서 + 서비스 분할 | opus |
|
|
143
|
-
| **Generator-Backend** | NestJS MSA 서비스 구현 | sonnet |
|
|
144
|
-
| **Generator-Frontend** | React/Next.js UI 구현 | sonnet |
|
|
145
|
-
| **Evaluator-Functional** | Playwright E2E 기능 검증 | opus |
|
|
146
|
-
| **Evaluator-Visual** | 디자인/접근성/AI슬롭 검증 | opus |
|
|
147
|
-
|
|
148
|
-
### Evaluation 기준
|
|
149
|
-
- PASS: Weighted Score ≥ 2.80/3.00
|
|
150
|
-
- AC 100% 충족 필수 (부분 통과 = FAIL)
|
|
151
|
-
- Regression 실패 1건+ = FAIL
|
|
152
|
-
- Evidence 없는 Score = 0점
|
|
153
|
-
- Team Mode: 최대 5회 재시도 후 사용자 개입 요청
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
281
|
## 디렉토리 구조
|
|
158
282
|
|
|
159
283
|
```
|
|
@@ -162,21 +286,34 @@ your-project/
|
|
|
162
286
|
│ ├── config.json # 하네스 설정
|
|
163
287
|
│ ├── progress.json # 런타임 상태 (mode, sprint, agent)
|
|
164
288
|
│ ├── progress.log # 실시간 이벤트 로그
|
|
289
|
+
│ ├── memory.md # 공유 학습 기록 (모든 에이전트 공통)
|
|
165
290
|
│ ├── HARNESS.md # 하네스 상세 가이드
|
|
166
291
|
│ ├── actions/ # 활성 스프린트 문서
|
|
167
|
-
│ │ ├──
|
|
168
|
-
│ │ ├──
|
|
292
|
+
│ │ ├── pipeline.json # Dispatcher 결정 (evaluator_chain 포함)
|
|
293
|
+
│ │ ├── plan.md
|
|
294
|
+
│ │ ├── feature-list.json # Feature 목록 + Executable AC
|
|
295
|
+
│ │ ├── api-contract.json
|
|
169
296
|
│ │ ├── feature-queue.json # Feature Queue 상태 (Team Mode)
|
|
170
|
-
│ │
|
|
297
|
+
│ │ ├── sprint-contract.md
|
|
298
|
+
│ │ ├── evaluation-code-quality.md
|
|
299
|
+
│ │ ├── evaluation-functional.md
|
|
300
|
+
│ │ └── evaluation-visual.md
|
|
171
301
|
│ ├── archive/ # 완료 스프린트 보관 (불변)
|
|
172
|
-
│ └── gotchas/ # 에이전트 실수 기록
|
|
302
|
+
│ └── gotchas/ # 에이전트 실수 기록 (누적 보존)
|
|
303
|
+
│ ├── planner.md
|
|
304
|
+
│ ├── generator-backend.md
|
|
305
|
+
│ ├── generator-frontend.md
|
|
306
|
+
│ ├── evaluator-code-quality.md
|
|
307
|
+
│ ├── evaluator-functional.md
|
|
308
|
+
│ └── evaluator-visual.md
|
|
173
309
|
├── .claude/
|
|
174
|
-
│ ├── skills/harness-*/ # 에이전트 스킬 (
|
|
310
|
+
│ ├── skills/harness-*/ # 에이전트 스킬 (8개)
|
|
175
311
|
│ ├── commands/harness-*.md # 모드 제어 커맨드 (3개)
|
|
176
312
|
│ └── settings.json # 훅, statusline
|
|
177
313
|
├── scripts/
|
|
178
314
|
│ ├── harness-tmux.sh # 통합 tmux 레이아웃 (Solo/Team)
|
|
179
315
|
│ ├── harness-dashboard.sh # 통합 대시보드
|
|
316
|
+
│ ├── harness-gotcha-memory.sh # Gotcha & Memory 패널
|
|
180
317
|
│ ├── harness-monitor.sh # 에이전트 모니터
|
|
181
318
|
│ ├── harness-queue-manager.sh # Feature Queue 관리
|
|
182
319
|
│ ├── harness-next.sh # 에이전트 전환 라우터
|
|
@@ -186,7 +323,7 @@ your-project/
|
|
|
186
323
|
│ ├── harness-prompt-history.sh # 프롬프트 히스토리
|
|
187
324
|
│ └── lib/ # 공유 라이브러리
|
|
188
325
|
├── AGENTS.md # 프로젝트 컨텍스트 (IA-MAP)
|
|
189
|
-
└── CLAUDE.md → AGENTS.md
|
|
326
|
+
└── CLAUDE.md → AGENTS.md # 심볼릭 링크
|
|
190
327
|
```
|
|
191
328
|
|
|
192
329
|
---
|
|
@@ -218,6 +355,14 @@ cat .harness/progress.json | jq '{mode, sprint, current_agent, next_agent}'
|
|
|
218
355
|
jq '.mode = "solo"' .harness/progress.json > /tmp/p.json && mv /tmp/p.json .harness/progress.json
|
|
219
356
|
```
|
|
220
357
|
|
|
358
|
+
### 대시보드에 feature title 이 "?" 로 표시
|
|
359
|
+
- v5.5.1 에서 해결 (feature 의 `name`/`title`/`description` 순으로 fallback).
|
|
360
|
+
- 그 이전 버전이면 `npm i @walwal-harness/cli@latest` 로 업데이트.
|
|
361
|
+
|
|
362
|
+
### Gotcha 가 누적되지 않고 사라짐
|
|
363
|
+
- v5.5.2 에서 해결 (postinstall 이 누적 엔트리를 절대 덮어쓰지 않도록 수정).
|
|
364
|
+
- 반드시 `5.5.2+` 사용.
|
|
365
|
+
|
|
221
366
|
---
|
|
222
367
|
|
|
223
368
|
## License
|
package/bin/init.js
CHANGED
|
@@ -101,27 +101,38 @@ function scaffoldHarness() {
|
|
|
101
101
|
ensureDir(path.join(HARNESS_DIR, 'archive'));
|
|
102
102
|
ensureDir(path.join(HARNESS_DIR, 'gotchas'));
|
|
103
103
|
|
|
104
|
-
// Copy gotchas —
|
|
104
|
+
// Copy gotchas — preserve any existing file that has accumulated entries.
|
|
105
|
+
// Dispatcher appends `### [G-NNN] ...` entries directly; we must NEVER overwrite
|
|
106
|
+
// a file that has such entries, or user learning history is lost.
|
|
105
107
|
const gotchasSrc = path.join(PKG_ROOT, 'gotchas');
|
|
106
108
|
if (fs.existsSync(gotchasSrc)) {
|
|
107
|
-
const
|
|
109
|
+
const ENTRY_PATTERN = /^### \[G-\d+\]/m; // Gotcha entry heading
|
|
110
|
+
const CUSTOM_MARKER = '## Custom Gotchas'; // Legacy marker still supported
|
|
108
111
|
const files = fs.readdirSync(gotchasSrc);
|
|
109
112
|
for (const file of files) {
|
|
110
113
|
const destPath = path.join(HARNESS_DIR, 'gotchas', file);
|
|
111
114
|
const srcPath = path.join(gotchasSrc, file);
|
|
112
|
-
if (fileExists(destPath)
|
|
113
|
-
// Preserve user-added custom section
|
|
114
|
-
const existing = fs.readFileSync(destPath, 'utf8');
|
|
115
|
-
const customIdx = existing.indexOf(CUSTOM_MARKER);
|
|
116
|
-
const userCustom = customIdx !== -1 ? existing.substring(customIdx) : '';
|
|
117
|
-
let newContent = fs.readFileSync(srcPath, 'utf8');
|
|
118
|
-
if (userCustom) {
|
|
119
|
-
newContent = newContent.trimEnd() + '\n\n' + userCustom;
|
|
120
|
-
}
|
|
121
|
-
fs.writeFileSync(destPath, newContent);
|
|
122
|
-
} else {
|
|
115
|
+
if (!fileExists(destPath)) {
|
|
123
116
|
copyFile(srcPath, destPath);
|
|
117
|
+
continue;
|
|
124
118
|
}
|
|
119
|
+
if (!file.endsWith('.md')) continue;
|
|
120
|
+
|
|
121
|
+
const existing = fs.readFileSync(destPath, 'utf8');
|
|
122
|
+
const hasEntries = ENTRY_PATTERN.test(existing);
|
|
123
|
+
const hasCustomSection = existing.indexOf(CUSTOM_MARKER) !== -1;
|
|
124
|
+
|
|
125
|
+
if (hasEntries || hasCustomSection) {
|
|
126
|
+
// User has accumulated data — DO NOT overwrite. Skip silently.
|
|
127
|
+
// README.md is the only exception (system doc, regenerated below).
|
|
128
|
+
if (file === 'README.md') {
|
|
129
|
+
copyFile(srcPath, destPath);
|
|
130
|
+
}
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// File exists but is just the scaffold template — safe to refresh
|
|
135
|
+
copyFile(srcPath, destPath);
|
|
125
136
|
}
|
|
126
137
|
}
|
|
127
138
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.3",
|
|
4
4
|
"description": "Production harness for AI agent engineering — Solo/Team mode, Planner, Generator(BE/FE), Evaluator chain (Code-Quality → Functional → Visual), optional Brainstormer. Supports React, Next.js, and Flutter FE stacks.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"walwal-harness": "bin/init.js"
|