@walwal-harness/cli 4.0.0-alpha.4 → 4.0.0-alpha.6

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.4",
3
+ "version": "4.0.0-alpha.6",
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"
@@ -44,18 +44,21 @@ render_queue_summary() {
44
44
  fi
45
45
 
46
46
  local ready blocked in_prog passed failed total concurrency
47
- ready=$(jq '.queue.ready | length' "$QUEUE" 2>/dev/null)
48
- blocked=$(jq '.queue.blocked | length' "$QUEUE" 2>/dev/null)
49
- in_prog=$(jq '.queue.in_progress | length' "$QUEUE" 2>/dev/null)
50
- passed=$(jq '.queue.passed | length' "$QUEUE" 2>/dev/null)
51
- failed=$(jq '.queue.failed | length' "$QUEUE" 2>/dev/null)
52
- concurrency=$(jq '.concurrency // 3' "$QUEUE" 2>/dev/null)
47
+ ready=$(jq '.queue.ready | length' "$QUEUE" 2>/dev/null || echo 0)
48
+ blocked=$(jq '.queue.blocked | length' "$QUEUE" 2>/dev/null || echo 0)
49
+ in_prog=$(jq '.queue.in_progress | length' "$QUEUE" 2>/dev/null || echo 0)
50
+ passed=$(jq '.queue.passed | length' "$QUEUE" 2>/dev/null || echo 0)
51
+ failed=$(jq '.queue.failed | length' "$QUEUE" 2>/dev/null || echo 0)
52
+ concurrency=$(jq '.concurrency // 3' "$QUEUE" 2>/dev/null || echo 3)
53
+ ready=${ready:-0}; blocked=${blocked:-0}; in_prog=${in_prog:-0}; passed=${passed:-0}; failed=${failed:-0}
53
54
  total=$((ready + blocked + in_prog + passed + failed))
54
55
 
55
56
  # Progress bar
56
57
  local pct=0
57
58
  if [ "$total" -gt 0 ]; then pct=$(( passed * 100 / total )); fi
58
- local bar_w=20 filled=$(( pct * bar_w / 100 )) empty=$(( bar_w - filled ))
59
+ local bar_w=20
60
+ local filled=$(( pct * bar_w / 100 ))
61
+ local empty=$(( bar_w - filled ))
59
62
  local bar=""
60
63
  for ((i=0; i<filled; i++)); do bar+="█"; done
61
64
  for ((i=0; i<empty; i++)); do bar+="░"; done
@@ -112,45 +115,37 @@ render_teams() {
112
115
  render_feature_list() {
113
116
  if [ ! -f "$QUEUE" ] || [ ! -f "$FEATURES" ]; then return; fi
114
117
 
115
- local total
116
- total=$(jq '.features | length' "$FEATURES" 2>/dev/null)
117
- if [ "${total:-0}" -eq 0 ]; then return; fi
118
-
119
118
  echo -e " ${BOLD}Features${RESET}"
120
119
 
121
- local i=0
122
- while [ "$i" -lt "$total" ]; do
123
- local fid fname status_icon
124
- fid=$(jq -r ".features[$i].id" "$FEATURES" 2>/dev/null)
125
- fname=$(jq -r ".features[$i].name // .features[$i].description // \"\"" "$FEATURES" 2>/dev/null)
126
- if [ ${#fname} -gt 22 ]; then fname="${fname:0:20}.."; fi
127
-
128
- # Determine status from queue
129
- local in_passed in_failed in_progress in_ready in_blocked
130
- in_passed=$(jq -r --arg f "$fid" '.queue.passed // [] | map(select(. == $f)) | length' "$QUEUE" 2>/dev/null)
131
- in_failed=$(jq -r --arg f "$fid" '.queue.failed // [] | map(select(. == $f)) | length' "$QUEUE" 2>/dev/null)
132
- in_progress=$(jq -r --arg f "$fid" '.queue.in_progress[$f] // empty' "$QUEUE" 2>/dev/null)
133
- in_ready=$(jq -r --arg f "$fid" '.queue.ready // [] | map(select(. == $f)) | length' "$QUEUE" 2>/dev/null)
134
-
135
- if [ "${in_passed:-0}" -gt 0 ]; then
136
- status_icon="${GREEN}●${RESET}"
137
- elif [ -n "$in_progress" ] && [ "$in_progress" != "" ]; then
138
- local team phase
139
- team=$(echo "$in_progress" | jq -r '.team // "?"' 2>/dev/null)
140
- phase=$(echo "$in_progress" | jq -r '.phase // "?"' 2>/dev/null)
141
- status_icon="${CYAN}◐${RESET} T${team}:${phase}"
142
- elif [ "${in_failed:-0}" -gt 0 ]; then
143
- status_icon="${RED}✗${RESET}"
144
- elif [ "${in_ready:-0}" -gt 0 ]; then
145
- status_icon="${YELLOW}○${RESET}"
146
- else
147
- status_icon="${DIM}◌${RESET}" # blocked
148
- fi
149
-
150
- printf " %b %-6s %-24s\n" "$status_icon" "$fid" "$fname"
151
-
152
- i=$((i + 1))
120
+ # Single jq call: merge feature-list + queue state → pre-formatted lines
121
+ jq -r --slurpfile q "$QUEUE" '
122
+ ($q[0].queue.passed // []) as $passed |
123
+ ($q[0].queue.failed // []) as $failed |
124
+ ($q[0].queue.ready // []) as $ready |
125
+ ($q[0].queue.in_progress // {}) as $prog |
126
+ .features[] |
127
+ .id as $fid |
128
+ (.name // .description // "?" | if length > 22 then .[0:20] + ".." else . end) as $fname |
129
+ (if ($fid | IN($passed[])) then "P"
130
+ elif $prog[$fid] then "I|\($prog[$fid].team)|\($prog[$fid].phase)"
131
+ elif ($fid | IN($failed[])) then "F"
132
+ elif ($fid | IN($ready[])) then "R"
133
+ else "B" end) as $st |
134
+ "\($st)\t\($fid)\t\($fname)"
135
+ ' "$FEATURES" 2>/dev/null | while IFS=$'\t' read -r st fid fname; do
136
+ case "$st" in
137
+ P) printf " ${GREEN}●${RESET} %-6s %s\n" "$fid" "$fname" ;;
138
+ F) printf " ${RED}✗${RESET} %-6s %s\n" "$fid" "$fname" ;;
139
+ R) printf " ${YELLOW}○${RESET} %-6s %s\n" "$fid" "$fname" ;;
140
+ B) printf " ${DIM}◌${RESET} %-6s %s\n" "$fid" "$fname" ;;
141
+ I\|*) # in_progress: extract team and phase
142
+ team=$(echo "$st" | cut -d'|' -f2)
143
+ phase=$(echo "$st" | cut -d'|' -f3)
144
+ printf " ${CYAN}◐${RESET} %-6s %-18s T%s:%s\n" "$fid" "$fname" "$team" "$phase" ;;
145
+ *) printf " ? %-6s %s\n" "$fid" "$fname" ;;
146
+ esac
153
147
  done
148
+
154
149
  echo ""
155
150
  }
156
151
 
@@ -169,8 +164,7 @@ trap 'tput cnorm 2>/dev/null; exit 0' EXIT INT TERM
169
164
  clear
170
165
 
171
166
  while true; do
172
- local buf
173
- buf=$(render_all 2>/dev/null)
167
+ buf=$(render_all 2>&1)
174
168
  tput cup 0 0 2>/dev/null
175
169
  echo "$buf"
176
170
  tput ed 2>/dev/null
@@ -26,6 +26,24 @@ current_agent=$(jq -r '.current_agent // "none"' "$PROGRESS" 2>/dev/null)
26
26
  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
 
29
+ # ─────────────────────────────────────────
30
+ # v4 Parallel Mode — feature-queue.json이 존재하면 v4 안내
31
+ # ─────────────────────────────────────────
32
+ FEATURE_QUEUE="$PROJECT_ROOT/.harness/actions/feature-queue.json"
33
+ if [ -f "$FEATURE_QUEUE" ]; then
34
+ passed=$(jq '.queue.passed | length' "$FEATURE_QUEUE" 2>/dev/null || echo 0)
35
+ total=$(jq '[.queue.ready, (.queue.blocked | keys), (.queue.in_progress | keys), .queue.passed, .queue.failed] | flatten | length' "$FEATURE_QUEUE" 2>/dev/null || echo 0)
36
+ in_prog=$(jq '.queue.in_progress | length' "$FEATURE_QUEUE" 2>/dev/null || echo 0)
37
+ failed=$(jq '.queue.failed | length' "$FEATURE_QUEUE" 2>/dev/null || echo 0)
38
+
39
+ echo "# Harness v4 — Parallel Agent Teams active"
40
+ echo "# Queue: ${passed}/${total} passed, ${in_prog} in progress, ${failed} failed"
41
+ echo "# Teams are running autonomously. You are the orchestrator."
42
+ echo "# Role: Monitor dashboard, resolve failures, manual interventions only."
43
+ echo "# Do NOT run /harness-generator-* or /harness-evaluator-* — Teams handle Gen+Eval."
44
+ exit 0
45
+ fi
46
+
29
47
  # ─────────────────────────────────────────
30
48
  # init 상태: 첫 안내
31
49
  # ─────────────────────────────────────────
@@ -51,7 +51,27 @@ current_agent=${CURRENT_AGENT} (running) 인데 /harness-${REQUESTED_SKILL} 호
51
51
  fi
52
52
  fi
53
53
 
54
- # ── Compact context 주입 ──
54
+ # ── v4 Parallel Mode 감지 ──
55
+ FEATURE_QUEUE="$CWD/.harness/actions/feature-queue.json"
56
+ if [ -f "$FEATURE_QUEUE" ]; then
57
+ V4_PASSED=$(jq '.queue.passed | length' "$FEATURE_QUEUE" 2>/dev/null || echo 0)
58
+ V4_TOTAL=$(jq '[.queue.ready, (.queue.blocked | keys), (.queue.in_progress | keys), .queue.passed, .queue.failed] | flatten | length' "$FEATURE_QUEUE" 2>/dev/null || echo 0)
59
+ V4_FAILED=$(jq '.queue.failed | length' "$FEATURE_QUEUE" 2>/dev/null || echo 0)
60
+
61
+ cat <<EOF
62
+ [harness-v4] ${V4_PASSED}/${V4_TOTAL} features passed | ${V4_FAILED} failed
63
+
64
+ ## v4 Parallel Mode Active
65
+ - 3 Agent Teams이 feature-queue에서 자율적으로 Gen→Eval 루프 실행 중
66
+ - 당신은 **오케스트레이터** 역할: 대시보드 모니터링, 실패 대응, 수동 개입
67
+ - /harness-generator-*, /harness-evaluator-* 스킬 호출 금지 (Teams가 처리)
68
+ - 할 수 있는 것: 코드 리뷰, 아키텍처 결정, failed feature 분석, requeue 판단
69
+ - skip: "harness skip" 시 일반 대화
70
+ EOF
71
+ exit 0
72
+ fi
73
+
74
+ # ── Compact context 주입 (v3 mode) ──
55
75
  cat <<EOF
56
76
  [harness] S${SPRINT_NUM} | ${PIPELINE} | agent=${CURRENT_AGENT} (${AGENT_STATUS}) | next=${NEXT_AGENT}
57
77
  ${CONTEXT_WARNING}