@walwal-harness/cli 5.6.4 → 5.6.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@walwal-harness/cli",
3
- "version": "5.6.4",
3
+ "version": "5.6.5",
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"
@@ -54,7 +54,7 @@ if [ -f "$PIPELINE_JSON" ]; then
54
54
  fe_target=$(jq -r '.fe_target // empty' "$PIPELINE_JSON" 2>/dev/null || true)
55
55
  if [ -z "$fe_target" ]; then
56
56
  # pipeline.json 에 fe_target 미지정 시 config.json 의 _default_target 사용
57
- fe_target=$(jq -r ".flow.pipeline_selection.fe_stack_substitution.${fe_stack}._default_target // \"web\"" "$CONFIG" 2>/dev/null || echo "web")
57
+ fe_target="web" # v5.6.5+: 치환 로직 제거. fe_target 은 pipeline.json 에서 명시하거나 web 기본.
58
58
  fi
59
59
  fi
60
60
 
@@ -29,9 +29,10 @@ get_allowed_paths() {
29
29
  echo "tsconfig"
30
30
  echo "docker-compose"
31
31
  ;;
32
- generator-frontend|generator-frontend-flutter)
32
+ generator-frontend)
33
33
  echo "apps/web/"
34
34
  echo "apps/flutter/"
35
+ echo "lib/"
35
36
  echo ".harness/actions/sprint-contract.md"
36
37
  echo ".harness/actions/feature-list.json"
37
38
  echo ".harness/progress.json"
@@ -43,7 +44,7 @@ get_allowed_paths() {
43
44
  echo ".harness/actions/evaluation-code-quality.md"
44
45
  echo ".harness/progress.json"
45
46
  ;;
46
- evaluator-functional|evaluator-functional-flutter)
47
+ evaluator-functional)
47
48
  echo ".harness/actions/evaluation-functional.md"
48
49
  echo ".harness/progress.json"
49
50
  echo "tests/"
