@walwal-harness/cli 4.0.0-alpha.9 → 4.0.0-beta.2
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 +235 -273
- package/assets/templates/config.json +1 -48
- package/assets/templates/gitignore-append.txt +1 -0
- package/bin/init.js +42 -18
- package/package.json +1 -1
- package/scripts/harness-dashboard-v4.sh +27 -88
- package/scripts/harness-next.sh +4 -15
- package/scripts/harness-user-prompt-submit.sh +10 -0
- package/skills/dispatcher/SKILL.md +7 -2
- package/skills/team-action/SKILL.md +26 -0
- package/skills/team-stop/SKILL.md +19 -0
- package/scripts/harness-control-v4.sh +0 -97
- package/scripts/harness-studio-v4.sh +0 -122
- package/scripts/harness-team-worker.sh +0 -415
- package/skills/evaluator-functional-flutter/SKILL.md +0 -206
- package/skills/evaluator-functional-flutter/references/ia-compliance.md +0 -77
- package/skills/evaluator-functional-flutter/references/scoring-rubric.md +0 -132
- package/skills/evaluator-functional-flutter/references/static-check-rules.md +0 -99
- package/skills/generator-frontend-flutter/SKILL.md +0 -173
- package/skills/generator-frontend-flutter/references/anti-patterns.md +0 -320
- package/skills/generator-frontend-flutter/references/api-layer-pattern.md +0 -233
- package/skills/generator-frontend-flutter/references/flutter-web-pattern.md +0 -273
- package/skills/generator-frontend-flutter/references/i18n-pattern.md +0 -102
- package/skills/generator-frontend-flutter/references/riverpod-pattern.md +0 -199
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: harness-evaluator-functional-flutter
|
|
3
|
-
description: "하네스 Flutter Functional Evaluator. Playwright 대신 flutter analyze / flutter test / build_runner 일관성 / 정적 anti-pattern 검증으로 Flutter 앱을 평가한다. Step 0 IA Gate → Step 1-6 정적/동적 검증. 기준 미달 = FAIL."
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Evaluator-Functional-Flutter — Dart/Flutter 정적·동적 검증
|
|
8
|
-
|
|
9
|
-
> **이 에이전트는 `fe_target = mobile` 또는 `desktop` 일 때만 사용된다.**
|
|
10
|
-
>
|
|
11
|
-
> Flutter Mobile/Desktop 앱은 브라우저가 아니므로 Playwright MCP(`browser_*`)를 쓸 수 없다.
|
|
12
|
-
> 이 에이전트는 `flutter analyze`, `flutter test`, `dart format`, 정적 grep 검증, 생성 파일
|
|
13
|
-
> 일관성으로 평가한다. 실기기/시뮬레이터 UI 검증은 사람 QA 또는 별도 파이프라인으로 위임.
|
|
14
|
-
>
|
|
15
|
-
> **`fe_target = web` 인 Flutter Web 프로젝트는 이 에이전트가 아니라 일반 `evaluator-functional`
|
|
16
|
-
> 과 `evaluator-visual` 이 Playwright 로 검증한다** (컴파일 결과가 HTML+JS+CSS 이므로).
|
|
17
|
-
> 이 경우 Generator-Frontend-Flutter 의 Self-Verification 단계에서 `flutter analyze` /
|
|
18
|
-
> `flutter test` / `flutter build web --release` 가 이미 통과했음이 전제된다.
|
|
19
|
-
|
|
20
|
-
## Session Boundary Protocol
|
|
21
|
-
|
|
22
|
-
### On Start
|
|
23
|
-
1. `.harness/progress.json` 읽기 — `next_agent`가 `"evaluator-functional-flutter"`인지 확인
|
|
24
|
-
2. `.harness/actions/pipeline.json.fe_stack == "flutter"` 재확인 — 아니면 즉시 STOP + 불일치 보고
|
|
25
|
-
3. progress.json 업데이트: `current_agent` → `"evaluator-functional-flutter"`, `agent_status` → `"running"`, `updated_at` 갱신
|
|
26
|
-
|
|
27
|
-
### On Complete (PASS)
|
|
28
|
-
1. progress.json 업데이트:
|
|
29
|
-
- `agent_status` → `"completed"`
|
|
30
|
-
- `completed_agents`에 `"evaluator-functional-flutter"` 추가
|
|
31
|
-
- `next_agent` → `"archive"` (fe_stack=flutter 이면 evaluator-visual 생략)
|
|
32
|
-
- `failure` 필드 초기화
|
|
33
|
-
2. `feature-list.json`의 통과 feature `passes`에 `"evaluator-functional-flutter"` 추가
|
|
34
|
-
3. `.harness/progress.log`에 PASS 요약 추가
|
|
35
|
-
4. **STOP. 다음 에이전트를 직접 호출하지 않는다.**
|
|
36
|
-
5. 출력: `"✓ Evaluator-Functional-Flutter PASS. bash scripts/harness-next.sh 실행하여 다음 단계 확인."`
|
|
37
|
-
|
|
38
|
-
### On Fail
|
|
39
|
-
1. progress.json 업데이트:
|
|
40
|
-
- `agent_status` → `"failed"`
|
|
41
|
-
- `failure.agent` → `"evaluator-functional-flutter"`
|
|
42
|
-
- `failure.location` → `"frontend"` (Flutter 앱은 항상 FE 재작업)
|
|
43
|
-
- `failure.message` → 실패 요약 (1줄)
|
|
44
|
-
- `failure.retry_target` → `"generator-frontend-flutter"`
|
|
45
|
-
- `next_agent` → `"generator-frontend-flutter"`
|
|
46
|
-
- `sprint.retry_count` 증가
|
|
47
|
-
2. `sprint.retry_count >= 10`이면 `agent_status` → `"blocked"`, 사용자 개입 요청
|
|
48
|
-
3. `.harness/progress.log`에 FAIL 요약 추가
|
|
49
|
-
4. **STOP.**
|
|
50
|
-
5. 출력: `"✖ Evaluator-Functional-Flutter FAIL. bash scripts/harness-next.sh 실행하여 재작업 대상 확인."`
|
|
51
|
-
|
|
52
|
-
## Critical Mindset
|
|
53
|
-
|
|
54
|
-
- **회의적 평가자**. Generator의 자체 평가를 신뢰하지 말고 직접 돌려라.
|
|
55
|
-
- `flutter analyze` 경고가 있으면 "사소하다"고 자기 설득 금지 — 기준 미달.
|
|
56
|
-
- 코드 읽기만으로 PASS 판정 금지 — **반드시 `flutter analyze` + `flutter test` 실행**.
|
|
57
|
-
- 기준 미달 = FAIL. 예외 없음.
|
|
58
|
-
|
|
59
|
-
## Startup
|
|
60
|
-
|
|
61
|
-
1. `AGENTS.md` 읽기 — IA-MAP (Flutter 경로 확인)
|
|
62
|
-
2. `.harness/gotchas/evaluator-functional-flutter.md` (없으면 skip) — **과거 실수 반복 금지**
|
|
63
|
-
3. `.harness/memory.md` 읽기 — **프로젝트 공유 학습 규칙 적용**
|
|
64
|
-
4. `actions/sprint-contract.md` — FE 성공 기준
|
|
65
|
-
5. `actions/feature-list.json` — 이번 스프린트 범위 (`layer: "frontend"` + `fe_stack: "flutter"`)
|
|
66
|
-
6. `actions/api-contract.json` — 기대 API 계약 (Retrofit 매핑 대조용)
|
|
67
|
-
7. `.harness/progress.json`
|
|
68
|
-
8. **Generator의 anti-patterns.md 로드** — 정적 검증 rule 소스
|
|
69
|
-
→ `skills/generator-frontend-flutter/references/anti-patterns.md`
|
|
70
|
-
|
|
71
|
-
## Evaluation Steps
|
|
72
|
-
|
|
73
|
-
### Step 0: IA Structure Compliance (GATE)
|
|
74
|
-
|
|
75
|
-
AGENTS.md IA-MAP vs 실제 구조 대조. **미통과 시 이하 전체 SKIP, 즉시 FAIL.**
|
|
76
|
-
|
|
77
|
-
상세 → [IA 검증 가이드](references/ia-compliance.md)
|
|
78
|
-
|
|
79
|
-
### Step 1: `flutter analyze` (정적 분석)
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
# 프로젝트 루트 또는 integrated_data_layer 하위에서
|
|
83
|
-
flutter analyze --no-fatal-infos
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
- **warning / error 1개 이상 → FAIL**
|
|
87
|
-
- info 수준은 허용 (하지만 evaluation 보고서에 카운트 기록)
|
|
88
|
-
|
|
89
|
-
### Step 2: `flutter test` (단위/위젯 테스트)
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
# integrated_data_layer 테스트
|
|
93
|
-
cd <integrated_data_layer 경로>
|
|
94
|
-
flutter test
|
|
95
|
-
|
|
96
|
-
# 앱 테스트 (존재 시)
|
|
97
|
-
cd <app 루트>
|
|
98
|
-
flutter test
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
- **실패 1개 이상 → FAIL**
|
|
102
|
-
- 이번 스프린트에서 추가된 Request Body / Response에 `fromJson`/`toJson` 왕복 테스트 **존재 확인**
|
|
103
|
-
- 누락 시 → FAIL (Coverage gate)
|
|
104
|
-
|
|
105
|
-
### Step 3: build_runner 일관성
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
cd <integrated_data_layer 경로>
|
|
109
|
-
flutter pub run build_runner build --delete-conflicting-outputs
|
|
110
|
-
git diff --name-only
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
- 재생성 후 `*.g.dart` diff 가 발생하면 → **FAIL** (Generator가 수동 편집 또는 재생성 누락)
|
|
114
|
-
|
|
115
|
-
### Step 4: Anti-Pattern 정적 검증
|
|
116
|
-
|
|
117
|
-
`skills/generator-frontend-flutter/references/anti-patterns.md` 의 **"셀프 체크 스크립트"** 섹션을
|
|
118
|
-
그대로 실행한다. 하나라도 결과가 있으면 → **FAIL**.
|
|
119
|
-
|
|
120
|
-
상세 → [정적 검증 룰](references/static-check-rules.md)
|
|
121
|
-
|
|
122
|
-
### Step 5: API Contract Compliance
|
|
123
|
-
|
|
124
|
-
`api-contract.json` 의 엔드포인트 vs `rest_api.dart` 의 Retrofit 어노테이션 대조:
|
|
125
|
-
|
|
126
|
-
- 계약에 있는 모든 엔드포인트가 `rest_api.dart` 에 존재하는가
|
|
127
|
-
- method, path, path param, body 타입이 일치하는가
|
|
128
|
-
- Response 타입이 계약 스키마와 구조적으로 일치하는가 (필드 존재 + nullable 여부)
|
|
129
|
-
- **불일치 1개 이상 → FAIL**
|
|
130
|
-
|
|
131
|
-
### Step 6: Sprint Contract Criteria
|
|
132
|
-
|
|
133
|
-
`sprint-contract.md` 의 FE 성공 기준을 순서대로 검증:
|
|
134
|
-
|
|
135
|
-
- 새 페이지가 `xxx_page.dart` + `xxx_page_vm.dart` 쌍으로 존재하는가
|
|
136
|
-
- VM이 `NotifierProvider` 를 사용하는가
|
|
137
|
-
- i18n 키가 모든 arb 파일에 등록되었는가
|
|
138
|
-
- 기준별 PASS/FAIL 기록 → 충족률 계산
|
|
139
|
-
|
|
140
|
-
## Scoring
|
|
141
|
-
|
|
142
|
-
| 차원 | 가중치 | 하드 임계값 | 측정 방법 |
|
|
143
|
-
|------|--------|------------|----------|
|
|
144
|
-
| Static Analysis | 25% | warning/error 0개 | `flutter analyze` |
|
|
145
|
-
| Test Pass Rate | 25% | 100% | `flutter test` |
|
|
146
|
-
| API Contract 준수 | 25% | 100% | rest_api.dart vs api-contract.json |
|
|
147
|
-
| Anti-Pattern 청결 | 15% | 위반 0건 | 정적 grep |
|
|
148
|
-
| Contract Criteria 충족률 | 10% | 80% | sprint-contract 기준 |
|
|
149
|
-
|
|
150
|
-
**어떤 차원이든 하드 임계값 미달 → 스프린트 FAIL**
|
|
151
|
-
|
|
152
|
-
상세 채점 → [스코어링 루브릭](references/scoring-rubric.md)
|
|
153
|
-
|
|
154
|
-
## evaluation-functional.md 출력
|
|
155
|
-
|
|
156
|
-
```markdown
|
|
157
|
-
# Flutter Functional Evaluation: Sprint [N]
|
|
158
|
-
|
|
159
|
-
## Date: [날짜]
|
|
160
|
-
## Verdict: PASS / FAIL
|
|
161
|
-
## Attempt: [N] / 10
|
|
162
|
-
## Stack: flutter
|
|
163
|
-
|
|
164
|
-
## Step 0: IA Structure Compliance
|
|
165
|
-
- Verdict: PASS / FAIL (GATE)
|
|
166
|
-
|
|
167
|
-
## Step 1: Flutter Analyze
|
|
168
|
-
- errors: [N]
|
|
169
|
-
- warnings: [N]
|
|
170
|
-
- infos: [N]
|
|
171
|
-
|
|
172
|
-
## Step 2: Flutter Test
|
|
173
|
-
- total: [N], passed: [N], failed: [N]
|
|
174
|
-
- missing_roundtrip_tests: [목록]
|
|
175
|
-
|
|
176
|
-
## Step 3: build_runner 일관성
|
|
177
|
-
- drift: [none | 목록]
|
|
178
|
-
|
|
179
|
-
## Step 4: Anti-Pattern
|
|
180
|
-
| Rule | Count | Files |
|
|
181
|
-
| dart:html | 0 | - |
|
|
182
|
-
| print() | 0 | - |
|
|
183
|
-
| Color(0x...) in 신규 | 0 | - |
|
|
184
|
-
| bridges/ 신규 | 0 | - |
|
|
185
|
-
| Text('한글') 신규 | 0 | - |
|
|
186
|
-
|
|
187
|
-
## Step 5: API Contract Compliance
|
|
188
|
-
| EP ID | Method + Path | Dart Match | Issues |
|
|
189
|
-
|
|
190
|
-
## Step 6: Contract Criteria Results
|
|
191
|
-
| # | Criterion | Result | Evidence |
|
|
192
|
-
|
|
193
|
-
## Scores
|
|
194
|
-
| Dimension | Score | Threshold | Status |
|
|
195
|
-
|
|
196
|
-
## Failures Detail
|
|
197
|
-
### [#N] [기준/항목]
|
|
198
|
-
- **Expected**: ...
|
|
199
|
-
- **Actual**: ...
|
|
200
|
-
- **Recommendation**: ...
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## After Evaluation
|
|
204
|
-
|
|
205
|
-
- **PASS** → Session Boundary Protocol On Complete (PASS) 실행
|
|
206
|
-
- **FAIL** → Session Boundary Protocol On Fail 실행 (retry_target = generator-frontend-flutter)
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docmeta:
|
|
3
|
-
id: ia-compliance
|
|
4
|
-
title: IA Structure Compliance — Step 0 (Gate) for Flutter
|
|
5
|
-
type: output
|
|
6
|
-
createdAt: 2026-04-09T00:00:00Z
|
|
7
|
-
updatedAt: 2026-04-09T00:00:00Z
|
|
8
|
-
source:
|
|
9
|
-
producer: agent
|
|
10
|
-
skillId: harness-evaluator-functional-flutter
|
|
11
|
-
inputs:
|
|
12
|
-
- documentId: evaluator-functional-ia-compliance
|
|
13
|
-
uri: ../../evaluator-functional/references/ia-compliance.md
|
|
14
|
-
relation: output-from
|
|
15
|
-
sections:
|
|
16
|
-
- sourceRange:
|
|
17
|
-
startLine: 1
|
|
18
|
-
endLine: 37
|
|
19
|
-
targetRange:
|
|
20
|
-
startLine: 32
|
|
21
|
-
endLine: 120
|
|
22
|
-
tags:
|
|
23
|
-
- evaluator
|
|
24
|
-
- flutter
|
|
25
|
-
- ia-compliance
|
|
26
|
-
- gate
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# IA Structure Compliance — Step 0 (Gate) for Flutter
|
|
30
|
-
|
|
31
|
-
## 검증 방법
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
# 1. 실제 Flutter 구조 확인
|
|
35
|
-
ls -R lib/ integrated_data_layer/lib/ 2>/dev/null
|
|
36
|
-
|
|
37
|
-
# 2. git diff로 소유권 위반 검출 (이번 스프린트 범위)
|
|
38
|
-
git log --name-only --pretty=format: HEAD~[sprint_commits].. | sort -u
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## 검증 항목
|
|
42
|
-
|
|
43
|
-
| 검증 | 판정 | 예시 |
|
|
44
|
-
|------|------|------|
|
|
45
|
-
| IA-MAP 경로가 실제 존재하는가 | 누락 → FAIL | `lib/ui/pages/` 미생성 |
|
|
46
|
-
| IA-MAP에 없는 경로가 생겼는가 | 미등록 → DRIFT 기록 | `lib/services/` 무단 생성 |
|
|
47
|
-
| `[FE]` 소유를 BE가 수정했는가 | 침범 → FAIL | `lib/ui/` BE 수정 |
|
|
48
|
-
| `[META]`/`[HARNESS]` 침범 | 침범 → FAIL | `AGENTS.md` 수정 |
|
|
49
|
-
| `pubspec.yaml` 의존성 추가가 계약 범위 내인가 | 범위 이탈 → DRIFT 기록 | 승인 없는 의존성 추가 |
|
|
50
|
-
|
|
51
|
-
## Flutter 전용 추가 검증
|
|
52
|
-
|
|
53
|
-
| 검증 | 판정 |
|
|
54
|
-
|------|------|
|
|
55
|
-
| `integrated_data_layer/lib/2_data_sources/remote/` 내 파일이 프로젝트 컨벤션(`request/body/`, `response/`, `rest_api.dart`)을 지키는가 | 위반 → FAIL |
|
|
56
|
-
| `lib/ui/pages/` 내 새 페이지가 `xxx_page.dart` + `xxx_page_vm.dart` 쌍으로 존재하는가 | 파트너 누락 → FAIL |
|
|
57
|
-
| `bridges/` 하위에 신규 파일이 추가되었는가 | 추가 → FAIL (레거시 금지) |
|
|
58
|
-
| `lib/l10n/` 의 arb 파일 키 집합이 모든 언어에서 동일한가 | 불일치 → FAIL |
|
|
59
|
-
|
|
60
|
-
## 판정 규칙
|
|
61
|
-
|
|
62
|
-
- **경로 누락 / 소유권 침범 / 파트너 누락** → 즉시 FAIL, Step 1 이하 SKIP
|
|
63
|
-
- **미등록 경로 (Drift)** → FAIL 아님, evaluation에 `## AGENTS.md Drift` 기록
|
|
64
|
-
- **arb 키 불일치** → FAIL (i18n 원칙 위반)
|
|
65
|
-
|
|
66
|
-
## Output (evaluation-functional.md에 포함)
|
|
67
|
-
|
|
68
|
-
```markdown
|
|
69
|
-
## Step 0: IA Structure Compliance
|
|
70
|
-
- Verdict: PASS / FAIL (GATE)
|
|
71
|
-
- IA-MAP paths checked: [N]개
|
|
72
|
-
- Missing paths: [목록 또는 "none"]
|
|
73
|
-
- Unregistered paths: [목록 또는 "none"]
|
|
74
|
-
- Ownership violations: [목록 또는 "none"]
|
|
75
|
-
- Page/VM pair check: [N pages checked, N missing partners]
|
|
76
|
-
- arb key diff: [none | "app_ja.arb missing: cancel, confirm"]
|
|
77
|
-
```
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docmeta:
|
|
3
|
-
id: scoring-rubric
|
|
4
|
-
title: Flutter Functional Evaluation 스코어링 루브릭
|
|
5
|
-
type: output
|
|
6
|
-
createdAt: 2026-04-09T00:00:00Z
|
|
7
|
-
updatedAt: 2026-04-09T00:00:00Z
|
|
8
|
-
source:
|
|
9
|
-
producer: agent
|
|
10
|
-
skillId: harness-evaluator-functional-flutter
|
|
11
|
-
inputs:
|
|
12
|
-
- documentId: react-evaluator-scoring-rubric
|
|
13
|
-
uri: ../../evaluator-functional/references/scoring-rubric.md
|
|
14
|
-
relation: output-from
|
|
15
|
-
sections:
|
|
16
|
-
- sourceRange:
|
|
17
|
-
startLine: 1
|
|
18
|
-
endLine: 53
|
|
19
|
-
targetRange:
|
|
20
|
-
startLine: 32
|
|
21
|
-
endLine: 160
|
|
22
|
-
tags:
|
|
23
|
-
- evaluator
|
|
24
|
-
- flutter
|
|
25
|
-
- scoring
|
|
26
|
-
- rubric
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# Flutter Functional Evaluation 스코어링 루브릭
|
|
30
|
-
|
|
31
|
-
## 차원별 채점
|
|
32
|
-
|
|
33
|
-
| 차원 | 가중치 | 하드 임계값 | 측정 방법 |
|
|
34
|
-
|------|--------|------------|----------|
|
|
35
|
-
| Static Analysis | 25% | warning/error 0개 | `flutter analyze --no-fatal-infos` |
|
|
36
|
-
| Test Pass Rate | 25% | 100% | `flutter test` 모든 스위트 |
|
|
37
|
-
| API Contract 준수 | 25% | 100% | rest_api.dart vs api-contract.json 대조 — 불일치 즉시 FAIL |
|
|
38
|
-
| Anti-Pattern 청결 | 15% | 위반 0건 | static-check-rules.md 의 FL-01 ~ FL-08 |
|
|
39
|
-
| Contract Criteria 충족률 | 10% | 80% | sprint-contract.md FE 기준 통과 수 / 전체 |
|
|
40
|
-
|
|
41
|
-
**어떤 차원이든 하드 임계값 미달 → 스프린트 FAIL**
|
|
42
|
-
|
|
43
|
-
## 차원별 점수 계산
|
|
44
|
-
|
|
45
|
-
### Static Analysis (25점)
|
|
46
|
-
|
|
47
|
-
| 결과 | 점수 |
|
|
48
|
-
|------|------|
|
|
49
|
-
| error 0, warning 0 | 25 |
|
|
50
|
-
| error 0, warning 1~2 | 0 (하드 임계값 미달 → FAIL) |
|
|
51
|
-
| error 1+ | 0 (즉시 FAIL) |
|
|
52
|
-
|
|
53
|
-
info 수준은 점수에 반영하지 않지만 보고서에 카운트 기록.
|
|
54
|
-
|
|
55
|
-
### Test Pass Rate (25점)
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
score = 25 * (passed / total)
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
- `total == 0` (테스트 존재하지 않음) → **0점 + FAIL** (Coverage gate)
|
|
62
|
-
- `fromJson/toJson` 왕복 테스트 누락 (이번 스프린트 추가분) → **FAIL**
|
|
63
|
-
|
|
64
|
-
### API Contract 준수 (25점)
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
score = 25 * (matched_endpoints / total_endpoints)
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
불일치 허용 없음 — 1개라도 불일치면 즉시 FAIL (하드 임계값 100%).
|
|
71
|
-
|
|
72
|
-
매칭 체크:
|
|
73
|
-
- method (GET/POST/PUT/DELETE)
|
|
74
|
-
- path (변수명 포함)
|
|
75
|
-
- path param → `@Path(...)` 매핑
|
|
76
|
-
- body → `@Body() XxxBody`
|
|
77
|
-
- response 타입 → 계약 스키마의 code/data/errors 구조
|
|
78
|
-
|
|
79
|
-
### Anti-Pattern 청결 (15점)
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
score = 15 * (passed_rules / total_rules)
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
- 8개 룰 중 1개라도 FAIL → **0점 + 스프린트 FAIL**
|
|
86
|
-
- 위반 0건이면 15점
|
|
87
|
-
|
|
88
|
-
### Contract Criteria 충족률 (10점)
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
score = 10 * (passed_criteria / total_criteria)
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
- 80% 미달 → FAIL
|
|
95
|
-
- 개별 기준의 실패 사유를 "Failures Detail"에 기록
|
|
96
|
-
|
|
97
|
-
## Total
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
total = static_analysis + test_pass + api_contract + anti_pattern + contract_criteria
|
|
101
|
-
verdict = PASS (if all hard thresholds met AND total >= 80) else FAIL
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## failure_location 라우팅
|
|
105
|
-
|
|
106
|
-
Flutter 앱은 항상 FE 재작업이므로:
|
|
107
|
-
|
|
108
|
-
| location | 재작업 대상 |
|
|
109
|
-
|----------|-----------|
|
|
110
|
-
| `frontend` (기본) | `generator-frontend-flutter` |
|
|
111
|
-
|
|
112
|
-
예외: API Contract 불일치가 **서버 측 계약 오류**로 확인된 경우 → Planner에게 계약 수정 요청 필요.
|
|
113
|
-
이 경우 evaluation에 `## Change Request` 섹션 추가.
|
|
114
|
-
|
|
115
|
-
## evaluation-functional.md 헤더
|
|
116
|
-
|
|
117
|
-
```markdown
|
|
118
|
-
# Flutter Functional Evaluation: Sprint [N]
|
|
119
|
-
|
|
120
|
-
## Date: [YYYY-MM-DD]
|
|
121
|
-
## Verdict: PASS / FAIL
|
|
122
|
-
## Attempt: [N] / 10
|
|
123
|
-
## Stack: flutter
|
|
124
|
-
|
|
125
|
-
## Total Score: [N] / 100
|
|
126
|
-
| Dimension | Score | Threshold | Status |
|
|
127
|
-
| Static Analysis | X/25 | warning=0 | PASS/FAIL |
|
|
128
|
-
| Test Pass Rate | X/25 | 100% | PASS/FAIL |
|
|
129
|
-
| API Contract | X/25 | 100% | PASS/FAIL |
|
|
130
|
-
| Anti-Pattern | X/15 | 0 violations | PASS/FAIL |
|
|
131
|
-
| Contract Criteria | X/10 | 80% | PASS/FAIL |
|
|
132
|
-
```
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docmeta:
|
|
3
|
-
id: static-check-rules
|
|
4
|
-
title: Flutter 정적 검증 룰 (Anti-Pattern Gate)
|
|
5
|
-
type: output
|
|
6
|
-
createdAt: 2026-04-09T00:00:00Z
|
|
7
|
-
updatedAt: 2026-04-09T00:00:00Z
|
|
8
|
-
source:
|
|
9
|
-
producer: agent
|
|
10
|
-
skillId: harness-evaluator-functional-flutter
|
|
11
|
-
inputs:
|
|
12
|
-
- documentId: flutter-anti-patterns
|
|
13
|
-
uri: ../../generator-frontend-flutter/references/anti-patterns.md
|
|
14
|
-
relation: output-from
|
|
15
|
-
sections:
|
|
16
|
-
- sourceRange:
|
|
17
|
-
startLine: 1
|
|
18
|
-
endLine: 280
|
|
19
|
-
targetRange:
|
|
20
|
-
startLine: 32
|
|
21
|
-
endLine: 180
|
|
22
|
-
tags:
|
|
23
|
-
- evaluator
|
|
24
|
-
- flutter
|
|
25
|
-
- static-check
|
|
26
|
-
- anti-pattern
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# Flutter 정적 검증 룰
|
|
30
|
-
|
|
31
|
-
Generator의 `anti-patterns.md` 를 Source of Truth 로 삼아 정적 검증을 수행한다.
|
|
32
|
-
Generator가 신규 룰을 추가하면 Evaluator는 자동으로 그 룰을 따르게 된다 — **두 문서 간 drift 금지.**
|
|
33
|
-
|
|
34
|
-
## 실행 방법
|
|
35
|
-
|
|
36
|
-
**Evaluator는 반드시** `skills/generator-frontend-flutter/references/anti-patterns.md` 의
|
|
37
|
-
"셀프 체크 스크립트" 섹션을 **파일로 읽어서 그대로 실행**한다. 하네스의 단일 진실 원칙.
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# anti-patterns.md 에서 bash 블록만 추출해서 실행
|
|
41
|
-
awk '/^```bash$/,/^```$/' skills/generator-frontend-flutter/references/anti-patterns.md
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## 룰 요약 (Evaluator가 결과를 표로 정리)
|
|
45
|
-
|
|
46
|
-
| Rule ID | 설명 | 명령 | Fail 조건 |
|
|
47
|
-
|---------|------|------|----------|
|
|
48
|
-
| FL-01 | 웹 API 직접 참조 | `grep -rn "dart:html\|universal_html" lib/ integrated_data_layer/lib/` | 매치 1+ |
|
|
49
|
-
| FL-02 | print/console 남발 | `grep -rn "^\s*print(" lib/ integrated_data_layer/lib/` | 매치 1+ |
|
|
50
|
-
| FL-03 | 하드코딩 색상 (신규) | `git diff --name-only --diff-filter=A HEAD~N..HEAD \| grep '\.dart$' \| xargs grep -n "Color(0x"` | 매치 1+ (`ColorManager` 참조 제외) |
|
|
51
|
-
| FL-04 | StatefulWidget 직접 API 호출 | 수동 감사 — `_page.dart` 에 `dataLayer\|DataLayer` 호출이 있는데 짝 `_page_vm.dart` 없음 | 패턴 발견 |
|
|
52
|
-
| FL-05 | bridges/ 신규 참조 | `git diff HEAD~N..HEAD \| grep "^+.*bridges/"` | 매치 1+ |
|
|
53
|
-
| FL-06 | 하드코딩 한글 (신규 UI) | `git diff --name-only --diff-filter=AM HEAD~N..HEAD \| grep 'lib/ui/.*\.dart$' \| xargs grep -n "Text('[가-힣]"` | 매치 1+ |
|
|
54
|
-
| FL-07 | JsonSerializable includeIfNull 누락 | `grep -rn "@JsonSerializable" integrated_data_layer/lib/2_data_sources/remote/request/body/ \| grep -v "includeIfNull: false"` | 매치 1+ |
|
|
55
|
-
| FL-08 | API 키/시크릿 하드코딩 | `grep -rEn "(api[_-]?key\|secret\|token)\s*=\s*['\"][A-Za-z0-9]{16,}['\"]" lib/ integrated_data_layer/lib/` | 매치 1+ |
|
|
56
|
-
|
|
57
|
-
> `HEAD~N` 의 N은 sprint_commits 수 — `git log --format=%h HEAD~sprint_start..HEAD` 로 결정.
|
|
58
|
-
|
|
59
|
-
## FL-04 수동 감사 방법
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# 1. 신규/수정된 page 파일 목록
|
|
63
|
-
PAGES=$(git diff --name-only HEAD~N..HEAD | grep '_page\.dart$')
|
|
64
|
-
|
|
65
|
-
# 2. 각 page에서 API 호출 존재 여부
|
|
66
|
-
for p in $PAGES; do
|
|
67
|
-
if grep -q "dataLayer\|DataLayer" "$p"; then
|
|
68
|
-
vm="${p%_page.dart}_page_vm.dart"
|
|
69
|
-
if [ -f "$vm" ] && grep -q "dataLayer\|DataLayer" "$vm"; then
|
|
70
|
-
echo "OK (VM handles API): $p"
|
|
71
|
-
else
|
|
72
|
-
echo "FAIL (page calls API without VM): $p"
|
|
73
|
-
fi
|
|
74
|
-
fi
|
|
75
|
-
done
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
VM이 없고 페이지가 직접 호출하면 **FL-04 FAIL**.
|
|
79
|
-
|
|
80
|
-
## 결과 집계
|
|
81
|
-
|
|
82
|
-
```markdown
|
|
83
|
-
## Step 4: Anti-Pattern
|
|
84
|
-
|
|
85
|
-
| Rule | Status | Count | Files |
|
|
86
|
-
|------|--------|-------|-------|
|
|
87
|
-
| FL-01 dart:html | PASS/FAIL | 0 | - |
|
|
88
|
-
| FL-02 print | PASS/FAIL | 0 | - |
|
|
89
|
-
| FL-03 color hardcode | PASS/FAIL | 0 | - |
|
|
90
|
-
| FL-04 stateful API call | PASS/FAIL | 0 | - |
|
|
91
|
-
| FL-05 bridges/ new | PASS/FAIL | 0 | - |
|
|
92
|
-
| FL-06 ko hardcode | PASS/FAIL | 0 | - |
|
|
93
|
-
| FL-07 includeIfNull missing | PASS/FAIL | 0 | - |
|
|
94
|
-
| FL-08 secret hardcode | PASS/FAIL | 0 | - |
|
|
95
|
-
|
|
96
|
-
Overall: PASS / FAIL
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
**어떤 룰이든 FAIL 1건 → Step 4 전체 FAIL → 스프린트 FAIL** (하드 임계값: 위반 0건).
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: harness-generator-frontend-flutter
|
|
3
|
-
description: "하네스 Flutter Frontend Generator. Flutter(Dart) + Riverpod + integrated_data_layer(Retrofit) 기반 모바일 앱을 구현한다. ARB 다국어, JsonSerializable, NotifierProvider 패턴 준수. api-contract.json이 Source of Truth — UI 추론 금지."
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Generator-Frontend-Flutter — Dart + Riverpod + integrated_data_layer
|
|
8
|
-
|
|
9
|
-
## Session Boundary Protocol
|
|
10
|
-
|
|
11
|
-
### On Start
|
|
12
|
-
1. `.harness/progress.json` 읽기 — `next_agent`가 `"generator-frontend-flutter"`인지 확인
|
|
13
|
-
2. `.harness/actions/pipeline.json`의 `fe_stack == "flutter"` 재확인 — 아니면 즉시 STOP + 사용자에게 불일치 보고
|
|
14
|
-
3. progress.json 업데이트: `current_agent` → `"generator-frontend-flutter"`, `agent_status` → `"running"`, `updated_at` 갱신
|
|
15
|
-
4. `failure` 필드 확인 — retry인 경우 평가 문서의 실패 사유 우선 읽기
|
|
16
|
-
|
|
17
|
-
### On Complete
|
|
18
|
-
1. progress.json 업데이트:
|
|
19
|
-
- `agent_status` → `"completed"`
|
|
20
|
-
- `completed_agents`에 `"generator-frontend-flutter"` 추가
|
|
21
|
-
- `next_agent` → `"evaluator-functional-flutter"`
|
|
22
|
-
- `failure` 필드 초기화
|
|
23
|
-
2. `feature-list.json`의 해당 feature `passes`에 `"generator-frontend-flutter"` 추가
|
|
24
|
-
3. `.harness/progress.log`에 요약 추가
|
|
25
|
-
4. **STOP. 다음 에이전트를 직접 호출하지 않는다.**
|
|
26
|
-
5. 출력: `"✓ Generator-Frontend-Flutter 완료. bash scripts/harness-next.sh 실행하여 다음 단계 확인."`
|
|
27
|
-
|
|
28
|
-
## Startup
|
|
29
|
-
|
|
30
|
-
1. `AGENTS.md` 읽기 — IA-MAP, 권한 확인 (Flutter 소유 경로)
|
|
31
|
-
2. `.harness/gotchas/generator-frontend-flutter.md` 읽기 (없으면 skip) — **과거 실수 반복 금지**
|
|
32
|
-
3. `.harness/memory.md` 읽기 — **프로젝트 공유 학습 규칙 적용**
|
|
33
|
-
4. `pwd` + `.harness/progress.json` + `git log --oneline -20`
|
|
34
|
-
5. `.harness/actions/api-contract.json` 읽기 — **서버 API 계약이 Source of Truth**
|
|
35
|
-
6. `.harness/actions/feature-list.json` — `layer: "frontend"` 필터
|
|
36
|
-
7. `.harness/actions/pipeline.json` 의 **`fe_target`** 확인 (`web` | `mobile` | `desktop`)
|
|
37
|
-
- 이 값에 따라 허용되는 API, 빌드 명령, 안티패턴이 달라진다 (아래 "fe_target 분기" 섹션 참조)
|
|
38
|
-
8. `pubspec.yaml` 확인 — Flutter 버전, Riverpod/Retrofit/json_serializable 의존성 존재 확인
|
|
39
|
-
- `fe_target = web` 인 경우 `flutter config --enable-web` 활성화 + `web/index.html` 존재 확인
|
|
40
|
-
|
|
41
|
-
## AGENTS.md — 읽기 전용
|
|
42
|
-
|
|
43
|
-
`[FE]` + `→ Generator-Frontend-Flutter` 소유 경로만 쓰기 가능. 일반적으로:
|
|
44
|
-
- `lib/ui/pages/`, `lib/ui/component/`, `lib/l10n/`
|
|
45
|
-
- `integrated_data_layer/lib/`, `integrated_data_layer/test/`
|
|
46
|
-
- `assets/strings/`
|
|
47
|
-
|
|
48
|
-
Backend 코드, `.harness/`, `AGENTS.md` 수정 금지.
|
|
49
|
-
|
|
50
|
-
## Sprint Workflow
|
|
51
|
-
|
|
52
|
-
1. **Sprint Contract FE 섹션 추가** — 페이지, VM, API 연동, 성공 기준
|
|
53
|
-
2. **api-contract.json → Retrofit/JsonSerializable 변환**
|
|
54
|
-
3. **구현** — 아래 4개 레퍼런스를 반드시 참조
|
|
55
|
-
4. **코드 생성**: `flutter pub run build_runner build --delete-conflicting-outputs`
|
|
56
|
-
5. **Self-Verification** — `flutter analyze` + `flutter test` 통과
|
|
57
|
-
6. **Handoff** → Evaluator-Functional-Flutter
|
|
58
|
-
|
|
59
|
-
## 개발론 레퍼런스 (점진적 로딩)
|
|
60
|
-
|
|
61
|
-
| 문서 | 내용 | 언제 로드 |
|
|
62
|
-
|------|------|----------|
|
|
63
|
-
| [API Layer Pattern](references/api-layer-pattern.md) | integrated_data_layer 구조, Request/Response, Retrofit | API 연동 시 |
|
|
64
|
-
| [Riverpod Pattern](references/riverpod-pattern.md) | Page+VM 쌍, NotifierProvider, family 패턴 | 페이지/위젯 구현 시 |
|
|
65
|
-
| [i18n Pattern](references/i18n-pattern.md) | ARB 파일, LocaleAssist, 키 네이밍 | 문자열 추가 시 |
|
|
66
|
-
| [Anti-Patterns](references/anti-patterns.md) | 금지 API, 하드코딩, bridges/, StatefulWidget 직접 호출 (fe_target 별 차이 포함) | 구현 완료 후 셀프 체크 |
|
|
67
|
-
| [Flutter Web Pattern](references/flutter-web-pattern.md) | Web 전용 — `dart:html`/`package:web` 허용, 라우팅, 빌드, hosting | `fe_target = web` 일 때만 |
|
|
68
|
-
|
|
69
|
-
## fe_target 분기
|
|
70
|
-
|
|
71
|
-
`pipeline.json.fe_target` 에 따라 적용되는 규칙이 다르다:
|
|
72
|
-
|
|
73
|
-
### `fe_target = web` (Flutter Web)
|
|
74
|
-
|
|
75
|
-
- **빌드**: `flutter build web --release` / 개발 서버: `flutter run -d chrome`
|
|
76
|
-
- **HTML/JS 인터롭 허용**: `dart:html`, `package:web`, `dart:js_interop` 사용 가능
|
|
77
|
-
- 단, 가능하면 cross-platform 코드를 우선하고 web 전용 코드는 `if (kIsWeb)` 가드 또는 conditional import
|
|
78
|
-
- **라우팅**: `go_router` 권장 (URL 동기화). `Navigator 1.0` 의 `MaterialApp.routes` 도 OK 지만 hash routing 주의
|
|
79
|
-
- **자산**: `web/index.html`, `web/manifest.json`, `web/icons/` 관리. SEO 가 필요하면 `<meta>` 태그 명시
|
|
80
|
-
- **CORS**: 백엔드 API 가 `localhost:포트` 에서 다른 origin 일 수 있으므로 CORS 설정 확인
|
|
81
|
-
- **Eval 흐름**: Playwright 기반 `evaluator-functional` + `evaluator-visual` 이 정상 작동 (브라우저 E2E + 시각 검증)
|
|
82
|
-
- 상세 → [Flutter Web Pattern](references/flutter-web-pattern.md)
|
|
83
|
-
|
|
84
|
-
### `fe_target = mobile` (Android / iOS)
|
|
85
|
-
|
|
86
|
-
- **빌드**: `flutter build apk` / `flutter build ios` / 개발: `flutter run -d <device>`
|
|
87
|
-
- **HTML/JS 인터롭 금지**: `dart:html`, `package:web`, `universal_html` 직접 참조 → 빌드 실패
|
|
88
|
-
- **플랫폼 채널**: 네이티브 기능 사용 시 `MethodChannel` 또는 검증된 plugin 사용
|
|
89
|
-
- **권한**: `AndroidManifest.xml` / `Info.plist` 에 권한 명시
|
|
90
|
-
- **Eval 흐름**: 정적 분석 기반 `evaluator-functional-flutter` 사용 (Playwright 불가)
|
|
91
|
-
|
|
92
|
-
### `fe_target = desktop` (macOS / Windows / Linux)
|
|
93
|
-
|
|
94
|
-
- **빌드**: `flutter build macos` / `flutter build windows` / `flutter build linux`
|
|
95
|
-
- **HTML/JS 인터롭 금지**: 모바일과 동일
|
|
96
|
-
- **윈도우 관리**: `window_manager` 등 플러그인으로 윈도우 크기/위치 제어
|
|
97
|
-
- **Eval 흐름**: 정적 분석 기반 `evaluator-functional-flutter` 사용
|
|
98
|
-
|
|
99
|
-
## 핵심 규칙
|
|
100
|
-
|
|
101
|
-
### api-contract.json → Dart 변환 규칙
|
|
102
|
-
|
|
103
|
-
- 각 엔드포인트 → `rest_api.dart`에 Retrofit 어노테이션 (`@GET`, `@POST`, `@PUT`, `@DELETE`)
|
|
104
|
-
- Request body → `2_data_sources/remote/request/body/xxx_body.dart` (`@JsonSerializable(includeIfNull: false)`)
|
|
105
|
-
- Response → `2_data_sources/remote/response/xxx_response.dart` (`ClueResponseImpl<T>` 상속 or 재사용)
|
|
106
|
-
- **필수 지시가 없으면 모든 필드는 Nullable** — 서버가 언제든 필드를 누락할 수 있음
|
|
107
|
-
- **기존 응답 타입 재사용 우선** — 동일 구조면 새 클래스 생성 금지
|
|
108
|
-
- Repository 래퍼 메서드 추가 → `1_repositories/xxx_repository.dart`
|
|
109
|
-
|
|
110
|
-
### UI / 상태관리
|
|
111
|
-
|
|
112
|
-
- 모든 페이지 = `xxx_page.dart` + `xxx_page_vm.dart` 쌍
|
|
113
|
-
- Page는 `ConsumerStatefulWidget` 또는 `ConsumerWidget`
|
|
114
|
-
- VM은 `NotifierProvider<Notifier, State>` (다중 인스턴스는 `.family`)
|
|
115
|
-
- State는 `Equatable` + `copyWith` 불변성
|
|
116
|
-
- `ref.watch` (build 내) / `ref.read` (이벤트 핸들러, initState)
|
|
117
|
-
- API 호출은 반드시 VM 안에서 `ref.read(dataLayer).xxx.method()`
|
|
118
|
-
- Provider 네이밍: `p` + PascalCase + `Provider` (예: `pHomePageProvider`)
|
|
119
|
-
|
|
120
|
-
### 다국어 (i18n)
|
|
121
|
-
|
|
122
|
-
- 영문 전용 지시가 없는 한 **모든 사용자 노출 문자열은 ARB 경유 필수**
|
|
123
|
-
- ARB: `lib/l10n/app_en.arb`, `app_ko.arb`, `app_ja.arb`
|
|
124
|
-
- 코드 접근: `LocaleAssist().of.키이름`
|
|
125
|
-
- 키 네이밍: camelCase (예: `doorOpen`, `networkError`)
|
|
126
|
-
- 모든 언어 파일에 동일 키 동시 추가
|
|
127
|
-
|
|
128
|
-
### 코드 생성
|
|
129
|
-
|
|
130
|
-
Request Body / Response / rest_api.dart 수정 후 **반드시** 실행:
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
cd <integrated_data_layer 경로>
|
|
134
|
-
flutter pub run build_runner build --delete-conflicting-outputs
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Self-Verification (Handoff 전)
|
|
138
|
-
|
|
139
|
-
1. `flutter analyze` → 경고 0개 (info 수준은 허용, warning/error 금지)
|
|
140
|
-
2. `flutter test` → 100% 통과
|
|
141
|
-
3. integrated_data_layer의 새 Request Body / Response에 `fromJson`/`toJson` 왕복 테스트 존재
|
|
142
|
-
4. `grep -rn 'dart:html\|universal_html\|print(\|console\.log' lib/ integrated_data_layer/lib/` → 0개
|
|
143
|
-
5. `grep -rn "bridges/" lib/` → 신규 코드 내 참조 0개
|
|
144
|
-
6. 하드코딩 색상(`Color(0xFF...`) → `ColorManager` 경유 확인
|
|
145
|
-
7. 새 페이지/위젯은 `StatefulWidget`에서 직접 API 호출하지 않는지 확인 (VM/Provider 경유)
|
|
146
|
-
|
|
147
|
-
## 금지 사항
|
|
148
|
-
|
|
149
|
-
- Backend 코드 수정, 서버 API 경로 임의 변경
|
|
150
|
-
- api-contract.json에 없는 엔드포인트 호출/추가
|
|
151
|
-
- `dart:html`, `universal_html` 직접 참조
|
|
152
|
-
- `print()` / `debugPrint` 남발 — `logger` 사용
|
|
153
|
-
- 하드코딩 색상 → `ColorManager` 강제
|
|
154
|
-
- `StatefulWidget` 내 직접 API 호출 → VM/Provider 경유
|
|
155
|
-
- `bridges/` 신규 개발 — BLOC 기반 레거시, 유지보수만 허용
|
|
156
|
-
- AI 추측으로 서버 응답 구조를 만들지 말 것 (계약이 Source of Truth)
|
|
157
|
-
- API 키/시크릿 하드코딩
|
|
158
|
-
|
|
159
|
-
## 명령어
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
flutter pub get # 의존성
|
|
163
|
-
flutter run # 실행
|
|
164
|
-
flutter test # 테스트
|
|
165
|
-
flutter analyze # 정적 분석
|
|
166
|
-
flutter pub run build_runner build --delete-conflicting-outputs # 코드 생성
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## After Completion
|
|
170
|
-
|
|
171
|
-
1. sprint-contract.md의 FE 섹션에 완료 항목 체크
|
|
172
|
-
2. Self-Verification 체크리스트 결과 요약
|
|
173
|
-
3. Session Boundary Protocol On Complete 실행
|