@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.
@@ -11,6 +11,7 @@
11
11
  .agents/
12
12
  .agent-log
13
13
  .agent-runner.sh
14
+ .session-id
14
15
 
15
16
  # Task directory runtime files
16
17
  .plan-log
@@ -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=0
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" << 'RUNNER_EOF'
257
+ cat > "$RUNNER_SCRIPT" << RUNNER_EOF
252
258
  #!/bin/bash
253
- cd "$(dirname "$0")"
254
- export https_proxy="${AGENT_HTTPS_PROXY:-}"
255
- export http_proxy="${AGENT_HTTP_PROXY:-}"
256
- export all_proxy="${AGENT_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=$(get_task_queue_stats "$PROJECT_ROOT")
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
- # Check if any agents are running and show detailed view
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
- # Detailed view for running agents
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
- echo -e "${GREEN}▶${NC} ${CYAN}${name}${NC} ${GREEN}[running]${NC} ${priority_color}[${priority}]${NC} @${developer}"
383
- echo -e " Phase: ${phase_info}"
384
- echo -e " Elapsed: ${elapsed}"
385
- echo -e " Branch: ${DIM}${branch}${NC}"
386
- echo -e " Modified: ${modified} file(s)"
387
- if [ -n "$last_tool" ]; then
388
- echo -e " Activity: ${YELLOW}${last_tool}${NC}"
389
- fi
390
- echo -e " PID: ${DIM}${pid}${NC}"
391
- echo ""
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 -e "${RED}○${NC} ${name} ${RED}[stopped]${NC}"
395
- echo -e " ${DIM}PID ${pid} is no longer running${NC}"
396
- echo ""
397
- else
398
- # No agent, just show status with developer and priority
399
- local developer=$(jq -r '.developer // "?"' "$task_json" 2>/dev/null)
400
- local priority=$(jq -r '.priority // "?"' "$task_json" 2>/dev/null)
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
- # Color priority
403
- local priority_color="${NC}"
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) priority_color="${RED}" ;;
406
- P1) priority_color="${YELLOW}" ;;
407
- P2) priority_color="${BLUE}" ;;
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
- echo -e " ${color}●${NC} ${name} (${status}) ${priority_color}[${priority}]${NC} @${developer}"
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindfoldhq/trellis",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "AI capabilities grow like ivy — Trellis provides the structure to guide them along a disciplined path",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",