@walwal-harness/cli 5.9.0 → 5.9.1
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 +1 -1
- package/scripts/harness-gotcha-memory.sh +107 -21
- package/scripts/harness-tmux.sh +23 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "5.9.
|
|
3
|
+
"version": "5.9.1",
|
|
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"
|
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
# harness-gotcha-memory.sh — Gotcha · Memory · Conventions pane (index view)
|
|
3
3
|
# 활성 에이전트의 gotcha를 최상단으로, 나머지는 요약(최근 3항목+총개수)으로 표시
|
|
4
4
|
# + Shared Memory 요약 + Conventions 요약 (shared + 활성 에이전트별)
|
|
5
|
-
#
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# bash scripts/harness-gotcha-memory.sh [project-root] # 전체 (legacy)
|
|
8
|
+
# bash scripts/harness-gotcha-memory.sh [project-root] --mode gotcha # gotcha 만
|
|
9
|
+
# bash scripts/harness-gotcha-memory.sh [project-root] --mode conventions # conventions 만
|
|
10
|
+
# bash scripts/harness-gotcha-memory.sh [project-root] --mode memory # memory 만
|
|
11
|
+
#
|
|
12
|
+
# tmux 분할 환경에서는 각 sub-pane 이 한 mode 만 렌더 → 좁은 창에서도 잘리지 않음.
|
|
13
|
+
# tmux copy-mode (prefix + [) 로 각 pane 독립 스크롤.
|
|
6
14
|
|
|
7
15
|
set -uo pipefail
|
|
8
16
|
|
|
@@ -10,11 +18,26 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
10
18
|
source "$SCRIPT_DIR/lib/harness-render-progress.sh"
|
|
11
19
|
source "$SCRIPT_DIR/lib/harness-keywait.sh"
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
# Args parsing — first non-flag = project root, --mode = view mode
|
|
22
|
+
PROJECT_ROOT=""
|
|
23
|
+
MODE="all"
|
|
24
|
+
while [ $# -gt 0 ]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--mode) MODE="$2"; shift 2 ;;
|
|
27
|
+
--mode=*) MODE="${1#--mode=}"; shift ;;
|
|
28
|
+
*) [ -z "$PROJECT_ROOT" ] && PROJECT_ROOT="$1"; shift ;;
|
|
29
|
+
esac
|
|
30
|
+
done
|
|
31
|
+
|
|
14
32
|
if [ -z "$PROJECT_ROOT" ]; then
|
|
15
33
|
PROJECT_ROOT="$(resolve_harness_root ".")" || { echo "[gotcha] .harness/ not found."; exit 1; }
|
|
16
34
|
fi
|
|
17
35
|
|
|
36
|
+
case "$MODE" in
|
|
37
|
+
all|gotcha|conventions|memory) ;;
|
|
38
|
+
*) echo "[gotcha] unknown mode: $MODE" >&2; exit 1 ;;
|
|
39
|
+
esac
|
|
40
|
+
|
|
18
41
|
MEMORY_FILE="$PROJECT_ROOT/.harness/memory.md"
|
|
19
42
|
GOTCHAS_DIR="$PROJECT_ROOT/.harness/gotchas"
|
|
20
43
|
CONVENTIONS_DIR="$PROJECT_ROOT/.harness/conventions"
|
|
@@ -190,54 +213,117 @@ render_memory_summary() {
|
|
|
190
213
|
fi
|
|
191
214
|
}
|
|
192
215
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
printf '\033[H\033[2J\033[3J'
|
|
216
|
+
render_header() {
|
|
217
|
+
local title="$1"
|
|
196
218
|
local cols hr
|
|
197
219
|
cols=$(tput cols 2>/dev/null || echo 80)
|
|
198
220
|
hr=$(printf '─%.0s' $(seq 1 "$cols"))
|
|
221
|
+
echo -e "${BOLD}${MAGENTA}${title}${RESET} ${DIM}$(date +%H:%M:%S) · recent=${RECENT_N} · refresh ${REFRESH_SEC}s${RESET}"
|
|
222
|
+
local active="$1_active"
|
|
223
|
+
[ -n "${2:-}" ] && echo -e "${DIM}active agent:${RESET} ${BOLD}${YELLOW}$2${RESET}"
|
|
224
|
+
echo -e "${DIM}${hr}${RESET}"
|
|
225
|
+
}
|
|
199
226
|
|
|
200
|
-
|
|
201
|
-
active
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
echo -e "${BOLD}${MAGENTA}
|
|
227
|
+
render_gotcha_section() {
|
|
228
|
+
local active="$1" active_file="$2"
|
|
229
|
+
local cols hr
|
|
230
|
+
cols=$(tput cols 2>/dev/null || echo 80)
|
|
231
|
+
hr=$(printf '─%.0s' $(seq 1 "$cols"))
|
|
232
|
+
echo -e "${BOLD}${MAGENTA}▣ GOTCHAS${RESET} ${DIM}(.harness/gotchas) · $(date +%H:%M:%S) · refresh ${REFRESH_SEC}s${RESET}"
|
|
206
233
|
if [ -n "$active" ]; then
|
|
207
234
|
echo -e "${DIM}active agent:${RESET} ${BOLD}${YELLOW}${active}${RESET}"
|
|
208
|
-
else
|
|
209
|
-
echo -e "${DIM}active agent: (none)${RESET}"
|
|
210
235
|
fi
|
|
211
236
|
echo -e "${DIM}${hr}${RESET}"
|
|
212
237
|
|
|
213
|
-
# 활성 에이전트 gotcha 최상단
|
|
214
238
|
if [ -n "$active_file" ]; then
|
|
215
239
|
render_gotcha_entry "$active_file" "true"
|
|
216
240
|
echo ""
|
|
217
241
|
fi
|
|
218
|
-
|
|
219
|
-
# 나머지 gotcha
|
|
220
242
|
if [ -d "$GOTCHAS_DIR" ]; then
|
|
221
243
|
for f in "$GOTCHAS_DIR"/*.md; do
|
|
222
244
|
[ -e "$f" ] || continue
|
|
223
245
|
[ "$f" = "$active_file" ] && continue
|
|
224
|
-
local base
|
|
225
|
-
base=$(basename "$f" .md)
|
|
246
|
+
local base; base=$(basename "$f" .md)
|
|
226
247
|
[ "$base" = "README" ] && continue
|
|
227
248
|
render_gotcha_entry "$f" "false"
|
|
228
249
|
done
|
|
229
250
|
fi
|
|
251
|
+
}
|
|
230
252
|
|
|
231
|
-
|
|
253
|
+
render_conventions_section() {
|
|
254
|
+
local active="$1"
|
|
255
|
+
local cols hr
|
|
256
|
+
cols=$(tput cols 2>/dev/null || echo 80)
|
|
257
|
+
hr=$(printf '─%.0s' $(seq 1 "$cols"))
|
|
258
|
+
echo -e "${BOLD}${CYAN}▣ CONVENTIONS${RESET} ${DIM}(.harness/conventions) · $(date +%H:%M:%S) · refresh ${REFRESH_SEC}s${RESET}"
|
|
232
259
|
echo -e "${DIM}${hr}${RESET}"
|
|
233
|
-
echo -e "${BOLD}${CYAN}▣ CONVENTIONS${RESET} ${DIM}(.harness/conventions)${RESET}"
|
|
234
260
|
render_conventions_summary "$active"
|
|
261
|
+
}
|
|
235
262
|
|
|
236
|
-
|
|
263
|
+
render_memory_section() {
|
|
264
|
+
local cols hr
|
|
265
|
+
cols=$(tput cols 2>/dev/null || echo 80)
|
|
266
|
+
hr=$(printf '─%.0s' $(seq 1 "$cols"))
|
|
267
|
+
echo -e "${BOLD}${CYAN}▣ SHARED MEMORY${RESET} ${DIM}(memory.md) · $(date +%H:%M:%S) · refresh ${REFRESH_SEC}s${RESET}"
|
|
237
268
|
echo -e "${DIM}${hr}${RESET}"
|
|
238
269
|
render_memory_summary
|
|
239
270
|
}
|
|
240
271
|
|
|
272
|
+
render() {
|
|
273
|
+
# clear 대신 커서 홈 + 화면 끝까지 지우기 — 깜빡임 최소화
|
|
274
|
+
printf '\033[H\033[2J\033[3J'
|
|
275
|
+
|
|
276
|
+
local active active_file
|
|
277
|
+
active=$(get_active_agent)
|
|
278
|
+
active_file=""
|
|
279
|
+
[ -n "$active" ] && active_file=$(file_for_agent "$active")
|
|
280
|
+
|
|
281
|
+
case "$MODE" in
|
|
282
|
+
gotcha)
|
|
283
|
+
render_gotcha_section "$active" "$active_file"
|
|
284
|
+
;;
|
|
285
|
+
conventions)
|
|
286
|
+
render_conventions_section "$active"
|
|
287
|
+
;;
|
|
288
|
+
memory)
|
|
289
|
+
render_memory_section
|
|
290
|
+
;;
|
|
291
|
+
all)
|
|
292
|
+
local cols hr
|
|
293
|
+
cols=$(tput cols 2>/dev/null || echo 80)
|
|
294
|
+
hr=$(printf '─%.0s' $(seq 1 "$cols"))
|
|
295
|
+
echo -e "${BOLD}${MAGENTA}RULES INDEX${RESET} ${DIM}Gotcha · Memory · Conventions · $(date +%H:%M:%S) · recent=${RECENT_N} · refresh ${REFRESH_SEC}s${RESET}"
|
|
296
|
+
if [ -n "$active" ]; then
|
|
297
|
+
echo -e "${DIM}active agent:${RESET} ${BOLD}${YELLOW}${active}${RESET}"
|
|
298
|
+
else
|
|
299
|
+
echo -e "${DIM}active agent: (none)${RESET}"
|
|
300
|
+
fi
|
|
301
|
+
echo -e "${DIM}${hr}${RESET}"
|
|
302
|
+
|
|
303
|
+
if [ -n "$active_file" ]; then
|
|
304
|
+
render_gotcha_entry "$active_file" "true"
|
|
305
|
+
echo ""
|
|
306
|
+
fi
|
|
307
|
+
if [ -d "$GOTCHAS_DIR" ]; then
|
|
308
|
+
for f in "$GOTCHAS_DIR"/*.md; do
|
|
309
|
+
[ -e "$f" ] || continue
|
|
310
|
+
[ "$f" = "$active_file" ] && continue
|
|
311
|
+
local base; base=$(basename "$f" .md)
|
|
312
|
+
[ "$base" = "README" ] && continue
|
|
313
|
+
render_gotcha_entry "$f" "false"
|
|
314
|
+
done
|
|
315
|
+
fi
|
|
316
|
+
echo ""
|
|
317
|
+
echo -e "${DIM}${hr}${RESET}"
|
|
318
|
+
echo -e "${BOLD}${CYAN}▣ CONVENTIONS${RESET} ${DIM}(.harness/conventions)${RESET}"
|
|
319
|
+
render_conventions_summary "$active"
|
|
320
|
+
echo ""
|
|
321
|
+
echo -e "${DIM}${hr}${RESET}"
|
|
322
|
+
render_memory_summary
|
|
323
|
+
;;
|
|
324
|
+
esac
|
|
325
|
+
}
|
|
326
|
+
|
|
241
327
|
trap 'exit 0' INT TERM
|
|
242
328
|
|
|
243
329
|
while true; do
|
package/scripts/harness-tmux.sh
CHANGED
|
@@ -112,7 +112,7 @@ launch_iterm2_team() {
|
|
|
112
112
|
write text "cd '${PROJECT_ROOT}' && bash '${SCRIPT_DIR}/harness-prompt-history.sh' '${PROJECT_ROOT}'"
|
|
113
113
|
end tell
|
|
114
114
|
|
|
115
|
-
-- Split right → Gotcha & Memory
|
|
115
|
+
-- Split right → Gotcha & Memory (combined view; tmux 경로는 3분할 사용)
|
|
116
116
|
set dashPane to (split vertically with default profile)
|
|
117
117
|
tell dashPane
|
|
118
118
|
write text "cd '${PROJECT_ROOT}' && bash '${SCRIPT_DIR}/harness-gotcha-memory.sh' '${PROJECT_ROOT}'"
|
|
@@ -163,7 +163,7 @@ launch_iterm2_solo() {
|
|
|
163
163
|
write text "cd '${PROJECT_ROOT}' && bash '${SCRIPT_DIR}/harness-prompt-history.sh' '${PROJECT_ROOT}'"
|
|
164
164
|
end tell
|
|
165
165
|
|
|
166
|
-
-- Split right → Gotcha · Memory · Conventions
|
|
166
|
+
-- Split right → Gotcha · Memory · Conventions (combined view; tmux 경로는 3분할)
|
|
167
167
|
set dashPane to (split vertically with default profile)
|
|
168
168
|
tell dashPane
|
|
169
169
|
write text "cd '${PROJECT_ROOT}' && bash '${SCRIPT_DIR}/harness-gotcha-memory.sh' '${PROJECT_ROOT}'"
|
|
@@ -198,12 +198,21 @@ launch_tmux_team() {
|
|
|
198
198
|
PANE_ARCHIVE=$(tmux split-window -v -p 35 -t "$PANE_DASH" -c "$PROJECT_ROOT" -P -F '#{pane_id}' \
|
|
199
199
|
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-prompt-history.sh\" \"${PROJECT_ROOT}\"'")
|
|
200
200
|
|
|
201
|
+
# Gotcha 패널을 3 개 sub-pane 으로 수직 분할: Gotchas / Conventions / Memory
|
|
202
|
+
# 각 pane 은 tmux copy-mode (prefix + [) 로 독립 스크롤 가능
|
|
203
|
+
PANE_CONV=$(tmux split-window -v -p 60 -t "$PANE_GOTCHA" -c "$PROJECT_ROOT" -P -F '#{pane_id}' \
|
|
204
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\" --mode conventions'")
|
|
205
|
+
PANE_MEM=$(tmux split-window -v -p 50 -t "$PANE_CONV" -c "$PROJECT_ROOT" -P -F '#{pane_id}' \
|
|
206
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\" --mode memory'")
|
|
207
|
+
|
|
201
208
|
tmux send-keys -t "$PANE_DASH" "bash \"${SCRIPT_DIR}/harness-dashboard.sh\" \"${PROJECT_ROOT}\"" Enter
|
|
202
|
-
tmux send-keys -t "$PANE_GOTCHA" "bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\"" Enter
|
|
209
|
+
tmux send-keys -t "$PANE_GOTCHA" "bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\" --mode gotcha" Enter
|
|
203
210
|
|
|
204
211
|
tmux select-pane -t "$PANE_DASH" -T "Dashboard"
|
|
205
212
|
tmux select-pane -t "$PANE_ARCHIVE" -T "Archive Prompt"
|
|
206
|
-
tmux select-pane -t "$PANE_GOTCHA" -T "
|
|
213
|
+
tmux select-pane -t "$PANE_GOTCHA" -T "Gotchas (scrollable: prefix + [ )"
|
|
214
|
+
tmux select-pane -t "$PANE_CONV" -T "Conventions (scrollable: prefix + [ )"
|
|
215
|
+
tmux select-pane -t "$PANE_MEM" -T "Shared Memory (scrollable: prefix + [ )"
|
|
207
216
|
tmux select-pane -t "$PANE_T1" -T "TEAM 1"
|
|
208
217
|
tmux select-pane -t "$PANE_T2" -T "TEAM 2"
|
|
209
218
|
tmux select-pane -t "$PANE_T3" -T "TEAM 3"
|
|
@@ -224,12 +233,20 @@ launch_tmux_solo() {
|
|
|
224
233
|
PANE_HISTORY=$(tmux split-window -v -p 35 -t "$PANE_DASH" -c "$PROJECT_ROOT" -P -F '#{pane_id}' \
|
|
225
234
|
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-prompt-history.sh\" \"${PROJECT_ROOT}\"'")
|
|
226
235
|
|
|
236
|
+
# Gotcha 패널을 3 개 sub-pane 으로 수직 분할: Gotchas / Conventions / Memory
|
|
237
|
+
PANE_CONV=$(tmux split-window -v -p 60 -t "$PANE_GOTCHA" -c "$PROJECT_ROOT" -P -F '#{pane_id}' \
|
|
238
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\" --mode conventions'")
|
|
239
|
+
PANE_MEM=$(tmux split-window -v -p 50 -t "$PANE_CONV" -c "$PROJECT_ROOT" -P -F '#{pane_id}' \
|
|
240
|
+
"bash --norc --noprofile -c 'exec bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\" --mode memory'")
|
|
241
|
+
|
|
227
242
|
tmux send-keys -t "$PANE_DASH" "bash \"${SCRIPT_DIR}/harness-dashboard.sh\" \"${PROJECT_ROOT}\"" Enter
|
|
228
|
-
tmux send-keys -t "$PANE_GOTCHA" "bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\"" Enter
|
|
243
|
+
tmux send-keys -t "$PANE_GOTCHA" "bash \"${SCRIPT_DIR}/harness-gotcha-memory.sh\" \"${PROJECT_ROOT}\" --mode gotcha" Enter
|
|
229
244
|
|
|
230
245
|
tmux select-pane -t "$PANE_DASH" -T "Dashboard"
|
|
231
246
|
tmux select-pane -t "$PANE_HISTORY" -T "Prompt History"
|
|
232
|
-
tmux select-pane -t "$PANE_GOTCHA" -T "
|
|
247
|
+
tmux select-pane -t "$PANE_GOTCHA" -T "Gotchas (scrollable: prefix + [ )"
|
|
248
|
+
tmux select-pane -t "$PANE_CONV" -T "Conventions (scrollable: prefix + [ )"
|
|
249
|
+
tmux select-pane -t "$PANE_MEM" -T "Shared Memory (scrollable: prefix + [ )"
|
|
233
250
|
tmux select-pane -t "$PANE_MONITOR" -T "Monitor"
|
|
234
251
|
tmux select-pane -t "$PANE_DASH"
|
|
235
252
|
|