@mindfoldhq/trellis 0.2.5 → 0.2.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/dist/templates/trellis/gitignore.txt +1 -0
- package/dist/templates/trellis/scripts/add-session.sh +1 -1
- package/dist/templates/trellis/scripts/multi-agent/start.sh +14 -6
- package/dist/templates/trellis/scripts/multi-agent/status.sh +148 -41
- package/package.json +1 -1
- package/readme.md +159 -1051
|
@@ -28,7 +28,7 @@ INDEX_FILE="$DEV_DIR/index.md"
|
|
|
28
28
|
|
|
29
29
|
get_latest_journal_info() {
|
|
30
30
|
local latest_file=""
|
|
31
|
-
local latest_num
|
|
31
|
+
local latest_num=-1 # Start at -1 so journal-0.md can be detected (0 > -1)
|
|
32
32
|
|
|
33
33
|
for f in "$DEV_DIR"/${FILE_JOURNAL_PREFIX}*.md; do
|
|
34
34
|
if [[ -f "$f" ]]; then
|
|
@@ -244,19 +244,25 @@ cd "$WORKTREE_PATH"
|
|
|
244
244
|
|
|
245
245
|
LOG_FILE="${WORKTREE_PATH}/.agent-log"
|
|
246
246
|
RUNNER_SCRIPT="${WORKTREE_PATH}/.agent-runner.sh"
|
|
247
|
+
SESSION_ID_FILE="${WORKTREE_PATH}/.session-id"
|
|
247
248
|
|
|
248
249
|
touch "$LOG_FILE"
|
|
249
250
|
|
|
251
|
+
# Generate session ID for resume support
|
|
252
|
+
SESSION_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
|
|
253
|
+
echo "$SESSION_ID" > "$SESSION_ID_FILE"
|
|
254
|
+
log_info "Session ID: ${SESSION_ID}"
|
|
255
|
+
|
|
250
256
|
# Create runner script (uses --agent flag to load dispatch agent directly)
|
|
251
|
-
cat > "$RUNNER_SCRIPT" <<
|
|
257
|
+
cat > "$RUNNER_SCRIPT" << RUNNER_EOF
|
|
252
258
|
#!/bin/bash
|
|
253
|
-
cd "
|
|
254
|
-
export https_proxy="
|
|
255
|
-
export http_proxy="
|
|
256
|
-
export all_proxy="
|
|
259
|
+
cd "\$(dirname "\$0")"
|
|
260
|
+
export https_proxy="\${AGENT_HTTPS_PROXY:-}"
|
|
261
|
+
export http_proxy="\${AGENT_HTTP_PROXY:-}"
|
|
262
|
+
export all_proxy="\${AGENT_ALL_PROXY:-}"
|
|
257
263
|
export CLAUDE_NON_INTERACTIVE=1
|
|
258
264
|
|
|
259
|
-
claude -p --agent dispatch --dangerously-skip-permissions --output-format stream-json --verbose "Start the pipeline"
|
|
265
|
+
claude -p --agent dispatch --session-id "${SESSION_ID}" --dangerously-skip-permissions --output-format stream-json --verbose "Start the pipeline"
|
|
260
266
|
RUNNER_EOF
|
|
261
267
|
chmod +x "$RUNNER_SCRIPT"
|
|
262
268
|
|
|
@@ -293,6 +299,7 @@ echo -e "${GREEN}=== Agent Started ===${NC}"
|
|
|
293
299
|
echo ""
|
|
294
300
|
echo " ID: $TASK_ID"
|
|
295
301
|
echo " PID: $AGENT_PID"
|
|
302
|
+
echo " Session: $SESSION_ID"
|
|
296
303
|
echo " Worktree: $WORKTREE_PATH"
|
|
297
304
|
echo " Task: $TASK_DIR_RELATIVE"
|
|
298
305
|
echo " Log: $LOG_FILE"
|
|
@@ -300,3 +307,4 @@ echo " Registry: $(registry_get_file "$PROJECT_ROOT")"
|
|
|
300
307
|
echo ""
|
|
301
308
|
echo -e "${YELLOW}To monitor:${NC} tail -f $LOG_FILE"
|
|
302
309
|
echo -e "${YELLOW}To stop:${NC} kill $AGENT_PID"
|
|
310
|
+
echo -e "${YELLOW}To resume:${NC} cd $WORKTREE_PATH && claude --resume $SESSION_ID"
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# =============================================================================
|
|
5
5
|
# Usage:
|
|
6
6
|
# ./status.sh Show summary of all tasks (default)
|
|
7
|
+
# ./status.sh -a <assignee> Filter tasks by assignee
|
|
7
8
|
# ./status.sh --list List all worktrees and agents
|
|
8
9
|
# ./status.sh --detail <task> Detailed task status
|
|
9
10
|
# ./status.sh --watch <task> Watch agent log in real-time
|
|
@@ -36,9 +37,14 @@ PROJECT_ROOT=$(get_repo_root)
|
|
|
36
37
|
# =============================================================================
|
|
37
38
|
ACTION="summary"
|
|
38
39
|
TARGET=""
|
|
40
|
+
FILTER_ASSIGNEE=""
|
|
39
41
|
|
|
40
42
|
while [[ $# -gt 0 ]]; do
|
|
41
43
|
case $1 in
|
|
44
|
+
-a|--assignee)
|
|
45
|
+
FILTER_ASSIGNEE="$2"
|
|
46
|
+
shift 2
|
|
47
|
+
;;
|
|
42
48
|
--list)
|
|
43
49
|
ACTION="list"
|
|
44
50
|
shift
|
|
@@ -186,6 +192,7 @@ Multi-Agent Pipeline: Status Monitor
|
|
|
186
192
|
|
|
187
193
|
Usage:
|
|
188
194
|
$0 Show summary of all tasks
|
|
195
|
+
$0 -a <assignee> Filter tasks by assignee
|
|
189
196
|
$0 --list List all worktrees and agents
|
|
190
197
|
$0 --detail <task> Detailed task status
|
|
191
198
|
$0 --progress <task> Quick progress view with recent activity
|
|
@@ -194,6 +201,7 @@ Usage:
|
|
|
194
201
|
$0 --registry Show agent registry
|
|
195
202
|
|
|
196
203
|
Examples:
|
|
204
|
+
$0 -a taosu
|
|
197
205
|
$0 --detail my-task
|
|
198
206
|
$0 --progress my-task
|
|
199
207
|
$0 --watch 01-16-worktree-support
|
|
@@ -308,14 +316,20 @@ cmd_summary() {
|
|
|
308
316
|
fi
|
|
309
317
|
|
|
310
318
|
# Task queue stats
|
|
311
|
-
local task_stats=$(
|
|
319
|
+
local task_stats=$(get_task_stats "$PROJECT_ROOT")
|
|
312
320
|
|
|
313
321
|
echo -e "${BLUE}=== Multi-Agent Status ===${NC}"
|
|
314
322
|
echo -e " Agents: ${GREEN}${running_count}${NC} running / ${total_agents} registered"
|
|
315
323
|
echo -e " Tasks: ${task_stats}"
|
|
316
324
|
echo ""
|
|
317
325
|
|
|
318
|
-
#
|
|
326
|
+
# Use temp files for grouping (compatible with old bash)
|
|
327
|
+
local tmp_dir=$(mktemp -d)
|
|
328
|
+
local running_file="$tmp_dir/running"
|
|
329
|
+
local stopped_file="$tmp_dir/stopped"
|
|
330
|
+
local tasks_file="$tmp_dir/tasks"
|
|
331
|
+
touch "$running_file" "$stopped_file" "$tasks_file"
|
|
332
|
+
|
|
319
333
|
local has_running_agent=false
|
|
320
334
|
|
|
321
335
|
for d in "$tasks_dir"/*/; do
|
|
@@ -325,9 +339,18 @@ cmd_summary() {
|
|
|
325
339
|
local name=$(basename "$d")
|
|
326
340
|
local task_json="$d/task.json"
|
|
327
341
|
local status="unknown"
|
|
342
|
+
local assignee="unassigned"
|
|
343
|
+
local priority="P2"
|
|
328
344
|
|
|
329
345
|
if [ -f "$task_json" ]; then
|
|
330
346
|
status=$(jq -r '.status // "unknown"' "$task_json")
|
|
347
|
+
assignee=$(jq -r '.assignee // "unassigned"' "$task_json")
|
|
348
|
+
priority=$(jq -r '.priority // "P2"' "$task_json")
|
|
349
|
+
fi
|
|
350
|
+
|
|
351
|
+
# Filter by assignee if specified
|
|
352
|
+
if [ -n "$FILTER_ASSIGNEE" ] && [ "$assignee" != "$FILTER_ASSIGNEE" ]; then
|
|
353
|
+
continue
|
|
331
354
|
fi
|
|
332
355
|
|
|
333
356
|
# Check agent status
|
|
@@ -352,9 +375,16 @@ cmd_summary() {
|
|
|
352
375
|
|
|
353
376
|
local color=$(status_color "$status")
|
|
354
377
|
|
|
378
|
+
# Color priority
|
|
379
|
+
local priority_color="${NC}"
|
|
380
|
+
case "$priority" in
|
|
381
|
+
P0) priority_color="${RED}" ;;
|
|
382
|
+
P1) priority_color="${YELLOW}" ;;
|
|
383
|
+
P2) priority_color="${BLUE}" ;;
|
|
384
|
+
esac
|
|
385
|
+
|
|
355
386
|
if [ "$is_agent_running" = true ]; then
|
|
356
|
-
#
|
|
357
|
-
# Read task.json from worktree (has live phase info)
|
|
387
|
+
# Running agent
|
|
358
388
|
local task_dir_rel=$(echo "$agent_info" | jq -r '.task_dir')
|
|
359
389
|
local worktree_task_json="$worktree/$task_dir_rel/task.json"
|
|
360
390
|
local phase_source="$task_json"
|
|
@@ -364,54 +394,119 @@ cmd_summary() {
|
|
|
364
394
|
local elapsed=$(calc_elapsed "$started")
|
|
365
395
|
local modified=$(count_modified_files "$worktree")
|
|
366
396
|
local branch=$(jq -r '.branch // "N/A"' "$phase_source" 2>/dev/null)
|
|
367
|
-
local developer=$(jq -r '.developer // "?"' "$phase_source" 2>/dev/null)
|
|
368
|
-
local priority=$(jq -r '.priority // "?"' "$phase_source" 2>/dev/null)
|
|
369
|
-
|
|
370
|
-
# Color priority
|
|
371
|
-
local priority_color="${NC}"
|
|
372
|
-
case "$priority" in
|
|
373
|
-
P0) priority_color="${RED}" ;;
|
|
374
|
-
P1) priority_color="${YELLOW}" ;;
|
|
375
|
-
P2) priority_color="${BLUE}" ;;
|
|
376
|
-
esac
|
|
377
|
-
|
|
378
|
-
# Get recent activity from log
|
|
379
397
|
local log_file="$worktree/.agent-log"
|
|
380
398
|
local last_tool=$(get_last_tool "$log_file")
|
|
381
399
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
echo -e " Activity: ${YELLOW}${last_tool}${NC}"
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
400
|
+
{
|
|
401
|
+
echo -e "${GREEN}▶${NC} ${CYAN}${name}${NC} ${GREEN}[running]${NC} ${priority_color}[${priority}]${NC} @${assignee}"
|
|
402
|
+
echo -e " Phase: ${phase_info}"
|
|
403
|
+
echo -e " Elapsed: ${elapsed}"
|
|
404
|
+
echo -e " Branch: ${DIM}${branch}${NC}"
|
|
405
|
+
echo -e " Modified: ${modified} file(s)"
|
|
406
|
+
[ -n "$last_tool" ] && echo -e " Activity: ${YELLOW}${last_tool}${NC}"
|
|
407
|
+
echo -e " PID: ${DIM}${pid}${NC}"
|
|
408
|
+
echo ""
|
|
409
|
+
} >> "$running_file"
|
|
410
|
+
|
|
392
411
|
elif [ -n "$agent_info" ] && [ "$agent_info" != "null" ]; then
|
|
393
|
-
# Stopped agent
|
|
394
|
-
echo
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
412
|
+
# Stopped agent - check if completed or interrupted
|
|
413
|
+
local task_dir_rel=$(echo "$agent_info" | jq -r '.task_dir')
|
|
414
|
+
local worktree_task_json="$worktree/$task_dir_rel/task.json"
|
|
415
|
+
local worktree_status="unknown"
|
|
416
|
+
if [ -f "$worktree_task_json" ]; then
|
|
417
|
+
worktree_status=$(jq -r '.status // "unknown"' "$worktree_task_json")
|
|
418
|
+
fi
|
|
419
|
+
|
|
420
|
+
if [ "$worktree_status" = "completed" ]; then
|
|
421
|
+
# Agent completed successfully
|
|
422
|
+
{
|
|
423
|
+
echo -e "${GREEN}✓${NC} ${name} ${GREEN}[completed]${NC}"
|
|
424
|
+
echo ""
|
|
425
|
+
} >> "$stopped_file"
|
|
426
|
+
else
|
|
427
|
+
# Agent was interrupted/blocked
|
|
428
|
+
{
|
|
429
|
+
local session_id_file="${worktree}/.session-id"
|
|
430
|
+
local log_file="$worktree/.agent-log"
|
|
431
|
+
local last_msg=$(get_last_message "$log_file" 150)
|
|
432
|
+
|
|
433
|
+
if [ -f "$session_id_file" ]; then
|
|
434
|
+
local session_id=$(cat "$session_id_file")
|
|
435
|
+
echo -e "${RED}○${NC} ${name} ${RED}[stopped]${NC}"
|
|
436
|
+
if [ -n "$last_msg" ]; then
|
|
437
|
+
echo -e "${DIM}\"${last_msg}\"${NC}"
|
|
438
|
+
fi
|
|
439
|
+
echo -e "${YELLOW}cd ${worktree} && claude --resume ${session_id}${NC}"
|
|
440
|
+
else
|
|
441
|
+
echo -e "${RED}○${NC} ${name} ${RED}[stopped]${NC} ${DIM}(no session-id)${NC}"
|
|
442
|
+
fi
|
|
443
|
+
echo ""
|
|
444
|
+
} >> "$stopped_file"
|
|
445
|
+
fi
|
|
401
446
|
|
|
402
|
-
|
|
403
|
-
|
|
447
|
+
else
|
|
448
|
+
# Normal task - store with assignee + priority_order + status_order + date for sorting
|
|
449
|
+
# Priority order: P0=0, P1=1, P2=2, P3=3 (lower = higher priority)
|
|
450
|
+
local priority_order="2"
|
|
404
451
|
case "$priority" in
|
|
405
|
-
P0)
|
|
406
|
-
P1)
|
|
407
|
-
P2)
|
|
452
|
+
P0) priority_order="0" ;;
|
|
453
|
+
P1) priority_order="1" ;;
|
|
454
|
+
P2) priority_order="2" ;;
|
|
455
|
+
P3) priority_order="3" ;;
|
|
408
456
|
esac
|
|
409
|
-
|
|
410
|
-
|
|
457
|
+
# Status order: in_progress=0, planning=1, completed=2 (lower = show first)
|
|
458
|
+
local status_order="1"
|
|
459
|
+
case "$status" in
|
|
460
|
+
in_progress) status_order="0" ;;
|
|
461
|
+
planning) status_order="1" ;;
|
|
462
|
+
completed) status_order="2" ;;
|
|
463
|
+
esac
|
|
464
|
+
# Extract date from name (MM-DD) for sorting, use reverse for desc
|
|
465
|
+
# Name format: MM-DD-xxx, extract MM-DD part and invert for desc sort
|
|
466
|
+
local date_part=$(echo "$name" | grep -oE '^[0-9]{2}-[0-9]{2}' || echo "00-00")
|
|
467
|
+
echo -e "${assignee}\t${priority_order}\t${status_order}\t${date_part}\t${color}●${NC} ${name} (${status}) ${priority_color}[${priority}]${NC}" >> "$tasks_file"
|
|
411
468
|
fi
|
|
412
469
|
done
|
|
413
470
|
|
|
471
|
+
# Output running agents first
|
|
472
|
+
if [ -s "$running_file" ]; then
|
|
473
|
+
echo -e "${CYAN}Running Agents:${NC}"
|
|
474
|
+
cat "$running_file"
|
|
475
|
+
fi
|
|
476
|
+
|
|
477
|
+
# Output stopped agents
|
|
478
|
+
if [ -s "$stopped_file" ]; then
|
|
479
|
+
echo -e "${RED}Stopped Agents:${NC}"
|
|
480
|
+
cat "$stopped_file"
|
|
481
|
+
fi
|
|
482
|
+
|
|
483
|
+
# Separator between agents and tasks
|
|
484
|
+
if [ -s "$running_file" ] || [ -s "$stopped_file" ]; then
|
|
485
|
+
if [ -s "$tasks_file" ]; then
|
|
486
|
+
echo -e "${DIM}───────────────────────────────────────${NC}"
|
|
487
|
+
echo ""
|
|
488
|
+
fi
|
|
489
|
+
fi
|
|
490
|
+
|
|
491
|
+
# Output tasks grouped by assignee, sorted by priority > status > date(desc)
|
|
492
|
+
if [ -s "$tasks_file" ]; then
|
|
493
|
+
local current_assignee=""
|
|
494
|
+
# Sort: assignee(asc), priority(asc), status(asc), date(desc/reverse)
|
|
495
|
+
sort -t$'\t' -k1,1 -k2,2n -k3,3n -k4,4r "$tasks_file" | while IFS=$'\t' read -r assignee priority_order status_order date_part task_line; do
|
|
496
|
+
if [ "$assignee" != "$current_assignee" ]; then
|
|
497
|
+
[ -n "$current_assignee" ] && echo ""
|
|
498
|
+
echo -e "${CYAN}@${assignee}:${NC}"
|
|
499
|
+
current_assignee="$assignee"
|
|
500
|
+
fi
|
|
501
|
+
echo -e " $task_line"
|
|
502
|
+
done
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
# Cleanup
|
|
506
|
+
rm -rf "$tmp_dir"
|
|
507
|
+
|
|
414
508
|
if [ "$has_running_agent" = true ]; then
|
|
509
|
+
echo ""
|
|
415
510
|
echo -e "${DIM}─────────────────────────────────────${NC}"
|
|
416
511
|
echo -e "${DIM}Use --progress <name> for quick activity view${NC}"
|
|
417
512
|
echo -e "${DIM}Use --detail <name> for more info${NC}"
|
|
@@ -535,10 +630,18 @@ cmd_detail() {
|
|
|
535
630
|
local task_dir=$(echo "$agent" | jq -r '.task_dir')
|
|
536
631
|
local started=$(echo "$agent" | jq -r '.started_at')
|
|
537
632
|
|
|
633
|
+
# Check for session-id
|
|
634
|
+
local session_id=""
|
|
635
|
+
local session_id_file="${worktree}/.session-id"
|
|
636
|
+
if [ -f "$session_id_file" ]; then
|
|
637
|
+
session_id=$(cat "$session_id_file")
|
|
638
|
+
fi
|
|
639
|
+
|
|
538
640
|
echo -e "${BLUE}=== Agent Detail: $id ===${NC}"
|
|
539
641
|
echo ""
|
|
540
642
|
echo " ID: $id"
|
|
541
643
|
echo " PID: $pid"
|
|
644
|
+
echo " Session: ${session_id:-N/A}"
|
|
542
645
|
echo " Worktree: $worktree"
|
|
543
646
|
echo " Task Dir: $task_dir"
|
|
544
647
|
echo " Started: $started"
|
|
@@ -549,6 +652,10 @@ cmd_detail() {
|
|
|
549
652
|
echo -e " Status: ${GREEN}Running${NC}"
|
|
550
653
|
else
|
|
551
654
|
echo -e " Status: ${RED}Stopped${NC}"
|
|
655
|
+
if [ -n "$session_id" ]; then
|
|
656
|
+
echo ""
|
|
657
|
+
echo -e " ${YELLOW}Resume:${NC} cd ${worktree} && claude --resume ${session_id}"
|
|
658
|
+
fi
|
|
552
659
|
fi
|
|
553
660
|
|
|
554
661
|
# Task info
|
package/package.json
CHANGED