@walwal-harness/cli 4.0.0-alpha.16 → 4.0.0-alpha.18

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": "4.0.0-alpha.16",
3
+ "version": "4.0.0-alpha.18",
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,12 +1,10 @@
1
1
  #!/bin/bash
2
- # harness-studio-v4.sh — Harness Studio v4: 3-Column + Dashboard Split
2
+ # harness-studio-v4.sh — Harness Studio v4
3
3
  #
4
4
  # ┌──────────────┬──────────────┬──────────────┐
5
5
  # │ │ Progress │ Team 1 │
6
- # │ │ (fixed) ├──────────────┤
7
6
  # │ Main ├──────────────┤ Team 2 │
8
- # │ (claude) │ Prompts ├──────────────┤
9
- # │ │ (scroll) │ Team 3 │
7
+ # │ (claude) │ Prompts │ Team 3 │
10
8
  # └──────────────┴──────────────┴──────────────┘
11
9
 
12
10
  set -euo pipefail
@@ -15,16 +13,10 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
15
13
  SESSION_NAME="harness-v4"
16
14
 
17
15
  PROJECT_ROOT=""
18
-
19
16
  for arg in "$@"; do
20
17
  case "$arg" in
21
- --kill)
22
- tmux kill-session -t "$SESSION_NAME" 2>/dev/null && echo "Killed." || echo "No session."
23
- exit 0
24
- ;;
25
- *)
26
- if [ -d "$arg" ]; then PROJECT_ROOT="$arg"; fi
27
- ;;
18
+ --kill) tmux kill-session -t "$SESSION_NAME" 2>/dev/null && echo "Killed." || echo "No session."; exit 0 ;;
19
+ *) if [ -d "$arg" ]; then PROJECT_ROOT="$arg"; fi ;;
28
20
  esac
29
21
  done
30
22
 
@@ -37,14 +29,14 @@ if [ -z "$PROJECT_ROOT" ]; then
37
29
  fi
38
30
 
39
31
  if [ -z "$PROJECT_ROOT" ] || [ ! -d "$PROJECT_ROOT/.harness" ]; then
40
- echo "Error: .harness/ not found."
41
- exit 1
32
+ echo "Error: .harness/ not found."; exit 1
42
33
  fi
43
34
 
44
35
  echo "Project: $PROJECT_ROOT"
45
36
  echo "Session: $SESSION_NAME"
46
37
 
47
38
  tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true
39
+ sleep 0.5
48
40
 
49
41
  # ── Init/recover queue ──
50
42
  QUEUE="$PROJECT_ROOT/.harness/actions/feature-queue.json"
@@ -57,90 +49,119 @@ else
57
49
  fi
58
50
 
59
51
  # ══════════════════════════════════════════
60
- # Layout: 3 columns first, then split middle column
61
- #
62
- # Step 1: [Main]
63
- # Step 2: [Main | Right] — h split 66%
64
- # Step 3: [Main | Mid | Right] — h split Mid from Right at 50%
65
- # Step 4: [Main | Progress / Prompts | Right] — v split Mid
66
- # Step 5: [Main | Progress / Prompts | T1 / T2 / T3] — v split Right
52
+ # Build layout all panes use direct command execution
53
+ # Panes that exit will show "Pane is dead" instead of closing
67
54
  # ══════════════════════════════════════════
68
55
 
69
- # 1. Main
56
+ tmux set-option -g remain-on-exit on 2>/dev/null || true
57
+
58
+ # 1. Main (left, 34%)
70
59
  PANE_MAIN=$(tmux new-session -d -s "$SESSION_NAME" -c "$PROJECT_ROOT" -x 220 -y 55 \
71
60
  -P -F '#{pane_id}')
72
61
 
73
- # 2. Right column (will become Team area)
62
+ # 2. Right area (66%) — will become Teams
74
63
  PANE_RIGHT=$(tmux split-window -h -p 66 -t "$PANE_MAIN" -c "$PROJECT_ROOT" \
75
- -P -F '#{pane_id}')
64
+ -P -F '#{pane_id}' \
65
+ "bash '${SCRIPT_DIR}/harness-team-worker.sh' 1 '${PROJECT_ROOT}'")
76
66
 
