@walwal-harness/cli 4.0.0-alpha.13 → 4.0.0-alpha.14
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/bin/init.js +1 -0
- package/package.json +1 -1
- package/scripts/harness-dashboard-v4.sh +27 -115
- package/scripts/harness-prompts-v4.sh +106 -0
- package/scripts/harness-studio-v4.sh +12 -6
package/bin/init.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.14",
|
|
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,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# harness-dashboard-v4.sh — v4 Dashboard
|
|
3
|
-
#
|
|
2
|
+
# harness-dashboard-v4.sh — v4 Dashboard 상단: Planner Progress
|
|
3
|
+
# Queue + Teams + Features 를 auto-refresh. 고정 영역, 스크롤 없음.
|
|
4
4
|
|
|
5
5
|
set -uo pipefail
|
|
6
6
|
|
|
@@ -30,42 +30,34 @@ render_header() {
|
|
|
30
30
|
now=$(date +"%H:%M:%S")
|
|
31
31
|
project_name=$(jq -r '.project_name // "Unknown"' "$PROGRESS" 2>/dev/null)
|
|
32
32
|
|
|
33
|
-
echo -e "${BOLD}
|
|
34
|
-
echo -e "${BOLD}║ HARNESS v4 — Parallel Agent Teams ║${RESET}"
|
|
35
|
-
echo -e "${BOLD}╚════════════════════════════════════════════════╝${RESET}"
|
|
36
|
-
echo -e " ${DIM}${project_name} | ${now}${RESET}"
|
|
37
|
-
echo ""
|
|
33
|
+
echo -e "${BOLD}HARNESS v4${RESET} ${DIM}${project_name} | ${now}${RESET}"
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
render_queue_summary() {
|
|
41
37
|
if [ ! -f "$QUEUE" ]; then
|
|
42
|
-
echo -e " ${DIM}(queue not initialized
|
|
38
|
+
echo -e " ${DIM}(queue not initialized)${RESET}"
|
|
43
39
|
return
|
|
44
40
|
fi
|
|
45
41
|
|
|
46
|
-
local ready blocked in_prog passed failed total
|
|
42
|
+
local ready blocked in_prog passed failed total
|
|
47
43
|
ready=$(jq '.queue.ready | length' "$QUEUE" 2>/dev/null || echo 0)
|
|
48
44
|
blocked=$(jq '.queue.blocked | length' "$QUEUE" 2>/dev/null || echo 0)
|
|
49
45
|
in_prog=$(jq '.queue.in_progress | length' "$QUEUE" 2>/dev/null || echo 0)
|
|
50
46
|
passed=$(jq '.queue.passed | length' "$QUEUE" 2>/dev/null || echo 0)
|
|
51
47
|
failed=$(jq '.queue.failed | length' "$QUEUE" 2>/dev/null || echo 0)
|
|
52
|
-
concurrency=$(jq '.concurrency // 3' "$QUEUE" 2>/dev/null || echo 3)
|
|
53
48
|
ready=${ready:-0}; blocked=${blocked:-0}; in_prog=${in_prog:-0}; passed=${passed:-0}; failed=${failed:-0}
|
|
54
49
|
total=$((ready + blocked + in_prog + passed + failed))
|
|
55
50
|
|
|
56
|
-
# Progress bar
|
|
57
51
|
local pct=0
|
|
58
52
|
if [ "$total" -gt 0 ]; then pct=$(( passed * 100 / total )); fi
|
|
59
|
-
local bar_w=
|
|
53
|
+
local bar_w=16
|
|
60
54
|
local filled=$(( pct * bar_w / 100 ))
|
|
61
55
|
local empty=$(( bar_w - filled ))
|
|
62
56
|
local bar=""
|
|
63
57
|
for ((i=0; i<filled; i++)); do bar+="█"; done
|
|
64
58
|
for ((i=0; i<empty; i++)); do bar+="░"; done
|
|
65
59
|
|
|
66
|
-
echo -e " ${
|
|
67
|
-
echo -e " Ready:${GREEN}${ready}${RESET} Blocked:${YELLOW}${blocked}${RESET} Progress:${CYAN}${in_prog}${RESET} Pass:${GREEN}${passed}${RESET} Fail:${RED}${failed}${RESET}"
|
|
68
|
-
echo ""
|
|
60
|
+
echo -e " ${bar} ${passed}/${total} (${pct}%) R:${GREEN}${ready}${RESET} B:${YELLOW}${blocked}${RESET} P:${CYAN}${in_prog}${RESET} ${GREEN}✓${passed}${RESET} ${RED}✗${failed}${RESET}"
|
|
69
61
|
}
|
|
70
62
|
|
|
71
63
|
render_teams() {
|
|
@@ -75,49 +67,44 @@ render_teams() {
|
|
|
75
67
|
team_count=$(jq '.teams | length' "$QUEUE" 2>/dev/null)
|
|
76
68
|
if [ "${team_count:-0}" -eq 0 ]; then return; fi
|
|
77
69
|
|
|
78
|
-
echo -e " ${BOLD}Teams${RESET}"
|
|
79
|
-
|
|
80
70
|
for i in $(seq 1 "$team_count"); do
|
|
81
71
|
local t_status t_feature t_phase t_attempt
|
|
82
72
|
t_status=$(jq -r ".teams[\"$i\"].status // \"idle\"" "$QUEUE" 2>/dev/null)
|
|
83
73
|
t_feature=$(jq -r ".teams[\"$i\"].feature // \"—\"" "$QUEUE" 2>/dev/null)
|
|
84
74
|
|
|
85
|
-
# Get phase from in_progress
|
|
86
75
|
if [ "$t_feature" != "—" ] && [ "$t_feature" != "null" ]; then
|
|
87
76
|
t_phase=$(jq -r --arg f "$t_feature" '.queue.in_progress[$f].phase // "?"' "$QUEUE" 2>/dev/null)
|
|
88
77
|
t_attempt=$(jq -r --arg f "$t_feature" '.queue.in_progress[$f].attempt // 1' "$QUEUE" 2>/dev/null)
|
|
89
78
|
else
|
|
90
|
-
t_phase="—"
|
|
91
|
-
t_attempt="—"
|
|
79
|
+
t_phase="—"; t_attempt=""
|
|
92
80
|
fi
|
|
93
81
|
|
|
94
82
|
local icon color
|
|
95
83
|
case "$t_status" in
|
|
96
|
-
busy) icon="▶"
|
|
97
|
-
idle) icon="○"
|
|
98
|
-
|
|
99
|
-
*) icon="?" ; color="$RESET" ;;
|
|
84
|
+
busy) icon="▶"; color="$GREEN" ;;
|
|
85
|
+
idle) icon="○"; color="$DIM" ;;
|
|
86
|
+
*) icon="?"; color="$RESET" ;;
|
|
100
87
|
esac
|
|
101
88
|
|
|
102
|
-
local
|
|
89
|
+
local phase_short=""
|
|
103
90
|
case "$t_phase" in
|
|
104
|
-
gen)
|
|
105
|
-
gate)
|
|
106
|
-
eval)
|
|
107
|
-
*)
|
|
91
|
+
gen) phase_short="${CYAN}G${RESET}" ;;
|
|
92
|
+
gate) phase_short="${YELLOW}K${RESET}" ;;
|
|
93
|
+
eval) phase_short="${MAGENTA}E${RESET}" ;;
|
|
94
|
+
*) phase_short="${DIM}-${RESET}" ;;
|
|
108
95
|
esac
|
|
109
96
|
|
|
110
|
-
printf " %b
|
|
97
|
+
printf " %b%b T%d %-7s %b" "$color" "$icon" "$i" "$t_feature" "$phase_short"
|
|
98
|
+
if [ -n "$t_attempt" ] && [ "$t_attempt" != "—" ]; then
|
|
99
|
+
printf " #%s" "$t_attempt"
|
|
100
|
+
fi
|
|
101
|
+
echo ""
|
|
111
102
|
done
|
|
112
|
-
echo ""
|
|
113
103
|
}
|
|
114
104
|
|
|
115
|
-
|
|
105
|
+
render_features() {
|
|
116
106
|
if [ ! -f "$QUEUE" ] || [ ! -f "$FEATURES" ]; then return; fi
|
|
117
107
|
|
|
118
|
-
echo -e " ${BOLD}Features${RESET}"
|
|
119
|
-
|
|
120
|
-
# Single jq call: merge feature-list + queue state → pre-formatted lines
|
|
121
108
|
jq -r --slurpfile q "$QUEUE" '
|
|
122
109
|
($q[0].queue.passed // []) as $passed |
|
|
123
110
|
($q[0].queue.failed // []) as $failed |
|
|
@@ -125,7 +112,7 @@ render_feature_list() {
|
|
|
125
112
|
($q[0].queue.in_progress // {}) as $prog |
|
|
126
113
|
.features[] |
|
|
127
114
|
.id as $fid |
|
|
128
|
-
(.name // .description // "?" | if length >
|
|
115
|
+
(.name // .description // "?" | if length > 18 then .[0:16] + ".." else . end) as $fname |
|
|
129
116
|
(if ($fid | IN($passed[])) then "P"
|
|
130
117
|
elif $prog[$fid] then "I|\($prog[$fid].team)|\($prog[$fid].phase)"
|
|
131
118
|
elif ($fid | IN($failed[])) then "F"
|
|
@@ -138,100 +125,25 @@ render_feature_list() {
|
|
|
138
125
|
F) printf " ${RED}✗${RESET} %-6s %s\n" "$fid" "$fname" ;;
|
|
139
126
|
R) printf " ${YELLOW}○${RESET} %-6s %s\n" "$fid" "$fname" ;;
|
|
140
127
|
B) printf " ${DIM}◌${RESET} %-6s %s\n" "$fid" "$fname" ;;
|
|
141
|
-
I\|*)
|
|
142
|
-
team=$(echo "$st" | cut -d'|' -f2)
|
|
128
|
+
I\|*) team=$(echo "$st" | cut -d'|' -f2)
|
|
143
129
|
phase=$(echo "$st" | cut -d'|' -f3)
|
|
144
|
-
printf " ${CYAN}◐${RESET} %-6s %-
|
|
130
|
+
printf " ${CYAN}◐${RESET} %-6s %-14s T%s:%s\n" "$fid" "$fname" "$team" "$phase" ;;
|
|
145
131
|
*) printf " ? %-6s %s\n" "$fid" "$fname" ;;
|
|
146
132
|
esac
|
|
147
133
|
done
|
|
148
|
-
|
|
149
|
-
echo ""
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
render_user_prompts() {
|
|
153
|
-
local log_file="$PROJECT_ROOT/.harness/progress.log"
|
|
154
|
-
if [ ! -f "$log_file" ]; then return; fi
|
|
155
|
-
|
|
156
|
-
# Extract user-prompt entries (newest first, max 5)
|
|
157
|
-
local user_lines
|
|
158
|
-
user_lines=$(grep 'user-prompt' "$log_file" 2>/dev/null | tail -r 2>/dev/null | head -5)
|
|
159
|
-
|
|
160
|
-
if [ -z "$user_lines" ]; then return; fi
|
|
161
|
-
|
|
162
|
-
echo -e " ${BOLD}Manual Prompts${RESET} ${DIM}(newest first)${RESET}"
|
|
163
|
-
|
|
164
|
-
echo "$user_lines" | while IFS= read -r line; do
|
|
165
|
-
local ts detail
|
|
166
|
-
ts=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$1); print $1}')
|
|
167
|
-
detail=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$4); print $4}')
|
|
168
|
-
|
|
169
|
-
# Short timestamp (HH:MM or MM-DD HH:MM)
|
|
170
|
-
local short_ts
|
|
171
|
-
short_ts=$(echo "$ts" | sed 's/^[0-9]*-//')
|
|
172
|
-
|
|
173
|
-
if [ ${#detail} -gt 55 ]; then detail="${detail:0:53}.."; fi
|
|
174
|
-
|
|
175
|
-
echo -e " ${BOLD}★${RESET} ${DIM}${short_ts}${RESET} ${detail}"
|
|
176
|
-
done
|
|
177
|
-
|
|
178
|
-
echo ""
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
render_team_activity() {
|
|
182
|
-
local log_file="$PROJECT_ROOT/.harness/progress.log"
|
|
183
|
-
if [ ! -f "$log_file" ]; then return; fi
|
|
184
|
-
|
|
185
|
-
local max_lines=8
|
|
186
|
-
|
|
187
|
-
echo -e " ${BOLD}Activity${RESET} ${DIM}(newest first)${RESET}"
|
|
188
|
-
|
|
189
|
-
# All non-user-prompt entries, newest first
|
|
190
|
-
grep -v '^#' "$log_file" 2>/dev/null | grep -v '^$' | grep -v 'user-prompt' | \
|
|
191
|
-
tail -r 2>/dev/null | head -"$max_lines" | \
|
|
192
|
-
while IFS= read -r line; do
|
|
193
|
-
local ts agent action detail
|
|
194
|
-
ts=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$1); print $1}')
|
|
195
|
-
agent=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$2); print $2}')
|
|
196
|
-
action=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$3); print $3}')
|
|
197
|
-
detail=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$4); print $4}')
|
|
198
|
-
|
|
199
|
-
local short_ts icon color
|
|
200
|
-
short_ts=$(echo "$ts" | sed 's/^[0-9]*-//')
|
|
201
|
-
|
|
202
|
-
case "$agent" in
|
|
203
|
-
dispatcher*) icon="▸"; color="$MAGENTA" ;;
|
|
204
|
-
team-*) icon="⚡"; color="$CYAN" ;;
|
|
205
|
-
manual) icon="★"; color="$BOLD" ;;
|
|
206
|
-
planner*) icon="□"; color="$YELLOW" ;;
|
|
207
|
-
gen*) icon="▶"; color="$GREEN" ;;
|
|
208
|
-
eval*) icon="✦"; color="$RED" ;;
|
|
209
|
-
system) icon="⚙"; color="$DIM" ;;
|
|
210
|
-
*) icon="·"; color="$DIM" ;;
|
|
211
|
-
esac
|
|
212
|
-
|
|
213
|
-
if [ ${#detail} -gt 45 ]; then detail="${detail:0:43}.."; fi
|
|
214
|
-
|
|
215
|
-
echo -e " ${color}${icon}${RESET} ${DIM}${short_ts}${RESET} ${agent} ${DIM}${action}${RESET} ${detail}"
|
|
216
|
-
done
|
|
217
|
-
|
|
218
|
-
echo ""
|
|
219
134
|
}
|
|
220
135
|
|
|
221
136
|
render_all() {
|
|
222
137
|
render_header
|
|
223
138
|
render_queue_summary
|
|
224
139
|
render_teams
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
render_feature_list
|
|
228
|
-
echo -e " ${DIM}Refreshing every 3s${RESET}"
|
|
140
|
+
echo ""
|
|
141
|
+
render_features
|
|
229
142
|
}
|
|
230
143
|
|
|
231
144
|
# ── Main loop ──
|
|
232
145
|
tput civis 2>/dev/null
|
|
233
146
|
trap 'tput cnorm 2>/dev/null; exit 0' EXIT INT TERM
|
|
234
|
-
|
|
235
147
|
clear
|
|
236
148
|
|
|
237
149
|
while true; do
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# harness-prompts-v4.sh — v4 Dashboard 하단: Manual Prompts + Activity
|
|
3
|
+
# progress.log에서 user-prompt와 team 활동을 newest-first로 표시.
|
|
4
|
+
# 스크롤 가능 영역 — 프롬프트가 많아져도 상단 Progress를 가리지 않음.
|
|
5
|
+
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
9
|
+
|
|
10
|
+
PROJECT_ROOT="${1:-}"
|
|
11
|
+
if [ -z "$PROJECT_ROOT" ]; then
|
|
12
|
+
source "$SCRIPT_DIR/lib/harness-render-progress.sh"
|
|
13
|
+
PROJECT_ROOT="$(resolve_harness_root ".")" || { echo "[prompts] .harness/ not found."; exit 1; }
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
LOG_FILE="$PROJECT_ROOT/.harness/progress.log"
|
|
17
|
+
|
|
18
|
+
BOLD="\033[1m"
|
|
19
|
+
DIM="\033[2m"
|
|
20
|
+
GREEN="\033[32m"
|
|
21
|
+
YELLOW="\033[33m"
|
|
22
|
+
RED="\033[31m"
|
|
23
|
+
CYAN="\033[36m"
|
|
24
|
+
MAGENTA="\033[35m"
|
|
25
|
+
RESET="\033[0m"
|
|
26
|
+
|
|
27
|
+
LAST_LINE_COUNT=0
|
|
28
|
+
|
|
29
|
+
render_prompts() {
|
|
30
|
+
if [ ! -f "$LOG_FILE" ]; then
|
|
31
|
+
echo -e " ${DIM}(progress.log not found)${RESET}"
|
|
32
|
+
return
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
local term_h
|
|
36
|
+
term_h=$(tput lines 2>/dev/null || echo 20)
|
|
37
|
+
local max_lines=$((term_h - 3)) # Leave room for header
|
|
38
|
+
if [ "$max_lines" -lt 5 ]; then max_lines=5; fi
|
|
39
|
+
|
|
40
|
+
echo -e "${BOLD}Prompts & Activity${RESET} ${DIM}(newest first)${RESET}"
|
|
41
|
+
echo ""
|
|
42
|
+
|
|
43
|
+
# Read all entries, reverse, limit to terminal height
|
|
44
|
+
grep -v '^#' "$LOG_FILE" 2>/dev/null | grep -v '^$' | \
|
|
45
|
+
tail -r 2>/dev/null | head -"$max_lines" | \
|
|
46
|
+
while IFS= read -r line; do
|
|
47
|
+
local ts agent action detail
|
|
48
|
+
ts=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$1); print $1}')
|
|
49
|
+
agent=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$2); print $2}')
|
|
50
|
+
action=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$3); print $3}')
|
|
51
|
+
detail=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$4); print $4}')
|
|
52
|
+
|
|
53
|
+
local short_ts icon color
|
|
54
|
+
short_ts=$(echo "$ts" | sed 's/^[0-9]*-//')
|
|
55
|
+
|
|
56
|
+
case "$agent" in
|
|
57
|
+
user-prompt)
|
|
58
|
+
icon="★"; color="$BOLD"
|
|
59
|
+
# User prompts get full width, highlighted
|
|
60
|
+
if [ ${#detail} -gt 60 ]; then detail="${detail:0:58}.."; fi
|
|
61
|
+
echo -e " ${color}${icon} ${short_ts}${RESET} ${detail}"
|
|
62
|
+
;;
|
|
63
|
+
dispatcher*)
|
|
64
|
+
icon="▸"; color="$MAGENTA"
|
|
65
|
+
if [ ${#detail} -gt 50 ]; then detail="${detail:0:48}.."; fi
|
|
66
|
+
echo -e " ${color}${icon}${RESET} ${DIM}${short_ts}${RESET} ${agent} ${DIM}${action}${RESET} ${detail}"
|
|
67
|
+
;;
|
|
68
|
+
team-*)
|
|
69
|
+
icon="⚡"; color="$CYAN"
|
|
70
|
+
if [ ${#detail} -gt 50 ]; then detail="${detail:0:48}.."; fi
|
|
71
|
+
# Color by action type
|
|
72
|
+
case "$action" in
|
|
73
|
+
*pass*) color="$GREEN"; icon="✓" ;;
|
|
74
|
+
*fail*) color="$RED"; icon="✗" ;;
|
|
75
|
+
*eval*) color="$MAGENTA"; icon="✦" ;;
|
|
76
|
+
*gen*) color="$CYAN"; icon="▶" ;;
|
|
77
|
+
*merge*) color="$GREEN"; icon="⊕" ;;
|
|
78
|
+
esac
|
|
79
|
+
echo -e " ${color}${icon}${RESET} ${DIM}${short_ts}${RESET} ${agent} ${DIM}${action}${RESET} ${detail}"
|
|
80
|
+
;;
|
|
81
|
+
manual)
|
|
82
|
+
icon="★"; color="$YELLOW"
|
|
83
|
+
if [ ${#detail} -gt 50 ]; then detail="${detail:0:48}.."; fi
|
|
84
|
+
echo -e " ${color}${icon}${RESET} ${DIM}${short_ts}${RESET} ${detail}"
|
|
85
|
+
;;
|
|
86
|
+
*)
|
|
87
|
+
icon="·"; color="$DIM"
|
|
88
|
+
if [ ${#detail} -gt 50 ]; then detail="${detail:0:48}.."; fi
|
|
89
|
+
echo -e " ${color}${icon}${RESET} ${DIM}${short_ts}${RESET} ${agent} ${DIM}${action}${RESET} ${detail}"
|
|
90
|
+
;;
|
|
91
|
+
esac
|
|
92
|
+
done
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# ── Main loop ──
|
|
96
|
+
tput civis 2>/dev/null
|
|
97
|
+
trap 'tput cnorm 2>/dev/null; exit 0' EXIT INT TERM
|
|
98
|
+
clear
|
|
99
|
+
|
|
100
|
+
while true; do
|
|
101
|
+
buf=$(render_prompts 2>&1)
|
|
102
|
+
tput cup 0 0 2>/dev/null
|
|
103
|
+
echo "$buf"
|
|
104
|
+
tput ed 2>/dev/null
|
|
105
|
+
sleep 3
|
|
106
|
+
done
|
|
@@ -72,11 +72,16 @@ fi
|
|
|
72
72
|
PANE_MAIN=$(tmux new-session -d -s "$SESSION_NAME" -c "$PROJECT_ROOT" -x 220 -y 55 \
|
|
73
73
|
-P -F '#{pane_id}')
|
|
74
74
|
|
|
75
|
-
# Column 2: Dashboard (split right from Main, 66% remaining
|
|
75
|
+
# Column 2: Dashboard Progress (split right from Main, 66% remaining)
|
|
76
76
|
PANE_DASH=$(tmux split-window -h -p 66 -t "$PANE_MAIN" -c "$PROJECT_ROOT" \
|
|
77
77
|
-P -F '#{pane_id}' \
|
|
78
78
|
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-dashboard-v4.sh\" \"${PROJECT_ROOT}\"'")
|
|
79
79
|
|
|
80
|
+
# Dashboard bottom: Prompts & Activity (split below Dashboard, 40% bottom)
|
|
81
|
+
PANE_PROMPTS=$(tmux split-window -v -p 40 -t "$PANE_DASH" -c "$PROJECT_ROOT" \
|
|
82
|
+
-P -F '#{pane_id}' \
|
|
83
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-prompts-v4.sh\" \"${PROJECT_ROOT}\"'")
|
|
84
|
+
|
|
80
85
|
# Column 3: Team 1 (split right from Dashboard, 50% of remaining = 33% total)
|
|
81
86
|
PANE_T1=$(tmux split-window -h -p 50 -t "$PANE_DASH" -c "$PROJECT_ROOT" \
|
|
82
87
|
-P -F '#{pane_id}' \
|
|
@@ -96,11 +101,12 @@ PANE_T3=$(tmux split-window -v -p 50 -t "$PANE_T2" -c "$PROJECT_ROOT" \
|
|
|
96
101
|
tmux send-keys -t "$PANE_MAIN" "unset npm_config_prefix 2>/dev/null; clear && claude --dangerously-skip-permissions" Enter
|
|
97
102
|
|
|
98
103
|
# ── Pane titles ──
|
|
99
|
-
tmux select-pane -t "$PANE_MAIN"
|
|
100
|
-
tmux select-pane -t "$PANE_DASH"
|
|
101
|
-
tmux select-pane -t "$
|
|
102
|
-
tmux select-pane -t "$
|
|
103
|
-
tmux select-pane -t "$
|
|
104
|
+
tmux select-pane -t "$PANE_MAIN" -T "Main"
|
|
105
|
+
tmux select-pane -t "$PANE_DASH" -T "Progress"
|
|
106
|
+
tmux select-pane -t "$PANE_PROMPTS" -T "Prompts"
|
|
107
|
+
tmux select-pane -t "$PANE_T1" -T "Team 1"
|
|
108
|
+
tmux select-pane -t "$PANE_T2" -T "Team 2"
|
|
109
|
+
tmux select-pane -t "$PANE_T3" -T "Team 3"
|
|
104
110
|
|
|
105
111
|
tmux set-option -t "$SESSION_NAME" pane-border-status top 2>/dev/null || true
|
|
106
112
|
tmux set-option -t "$SESSION_NAME" pane-border-format " #{pane_title} " 2>/dev/null || true
|