@walwal-harness/cli 5.6.2 → 5.6.4
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 +24 -1
- package/commands/harness-team.md +24 -17
- package/package.json +1 -1
- package/scripts/harness-dashboard.sh +13 -9
- package/scripts/harness-progress-set.sh +41 -0
- package/scripts/harness-queue-manager.sh +75 -10
- package/scripts/harness-session-start.sh +23 -0
- package/skills/brainstorming/SKILL.md +18 -0
- package/skills/dispatcher/SKILL.md +18 -0
- package/skills/evaluator-code-quality/SKILL.md +18 -0
- package/skills/evaluator-functional/SKILL.md +18 -0
- package/skills/evaluator-visual/SKILL.md +18 -0
- package/skills/generator-backend/SKILL.md +18 -0
- package/skills/generator-frontend/SKILL.md +18 -0
- package/skills/planner/SKILL.md +18 -0
package/README.md
CHANGED
|
@@ -83,11 +83,34 @@ npx walwal-harness team
|
|
|
83
83
|
|
|
84
84
|
| 패널 | 내용 | 소스 |
|
|
85
85
|
|------|------|------|
|
|
86
|
-
| **Dashboard** | Pipeline · Sprint · Feature passes
|
|
86
|
+
| **Dashboard** | Pipeline · Sprint · Feature passes · Queue R:B:P · Retry | `harness-dashboard.sh` |
|
|
87
87
|
| **Gotcha & Memory** | 활성 에이전트의 누적 실수 + 나머지 요약 + 공유 메모리 | `harness-gotcha-memory.sh` |
|
|
88
88
|
| **TEAM 1–3** | 각 워커의 현재 feature · phase(Gen/Eval) · 실시간 stdout | `harness-queue-manager.sh` worker loop |
|
|
89
89
|
| **Archive Prompt** | 직전 완료 feature 요약 (다음 팀 컨텍스트 주입용) | archive 디렉토리 |
|
|
90
90
|
|
|
91
|
+
##### Feature 상태 아이콘 (v5.6.4+)
|
|
92
|
+
|
|
93
|
+
| 아이콘 | 상태 | 의미 |
|
|
94
|
+
|--------|------|------|
|
|
95
|
+
| `●` (녹색) | PASS | Evaluator 통과 · merge 완료 |
|
|
96
|
+
| `◐` (청색) | IN PROGRESS | 현재 team 배정됨 (phase 표기: T1:gen / T2:eval) |
|
|
97
|
+
| `○` (노랑) | READY | 의존성 해소됨 · idle team 배정 대기 |
|
|
98
|
+
| `◍` (자색) | **BLOCKED** | 선행 feature 대기 · deps 개수 함께 표시 |
|
|
99
|
+
| `◌` (어두움) | PENDING | 아직 큐 미등록 (sprint 미진입 or 사전 분석 단계) |
|
|
100
|
+
| `✗` (빨강) | FAILED | 재시도 한도 도달 · 사용자 개입 필요 |
|
|
101
|
+
|
|
102
|
+
##### Team Idle Auto-Dispatch (v5.6.4+)
|
|
103
|
+
|
|
104
|
+
Worker 완료 시 Lead 는 `auto-dispatch` 한 호출로 **모든 idle team ↔ ready feature** 쌍을 원자적으로 재배정합니다. 의존성 없는 작업은 병렬로 즉시 시작되어 team idle 시간은 "Agent 생성 소요 초" 로 수렴:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
bash scripts/harness-queue-manager.sh auto-dispatch .
|
|
108
|
+
# → [{"team":1,"feature":"F-001"},{"team":2,"feature":"F-002"}]
|
|
109
|
+
|
|
110
|
+
bash scripts/harness-queue-manager.sh idle-slots .
|
|
111
|
+
# → {"idle_teams":["3"], "ready_features":["F-003","F-004"], "dispatchable":1}
|
|
112
|
+
```
|
|
113
|
+
|
|
91
114
|
- 새로고침 주기: `HARNESS_REFRESH=5` (초). 환경변수로 조정.
|
|
92
115
|
- 단축키: `tmux prefix + 방향키` 로 패널 이동, `prefix + z` 로 확대/축소.
|
|
93
116
|
- 종료: `npx walwal-harness team --kill`.
|
package/commands/harness-team.md
CHANGED
|
@@ -59,17 +59,20 @@ bash scripts/harness-tmux.sh --team --force-tmux
|
|
|
59
59
|
|
|
60
60
|
**`--force-tmux` 필수**: iTerm2 감지 경로는 백그라운드에 iTerm2가 떠 있기만 해도 활성화되어 AppleScript 실패 시 팀 레이아웃이 조용히 사라짐. Team Mode는 항상 tmux로 강제하여 재현 가능한 레이아웃을 보장.
|
|
61
61
|
|
|
62
|
-
### Step 3: 초기 Worker 생성
|
|
62
|
+
### Step 3: 초기 Worker 생성 (Auto-Dispatch)
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
**v5.6.4+**: 개별 dequeue 대신 **`auto-dispatch`** 한 번으로 모든 idle team 에 ready feature 를 원자적으로 배정합니다. 의존성 없는 작업은 병렬로 즉시 시작됩니다.
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
#
|
|
68
|
-
bash scripts/harness-queue-manager.sh
|
|
69
|
-
|
|
70
|
-
bash scripts/harness-queue-manager.sh dequeue 3 .
|
|
67
|
+
# 모든 idle team ↔ ready feature 쌍을 한 번에 배정
|
|
68
|
+
bash scripts/harness-queue-manager.sh auto-dispatch .
|
|
69
|
+
# → [{"team":1,"feature":"F-001"},{"team":2,"feature":"F-002"},{"team":3,"feature":"F-003"}]
|
|
71
70
|
```
|
|
72
71
|
|
|
72
|
+
출력(JSON 배열)을 파싱해 각 `{team, feature}` 쌍마다 **background Agent** 를 생성합니다.
|
|
73
|
+
|
|
74
|
+
> **Fallback**: 단일 팀만 배정하려면 `dequeue <team_id>` 도 계속 사용 가능.
|
|
75
|
+
|
|
73
76
|
dequeue 성공한 피처마다 **background Agent**를 생성합니다:
|
|
74
77
|
|
|
75
78
|
```
|
|
@@ -99,25 +102,29 @@ ORCHESTRATION LOOP:
|
|
|
99
102
|
- FAIL (재시도 가능)인 경우 → Step 4b (Retry)
|
|
100
103
|
- ESCALATED인 경우 → 사용자에게 알림, 해당 팀 유휴
|
|
101
104
|
|
|
102
|
-
2.
|
|
103
|
-
|
|
105
|
+
2. **Auto-Dispatch (필수)** — worker 완료 직후 idle 이 된 팀뿐 아니라
|
|
106
|
+
모든 idle team 에 ready feature 를 즉시 재배정:
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
→ 새 Worker를 background Agent로 생성 (Step 3과 동일)
|
|
107
|
-
→ LOOP 계속
|
|
108
|
+
bash scripts/harness-queue-manager.sh auto-dispatch .
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
→ LOOP 계속
|
|
110
|
+
반환된 모든 (team, feature) 쌍에 대해 즉시 background Agent 생성.
|
|
111
|
+
한 작업의 merge 지연이 다른 idle team 을 놀게 두지 않는다.
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
3. Queue 상태 확인 (로그용):
|
|
114
|
+
bash scripts/harness-queue-manager.sh idle-slots .
|
|
115
|
+
bash scripts/harness-queue-manager.sh status .
|
|
116
|
+
|
|
117
|
+
4. auto-dispatch 가 pairs=[] (= ready 도 0, idle 도 0 혹은 idle 만 있고 ready 가 0) 이면:
|
|
118
|
+
→ ready=0 AND in_progress>0 → 다른 worker 완료 대기. LOOP 계속
|
|
119
|
+
→ ready=0 AND in_progress=0 → Sprint 전환 시도:
|
|
115
120
|
bash scripts/harness-queue-manager.sh next-sprint .
|
|
116
|
-
- "Advancing" →
|
|
121
|
+
- "Advancing" → auto-dispatch 다시 실행 (Step 2로 복귀)
|
|
117
122
|
- "ALL SPRINTS COMPLETE" → 최종 보고. LOOP 종료.
|
|
118
123
|
- "Cannot advance" → 실패 피처 사용자 개입 요청. LOOP 종료.
|
|
119
124
|
```
|
|
120
125
|
|
|
126
|
+
**핵심 원칙**: worker 완료 알림 → **즉시 auto-dispatch** → 반환된 모든 쌍에 대해 병렬 spawn. 팀 간 의존성이 없으면 idle 시간은 "Agent 생성에 걸리는 수초" 로 수렴한다.
|
|
127
|
+
|
|
121
128
|
#### Step 4a: Merge + Unblock (PASS 처리)
|
|
122
129
|
|
|
123
130
|
Worker가 PASS로 반환되면:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "5.6.
|
|
3
|
+
"version": "5.6.4",
|
|
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"
|
|
@@ -269,6 +269,7 @@ render_team_features() {
|
|
|
269
269
|
($q[0].queue.failed // []) as $failed |
|
|
270
270
|
($q[0].queue.ready // []) as $ready |
|
|
271
271
|
($q[0].queue.in_progress // {}) as $prog |
|
|
272
|
+
($q[0].queue.blocked // {}) as $blocked |
|
|
272
273
|
.features[] |
|
|
273
274
|
.id as $fid |
|
|
274
275
|
(.name // .title // .description // "?" | if length > 18 then .[0:16] + ".." else . end) as $fname |
|
|
@@ -276,18 +277,21 @@ render_team_features() {
|
|
|
276
277
|
elif $prog[$fid] then "I|\($prog[$fid].team)|\($prog[$fid].phase)"
|
|
277
278
|
elif ($fid | IN($failed[])) then "F"
|
|
278
279
|
elif ($fid | IN($ready[])) then "R"
|
|
279
|
-
|
|
280
|
+
elif $blocked[$fid] then "BLK|\($blocked[$fid] | length)"
|
|
281
|
+
else "U" end) as $st |
|
|
280
282
|
"\($st)\t\($fid)\t\($fname)"
|
|
281
283
|
' "$FEATURES" 2>/dev/null | while IFS=$'\t' read -r st fid fname; do
|
|
282
284
|
case "$st" in
|
|
283
|
-
P)
|
|
284
|
-
F)
|
|
285
|
-
R)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
285
|
+
P) printf " ${GREEN}●${RESET} %-6s %s\n" "$fid" "$fname" ;;
|
|
286
|
+
F) printf " ${RED}✗${RESET} %-6s %s\n" "$fid" "$fname" ;;
|
|
287
|
+
R) printf " ${YELLOW}○${RESET} %-6s %s\n" "$fid" "$fname" ;;
|
|
288
|
+
BLK\|*) deps=$(echo "$st" | cut -d'|' -f2)
|
|
289
|
+
printf " ${MAGENTA}◍${RESET} %-6s %-22s ${DIM}blocked (deps:%s)${RESET}\n" "$fid" "$fname" "$deps" ;;
|
|
290
|
+
U) printf " ${DIM}◌${RESET} %-6s %s\n" "$fid" "$fname" ;;
|
|
291
|
+
I\|*) team=$(echo "$st" | cut -d'|' -f2)
|
|
292
|
+
phase=$(echo "$st" | cut -d'|' -f3)
|
|
293
|
+
printf " ${CYAN}◐${RESET} %-6s %-22s T%s:%s\n" "$fid" "$fname" "$team" "$phase" ;;
|
|
294
|
+
*) printf " ? %-6s %s\n" "$fid" "$fname" ;;
|
|
291
295
|
esac
|
|
292
296
|
done
|
|
293
297
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# harness-progress-set.sh — Safe partial update to .harness/progress.json
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# bash scripts/harness-progress-set.sh <project-root> <jq_filter>
|
|
6
|
+
#
|
|
7
|
+
# The jq filter is a partial assignment expression. All other fields are
|
|
8
|
+
# preserved. NEVER rewrite progress.json as a full JSON blob — mode,
|
|
9
|
+
# team_state, and similar top-level fields will be lost.
|
|
10
|
+
#
|
|
11
|
+
# Example:
|
|
12
|
+
# bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
13
|
+
|
|
14
|
+
set -uo pipefail
|
|
15
|
+
|
|
16
|
+
PROJECT_ROOT="${1:-.}"
|
|
17
|
+
FILTER="${2:-}"
|
|
18
|
+
|
|
19
|
+
if [ -z "$FILTER" ]; then
|
|
20
|
+
echo "[progress-set] usage: $0 <project-root> <jq_filter>" >&2
|
|
21
|
+
exit 2
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
PROGRESS="$PROJECT_ROOT/.harness/progress.json"
|
|
25
|
+
|
|
26
|
+
if [ ! -f "$PROGRESS" ]; then
|
|
27
|
+
echo "[progress-set] not found: $PROGRESS" >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Always add .updated_at = now so callers don't forget
|
|
32
|
+
FINAL_FILTER="$FILTER | .updated_at = (now | todate)"
|
|
33
|
+
|
|
34
|
+
TMP="${PROGRESS}.tmp.$$"
|
|
35
|
+
if jq "$FINAL_FILTER" "$PROGRESS" > "$TMP" 2>/dev/null; then
|
|
36
|
+
mv "$TMP" "$PROGRESS"
|
|
37
|
+
else
|
|
38
|
+
rm -f "$TMP"
|
|
39
|
+
echo "[progress-set] jq filter failed: $FILTER" >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
@@ -424,19 +424,84 @@ cmd_recover() {
|
|
|
424
424
|
echo "[queue] Recovered ${stale_count} stale features back to ready queue."
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
# ══════════════════════════════════════════
|
|
428
|
+
# auto-dispatch — Pair all idle teams with ready features in one atomic step.
|
|
429
|
+
# Output: JSON array of {team, feature} on stdout.
|
|
430
|
+
# Atomically moves ready → in_progress + teams[tid] = busy for each pair.
|
|
431
|
+
# Dependencies are already honored (ready queue only holds unblocked features).
|
|
432
|
+
# ══════════════════════════════════════════
|
|
433
|
+
cmd_auto_dispatch() {
|
|
434
|
+
if [ ! -f "$QUEUE" ]; then echo "[queue] Run 'init' first." >&2; exit 1; fi
|
|
435
|
+
|
|
436
|
+
acquire_queue_lock
|
|
437
|
+
|
|
438
|
+
local result
|
|
439
|
+
result=$(jq '
|
|
440
|
+
. as $root |
|
|
441
|
+
($root.teams | to_entries | map(select(.value.status == "idle")) | map(.key)) as $idle |
|
|
442
|
+
($root.queue.ready) as $ready |
|
|
443
|
+
(if ($idle | length) < ($ready | length) then ($idle | length) else ($ready | length) end) as $n |
|
|
444
|
+
[range(0; $n) | { team: ($idle[.] | tonumber), feature: $ready[.] }] as $pairs |
|
|
445
|
+
(reduce $pairs[] as $p ($root;
|
|
446
|
+
.queue.ready -= [$p.feature] |
|
|
447
|
+
.queue.in_progress[$p.feature] = { team: $p.team, phase: "gen", attempt: 1 } |
|
|
448
|
+
.teams[($p.team | tostring)] = {
|
|
449
|
+
status: "busy",
|
|
450
|
+
feature: $p.feature,
|
|
451
|
+
branch: ("feature/" + $p.feature),
|
|
452
|
+
pid: null
|
|
453
|
+
}
|
|
454
|
+
)) as $updated |
|
|
455
|
+
{ state: $updated, pairs: $pairs }
|
|
456
|
+
' "$QUEUE")
|
|
457
|
+
|
|
458
|
+
local new_state pairs
|
|
459
|
+
new_state=$(echo "$result" | jq '.state')
|
|
460
|
+
pairs=$(echo "$result" | jq -c '.pairs')
|
|
461
|
+
|
|
462
|
+
# Write updated state
|
|
463
|
+
echo "$new_state" > "${QUEUE}.tmp" && mv "${QUEUE}.tmp" "$QUEUE"
|
|
464
|
+
|
|
465
|
+
release_queue_lock
|
|
466
|
+
|
|
467
|
+
# Emit pairs (single JSON line) for caller
|
|
468
|
+
echo "$pairs"
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
# ══════════════════════════════════════════
|
|
472
|
+
# idle-slots — Report how many teams are idle + how many ready features wait.
|
|
473
|
+
# No state mutation. Useful for dashboards / quick checks.
|
|
474
|
+
# ══════════════════════════════════════════
|
|
475
|
+
cmd_idle_slots() {
|
|
476
|
+
if [ ! -f "$QUEUE" ]; then echo "[queue] Run 'init' first." >&2; exit 1; fi
|
|
477
|
+
jq '{
|
|
478
|
+
idle_teams: [.teams | to_entries[] | select(.value.status == "idle") | .key],
|
|
479
|
+
ready_features: .queue.ready,
|
|
480
|
+
dispatchable: (
|
|
481
|
+
(if ([.teams | to_entries[] | select(.value.status == "idle") | .key] | length) <
|
|
482
|
+
(.queue.ready | length)
|
|
483
|
+
then [.teams | to_entries[] | select(.value.status == "idle") | .key] | length
|
|
484
|
+
else .queue.ready | length
|
|
485
|
+
end)
|
|
486
|
+
)
|
|
487
|
+
}' "$QUEUE"
|
|
488
|
+
}
|
|
489
|
+
|
|
427
490
|
# ── Dispatch ──
|
|
428
491
|
case "$CMD" in
|
|
429
|
-
init)
|
|
430
|
-
dequeue)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
492
|
+
init) cmd_init "$@" ;;
|
|
493
|
+
dequeue) cmd_dequeue "$@" ;;
|
|
494
|
+
auto-dispatch) cmd_auto_dispatch ;;
|
|
495
|
+
idle-slots) cmd_idle_slots ;;
|
|
496
|
+
pass) cmd_pass "$@" ;;
|
|
497
|
+
fail) cmd_fail "$@" ;;
|
|
498
|
+
requeue) cmd_requeue "$@" ;;
|
|
499
|
+
update_phase) cmd_update_phase "$@" ;;
|
|
500
|
+
recover) cmd_recover ;;
|
|
501
|
+
next-sprint) cmd_next_sprint ;;
|
|
502
|
+
status) cmd_status ;;
|
|
438
503
|
*)
|
|
439
|
-
echo "Usage: harness-queue-manager.sh <init|dequeue|pass|fail|requeue|recover|next-sprint|update_phase|status> [args]"
|
|
504
|
+
echo "Usage: harness-queue-manager.sh <init|dequeue|auto-dispatch|idle-slots|pass|fail|requeue|recover|next-sprint|update_phase|status> [args]"
|
|
440
505
|
exit 1
|
|
441
506
|
;;
|
|
442
507
|
esac
|
|
@@ -27,6 +27,29 @@ next_agent=$(jq -r '.next_agent // "none"' "$PROGRESS" 2>/dev/null)
|
|
|
27
27
|
agent_status=$(jq -r '.agent_status // "pending"' "$PROGRESS" 2>/dev/null)
|
|
28
28
|
mode=$(jq -r '.mode // "solo"' "$PROGRESS" 2>/dev/null)
|
|
29
29
|
|
|
30
|
+
# ─────────────────────────────────────────
|
|
31
|
+
# Auto-heal mode drift — Team 상태 유실 복구
|
|
32
|
+
# feature-queue.json 에 활성 작업(in_progress)이 있는데 mode 가 solo/paused 면
|
|
33
|
+
# 누군가 progress.json 을 통째로 덮어써서 team_state 를 날린 것. mode=team 으로
|
|
34
|
+
# 자동 복원하고 경고 로그 남김.
|
|
35
|
+
# ─────────────────────────────────────────
|
|
36
|
+
FEATURE_QUEUE_HEAL="$PROJECT_ROOT/.harness/actions/feature-queue.json"
|
|
37
|
+
if [ -f "$FEATURE_QUEUE_HEAL" ] && [ "$mode" != "team" ]; then
|
|
38
|
+
active_count=$(jq -r '(.queue.in_progress | length) // 0' "$FEATURE_QUEUE_HEAL" 2>/dev/null || echo 0)
|
|
39
|
+
if [ "${active_count:-0}" -gt 0 ]; then
|
|
40
|
+
heal_teams=$active_count
|
|
41
|
+
[ "$heal_teams" -gt 3 ] && heal_teams=3
|
|
42
|
+
bash "$SCRIPT_DIR/harness-progress-set.sh" "$PROJECT_ROOT" \
|
|
43
|
+
".mode = \"team\" | .team_state.active_teams = ${heal_teams} | .team_state.paused_at = null" \
|
|
44
|
+
2>/dev/null
|
|
45
|
+
mode="team"
|
|
46
|
+
echo "# Harness: mode auto-healed to 'team' (feature-queue has ${active_count} active, but mode was drifted)" >&2
|
|
47
|
+
if [ -f "$PROJECT_ROOT/.harness/progress.log" ]; then
|
|
48
|
+
echo "$(date +'%Y-%m-%d %H:%M') | system | heal | mode | reset solo→team (queue had ${active_count} in_progress)" >> "$PROJECT_ROOT/.harness/progress.log"
|
|
49
|
+
fi
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
|
|
30
53
|
# ─────────────────────────────────────────
|
|
31
54
|
# Team Mode — 팀이 자율 실행 중이면 오케스트레이터 안내
|
|
32
55
|
# ─────────────────────────────────────────
|
|
@@ -31,6 +31,24 @@ Planner 가 곧바로 plan.md / feature-list.json / api-contract.json 으로 변
|
|
|
31
31
|
제공하거나 브레인스토밍 불필요를 선언하면 Dispatcher 는 곧바로 `next_agent = planner`
|
|
32
32
|
로 라우팅한다.
|
|
33
33
|
|
|
34
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
35
|
+
|
|
36
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
37
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
38
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
39
|
+
|
|
40
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# 헬퍼 스크립트 (권장)
|
|
44
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
45
|
+
|
|
46
|
+
# 또는 직접 jq 로 partial update
|
|
47
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
51
|
+
|
|
34
52
|
## Session Boundary Protocol
|
|
35
53
|
|
|
36
54
|
### On Start
|
|
@@ -6,6 +6,24 @@ disable-model-invocation: false
|
|
|
6
6
|
|
|
7
7
|
# Dispatcher — Pipeline Selector + Gotcha Manager
|
|
8
8
|
|
|
9
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
10
|
+
|
|
11
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
12
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
13
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
14
|
+
|
|
15
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 헬퍼 스크립트 (권장)
|
|
19
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
20
|
+
|
|
21
|
+
# 또는 직접 jq 로 partial update
|
|
22
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
26
|
+
|
|
9
27
|
## Session Boundary Protocol
|
|
10
28
|
|
|
11
29
|
### On Start
|
|
@@ -9,6 +9,24 @@ disable-model-invocation: true
|
|
|
9
9
|
> Functional/Visual 평가자보다 **먼저** 실행된다. 코드가 구조적으로 망가졌으면
|
|
10
10
|
> 동작 테스트는 의미 없다. 이 게이트에서 FAIL 이면 Functional/Visual 은 아예 시작도 하지 않는다.
|
|
11
11
|
|
|
12
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
13
|
+
|
|
14
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
15
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
16
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
17
|
+
|
|
18
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# 헬퍼 스크립트 (권장)
|
|
22
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
23
|
+
|
|
24
|
+
# 또는 직접 jq 로 partial update
|
|
25
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
29
|
+
|
|
12
30
|
## Session Boundary Protocol
|
|
13
31
|
|
|
14
32
|
### On Start
|
|
@@ -6,6 +6,24 @@ disable-model-invocation: true
|
|
|
6
6
|
|
|
7
7
|
# Evaluator-Functional — Playwright MCP
|
|
8
8
|
|
|
9
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
10
|
+
|
|
11
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
12
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
13
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
14
|
+
|
|
15
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 헬퍼 스크립트 (권장)
|
|
19
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
20
|
+
|
|
21
|
+
# 또는 직접 jq 로 partial update
|
|
22
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
26
|
+
|
|
9
27
|
## Session Boundary Protocol
|
|
10
28
|
|
|
11
29
|
### On Start
|
|
@@ -6,6 +6,24 @@ disable-model-invocation: true
|
|
|
6
6
|
|
|
7
7
|
# Evaluator-Visual — Design & Accessibility
|
|
8
8
|
|
|
9
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
10
|
+
|
|
11
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
12
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
13
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
14
|
+
|
|
15
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 헬퍼 스크립트 (권장)
|
|
19
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
20
|
+
|
|
21
|
+
# 또는 직접 jq 로 partial update
|
|
22
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
26
|
+
|
|
9
27
|
## Session Boundary Protocol
|
|
10
28
|
|
|
11
29
|
### On Start
|
|
@@ -6,6 +6,24 @@ disable-model-invocation: true
|
|
|
6
6
|
|
|
7
7
|
# Generator-Backend — Adaptive (Stack-Agnostic)
|
|
8
8
|
|
|
9
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
10
|
+
|
|
11
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
12
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
13
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
14
|
+
|
|
15
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 헬퍼 스크립트 (권장)
|
|
19
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
20
|
+
|
|
21
|
+
# 또는 직접 jq 로 partial update
|
|
22
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
26
|
+
|
|
9
27
|
## Session Boundary Protocol
|
|
10
28
|
|
|
11
29
|
### On Start
|
|
@@ -6,6 +6,24 @@ disable-model-invocation: true
|
|
|
6
6
|
|
|
7
7
|
# Generator-Frontend — Adaptive (Stack-Agnostic)
|
|
8
8
|
|
|
9
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
10
|
+
|
|
11
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
12
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
13
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
14
|
+
|
|
15
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 헬퍼 스크립트 (권장)
|
|
19
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
20
|
+
|
|
21
|
+
# 또는 직접 jq 로 partial update
|
|
22
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
26
|
+
|
|
9
27
|
## Session Boundary Protocol
|
|
10
28
|
|
|
11
29
|
### On Start
|
package/skills/planner/SKILL.md
CHANGED
|
@@ -6,6 +6,24 @@ disable-model-invocation: true
|
|
|
6
6
|
|
|
7
7
|
# Planner Agent
|
|
8
8
|
|
|
9
|
+
## progress.json 업데이트 규칙 (v5.6.3+)
|
|
10
|
+
|
|
11
|
+
⚠️ **절대로 progress.json 을 통째로 재작성하지 마라**. `Write` 도구로 전체 파일을
|
|
12
|
+
덮어쓰면 `mode` / `team_state` / 기타 top-level 필드가 누락되어 Team Mode 가 Solo 로
|
|
13
|
+
되돌아가는 등 런타임 오류가 발생한다.
|
|
14
|
+
|
|
15
|
+
**올바른 방법** — 반드시 partial update 로 갱신:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 헬퍼 스크립트 (권장)
|
|
19
|
+
bash scripts/harness-progress-set.sh . '.current_agent = "planner" | .agent_status = "running"'
|
|
20
|
+
|
|
21
|
+
# 또는 직접 jq 로 partial update
|
|
22
|
+
jq '.agent_status = "completed" | .completed_agents += ["planner"]' .harness/progress.json > .harness/progress.json.tmp && mv .harness/progress.json.tmp .harness/progress.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
위 두 방식은 파일의 나머지 필드를 보존한다. Read → 수정 → Write 패턴은 사용 금지.
|
|
26
|
+
|
|
9
27
|
## Session Boundary Protocol
|
|
10
28
|
|
|
11
29
|
### On Start
|