77
- # 3. Middle column (split from Right, 50% = Mid gets left half, Right keeps right half)
67
+ # 3. Middle column split from Right (50/50)
78
68
  PANE_MID=$(tmux split-window -h -p 50 -t "$PANE_RIGHT" -c "$PROJECT_ROOT" \
79
- -P -F '#{pane_id}')
80
- # Now: PANE_MID is the NEW pane (right side of split), PANE_RIGHT stays left
81
- # Wait — tmux split-window -h on PANE_RIGHT creates new pane to the RIGHT of PANE_RIGHT
82
- # So PANE_MID ends up on the right, and PANE_RIGHT is in the middle
83
- # We need to swap: split PANE_MAIN's right, then the rightmost becomes teams
84
-
85
- # Actually let me reconsider. After step 2:
86
- # [Main 33%] [Right 66%]
87
- # After step 3 (split Right horizontally at 50%):
88
- # [Main 33%] [Right_left 33%] [Right_right 33%]
89
- # Right_left = PANE_RIGHT (original), Right_right = PANE_MID (new)
90
- # We want: Right_left = Dashboard area, Right_right = Team area
91
- # So PANE_RIGHT becomes Dashboard, PANE_MID becomes Teams. But pane IDs...
92
- # Actually: split-window creates the NEW pane. -h splits horizontally.
93
- # The new pane goes to the right. So:
94
- # PANE_RIGHT (original) = middle column (Dashboard)
95
- # PANE_MID (new) = right column (Teams)
96
- # Perfect!
97
-
98
- # 4. Split middle column (PANE_RIGHT = Dashboard area) into Progress + Prompts
99
- # Kill the shell in PANE_RIGHT first, replace with Progress
100
- tmux send-keys -t "$PANE_RIGHT" "exec bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-dashboard-v4.sh\" \"${PROJECT_ROOT}\"'" Enter
101
-
102
- PANE_PROMPTS=$(tmux split-window -v -p 40 -t "$PANE_RIGHT" -c "$PROJECT_ROOT" \
103
69
  -P -F '#{pane_id}' \
104
- "bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-prompts-v4.sh\" \"${PROJECT_ROOT}\"'")
70
+ "bash '${SCRIPT_DIR}/harness-team-worker.sh' 2 '${PROJECT_ROOT}'")
105
71
 
106
- # 5. Split right column (PANE_MID = Team area) into Team 1/2/3
107
- tmux send-keys -t "$PANE_MID" "exec bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-team-worker.sh\" 1 \"${PROJECT_ROOT}\"'" Enter
72
+ # Now layout: [Main 34%] [Right 33%] [Mid 33%]
73
+ # Right = Team 1, Mid = Team 2
74
+ # But we need: [Main] [Dashboard area] [Teams area]
75
+ # Swap: Right should be dashboard, Mid should stay as teams
76
+ # Actually after split: PANE_RIGHT stays left (=Team1), PANE_MID is new right (=Team2)
77
+ # We need to rethink...
108
78
 
109
- PANE_T2=$(tmux split-window -v -p 66 -t "$PANE_MID" -c "$PROJECT_ROOT" \
110
- -P -F '#{pane_id}' \
111
- "bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-team-worker.sh\" 2 \"${PROJECT_ROOT}\"'")
79
+ # Let me use a cleaner approach: create all columns first with placeholder shells
112
80
 
113
- PANE_T3=$(tmux split-window -v -p 50 -t "$PANE_T2" -c "$PROJECT_ROOT" \
114
- -P -F '#{pane_id}' \
115
- "bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-team-worker.sh\" 3 \"${PROJECT_ROOT}\"'")
81
+ tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true
82
+ sleep 0.3
83
+
84
+ # === Clean rebuild ===
85
+
86
+ # Pane 0: Main
87
+ tmux new-session -d -s "$SESSION_NAME" -c "$PROJECT_ROOT" -x 220 -y 55
116
88
 
117
- # ── Launch Claude in Main ──
118
- tmux send-keys -t "$PANE_MAIN" "unset npm_config_prefix 2>/dev/null; clear && claude --dangerously-skip-permissions" Enter
89
+ # Split: [Main 34% | Rest 66%]
90
+ tmux split-window -h -p 66 -t "${SESSION_NAME}:0.0" -c "$PROJECT_ROOT"
119
91
 
