@walwal-harness/cli 4.0.0-beta.4 → 4.0.0-beta.5
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-beta.
|
|
3
|
+
"version": "4.0.0-beta.5",
|
|
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,19 +1,19 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# harness-studio-setup.sh — Claude
|
|
3
|
-
#
|
|
4
|
-
# Claude가 이미 실행 중인 tmux pane에서 호출됨.
|
|
5
|
-
# 현재 pane(Claude가 있는 곳)을 Left로 유지하고,
|
|
6
|
-
# Center(Dashboard + History)와 Right(Monitor)를 split으로 생성.
|
|
2
|
+
# harness-studio-setup.sh — Claude 세션에서 3-column 레이아웃 자동 구축
|
|
7
3
|
#
|
|
8
4
|
# ┌──────────────┬──────────────┬──────────────┐
|
|
9
5
|
# │ │ Dashboard │ │
|
|
10
|
-
# │
|
|
11
|
-
# │
|
|
6
|
+
# │ Claude │ (v4 queue) │ Team Monitor│
|
|
7
|
+
# │ (Lead) ├──────────────┤ (lifecycle) │
|
|
12
8
|
# │ │ Command │ │
|
|
13
9
|
# │ │ History │ │
|
|
14
10
|
# └──────────────┴──────────────┴──────────────┘
|
|
15
11
|
#
|
|
16
|
-
#
|
|
12
|
+
# 두 가지 상황을 모두 처리:
|
|
13
|
+
# A) tmux 안에서 실행 → 현재 pane을 split하여 레이아웃 구축
|
|
14
|
+
# B) tmux 밖에서 실행 → 새 tmux 세션 생성, Claude를 좌측 pane에서 재실행
|
|
15
|
+
#
|
|
16
|
+
# Usage:
|
|
17
17
|
# bash scripts/harness-studio-setup.sh [project-root]
|
|
18
18
|
#
|
|
19
19
|
# 이미 구축됐으면 skip (멱등성 보장)
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
set -euo pipefail
|
|
22
22
|
|
|
23
23
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
24
|
+
SESSION_NAME="harness-studio"
|
|
24
25
|
|
|
25
26
|
PROJECT_ROOT="${1:-}"
|
|
26
27
|
if [ -z "$PROJECT_ROOT" ]; then
|
|
@@ -36,53 +37,107 @@ if [ -z "$PROJECT_ROOT" ] || [ ! -d "$PROJECT_ROOT/.harness" ]; then
|
|
|
36
37
|
exit 1
|
|
37
38
|
fi
|
|
38
39
|
|
|
39
|
-
# ──
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
# ── Resolve Claude command ──
|
|
41
|
+
CLAUDE_CMD="claude --dangerously-skip-permissions"
|
|
42
|
+
if [ -f "$PROJECT_ROOT/.harness/handoff.json" ]; then
|
|
43
|
+
_model=$(jq -r '.model // empty' "$PROJECT_ROOT/.harness/handoff.json" 2>/dev/null)
|
|
44
|
+
if [ -n "$_model" ] && [ "$_model" != "null" ]; then
|
|
45
|
+
CLAUDE_CMD="$CLAUDE_CMD --model $_model"
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# ══════════════════════════════════════════
|
|
50
|
+
# Case A: 이미 tmux 안에 있음 → pane split
|
|
51
|
+
# ══════════════════════════════════════════
|
|
52
|
+
if [ -n "${TMUX:-}" ]; then
|
|
53
|
+
# 멱등성: 이미 pane이 3개 이상이면 skip
|
|
54
|
+
PANE_COUNT=$(tmux list-panes | wc -l | tr -d ' ')
|
|
55
|
+
if [ "$PANE_COUNT" -ge 3 ]; then
|
|
56
|
+
echo "[studio] Layout already set up ($PANE_COUNT panes). Skipping."
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
PANE_CLAUDE=$(tmux display-message -p '#{pane_id}')
|
|
61
|
+
echo "[studio] Setting up 3-column layout (in-place split)..."
|
|
62
|
+
|
|
63
|
+
# Left 35% | Right 65%
|
|
64
|
+
PANE_MID=$(tmux split-window -h -p 65 -t "$PANE_CLAUDE" -c "$PROJECT_ROOT" \
|
|
65
|
+
-P -F '#{pane_id}' \
|
|
66
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-dashboard-v4.sh\" \"${PROJECT_ROOT}\"'")
|
|
67
|
+
|
|
68
|
+
# Middle 45% | Right 55%
|
|
69
|
+
PANE_RIGHT=$(tmux split-window -h -p 55 -t "$PANE_MID" -c "$PROJECT_ROOT" \
|
|
70
|
+
-P -F '#{pane_id}' \
|
|
71
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-monitor.sh\" \"${PROJECT_ROOT}\"'")
|
|
72
|
+
|
|
73
|
+
# Dashboard top 45% | History bottom 55%
|
|
74
|
+
PANE_HISTORY=$(tmux split-window -v -p 55 -t "$PANE_MID" -c "$PROJECT_ROOT" \
|
|
75
|
+
-P -F '#{pane_id}' \
|
|
76
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-prompt-history.sh\" \"${PROJECT_ROOT}\"'")
|
|
77
|
+
|
|
78
|
+
# Pane titles
|
|
79
|
+
tmux select-pane -t "$PANE_CLAUDE" -T "Lead (Claude)"
|
|
80
|
+
tmux select-pane -t "$PANE_MID" -T "Dashboard"
|
|
81
|
+
tmux select-pane -t "$PANE_HISTORY" -T "Command History"
|
|
82
|
+
tmux select-pane -t "$PANE_RIGHT" -T "Team Monitor"
|
|
83
|
+
|
|
84
|
+
tmux set-option pane-border-status top 2>/dev/null || true
|
|
85
|
+
tmux set-option pane-border-format " #{pane_title} " 2>/dev/null || true
|
|
86
|
+
|
|
87
|
+
# 포커스를 Claude pane으로 복귀
|
|
88
|
+
tmux select-pane -t "$PANE_CLAUDE"
|
|
89
|
+
|
|
90
|
+
echo "[studio] Layout ready (in-place)."
|
|
91
|
+
exit 0
|
|
44
92
|
fi
|
|
45
93
|
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
94
|
+
# ══════════════════════════════════════════
|
|
95
|
+
# Case B: tmux 밖에 있음 → 새 세션 생성
|
|
96
|
+
# ══════════════════════════════════════════
|
|
97
|
+
|
|
98
|
+
# 이미 세션이 있으면 attach만
|
|
99
|
+
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
|
|
100
|
+
echo "[studio] Session '$SESSION_NAME' already exists. Attaching..."
|
|
101
|
+
echo "[studio] ATTACH_TMUX=$SESSION_NAME"
|
|
50
102
|
exit 0
|
|
51
103
|
fi
|
|
52
104
|
|
|
53
|
-
|
|
54
|
-
PANE_CLAUDE=$(tmux display-message -p '#{pane_id}')
|
|
105
|
+
echo "[studio] Creating new tmux session with 3-column layout..."
|
|
55
106
|
|
|
56
|
-
|
|
107
|
+
# 1. 새 세션 → Left pane (Claude 실행)
|
|
108
|
+
PANE_MAIN=$(tmux new-session -d -s "$SESSION_NAME" -c "$PROJECT_ROOT" -x 220 -y 55 \
|
|
109
|
+
-P -F '#{pane_id}')
|
|
57
110
|
|
|
58
|
-
#
|
|
59
|
-
PANE_MID=$(tmux split-window -h -p 65 -t "$
|
|
111
|
+
# 2. Left 35% | Right 65%
|
|
112
|
+
PANE_MID=$(tmux split-window -h -p 65 -t "$PANE_MAIN" -c "$PROJECT_ROOT" \
|
|
60
113
|
-P -F '#{pane_id}' \
|
|
61
114
|
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-dashboard-v4.sh\" \"${PROJECT_ROOT}\"'")
|
|
62
115
|
|
|
63
|
-
#
|
|
116
|
+
# 3. Middle 45% | Right 55%
|
|
64
117
|
PANE_RIGHT=$(tmux split-window -h -p 55 -t "$PANE_MID" -c "$PROJECT_ROOT" \
|
|
65
118
|
-P -F '#{pane_id}' \
|
|
66
119
|
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-monitor.sh\" \"${PROJECT_ROOT}\"'")
|
|
67
120
|
|
|
68
|
-
#
|
|
121
|
+
# 4. Dashboard top 45% | History bottom 55%
|
|
69
122
|
PANE_HISTORY=$(tmux split-window -v -p 55 -t "$PANE_MID" -c "$PROJECT_ROOT" \
|
|
70
123
|
-P -F '#{pane_id}' \
|
|
71
124
|
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-prompt-history.sh\" \"${PROJECT_ROOT}\"'")
|
|
72
125
|
|
|
73
|
-
#
|
|
74
|
-
tmux
|
|
126
|
+
# 5. Left pane에서 Claude 자동 실행
|
|
127
|
+
tmux send-keys -t "$PANE_MAIN" "unset npm_config_prefix 2>/dev/null" Enter
|
|
128
|
+
tmux send-keys -t "$PANE_MAIN" "clear && $CLAUDE_CMD" Enter
|
|
129
|
+
|
|
130
|
+
# Pane titles
|
|
131
|
+
tmux select-pane -t "$PANE_MAIN" -T "Lead (Claude)"
|
|
75
132
|
tmux select-pane -t "$PANE_MID" -T "Dashboard"
|
|
76
133
|
tmux select-pane -t "$PANE_HISTORY" -T "Command History"
|
|
77
134
|
tmux select-pane -t "$PANE_RIGHT" -T "Team Monitor"
|
|
78
135
|
|
|
79
|
-
tmux set-option pane-border-status top 2>/dev/null || true
|
|
80
|
-
tmux set-option pane-border-format " #{pane_title} " 2>/dev/null || true
|
|
136
|
+
tmux set-option -t "$SESSION_NAME" pane-border-status top 2>/dev/null || true
|
|
137
|
+
tmux set-option -t "$SESSION_NAME" pane-border-format " #{pane_title} " 2>/dev/null || true
|
|
81
138
|
|
|
82
|
-
#
|
|
83
|
-
tmux select-pane -t "$
|
|
139
|
+
# Focus on Claude pane
|
|
140
|
+
tmux select-pane -t "$PANE_MAIN"
|
|
84
141
|
|
|
85
|
-
echo "[studio]
|
|
86
|
-
echo "[studio]
|
|
87
|
-
echo "[studio] Center : Dashboard + Command History"
|
|
88
|
-
echo "[studio] Right : Team Monitor"
|
|
142
|
+
echo "[studio] Session '$SESSION_NAME' created."
|
|
143
|
+
echo "[studio] ATTACH_TMUX=$SESSION_NAME"
|
|
@@ -8,14 +8,28 @@ disable-model-invocation: false
|
|
|
8
8
|
|
|
9
9
|
## Step 0: Studio 레이아웃 자동 구축
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
3-column 대시보드 레이아웃을 자동 구축합니다:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
bash scripts/harness-studio-setup.sh .
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
스크립트 출력을 확인합니다:
|
|
18
|
+
|
|
19
|
+
- **`Layout ready`** → 현재 터미널에 split 완료. 바로 Step 1로.
|
|
20
|
+
- **`ATTACH_TMUX=harness-studio`** → 새 tmux 세션이 생성됨 (tmux 밖에서 실행한 경우).
|
|
21
|
+
사용자에게 아래 안내를 출력하고 **STOP**합니다:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Studio 레이아웃이 준비되었습니다!
|
|
25
|
+
다른 터미널에서 아래 명령을 실행하세요:
|
|
26
|
+
|
|
27
|
+
tmux attach -t harness-studio
|
|
28
|
+
|
|
29
|
+
새 창에서 Claude가 자동 실행됩니다. 거기서 "팀 가동"을 입력하면 Teams가 시작됩니다.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- **`already set up`** → 이미 구축됨. 바로 Step 1로.
|
|
19
33
|
|
|
20
34
|
## Step 1: Queue 초기화
|
|
21
35
|
|