@mindfoldhq/trellis 0.2.5 → 0.2.7

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.
@@ -2,7 +2,7 @@
2
2
  name: research
3
3
  description: |
4
4
  Code and tech search expert. Pure research, no code modifications. Finds files, patterns, and tech solutions.
5
- tools: Read, Glob, Grep, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa, Skill
5
+ tools: Read, Glob, Grep, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa, Skill, mcp__chrome-devtools__*
6
6
  model: opus
7
7
  ---
8
8
  # Research Agent
@@ -37,7 +37,7 @@ pnpm test
37
37
  **Key Question**:
38
38
  > "If I fixed a bug or discovered something non-obvious, should I document it so future me (or others) won't hit the same issue?"
39
39
 
40
- If YES -> Update the relevant structure doc.
40
+ If YES -> Update the relevant spec doc.
41
41
 
42
42
  ### 3. API Changes
43
43
 
@@ -316,7 +316,7 @@ I recommend reading through `.trellis/spec/` to familiarize yourself with the te
316
316
  If the developer wants help filling guidelines, create a feature to track this:
317
317
 
318
318
  ```bash
319
- ./.trellis/scripts/task.sh create "Fill structure guidelines" --slug fill-structure-guidelines
319
+ ./.trellis/scripts/task.sh create "Fill spec guidelines" --slug fill-spec-guidelines
320
320
  ```
321
321
 
322
322
  Then systematically analyze the codebase and fill each guideline file:
@@ -77,9 +77,9 @@ Use when:
77
77
  Plan Agent will:
78
78
  1. Evaluate requirement validity (may reject if unclear/too large)
79
79
  2. Call research agent to analyze codebase
80
- 3. Create and configure feature directory
80
+ 3. Create and configure task directory
81
81
  4. Write prd.md with acceptance criteria
82
- 5. Output ready-to-use feature directory
82
+ 5. Output ready-to-use task directory
83
83
 
84
84
  After plan.sh completes, start the worktree agent:
85
85
 
@@ -26,7 +26,7 @@ pnpm test
26
26
 
27
27
  ### 2. Documentation Sync
28
28
 
29
- **Structure Docs**:
29
+ **Spec Docs**:
30
30
  - [ ] Does `.trellis/spec/backend/` need updates?
31
31
  - New patterns, new modules, new conventions
32
32
  - [ ] Does `.trellis/spec/frontend/` need updates?
@@ -37,7 +37,7 @@ pnpm test
37
37
  **Key Question**:
38
38
  > "If I fixed a bug or discovered something non-obvious, should I document it so future me (or others) won't hit the same issue?"
39
39
 
40
- If YES -> Update the relevant structure doc.
40
+ If YES -> Update the relevant spec doc.
41
41
 
42
42
  ### 3. API Changes
43
43
 
@@ -94,7 +94,7 @@ git diff --name-only
94
94
 
95
95
  | Oversight | Consequence | Check |
96
96
  |-----------|-------------|-------|
97
- | Structure docs not updated | Others don't know the change | Check .trellis/spec/ |
97
+ | Spec docs not updated | Others don't know the change | Check .trellis/spec/ |
98
98
  | Migration not created | Schema out of sync | Check db/migrations/ |
99
99
  | Types not synced | Runtime errors | Check shared types |
100
100
  | Tests not updated | False confidence | Run full test suite |
@@ -316,7 +316,7 @@ I recommend reading through `.trellis/spec/` to familiarize yourself with the te
316
316
  If the developer wants help filling guidelines, create a feature to track this:
317
317
 
318
318
  ```bash
319
- ./.trellis/scripts/task.sh create "Fill structure guidelines" --slug fill-structure-guidelines
319
+ ./.trellis/scripts/task.sh create "Fill spec guidelines" --slug fill-spec-guidelines
320
320
  ```
321
321
 
322
322
  Then systematically analyze the codebase and fill each guideline file:
@@ -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
@@ -8,7 +8,7 @@
8
8
  # registry_get_file - Get registry file path
9
9
  # registry_get_agent_by_id - Find agent by ID
10
10
  # registry_get_agent_by_worktree - Find agent by worktree path
11
- # registry_get_task_dir - Get feature dir for a worktree
11
+ # registry_get_task_dir - Get task dir for a worktree
12
12
  # registry_remove_by_id - Remove agent by ID
13
13
  # registry_remove_by_worktree - Remove agent by worktree path
14
14
  # registry_add_agent - Add agent to registry
@@ -123,7 +123,7 @@ registry_search_agent() {
123
123
  return 1
124
124
  }
125
125
 
126
- # Get feature directory for a worktree
126
+ # Get task directory for a worktree
127
127
  # Args: worktree_path, [repo_root]
128
128
  # Returns: task_dir value, or empty if not found
129
129
  registry_get_task_dir() {
@@ -43,7 +43,7 @@ while [[ $# -gt 0 ]]; do
43
43
  shift
44
44
  ;;
45
45
  -h|--help)
46
- echo "Usage: $0 [feature-dir] [--dry-run]"
46
+ echo "Usage: $0 [task-dir] [--dry-run]"
47
47
  echo ""
48
48
  echo "Options:"
49
49
  echo " --dry-run Show what would be done without making changes"
@@ -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
@@ -762,7 +762,7 @@ cmd_set_branch() {
762
762
  if [[ -z "$target_dir" ]] || [[ -z "$branch" ]]; then
763
763
  echo -e "${RED}Error: Missing arguments${NC}"
764
764
  echo "Usage: $0 set-branch <task-dir> <branch-name>"
765
- echo "Example: $0 set-branch <dir> feature/my-task"
765
+ echo "Example: $0 set-branch <dir> task/my-task"
766
766
  exit 1
767
767
  fi
768
768
 
@@ -1048,7 +1048,7 @@ Examples:
1048
1048
  $0 create "Add login feature" --slug add-login
1049
1049
  $0 init-context .trellis/tasks/01-21-add-login backend
1050
1050
  $0 add-context <dir> implement .trellis/spec/backend/auth.md "Auth guidelines"
1051
- $0 set-branch <dir> feature/add-login
1051
+ $0 set-branch <dir> task/add-login
1052
1052
  $0 start .trellis/tasks/01-21-add-login
1053
1053
  $0 create-pr # Uses current task
1054
1054
  $0 create-pr <dir> --dry-run # Preview without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindfoldhq/trellis",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
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",