@walwal-harness/cli 3.3.1 → 3.4.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.
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# CONVENTIONS.md — Project Conventions
|
|
2
|
+
|
|
3
|
+
> 이 파일은 프로젝트의 코딩 컨벤션, 선호 패턴, 금지 패턴을 자유 형식으로 정의합니다.
|
|
4
|
+
> 모든 에이전트는 세션 시작 시 이 파일을 읽고 규칙을 적용합니다.
|
|
5
|
+
>
|
|
6
|
+
> **진실의 원천**: 이 파일이 유일한 컨벤션 정의 소스입니다.
|
|
7
|
+
> Gotcha나 AGENTS.md에 복사하지 마세요 — 에이전트가 직접 이 파일을 참조합니다.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
<!-- 아키텍처 수준의 규칙을 여기에 작성하세요 -->
|
|
12
|
+
<!-- 예시:
|
|
13
|
+
- 서비스 간 직접 DB 접근 금지 — 반드시 API 또는 메시지 패턴 사용
|
|
14
|
+
- 모노리스보다 모듈러 아키텍처 선호
|
|
15
|
+
-->
|
|
16
|
+
|
|
17
|
+
## Code Style
|
|
18
|
+
|
|
19
|
+
<!-- 코드 스타일 규칙을 여기에 작성하세요 -->
|
|
20
|
+
<!-- 예시:
|
|
21
|
+
- any 타입 사용 금지
|
|
22
|
+
- console.log 대신 structured logger 사용
|
|
23
|
+
- 함수는 30줄 이내, 파일은 300줄 이내
|
|
24
|
+
-->
|
|
25
|
+
|
|
26
|
+
## Preferred Patterns
|
|
27
|
+
|
|
28
|
+
<!-- 선호하는 라이브러리, 패턴, 접근 방식 -->
|
|
29
|
+
<!-- 예시:
|
|
30
|
+
- 상태관리: Zustand
|
|
31
|
+
- API 호출: TanStack Query
|
|
32
|
+
- 폼 처리: React Hook Form + Zod
|
|
33
|
+
-->
|
|
34
|
+
|
|
35
|
+
## Avoid
|
|
36
|
+
|
|
37
|
+
<!-- 사용을 피해야 하는 패턴, 라이브러리, 접근 방식 -->
|
|
38
|
+
<!-- 예시:
|
|
39
|
+
- CSS-in-JS (styled-components, emotion)
|
|
40
|
+
- Class components
|
|
41
|
+
- Redux (Zustand으로 대체)
|
|
42
|
+
-->
|
|
43
|
+
|
|
44
|
+
## Testing
|
|
45
|
+
|
|
46
|
+
<!-- 테스트 관련 규칙 -->
|
|
47
|
+
<!-- 예시:
|
|
48
|
+
- E2E 테스트는 핵심 사용자 플로우만
|
|
49
|
+
- 단위 테스트 커버리지 80% 이상
|
|
50
|
+
- mock 최소화, 실제 DB 사용 선호
|
|
51
|
+
-->
|
|
52
|
+
|
|
53
|
+
## Naming
|
|
54
|
+
|
|
55
|
+
<!-- 네이밍 컨벤션 -->
|
|
56
|
+
<!-- 예시:
|
|
57
|
+
- 컴포넌트: PascalCase
|
|
58
|
+
- 변수/함수: camelCase
|
|
59
|
+
- 파일: kebab-case
|
|
60
|
+
- DB 테이블: snake_case
|
|
61
|
+
-->
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
## 디렉토리 구조
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
+
CONVENTIONS.md # 프로젝트 컨벤션 (사용자 작성, 에이전트 읽기 전용)
|
|
10
11
|
.harness/
|
|
11
12
|
├── HARNESS.md # 이 파일
|
|
12
13
|
├── config.json # 하네스 설정
|
|
@@ -152,29 +153,45 @@ pending → draft → reviewed → approved
|
|
|
152
153
|
"하네스 엔지니어링 시작" 또는 /harness-dispatcher
|
|
153
154
|
```
|
|
154
155
|
|
|
155
|
-
#### 2. 이후 세션:
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
#### 2. 이후 세션: 새 세션만 열면 자동 진행
|
|
157
|
+
|
|
158
|
+
에이전트가 완료 후 STOP하면, **새 세션을 시작하기만 하면 됩니다**.
|
|
159
|
+
SessionStart 훅이 자동으로:
|
|
160
|
+
1. 이전 에이전트의 완료 상태 감지
|
|
161
|
+
2. 게이트 체크 실행 (Pre-Eval Gate, 파일 소유권, 아티팩트 선행조건)
|
|
162
|
+
3. `handoff.json` 생성 (prompt, model, thinking_mode, regression 등)
|
|
163
|
+
4. 다음 에이전트 안내 출력
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
# 새 세션 시작 시 자동 출력 예시:
|
|
167
|
+
# Harness: next → /harness-generator-backend (sonnet)
|
|
158
168
|
```
|
|
159
|
-
Feature-level 프로그래스를 출력하고 다음 에이전트를 안내합니다.
|
|
160
169
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
/harness-generator-backend
|
|
170
|
+
사용자는 안내에 따라 스킬을 호출하면 됩니다.
|
|
171
|
+
|
|
172
|
+
#### 자동 CLI 실행 (옵션)
|
|
165
173
|
|
|
166
|
-
|
|
174
|
+
완전 자동화를 원하면 아래 명령으로 다음 에이전트를 즉시 시작할 수 있습니다:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
167
177
|
claude --model $(jq -r .model .harness/handoff.json) --prompt "$(jq -r .prompt .harness/handoff.json)"
|
|
168
178
|
```
|
|
169
179
|
|
|
170
|
-
####
|
|
171
|
-
|
|
180
|
+
#### 디버깅 (수동)
|
|
181
|
+
|
|
182
|
+
문제가 생겼을 때만 수동으로 상태를 확인합니다:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
bash scripts/harness-next.sh # 게이트 체크 + 프로그래스 출력
|
|
186
|
+
jq . .harness/handoff.json # handoff 내용 확인
|
|
187
|
+
jq . .harness/progress.json # 현재 상태 확인
|
|
188
|
+
```
|
|
172
189
|
|
|
173
190
|
### Session Boundary Protocol
|
|
174
191
|
|
|
175
192
|
모든 에이전트 스킬에 내장된 프로토콜:
|
|
176
193
|
|
|
177
|
-
- **On Start**: `progress.json` 읽기 → `agent_status: "running"` 설정 → `handoff.json` 참조
|
|
194
|
+
- **On Start**: `progress.json` 읽기 → `agent_status: "running"` 설정 → `handoff.json` 참조 → `CONVENTIONS.md` 읽기 (존재 시)
|
|
178
195
|
- **On Complete**: `progress.json` 업데이트 → 아티팩트 상태 갱신 → `next_agent` 계산 → **STOP**
|
|
179
196
|
- **On Fail** (Evaluator): `failure` 정보 기록 → `retry_target` 설정 → **STOP**
|
|
180
197
|
- **On Transition**: 파일 소유권 검증 → Pre-Eval Gate (해당 시) → 아티팩트 선행조건 검증
|
|
@@ -333,9 +333,17 @@
|
|
|
333
333
|
"actions": ".harness/actions",
|
|
334
334
|
"archive": ".harness/archive",
|
|
335
335
|
"gotchas": ".harness/gotchas",
|
|
336
|
+
"conventions": "CONVENTIONS.md",
|
|
336
337
|
"progress_state": ".harness/progress.json",
|
|
337
338
|
"progress_log": ".harness/progress.log"
|
|
338
339
|
},
|
|
340
|
+
"conventions": {
|
|
341
|
+
"comment": "CONVENTIONS.md — 사용자가 자유 형식으로 작성하는 프로젝트 컨벤션. 모든 에이전트가 세션 시작 시 직접 읽음. Gotcha/AGENTS.md에 복사하지 않음.",
|
|
342
|
+
"file": "CONVENTIONS.md",
|
|
343
|
+
"read_by": "all_agents",
|
|
344
|
+
"write_by": "user_only",
|
|
345
|
+
"read_timing": "session_start"
|
|
346
|
+
},
|
|
339
347
|
"recommended_skills": {
|
|
340
348
|
"comment": "Claude Code에 설치하면 하네스 품질이 향상되는 외부 스킬 목록",
|
|
341
349
|
"vercel": {
|
package/bin/init.js
CHANGED
|
@@ -148,6 +148,14 @@ function scaffoldHarness() {
|
|
|
148
148
|
copyFile(memorySrc, memoryDest);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
// Copy CONVENTIONS.md to project root
|
|
152
|
+
const conventionsSrc = path.join(PKG_ROOT, 'assets', 'templates', 'CONVENTIONS.md');
|
|
153
|
+
const conventionsDest = path.join(PROJECT_ROOT, 'CONVENTIONS.md');
|
|
154
|
+
if (fs.existsSync(conventionsSrc) && (!fileExists(conventionsDest) || isForce)) {
|
|
155
|
+
copyFile(conventionsSrc, conventionsDest);
|
|
156
|
+
log('CONVENTIONS.md created — edit to define your project conventions');
|
|
157
|
+
}
|
|
158
|
+
|
|
151
159
|
// Create progress.log
|
|
152
160
|
const progressLog = path.join(HARNESS_DIR, 'progress.log');
|
|
153
161
|
if (!fileExists(progressLog) || isForce) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Production harness for AI agent engineering — Planner, Generator(BE/FE), Evaluator(Func/Visual), optional Brainstormer (requirements refinement). Supports React and Flutter FE stacks.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"walwal-harness": "bin/init.js"
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# harness-session-start.sh — SessionStart 훅
|
|
3
|
-
#
|
|
2
|
+
# harness-session-start.sh — SessionStart 훅
|
|
3
|
+
# 새 세션 시작 시 자동으로:
|
|
4
|
+
# 1) 이전 에이전트가 completed이면 harness-next.sh를 실행하여 게이트 체크 + handoff 생성
|
|
5
|
+
# 2) handoff.json이 있으면 다음 에이전트 안내
|
|
6
|
+
# 3) statusline이 상시 상태를 표시하므로 여기서는 핵심 안내만 출력
|
|
7
|
+
#
|
|
8
|
+
# 사용자가 수동으로 harness-next.sh를 실행할 필요가 없도록 자동화.
|
|
4
9
|
|
|
5
10
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
6
11
|
LIB="$SCRIPT_DIR/lib/harness-render-progress.sh"
|
|
@@ -11,6 +16,8 @@ command -v jq &>/dev/null || exit 0
|
|
|
11
16
|
|
|
12
17
|
PROJECT_ROOT="$(resolve_harness_root "." 2>/dev/null)" || exit 0
|
|
13
18
|
PROGRESS="$PROJECT_ROOT/.harness/progress.json"
|
|
19
|
+
CONFIG="$PROJECT_ROOT/.harness/config.json"
|
|
20
|
+
HANDOFF="$PROJECT_ROOT/.harness/handoff.json"
|
|
14
21
|
[ -f "$PROGRESS" ] || exit 0
|
|
15
22
|
|
|
16
23
|
sprint_status=$(jq -r '.sprint.status // "init"' "$PROGRESS" 2>/dev/null)
|
|
@@ -18,17 +25,45 @@ current_agent=$(jq -r '.current_agent // "none"' "$PROGRESS" 2>/dev/null)
|
|
|
18
25
|
next_agent=$(jq -r '.next_agent // "none"' "$PROGRESS" 2>/dev/null)
|
|
19
26
|
agent_status=$(jq -r '.agent_status // "pending"' "$PROGRESS" 2>/dev/null)
|
|
20
27
|
|
|
21
|
-
#
|
|
28
|
+
# ─────────────────────────────────────────
|
|
29
|
+
# init 상태: 첫 안내
|
|
30
|
+
# ─────────────────────────────────────────
|
|
22
31
|
if [ "$sprint_status" = "init" ]; then
|
|
23
32
|
echo "# Harness ready — say \"하네스 엔지니어링 시작\" or /harness-dispatcher"
|
|
24
33
|
exit 0
|
|
25
34
|
fi
|
|
26
35
|
|
|
27
|
-
#
|
|
36
|
+
# ─────────────────────────────────────────
|
|
37
|
+
# 이전 에이전트가 completed → 자동으로 harness-next 실행
|
|
38
|
+
# (게이트 체크, 아티팩트 검증, handoff.json 생성)
|
|
39
|
+
# ─────────────────────────────────────────
|
|
40
|
+
if [ "$agent_status" = "completed" ] || [ "$agent_status" = "failed" ]; then
|
|
41
|
+
# harness-next.sh를 백그라운드로 실행하면 안 됨 — 결과가 필요
|
|
42
|
+
bash "$SCRIPT_DIR/harness-next.sh" "$PROJECT_ROOT" 2>/dev/null
|
|
43
|
+
|
|
44
|
+
# harness-next.sh가 progress.json과 handoff.json을 업데이트했으므로 다시 읽기
|
|
45
|
+
next_agent=$(jq -r '.next_agent // "none"' "$PROGRESS" 2>/dev/null)
|
|
46
|
+
agent_status=$(jq -r '.agent_status // "pending"' "$PROGRESS" 2>/dev/null)
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# ─────────────────────────────────────────
|
|
50
|
+
# 상태별 안내 출력
|
|
51
|
+
# ─────────────────────────────────────────
|
|
28
52
|
if [ "$agent_status" = "blocked" ]; then
|
|
29
|
-
echo "# Harness BLOCKED — user intervention required
|
|
30
|
-
|
|
31
|
-
|
|
53
|
+
echo "# Harness BLOCKED — retry limit reached, user intervention required"
|
|
54
|
+
|
|
55
|
+
elif [ -f "$HANDOFF" ] && [ "$next_agent" != "none" ] && [ "$next_agent" != "null" ]; then
|
|
56
|
+
# handoff.json에서 모델/모드 정보 읽기
|
|
57
|
+
handoff_model=$(jq -r '.model // "opus"' "$HANDOFF" 2>/dev/null)
|
|
58
|
+
handoff_thinking=$(jq -r '.thinking_mode // empty' "$HANDOFF" 2>/dev/null)
|
|
59
|
+
|
|
60
|
+
mode_str=""
|
|
61
|
+
if [ -n "$handoff_thinking" ] && [ "$handoff_thinking" != "null" ]; then
|
|
62
|
+
mode_str=" /${handoff_thinking}"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
echo "# Harness: next → /harness-${next_agent} (${handoff_model}${mode_str})"
|
|
66
|
+
|
|
32
67
|
elif [ "$current_agent" != "none" ] && [ "$current_agent" != "null" ]; then
|
|
33
68
|
echo "# Harness: ${current_agent} [${agent_status}]"
|
|
34
69
|
fi
|
|
@@ -282,14 +282,8 @@ render_progress() {
|
|
|
282
282
|
fi
|
|
283
283
|
|
|
284
284
|
echo ""
|
|
285
|
-
echo " Next → /harness-${next_agent} (
|
|
286
|
-
|
|
287
|
-
# Build auto CLI command with model flag, reading prompt from handoff.json
|
|
288
|
-
local model_flag=""
|
|
289
|
-
if [ "$next_model" != "opus" ]; then
|
|
290
|
-
model_flag=" --model ${next_model}"
|
|
291
|
-
fi
|
|
292
|
-
echo " Auto → claude${model_flag} --prompt \"\$(jq -r .prompt .harness/handoff.json)\""
|
|
285
|
+
echo " Next → /harness-${next_agent} (${next_model}${mode_str})"
|
|
286
|
+
echo " Tip → 새 세션을 시작하면 자동으로 안내됩니다"
|
|
293
287
|
fi
|
|
294
288
|
|
|
295
289
|
echo ""
|