@@ -311,7 +311,7 @@ render_agent_bar() {
311
311
  fe_stack=$(jq -r '.fe_stack // "react"' "$PIPELINE_JSON" 2>/dev/null || echo "react")
312
312
  fe_target=$(jq -r '.fe_target // empty' "$PIPELINE_JSON" 2>/dev/null || true)
313
313
  if [ -z "$fe_target" ]; then
314
- fe_target=$(jq -r ".flow.pipeline_selection.fe_stack_substitution.${fe_stack}._default_target // \"web\"" "$CONFIG" 2>/dev/null || echo "web")
314
+ fe_target="web" # v5.6.5+: 치환 로직 제거. 기본 web.
315
315
  fi
316
316
  fi
317
317
 
@@ -325,14 +325,7 @@ render_agent_bar() {
325
325
 
326
326
  while IFS= read -r agent; do
327
327
  agent=$(echo "$agent" | sed 's/:.*//') # strip mode suffix like :light, :api-only
328
-
329
- # fe_stack + fe_target 치환 적용
330
- if [ "$fe_stack" = "flutter" ]; then
331
- local sub
332
- sub=$(jq -r ".flow.pipeline_selection.fe_stack_substitution.flutter.by_target[\"${fe_target}\"][\"${agent}\"] // \"${agent}\"" "$CONFIG" 2>/dev/null)
333
- if [ "$sub" = "__skip__" ]; then continue; fi
334
- agent="$sub"
335
- fi
328
+ # v5.6.5+: fe_stack 에이전트 치환 제거. 스택별 동작은 ref-docs 로 조절.
336
329
 
337
330
  if [ "$first" = true ]; then
338
331
  first=false
@@ -147,7 +147,7 @@ AGENTS.md 비하네스 → 기존 백업 + 리빌드
147
147
  - FULLSTACK / FE-ONLY: `["evaluator-code-quality", "evaluator-functional", "evaluator-visual"]`
148
148
  - BE-ONLY: `["evaluator-code-quality", "evaluator-functional"]` (functional 은 api-only 모드)
149
149
 
150
- Flutter 치환 규칙은 chain 배열의 각 원소에도 동일 적용. `fe_stack == "flutter"` + `fe_target in (mobile, desktop)` 이면 `evaluator-visual` 을 chain 에서 제거하고 `evaluator-functional` → `evaluator-functional-flutter` 로 치환한다. `evaluator-code-quality` 는 스택/타겟 무관 공통.
150
+ 스택 특성(예: Flutter mobile 에서 Visual skip) 이 필요하면 해당 스택 ref-docs (`.harness/ref/fe-<stack>.md`) 의 `validation.visual.enabled` 를 false 로 두면 evaluator-visual 이 MANUAL_REQUIRED 로 우아하게 우회한다. 별도 치환 에이전트는 사용하지 않는다.
151
151
 
152
152
  ### Evaluator 체인 라우팅 규칙
153
153
 
@@ -163,11 +163,9 @@ Gotcha retry 시에도 체인 시작점은 chain[0] 부터 재실행.
163
163
 
164
164
  FE-ONLY 또는 FULLSTACK 선택 시, `pipeline.json`에 **`fe_stack`** 필드를 포함해야 한다:
165
165
 
166
- - `scan-result.json.tech_stack.fe_stack` 값을 기본으로 사용 (`react` | `flutter`)
166
+ - `scan-result.json.tech_stack.fe_stack` 값을 기본으로 사용 (예: `react`, `nextjs`, `vue`, `flutter`, `swift` 등)
167
167
  - 값이 없거나 불명확하면 Planner가 확정하도록 위임 (Dispatcher는 `"unknown"` 기록 + `notes` 에 메모)
168
- - Flutter 선택 시 `agents_active`/`agents_skipped`에 치환된 에이전트명을 기록
169
- - active: `generator-frontend-flutter`, `evaluator-functional-flutter`
170
- - skipped: `generator-frontend`, `evaluator-functional`, `evaluator-visual`
168
+ - **에이전트 이름 치환은 하지 않는다** (v5.6.5+). 모든 FE 스택은 공통 `generator-frontend` / `evaluator-functional` / `evaluator-visual` 을 사용하고, 스택 특성은 `.harness/ref/fe-<stack>.md` (adaptive ref-docs) 에서 로드한다.
171
169
 
172
170
  ## 6. Brainstormer Routing Decision
173
171
 
@@ -222,7 +220,7 @@ Planner 를 호출해야 한다고 판단되면, **사용자에게 단 하나의
222
220
  | 상황 | next_agent |
223
221
  |------|-----------|
224
222
  | "Eval, X 다시 검증해" | `evaluator-functional` (또는 `evaluator-visual`) |
225
- | "Generator-FE, Y 버그 고쳐" | `generator-frontend` (또는 Flutter 변형) |
223
+ | "Generator-FE, Y 버그 고쳐" | `generator-frontend` |
226
224
  | "Generator-BE, API 재생성해" | `generator-backend` |
227
225
  | Eval FAIL → retry | `failure.retry_target` |
228
226
  | Gotcha 수정 | `failure.retry_target` 또는 현재 에이전트 |
@@ -240,14 +238,8 @@ Planner 를 호출해야 한다고 판단되면, **사용자에게 단 하나의
240
238
  이 경우 기존 `.harness/actions/brainstorm-spec.md` 는 Brainstormer 의 On Start 에서
241
239
  `.harness/archive/brainstorm-spec-<timestamp>.md` 로 백업된다.
242
240
 
243
- ## 7. Handoff 라우팅 (fe_stack 반영)
241
+ ## 7. Handoff 라우팅
244
242
 
245
- Dispatcher가 `next_agent` 를 세팅할 때 pipeline.json.fe_stack 을 참조해 치환:
243
+ Dispatcher 가 `next_agent` 를 세팅할 때 **스택별 에이전트 이름 치환은 하지 않는다** (v5.6.5+). 모든 FE 스택이 공통 `generator-frontend` / `evaluator-functional` / `evaluator-visual` 을 사용하고, 스택 특성은 adaptive ref-docs(`.harness/ref/fe-<stack>.md`) 에서 로드한다.
246
244
 
247
- | 원본 next_agent | fe_stack=react | fe_stack=flutter |
248
- |-----------------|----------------|------------------|
249
- | generator-frontend | generator-frontend | generator-frontend-flutter |
250
- | evaluator-functional (FE 단계) | evaluator-functional | evaluator-functional-flutter |
251
- | evaluator-visual | evaluator-visual | (skip → 다음 단계로 이동) |
252
-
253
- **Brainstormer 는 fe_stack 치환 대상이 아니다** — 언어/스택 무관 공통 에이전트.
245
+ 예외적 스킵 규칙은 ref-docs 의 `validation.visual.enabled` 플래그로 제어 — false 면 evaluator-visual 이 MANUAL_REQUIRED 로 우아하게 우회한다 (별도 에이전트 이름 변경 없음).
@@ -28,35 +28,19 @@ docmeta:
28
28
 
29
29
  # Pipeline Definitions
30
30
 
31
- > **FE Stack 차원**: 모든 FE 관련 파이프라인은 `fe_stack` 필드로 React/Flutter를 구분한다.
31
+ > **FE Stack 차원**: 모든 FE 관련 파이프라인은 `fe_stack` 필드로 스택을 기록한다.
32
32
  > Planner가 scan-result.json(`tech_stack.fe_stack`) 또는 사용자 질문으로 확정한다.
33
33
 
34
- ## fe_stack + fe_target 스위치 매트릭스
34
+ ## 단일 에이전트 체인 (v5.6.5+)
35
35
 
36
- | fe_stack | fe_target | FE Generator | Eval-Functional | Eval-Visual |
37
- |----------|-----------|--------------|----------------|-------------|
38
- | `react` | (n/a) | `generator-frontend` | `evaluator-functional` (Playwright) | `evaluator-visual` |
39
- | `flutter`| **`web`** | `generator-frontend-flutter` | **`evaluator-functional`** (Playwright!) | **`evaluator-visual`** (Playwright!) |
40
- | `flutter`| `mobile` | `generator-frontend-flutter` | `evaluator-functional-flutter` (정적 분석) | **SKIP** |
41
- | `flutter`| `desktop` | `generator-frontend-flutter` | `evaluator-functional-flutter` (정적 분석) | **SKIP** |
36
+ **에이전트 이름 치환은 하지 않는다**. 모든 FE 스택(React, Next.js, Vue, Svelte, Flutter, Swift, 기타) 은 공통 `generator-frontend` / `evaluator-functional` / `evaluator-visual` 을 사용하며, 스택 특성(runner, paths, API, validation) 은 **adaptive ref-docs** (`.harness/ref/fe-<stack>.md`) 에서 로드한다.
42
37
 
43
- > **Flutter Web**: 컴파일 결과가 HTML+JS+CSS 이므로 React 경로의 Playwright evaluator 가 정상 동작.
44
- > Generator-Frontend-Flutter 의 Self-Verification 에서 `flutter analyze` / `flutter test` /
45
- > `flutter build web --release` 가 이미 통과한 상태로 handoff 됨이 전제.
38
+ | 스택별 스킵/우회 | 방법 |
39
+ |------------------|------|
40
+ | Visual 렌더 검증이 불가능한 네이티브 모바일/데스크톱 | ref-docs 의 `validation.visual.enabled = false` — `evaluator-visual` 이 MANUAL_REQUIRED 로 우아하게 우회 |
41
+ | Playwright 대신 스택 네이티브 E2E (예: XCUITest, Flutter `flutter_driver`) | ref-docs 의 `validation.functional_tests` 에 해당 명령 나열 — `evaluator-functional` 이 로드 실행 |
46
42
 
47
- Dispatcher는 `next_agent`를 설정할 때 `pipeline.json` 의 `fe_stack` + `fe_target` 두 값을 보고 치환한다:
48
-
49
- ```
50
- if pipeline.json.fe_stack == "flutter":
51
- "generator-frontend" → "generator-frontend-flutter" (모든 fe_target 공통)
52
-
53
- if fe_target == "web":
54
- "evaluator-functional" → "evaluator-functional" (그대로, Playwright 사용)
55
- "evaluator-visual" → "evaluator-visual" (그대로)
56
- elif fe_target in ("mobile", "desktop"):
57
- "evaluator-functional" → "evaluator-functional-flutter"
58
- "evaluator-visual" → __skip__
59
- ```
43
+ Dispatcher 는 `fe_stack` 을 `pipeline.json` 에 기록만 하고, 에이전트 이름은 변경하지 않는다. Generator/Evaluator 는 세션 시작 시 스스로 ref-docs 를 로드해 스택에 맞는 동작을 한다.
60
44
 
61
45
  ## Evaluator Chain (공통)
62
46
 
@@ -83,10 +67,10 @@ agents:
83
67
  - planner (light):
84
68
  skip: MSA 서비스 설계, BE 기능 목록
85
69
  do: OpenAPI → api-contract.json 변환, FE 컴포넌트 설계, feature-list (layer: frontend만), fe_stack 확정
86
- - generator-frontend OR generator-frontend-flutter # fe_stack에 따라
70
+ - generator-frontend # 모든 스택 공통 (ref-docs 로드)
87
71
  - evaluator-code-quality # 공통 — 브라우저 없음
88
- - evaluator-functional OR evaluator-functional-flutter
89
- - evaluator-visual # fe_stack == "flutter" + fe_target in (mobile,desktop) 이면 SKIP
72
+ - evaluator-functional # 모든 스택 공통
73
+ - evaluator-visual # ref.validation.visual.enabled=false 면 MANUAL_REQUIRED 로 우회
90
74
  evaluator_chain:
91
75
  - evaluator-code-quality
92
76
  - evaluator-functional
@@ -95,9 +79,9 @@ skip:
95
79
  - generator-backend
96
80
  notes:
97
81
  - api-contract.json은 OpenAPI에서 파생 (Planner가 변환)
98
- - Eval-Func(React)의 API Health Check는 외부 서버 대상
82
+ - Eval-Func 의 API Health Check는 외부 서버 대상 (ref.api.base_url)
99
83
  - AGENTS.md IA-MAP에 BE 경로 없음 (외부 서버)
100
- - fe_stack=flutter (mobile/desktop) 인 경우 evaluator-visual 생략
84
+ - 네이티브 모바일/데스크톱 스택은 ref-docs 에서 visual.enabled=false 로 설정
101
85
  ```
102
86
 
103
87
  ## BE-ONLY
@@ -76,14 +76,15 @@ jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/p
76
76
 
77
77
  ## fe_stack (FE 파이프라인 분기)
78
78
 
79
- `pipeline.json.fe_stack`은 FE Generator/Evaluator 선택을 결정한다:
79
+ `pipeline.json.fe_stack` 은 스택 기록용 메타데이터이며, **에이전트 이름 치환에는 사용되지 않는다** (v5.6.5+). 모든 스택이 공통 `generator-frontend` / `evaluator-functional` / `evaluator-visual` 을 사용하고, 스택별 동작(runner, paths, API, validation) 은 adaptive ref-docs(`.harness/ref/fe-<stack>.md`) 에서 로드한다.
80
80
 
81
- | 값 | FE Generator | FE Evaluator | 비고 |
82
- |----|--------------|--------------|------|
83
- | `react` (기본) | `generator-frontend` | `evaluator-functional` + `evaluator-visual` | Vercel/Next.js/Tailwind |
84
- | `flutter` | `generator-frontend-flutter` | `evaluator-functional-flutter` | Riverpod + integrated_data_layer, Eval-Visual 생략 |
81
+ | 스택 예 | ref-docs 경로 | 비고 |
82
+ |---------|--------------|------|
83
+ | `react`, `nextjs` | `.harness/ref/fe-react.md`, `.harness/ref/fe-nextjs.md` | Vercel/Next.js/Tailwind |
84
+ | `flutter` | `.harness/ref/fe-flutter.md` | Riverpod · validation.visual.enabled=false (모바일/데스크톱) |
85
+ | `vue`, `svelte`, `swift` 등 | `.harness/ref/fe-<stack>.md` | 각 스택 관례 |
85
86
 
86
- **Planner는 `pipeline.json`에 `fe_stack`을 반드시 기록해야 한다.** Dispatcher가 이 값으로 `next_agent`를 라우팅한다.
87
+ **Planner는 `pipeline.json`에 `fe_stack`을 반드시 기록해야 한다.** Generator/Evaluator 는 세션 시작 시 이 값으로 올바른 ref-docs 를 로드한다.
87
88
 
88
89
  ## Process
89
90
 
@@ -107,72 +107,58 @@ Flutter 프로젝트의 타깃을 확인합니다:
107
107
  이번 스프린트의 타깃은? (A/B/C)
108
108
  ```
109
109
 
110
- ### fe_target → Eval 흐름
110
+ ### fe_target 과 Eval 흐름 (v5.6.5+)
111
111
 
112
- | fe_target | Generator | Eval-Functional | Eval-Visual |
113
- |-----------|-----------|----------------|-------------|
114
- | `web` | `generator-frontend-flutter` | `evaluator-functional` (Playwright!) | `evaluator-visual` (Playwright!) |
115
- | `mobile` | `generator-frontend-flutter` | `evaluator-functional-flutter` (정적 분석) | SKIP |
116
- | `desktop` | `generator-frontend-flutter` | `evaluator-functional-flutter` (정적 분석) | SKIP |
112
+ 에이전트 이름 치환은 하지 않는다. 모든 스택이 공통 `generator-frontend` / `evaluator-functional` / `evaluator-visual` 을 사용하고, 스택 특성은 `.harness/ref/fe-<stack>.md` (adaptive ref-docs) 의 `validation` 블록으로 조절된다.
117
113
 
118
- **핵심**: Flutter Web 의 빌드 결과물(HTML/JS/CSS)은 일반 웹앱과 동일하므로 Playwright 기반
119
- React 경로의 evaluator 를 그대로 재사용한다. Generator-Frontend-Flutter 의 Self-Verification
120
- 단계에서 `flutter analyze`/`flutter test`/`flutter build web` 정적 검증이 이미 통과한 상태로 handoff 된다.
114
+ | fe_target | 전략 | 방법 |
115
+ |-----------|------|------|
116
+ | `web` (Flutter Web, Next.js 등) | 일반 Playwright 평가 | ref.validation.visual.enabled = true |
117
+ | `mobile` (iOS/Android 네이티브) | Visual 은 MANUAL_REQUIRED | ref.validation.visual.enabled = false + functional_tests 에 스택 네이티브 명령 |
118
+ | `desktop` (macOS/Windows/Linux 네이티브) | Visual MANUAL_REQUIRED | 동일 |
119
+
120
+ Generator 는 `ref.runner.dev_command` / `ref.paths.*` 를 로드해 스택별 빌드·테스트·구조를 따른다.
121
121
 
122
122
  ## 3. pipeline.json 갱신
123
123
 
124
- `fe_stack` + `fe_target` 확정 후 `pipeline.json`에 반드시 추가:
124
+ `fe_stack` + `fe_target` 확정 후 `pipeline.json` 에 기록:
125
125
 
126
126
  ```json
127
127
  {
128
128
  "pipeline": "FULLSTACK",
129
129
  "planner_mode": "full",
130
130
  "fe_stack": "flutter",
131
- "fe_target": "web",
131
+ "fe_target": "mobile",
132
132
  "agents_active": [
133
133
  "planner",
134
134
  "generator-backend",
135
- "generator-frontend-flutter",
136
- "evaluator-functional",
137
- "evaluator-visual"
138
- ],
139
- "agents_skipped": [
140
135
  "generator-frontend",
141
- "evaluator-functional-flutter"
136
+ "evaluator-code-quality",
137
+ "evaluator-functional"
142
138
  ],
143
- "evaluator_mode": "playwright-web",
144
- "notes": "Flutter Web — 컴파일 결과가 HTML+JS+CSS 이므로 React 경로의 Playwright evaluator 사용. Generator 의 Self-Verification 에서 flutter analyze/test 통과 전제."
139
+ "agents_skipped": [],
140
+ "evaluator_mode": "native",
141
+ "notes": "Flutter mobile — ref.validation.visual.enabled=false, evaluator-visual 은 MANUAL_REQUIRED 로 우회."
145
142
  }
146
143
  ```
147
144
 
148
145
  ### fe_stack + fe_target → 파이프라인 매핑
149
146
 
150
- | pipeline | fe_stack | fe_target | agents_active 예시 |
151
- |----------|----------|-----------|-------------------|
152
- | FULLSTACK | react | (n/a) | planner, generator-backend, generator-frontend, evaluator-functional, evaluator-visual |
153
- | FULLSTACK | flutter | **web** | planner, generator-backend, generator-frontend-flutter, evaluator-functional, evaluator-visual |
154
- | FULLSTACK | flutter | mobile | planner, generator-backend, generator-frontend-flutter, evaluator-functional-flutter |
155
- | FULLSTACK | flutter | desktop | planner, generator-backend, generator-frontend-flutter, evaluator-functional-flutter |
156
- | FE-ONLY | react | (n/a) | planner, generator-frontend, evaluator-functional, evaluator-visual |
157
- | FE-ONLY | flutter | **web** | planner, generator-frontend-flutter, evaluator-functional, evaluator-visual |
158
- | FE-ONLY | flutter | mobile | planner, generator-frontend-flutter, evaluator-functional-flutter |
159
- | BE-ONLY | (무관) | (n/a) | planner, generator-backend, evaluator-functional |
160
-
161
- ## 4. Flutter 선택 시 추가 작업
162
-
163
- Flutter로 확정되면 Planner는:
164
-
165
- 1. **AGENTS.md IA-MAP** 의 `[FE]` 섹션을 Flutter 구조로 바꿔야 한다.
166
- - `apps/web/` → `lib/ui/pages/`, `lib/ui/component/`
167
- - `libs/shared-dto/` 대신 `integrated_data_layer/` 경로 등록
168
- - 소유자: `→ Generator-Frontend-Flutter`
147
+ | pipeline | 에이전트 체인 (스택 무관) | ref-docs 로 조절되는 부분 |
148
+ |----------|--------------------------|---------------------------|
149
+ | FULLSTACK | planner → gen-be → gen-fe → eval-code-quality → eval-func → eval-visual | Gen/Eval 모두 ref.* 로드 |
150
+ | FE-ONLY | planner(light) → gen-fe → eval-code-quality → eval-func → eval-visual | 동일 |
151
+ | BE-ONLY | planner → gen-be → eval-code-quality → eval-func | visual 체인 없음 |
169
152
 
170
- 2. **api-contract.json** 은 언어 중립적이어야 한다 — Planner는 TypeScript 타입이 아니라 **스키마 JSON** 으로만 작성. Flutter Generator가 Retrofit/JsonSerializable로 변환한다.
153
+ ## 4. Flutter 등 네이티브 스택 선택 시 추가 작업
171
154
 
172
- 3. **feature-list.json** 의 `layer: "frontend"` feature들은 `fe_stack: "flutter"` 태그를 달아서 Evaluator가 구분하도록 한다.
155
+ 1. **AGENTS.md IA-MAP** 의 `[FE]` 섹션에 해당 스택 구조 반영 (예: Flutter 면 `lib/ui/pages/`, `integrated_data_layer/` 등).
156
+ 2. **api-contract.json** 은 언어 중립 스키마 JSON — Generator 가 스택 타입으로 변환.
157
+ 3. **feature-list.json** 의 `layer: "frontend"` feature 에 `fe_stack` 태그 유지 (필터링 용도).
158
+ 4. **`.harness/ref/fe-<stack>.md`** 의 `validation` 블록을 스택에 맞게 채워 두기 — 이게 실제 동작을 바꾸는 유일한 지점.
173
159
 
174
160
  ## 5. 금지
175
161
 
176
162
  - 파이프라인 실행 도중 `fe_stack` 변경 금지 — 스프린트 경계에서만 가능
177
- - React/Flutter 코드 혼재 생성 금지 — Generator는 하나의 stack만 담당
163
+ - 서로 다른 스택 코드 혼재 생성 금지 — Generator 는 하나의 stack만 담당
178
164
  - 사용자가 명시적으로 한 스택을 지시했는데 감지 결과로 다른 스택을 강제하지 말 것