120
- # ── Pane titles ──
121
- tmux select-pane -t "$PANE_MAIN" -T "Main"
122
- tmux select-pane -t "$PANE_RIGHT" -T "Progress"
123
- tmux select-pane -t "$PANE_PROMPTS" -T "Prompts"
124
- tmux select-pane -t "$PANE_MID" -T "Team 1"
125
- tmux select-pane -t "$PANE_T2" -T "Team 2"
126
- tmux select-pane -t "$PANE_T3" -T "Team 3"
92
+ # Split Rest: [Main 34% | Mid 50% | Right 50%] (of the 66%)
93
+ tmux split-window -h -p 50 -t "${SESSION_NAME}:0.1" -c "$PROJECT_ROOT"
94
+
95
+ # Now: pane 0 = Main (left), pane 1 = Mid, pane 2 = Right
96
+ # Split Mid vertically: Progress (60%) / Prompts (40%)
97
+ tmux split-window -v -p 40 -t "${SESSION_NAME}:0.1" -c "$PROJECT_ROOT"
98
+
99
+ # Now: pane 0=Main, pane 1=Mid-top(Progress), pane 2=Right, pane 3=Mid-bottom(Prompts)
100
+ # Split Right into 3 Teams
101
+ tmux split-window -v -p 66 -t "${SESSION_NAME}:0.2" -c "$PROJECT_ROOT"
102
+ tmux split-window -v -p 50 -t "${SESSION_NAME}:0.3" -c "$PROJECT_ROOT"
103
+
104
+ # Now 6 panes. Let's identify them by listing:
105
+ # pane 0 = Main (left)
106
+ # pane 1 = Progress (mid-top)
107
+ # pane 2 = Team area top
108
+ # pane 3 = Prompts (mid-bottom)
109
+ # pane 4 = Team area mid (split from pane 2's bottom sibling? — tmux numbering is tricky)
110
+
111
+ # Instead of guessing pane numbers, send commands to each pane by index after creation
112
+ # First set remain-on-exit for this session
113
+ tmux set-option -t "$SESSION_NAME" remain-on-exit on 2>/dev/null || true
114
+
115
+ # Get all pane IDs in order
116
+ PANES=($(tmux list-panes -t "$SESSION_NAME" -F '#{pane_id}'))
117
+
118
+ # Should be 6 panes. Assign by position:
119
+ # Visual order (left-to-right, top-to-bottom):
120
+ # [0] Main [1] Progress [2] Team-top
121
+ # [3] Prompts [4] Team-mid
122
+ # [5] Team-bottom
123
+
124
+ if [ ${#PANES[@]} -ne 6 ]; then
125
+ echo "ERROR: Expected 6 panes, got ${#PANES[@]}"
126
+ echo "Panes: ${PANES[*]}"
127
+ tmux attach -t "$SESSION_NAME"
128
+ exit 1
129
+ fi
130
+
131
+ P_MAIN="${PANES[0]}"
132
+ P_PROGRESS="${PANES[1]}"
133
+ P_TEAM1="${PANES[2]}"
134
+ P_PROMPTS="${PANES[3]}"
135
+ P_TEAM2="${PANES[4]}"
136
+ P_TEAM3="${PANES[5]}"
137
+
138
+ # Send commands to each pane
139
+ tmux send-keys -t "$P_MAIN" "unset npm_config_prefix 2>/dev/null; clear && claude --dangerously-skip-permissions" Enter
140
+ tmux send-keys -t "$P_PROGRESS" "bash '${SCRIPT_DIR}/harness-dashboard-v4.sh' '${PROJECT_ROOT}'" Enter
141
+ tmux send-keys -t "$P_PROMPTS" "bash '${SCRIPT_DIR}/harness-prompts-v4.sh' '${PROJECT_ROOT}'" Enter
142
+ tmux send-keys -t "$P_TEAM1" "bash '${SCRIPT_DIR}/harness-team-worker.sh' 1 '${PROJECT_ROOT}'" Enter
143
+ tmux send-keys -t "$P_TEAM2" "bash '${SCRIPT_DIR}/harness-team-worker.sh' 2 '${PROJECT_ROOT}'" Enter
144
+ tmux send-keys -t "$P_TEAM3" "bash '${SCRIPT_DIR}/harness-team-worker.sh' 3 '${PROJECT_ROOT}'" Enter
145
+
146
+ # Titles
147
+ tmux select-pane -t "$P_MAIN" -T "Main"
148
+ tmux select-pane -t "$P_PROGRESS" -T "Progress"
149
+ tmux select-pane -t "$P_PROMPTS" -T "Prompts"
150
+ tmux select-pane -t "$P_TEAM1" -T "Team 1"
151
+ tmux select-pane -t "$P_TEAM2" -T "Team 2"
152
+ tmux select-pane -t "$P_TEAM3" -T "Team 3"
127
153
 
128
154
  tmux set-option -t "$SESSION_NAME" pane-border-status top 2>/dev/null || true
129
155
  tmux set-option -t "$SESSION_NAME" pane-border-format " #{pane_title} " 2>/dev/null || true
130
156
 
131
- # ── Focus Main ──
132
- tmux select-pane -t "$PANE_MAIN"
157
+ # Focus Main
158
+ tmux select-pane -t "$P_MAIN"
133
159
 
134
- # ── Attach ──
160
+ # Attach
135
161
  if [ -n "${TMUX:-}" ]; then
136
162
  tmux switch-client -t "$SESSION_NAME"
137
163
  else
138
164
  echo ""
139
165
  echo "Launching Harness Studio v4..."
140
- echo " Main (left) : Claude interactive"
141
- echo " Progress (mid↑) : Queue + Teams + Features"
142
- echo " Prompts (mid↓) : Manual prompts + activity"
143
- echo " Team 1-3 (right) : Parallel workers"
144
- echo ""
145
166
  tmux attach -t "$SESSION_NAME"
146
167
  fi
@@ -1,27 +1,77 @@
1
1
  ---
2
2
  name: harness-team
3
- description: "v4 Parallel Agent Teams 모드 실행. 3개 Team Feature 단위 Gen→Eval 루프를 병렬 실행하는 tmux Studio를 띄운다."
3
+ description: "v4 Parallel Agent Teams 모드 활성화. feature-queue 초기화 후 3개 Team worker를 백그라운드 실행한다. 트리거: '/harness-team', 'agent team 시작', 'team 모드'"
4
+ disable-model-invocation: false
4
5
  ---
5
6
 
6
- # /harness-team — Parallel Agent Teams
7
+ # /harness-team — Parallel Agent Teams 활성화
7
8
 
8
- 이 스킬이 호출되면 **즉시** tmux Studio v4를 실행합니다.
9
+ ## 이 스킬이 호출되면
10
+
11
+ 1. **feature-queue.json 확인/초기화** — 없으면 feature-list.json에서 생성, 있으면 stale 복구
12
+ 2. **3개 Team Worker를 백그라운드로 시작** — 각각 claude -p로 Gen→Eval 루프 자율 실행
13
+ 3. **현재 세션은 유지** — 사용자는 오케스트레이터 역할 (모니터링, 실패 대응, 수동 개입)
9
14
 
10
15
  ## 실행 절차
11
16
 
12
- 1. `npx walwal-harness v4` 를 Bash로 실행
13
- 2. 현재 Claude 세션은 종료됨 (tmux가 터미널을 인수)
14
- 3. tmux Studio v4 레이아웃이 활성화:
15
- - Main (left): Claude --dangerously-skip-permissions 자동 실행
16
- - Dashboard (mid): Feature Queue + Team 상태 실시간 갱신
17
- - Team 1~3 (right): claude -p headless worker 자동 실행
17
+ 아래 명령을 순서대로 실행하세요:
18
+
19
+ ### Step 1: Queue 초기화/복구
20
+
21
+ ```bash
22
+ bash scripts/harness-queue-manager.sh init .
23
+ ```
24
+
25
+ 이미 queue가 있으면:
26
+
27
+ ```bash
28
+ bash scripts/harness-queue-manager.sh recover .
29
+ ```
30
+
31
+ ### Step 2: Team Worker 백그라운드 실행
32
+
33
+ ```bash
34
+ nohup bash scripts/harness-team-worker.sh 1 . > /tmp/harness-team-1.log 2>&1 &
35
+ nohup bash scripts/harness-team-worker.sh 2 . > /tmp/harness-team-2.log 2>&1 &
36
+ nohup bash scripts/harness-team-worker.sh 3 . > /tmp/harness-team-3.log 2>&1 &
37
+ ```
38
+
39
+ ### Step 3: 상태 확인
40
+
41
+ ```bash
42
+ bash scripts/harness-queue-manager.sh status .
43
+ ```
44
+
45
+ ## 실행 후 역할
46
+
47
+ 이 세션은 **오케스트레이터**입니다:
48
+ - `/harness-generator-*`, `/harness-evaluator-*` 스킬 호출 금지 (Teams가 처리)
49
+ - 할 수 있는 것: 큐 상태 확인, 실패 분석, 코드 리뷰, gotcha 등록, requeue
50
+
51
+ ### 유용한 명령
52
+
53
+ ```bash
54
+ # 큐 상태
55
+ bash scripts/harness-queue-manager.sh status .
56
+
57
+ # 실패한 feature 재큐
58
+ bash scripts/harness-queue-manager.sh requeue F-XXX .
59
+
60
+ # Team 로그 실시간 확인
61
+ tail -f /tmp/harness-team-1.log
62
+ tail -f /tmp/harness-team-2.log
63
+ tail -f /tmp/harness-team-3.log
64
+
65
+ # 모든 Team 중지
66
+ pkill -f harness-team-worker || true
67
+ ```
18
68
 
19
- ## 실행
69
+ ## tmux Studio (선택사항)
20
70
 
21
- 아래 명령을 **반드시 실행**하세요. 설명이나 확인 없이 바로 실행합니다:
71
+ 별도 터미널에서 tmux 레이아웃을 원하면:
22
72
 
23
73
  ```bash
24
- exec npx walwal-harness v4
74
+ npx walwal-harness v4
25
75
  ```
26
76
 
27
- 명령은 `exec`로 현재 셸을 대체하므로, Claude 세션이 tmux Studio로 전환됩니다.
77
+ 명령은 **Claude 세션 밖에서** (일반 터미널에서) 실행해야 합니다.