@mindfoldhq/trellis 0.1.1 → 0.1.3

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.
Files changed (132) hide show
  1. package/dist/{templates/agents/bodies → .claude/agents}/check.md +7 -0
  2. package/dist/{templates/agents/bodies → .claude/agents}/debug.md +7 -0
  3. package/dist/{templates/agents/bodies → .claude/agents}/dispatch.md +11 -8
  4. package/dist/{templates/agents/bodies → .claude/agents}/implement.md +7 -0
  5. package/dist/.claude/agents/plan.md +396 -0
  6. package/dist/{templates/agents/bodies → .claude/agents}/research.md +7 -0
  7. package/dist/{templates/commands/common/check-cross-layer.txt → .claude/commands/check-cross-layer.md} +29 -29
  8. package/dist/{templates → .claude}/hooks/inject-subagent-context.py +63 -0
  9. package/dist/.cursor/commands/before-backend-dev.md +13 -0
  10. package/dist/.cursor/commands/before-frontend-dev.md +13 -0
  11. package/dist/.cursor/commands/break-loop.md +107 -0
  12. package/dist/.cursor/commands/check-backend.md +13 -0
  13. package/dist/.cursor/commands/check-cross-layer.md +153 -0
  14. package/dist/.cursor/commands/check-frontend.md +13 -0
  15. package/dist/.cursor/commands/create-command.md +154 -0
  16. package/dist/.cursor/commands/finish-work.md +129 -0
  17. package/dist/.cursor/commands/integrate-skill.md +219 -0
  18. package/dist/.cursor/commands/onboard-developer.md +355 -0
  19. package/dist/.cursor/commands/record-agent-flow.md +62 -0
  20. package/dist/.trellis/scripts/common/phase.sh +150 -0
  21. package/dist/{templates/scripts/feature.sh.txt → .trellis/scripts/feature.sh} +8 -3
  22. package/dist/{templates/scripts/multi-agent/cleanup.sh.txt → .trellis/scripts/multi-agent/cleanup.sh} +107 -18
  23. package/dist/.trellis/scripts/multi-agent/create-pr.sh +241 -0
  24. package/dist/.trellis/scripts/multi-agent/plan.sh +232 -0
  25. package/dist/{templates/scripts/multi-agent/start.sh.txt → .trellis/scripts/multi-agent/start.sh} +21 -0
  26. package/dist/{templates/scripts/multi-agent/status.sh.txt → .trellis/scripts/multi-agent/status.sh} +282 -10
  27. package/dist/.trellis/structure/backend/database-guidelines.md +51 -0
  28. package/dist/.trellis/structure/backend/directory-structure.md +209 -0
  29. package/dist/.trellis/structure/backend/error-handling.md +278 -0
  30. package/dist/.trellis/structure/backend/index.md +38 -0
  31. package/dist/.trellis/structure/backend/logging-guidelines.md +266 -0
  32. package/dist/.trellis/structure/backend/quality-guidelines.md +313 -0
  33. package/dist/.trellis/structure/frontend/component-guidelines.md +59 -0
  34. package/dist/.trellis/structure/frontend/directory-structure.md +54 -0
  35. package/dist/.trellis/structure/frontend/hook-guidelines.md +51 -0
  36. package/dist/.trellis/structure/frontend/index.md +39 -0
  37. package/dist/.trellis/structure/frontend/quality-guidelines.md +51 -0
  38. package/dist/.trellis/structure/frontend/state-management.md +51 -0
  39. package/dist/.trellis/structure/frontend/type-safety.md +51 -0
  40. package/dist/.trellis/structure/guides/code-reuse-thinking-guide.md +92 -0
  41. package/dist/.trellis/structure/guides/cross-layer-thinking-guide.md +94 -0
  42. package/dist/.trellis/structure/guides/index.md +79 -0
  43. package/dist/{templates/scripts/worktree.yaml.txt → .trellis/worktree.yaml} +1 -1
  44. package/dist/commands/init.d.ts.map +1 -1
  45. package/dist/commands/init.js +5 -16
  46. package/dist/commands/init.js.map +1 -1
  47. package/dist/configurators/claude.d.ts +17 -17
  48. package/dist/configurators/claude.d.ts.map +1 -1
  49. package/dist/configurators/claude.js +29 -59
  50. package/dist/configurators/claude.js.map +1 -1
  51. package/dist/configurators/cursor.d.ts +3 -3
  52. package/dist/configurators/cursor.d.ts.map +1 -1
  53. package/dist/configurators/cursor.js +11 -15
  54. package/dist/configurators/cursor.js.map +1 -1
  55. package/dist/configurators/opencode.d.ts +11 -10
  56. package/dist/configurators/opencode.d.ts.map +1 -1
  57. package/dist/configurators/opencode.js +14 -33
  58. package/dist/configurators/opencode.js.map +1 -1
  59. package/dist/configurators/workflow.d.ts +7 -0
  60. package/dist/configurators/workflow.d.ts.map +1 -1
  61. package/dist/configurators/workflow.js +30 -99
  62. package/dist/configurators/workflow.js.map +1 -1
  63. package/dist/templates/extract.d.ts +73 -8
  64. package/dist/templates/extract.d.ts.map +1 -1
  65. package/dist/templates/extract.js +149 -10
  66. package/dist/templates/extract.js.map +1 -1
  67. package/dist/templates/markdown/gitignore.txt +6 -1
  68. package/dist/templates/markdown/index.d.ts +5 -1
  69. package/dist/templates/markdown/index.d.ts.map +1 -1
  70. package/dist/templates/markdown/index.js +54 -26
  71. package/dist/templates/markdown/index.js.map +1 -1
  72. package/dist/templates/markdown/structure/backend/directory-structure.md.txt +6 -6
  73. package/dist/templates/markdown/structure/backend/error-handling.md.txt +8 -8
  74. package/dist/templates/markdown/structure/backend/index.md.txt +5 -5
  75. package/dist/templates/markdown/structure/backend/logging-guidelines.md.txt +8 -8
  76. package/dist/templates/markdown/structure/frontend/index.md.txt +6 -6
  77. package/dist/templates/markdown/structure/guides/cross-layer-thinking-guide.md.txt +5 -5
  78. package/dist/templates/markdown/structure/guides/index.md.txt +7 -7
  79. package/dist/templates/markdown/worktree.yaml.txt +58 -0
  80. package/package.json +1 -1
  81. package/dist/configurators/templates.d.ts +0 -40
  82. package/dist/configurators/templates.d.ts.map +0 -1
  83. package/dist/configurators/templates.js +0 -67
  84. package/dist/configurators/templates.js.map +0 -1
  85. package/dist/templates/agents/index.d.ts +0 -42
  86. package/dist/templates/agents/index.d.ts.map +0 -1
  87. package/dist/templates/agents/index.js +0 -148
  88. package/dist/templates/agents/index.js.map +0 -1
  89. package/dist/templates/agents/metadata.d.ts +0 -48
  90. package/dist/templates/agents/metadata.d.ts.map +0 -1
  91. package/dist/templates/agents/metadata.js +0 -101
  92. package/dist/templates/agents/metadata.js.map +0 -1
  93. package/dist/templates/commands/index.d.ts +0 -48
  94. package/dist/templates/commands/index.d.ts.map +0 -1
  95. package/dist/templates/commands/index.js +0 -167
  96. package/dist/templates/commands/index.js.map +0 -1
  97. package/dist/templates/commands/opencode/start.md.txt +0 -127
  98. package/dist/templates/hooks/index.d.ts +0 -33
  99. package/dist/templates/hooks/index.d.ts.map +0 -1
  100. package/dist/templates/hooks/index.js +0 -53
  101. package/dist/templates/hooks/index.js.map +0 -1
  102. package/dist/templates/scripts/index.d.ts +0 -36
  103. package/dist/templates/scripts/index.d.ts.map +0 -1
  104. package/dist/templates/scripts/index.js +0 -41
  105. package/dist/templates/scripts/index.js.map +0 -1
  106. /package/dist/{templates/commands/common/before-backend-dev.txt → .claude/commands/before-backend-dev.md} +0 -0
  107. /package/dist/{templates/commands/common/before-frontend-dev.txt → .claude/commands/before-frontend-dev.md} +0 -0
  108. /package/dist/{templates/commands/common/break-loop.txt → .claude/commands/break-loop.md} +0 -0
  109. /package/dist/{templates/commands/common/check-backend.txt → .claude/commands/check-backend.md} +0 -0
  110. /package/dist/{templates/commands/common/check-frontend.txt → .claude/commands/check-frontend.md} +0 -0
  111. /package/dist/{templates/commands/common/create-command.txt → .claude/commands/create-command.md} +0 -0
  112. /package/dist/{templates/commands/common/finish-work.txt → .claude/commands/finish-work.md} +0 -0
  113. /package/dist/{templates/commands/common/integrate-skill.txt → .claude/commands/integrate-skill.md} +0 -0
  114. /package/dist/{templates/commands/common/onboard-developer.txt → .claude/commands/onboard-developer.md} +0 -0
  115. /package/dist/{templates/commands/claude/parallel.md.txt → .claude/commands/parallel.md} +0 -0
  116. /package/dist/{templates/commands/common/record-agent-flow.txt → .claude/commands/record-agent-flow.md} +0 -0
  117. /package/dist/{templates/commands/claude/start.md.txt → .claude/commands/start.md} +0 -0
  118. /package/dist/{templates/hooks → .claude}/settings.json +0 -0
  119. /package/dist/{templates/commands/cursor/start.md.txt → .cursor/commands/start.md} +0 -0
  120. /package/dist/{templates/markdown/agent-traces-index.md.txt → .trellis/agent-traces/index.md} +0 -0
  121. /package/dist/{templates/scripts/add-session.sh.txt → .trellis/scripts/add-session.sh} +0 -0
  122. /package/dist/{templates/scripts/common/developer.sh.txt → .trellis/scripts/common/developer.sh} +0 -0
  123. /package/dist/{templates/scripts/common/git-context.sh.txt → .trellis/scripts/common/git-context.sh} +0 -0
  124. /package/dist/{templates/scripts/common/paths.sh.txt → .trellis/scripts/common/paths.sh} +0 -0
  125. /package/dist/{templates/scripts/common/worktree.sh.txt → .trellis/scripts/common/worktree.sh} +0 -0
  126. /package/dist/{templates/scripts/create-bootstrap.sh.txt → .trellis/scripts/create-bootstrap.sh} +0 -0
  127. /package/dist/{templates/scripts/get-context.sh.txt → .trellis/scripts/get-context.sh} +0 -0
  128. /package/dist/{templates/scripts/get-developer.sh.txt → .trellis/scripts/get-developer.sh} +0 -0
  129. /package/dist/{templates/scripts/init-developer.sh.txt → .trellis/scripts/init-developer.sh} +0 -0
  130. /package/dist/{templates/markdown/workflow.md.txt → .trellis/workflow.md} +0 -0
  131. /package/dist/templates/markdown/{agents.md.txt → agents.md} +0 -0
  132. /package/dist/templates/markdown/{init-agent.md.txt → init-agent.md} +0 -0
@@ -0,0 +1,232 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # Multi-Agent Pipeline: Plan Agent Launcher
4
+ # =============================================================================
5
+ # Usage: ./plan.sh --name <feature-name> --type <dev-type> --requirement "<requirement>"
6
+ #
7
+ # This script:
8
+ # 1. Creates feature directory
9
+ # 2. Starts Plan Agent in background
10
+ # 3. Plan Agent produces fully configured feature directory
11
+ #
12
+ # After completion, use start.sh to launch the Dispatch Agent.
13
+ #
14
+ # Prerequisites:
15
+ # - .claude/agents/plan.md must exist
16
+ # - Developer must be initialized
17
+ # =============================================================================
18
+
19
+ set -e
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ source "$SCRIPT_DIR/../common/paths.sh"
23
+ source "$SCRIPT_DIR/../common/developer.sh"
24
+
25
+ # Colors
26
+ RED='\033[0;31m'
27
+ GREEN='\033[0;32m'
28
+ YELLOW='\033[1;33m'
29
+ BLUE='\033[0;34m'
30
+ NC='\033[0m'
31
+
32
+ log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
33
+ log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
34
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
35
+ log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
36
+
37
+ # =============================================================================
38
+ # Constants
39
+ # =============================================================================
40
+ PROJECT_ROOT=$(get_repo_root)
41
+ PLAN_MD_PATH=".claude/agents/plan.md"
42
+
43
+ # =============================================================================
44
+ # Parse Arguments
45
+ # =============================================================================
46
+ FEATURE_NAME=""
47
+ DEV_TYPE=""
48
+ REQUIREMENT=""
49
+
50
+ show_usage() {
51
+ cat << EOF
52
+ Usage: $0 --name <feature-name> --type <dev-type> --requirement "<requirement>"
53
+
54
+ Arguments:
55
+ --name, -n Feature name (e.g., user-auth, add-rate-limiting)
56
+ --type, -t Development type: backend | frontend | fullstack
57
+ --requirement, -r Requirement description (quote if contains spaces)
58
+
59
+ Examples:
60
+ $0 --name user-auth --type backend --requirement "Add JWT-based user authentication"
61
+ $0 -n rate-limit -t backend -r "Add rate limiting to API endpoints"
62
+
63
+ The Plan Agent runs in background. Monitor with:
64
+ tail -f <feature-dir>/.plan-log
65
+ EOF
66
+ }
67
+
68
+ while [[ $# -gt 0 ]]; do
69
+ case $1 in
70
+ --name|-n)
71
+ FEATURE_NAME="$2"
72
+ shift 2
73
+ ;;
74
+ --type|-t)
75
+ DEV_TYPE="$2"
76
+ shift 2
77
+ ;;
78
+ --requirement|-r)
79
+ REQUIREMENT="$2"
80
+ shift 2
81
+ ;;
82
+ --help|-h)
83
+ show_usage
84
+ exit 0
85
+ ;;
86
+ *)
87
+ log_error "Unknown argument: $1"
88
+ show_usage
89
+ exit 1
90
+ ;;
91
+ esac
92
+ done
93
+
94
+ # =============================================================================
95
+ # Validation
96
+ # =============================================================================
97
+ if [ -z "$FEATURE_NAME" ]; then
98
+ log_error "Feature name is required (--name)"
99
+ show_usage
100
+ exit 1
101
+ fi
102
+
103
+ if [ -z "$DEV_TYPE" ]; then
104
+ log_error "Development type is required (--type)"
105
+ show_usage
106
+ exit 1
107
+ fi
108
+
109
+ if [[ ! "$DEV_TYPE" =~ ^(backend|frontend|fullstack)$ ]]; then
110
+ log_error "Invalid dev type: $DEV_TYPE (must be: backend, frontend, fullstack)"
111
+ exit 1
112
+ fi
113
+
114
+ if [ -z "$REQUIREMENT" ]; then
115
+ log_error "Requirement is required (--requirement)"
116
+ show_usage
117
+ exit 1
118
+ fi
119
+
120
+ PLAN_MD="${PROJECT_ROOT}/${PLAN_MD_PATH}"
121
+ if [ ! -f "$PLAN_MD" ]; then
122
+ log_error "plan.md not found at ${PLAN_MD}"
123
+ exit 1
124
+ fi
125
+
126
+ ensure_developer "$PROJECT_ROOT"
127
+
128
+ # =============================================================================
129
+ # Step 1: Create Feature Directory
130
+ # =============================================================================
131
+ echo ""
132
+ echo -e "${BLUE}=== Multi-Agent Pipeline: Plan ===${NC}"
133
+ log_info "Feature: ${FEATURE_NAME}"
134
+ log_info "Type: ${DEV_TYPE}"
135
+ log_info "Requirement: ${REQUIREMENT}"
136
+ echo ""
137
+
138
+ log_info "Step 1: Creating feature directory..."
139
+
140
+ FEATURE_DIR=$("$SCRIPT_DIR/../feature.sh" create "$FEATURE_NAME")
141
+ FEATURE_DIR_ABS="${PROJECT_ROOT}/${FEATURE_DIR}"
142
+
143
+ log_success "Feature directory: ${FEATURE_DIR}"
144
+
145
+ # =============================================================================
146
+ # Step 2: Prepare and Start Plan Agent
147
+ # =============================================================================
148
+ log_info "Step 2: Starting Plan Agent in background..."
149
+
150
+ # Extract plan.md content (skip frontmatter)
151
+ PLAN_PROMPT=$(awk '
152
+ BEGIN { in_frontmatter = 0; started = 0 }
153
+ /^---$/ {
154
+ if (!started) { in_frontmatter = 1; started = 1; next }
155
+ else if (in_frontmatter) { in_frontmatter = 0; next }
156
+ }
157
+ !in_frontmatter { print }
158
+ ' "$PLAN_MD")
159
+
160
+ LOG_FILE="${FEATURE_DIR_ABS}/.plan-log"
161
+ touch "$LOG_FILE"
162
+
163
+ # Create a temporary runner script (will be deleted after agent starts)
164
+ RUNNER_SCRIPT=$(mktemp)
165
+ cat > "$RUNNER_SCRIPT" << RUNNER_EOF
166
+ #!/bin/bash
167
+ cd "${PROJECT_ROOT}"
168
+
169
+ export PLAN_FEATURE_NAME="${FEATURE_NAME}"
170
+ export PLAN_DEV_TYPE="${DEV_TYPE}"
171
+ export PLAN_FEATURE_DIR="${FEATURE_DIR}"
172
+ export PLAN_REQUIREMENT="${REQUIREMENT}"
173
+
174
+ export https_proxy="\${AGENT_HTTPS_PROXY:-}"
175
+ export http_proxy="\${AGENT_HTTP_PROXY:-}"
176
+ export all_proxy="\${AGENT_ALL_PROXY:-}"
177
+
178
+ # Create prompt content inline (no temp file needed)
179
+ claude -p --dangerously-skip-permissions --output-format stream-json --verbose << 'PROMPT_EOF'
180
+ # Environment Variables
181
+
182
+ The following environment variables are set for this planning session:
183
+
184
+ \`\`\`
185
+ PLAN_FEATURE_NAME=${FEATURE_NAME}
186
+ PLAN_DEV_TYPE=${DEV_TYPE}
187
+ PLAN_FEATURE_DIR=${FEATURE_DIR}
188
+ PLAN_REQUIREMENT=${REQUIREMENT}
189
+ \`\`\`
190
+
191
+ You can read these directly from the environment or use the values above.
192
+
193
+ ---
194
+
195
+ ${PLAN_PROMPT}
196
+ PROMPT_EOF
197
+
198
+ # Self-delete the runner script
199
+ rm -f "\$0"
200
+ RUNNER_EOF
201
+ chmod +x "$RUNNER_SCRIPT"
202
+
203
+ # Start agent in background
204
+ AGENT_HTTPS_PROXY="${https_proxy:-}" \
205
+ AGENT_HTTP_PROXY="${http_proxy:-}" \
206
+ AGENT_ALL_PROXY="${all_proxy:-}" \
207
+ nohup "$RUNNER_SCRIPT" > "$LOG_FILE" 2>&1 &
208
+ AGENT_PID=$!
209
+
210
+ log_success "Plan Agent started (PID: ${AGENT_PID})"
211
+
212
+ # =============================================================================
213
+ # Summary
214
+ # =============================================================================
215
+ echo ""
216
+ echo -e "${GREEN}=== Plan Agent Running ===${NC}"
217
+ echo ""
218
+ echo " Feature: $FEATURE_NAME"
219
+ echo " Type: $DEV_TYPE"
220
+ echo " Dir: $FEATURE_DIR"
221
+ echo " Log: $LOG_FILE"
222
+ echo " PID: $AGENT_PID"
223
+ echo ""
224
+ echo -e "${YELLOW}To monitor:${NC}"
225
+ echo " tail -f $LOG_FILE"
226
+ echo ""
227
+ echo -e "${YELLOW}To check status:${NC}"
228
+ echo " ps -p $AGENT_PID"
229
+ echo " ls -la $FEATURE_DIR"
230
+ echo ""
231
+ echo -e "${YELLOW}After completion, run:${NC}"
232
+ echo " ./.trellis/scripts/multi-agent/start.sh $FEATURE_DIR"
@@ -95,8 +95,29 @@ log_info "Feature: ${FEATURE_DIR_ABS}"
95
95
 
96
96
  BRANCH=$(jq -r '.branch' "$FEATURE_JSON")
97
97
  FEATURE_NAME=$(jq -r '.name' "$FEATURE_JSON")
98
+ FEATURE_STATUS=$(jq -r '.status' "$FEATURE_JSON")
98
99
  WORKTREE_PATH=$(jq -r '.worktree_path // empty' "$FEATURE_JSON")
99
100
 
101
+ # Check if feature was rejected
102
+ if [ "$FEATURE_STATUS" = "rejected" ]; then
103
+ log_error "Feature was rejected by Plan Agent"
104
+ if [ -f "${FEATURE_DIR_ABS}/REJECTED.md" ]; then
105
+ echo ""
106
+ echo -e "${YELLOW}Rejection reason:${NC}"
107
+ cat "${FEATURE_DIR_ABS}/REJECTED.md"
108
+ fi
109
+ echo ""
110
+ log_info "To retry, delete this directory and run plan.sh again with revised requirements"
111
+ exit 1
112
+ fi
113
+
114
+ # Check if prd.md exists (plan completed successfully)
115
+ if [ ! -f "${FEATURE_DIR_ABS}/prd.md" ]; then
116
+ log_error "prd.md not found - Plan Agent may not have completed"
117
+ log_info "Check plan log: ${FEATURE_DIR_ABS}/.plan-log"
118
+ exit 1
119
+ fi
120
+
100
121
  if [ -z "$BRANCH" ] || [ "$BRANCH" = "null" ]; then
101
122
  log_error "branch field not set in feature.json"
102
123
  log_info "Please set branch field first, e.g.:"
@@ -17,6 +17,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
17
  source "$SCRIPT_DIR/../common/paths.sh"
18
18
  source "$SCRIPT_DIR/../common/worktree.sh"
19
19
  source "$SCRIPT_DIR/../common/developer.sh"
20
+ source "$SCRIPT_DIR/../common/phase.sh"
20
21
 
21
22
  # Colors
22
23
  RED='\033[0;31m'
@@ -56,6 +57,11 @@ while [[ $# -gt 0 ]]; do
56
57
  TARGET="$2"
57
58
  shift 2
58
59
  ;;
60
+ --progress)
61
+ ACTION="progress"
62
+ TARGET="$2"
63
+ shift 2
64
+ ;;
59
65
  --registry)
60
66
  ACTION="registry"
61
67
  shift
@@ -113,6 +119,62 @@ find_agent() {
113
119
  echo "$agent"
114
120
  }
115
121
 
122
+ # Get the last tool call from agent log
123
+ get_last_tool() {
124
+ local log_file="$1"
125
+ if [ ! -f "$log_file" ]; then
126
+ echo ""
127
+ return
128
+ fi
129
+ # Use tail -r on macOS, tac on Linux
130
+ if command -v tac &>/dev/null; then
131
+ tac "$log_file" 2>/dev/null | head -100 | jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use") | .name' 2>/dev/null | head -1
132
+ else
133
+ tail -r "$log_file" 2>/dev/null | head -100 | jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="tool_use") | .name' 2>/dev/null | head -1
134
+ fi
135
+ }
136
+
137
+ # Get the last assistant text from agent log
138
+ get_last_message() {
139
+ local log_file="$1"
140
+ local max_len="${2:-100}"
141
+ if [ ! -f "$log_file" ]; then
142
+ echo ""
143
+ return
144
+ fi
145
+ local text
146
+ # Use tail -r on macOS, tac on Linux
147
+ if command -v tac &>/dev/null; then
148
+ text=$(tac "$log_file" 2>/dev/null | head -100 | jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="text") | .text' 2>/dev/null | head -1)
149
+ else
150
+ text=$(tail -r "$log_file" 2>/dev/null | head -100 | jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="text") | .text' 2>/dev/null | head -1)
151
+ fi
152
+ if [ -n "$text" ] && [ "$text" != "null" ]; then
153
+ echo "${text:0:$max_len}"
154
+ fi
155
+ }
156
+
157
+ # Get recent task notifications from agent log
158
+ # Looks for async_launched tasks and infers completion from current_phase
159
+ get_recent_tasks() {
160
+ local log_file="$1"
161
+ local count="${2:-5}"
162
+ local current_phase="${3:-0}"
163
+ if [ ! -f "$log_file" ]; then
164
+ return
165
+ fi
166
+ # Get async_launched tasks with phase number extracted from description
167
+ tail -500 "$log_file" 2>/dev/null | jq -r --argjson current_phase "$current_phase" '
168
+ select(.type=="user" and .tool_use_result.status == "async_launched" and .tool_use_result.description != null) |
169
+ .tool_use_result.description as $desc |
170
+ # Extract phase number from "Phase N:" pattern
171
+ ($desc | capture("Phase (?<num>[0-9]+)") | .num | tonumber) as $phase_num |
172
+ # If current_phase > this phase, it is completed
173
+ (if $phase_num < $current_phase then "completed" else "async_launched" end) as $status |
174
+ "\($status)|\($desc)"
175
+ ' 2>/dev/null | tail -"$count"
176
+ }
177
+
116
178
  # =============================================================================
117
179
  # Commands
118
180
  # =============================================================================
@@ -125,12 +187,14 @@ Usage:
125
187
  $0 Show summary of all features
126
188
  $0 --list List all worktrees and agents
127
189
  $0 --detail <feature> Detailed feature status
190
+ $0 --progress <feature> Quick progress view with recent activity
128
191
  $0 --watch <feature> Watch agent log in real-time
129
192
  $0 --log <feature> Show recent log entries
130
193
  $0 --registry Show agent registry
131
194
 
132
195
  Examples:
133
196
  $0 --detail my-feature
197
+ $0 --progress my-feature
134
198
  $0 --watch 16-worktree-support
135
199
  $0 --log worktree-support
136
200
  EOF
@@ -174,6 +238,52 @@ cmd_list() {
174
238
  done
175
239
  }
176
240
 
241
+ # Calculate elapsed time from ISO timestamp
242
+ calc_elapsed() {
243
+ local started="$1"
244
+ if [ -z "$started" ] || [ "$started" = "null" ]; then
245
+ echo "N/A"
246
+ return
247
+ fi
248
+
249
+ # Parse started time (handle both formats: with and without timezone)
250
+ local start_epoch
251
+ if command -v gdate &>/dev/null; then
252
+ start_epoch=$(gdate -d "$started" +%s 2>/dev/null)
253
+ else
254
+ # Try to parse ISO format
255
+ start_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${started%%+*}" +%s 2>/dev/null || date -d "$started" +%s 2>/dev/null)
256
+ fi
257
+
258
+ if [ -z "$start_epoch" ]; then
259
+ echo "N/A"
260
+ return
261
+ fi
262
+
263
+ local now_epoch=$(date +%s)
264
+ local elapsed=$((now_epoch - start_epoch))
265
+
266
+ if [ $elapsed -lt 60 ]; then
267
+ echo "${elapsed}s"
268
+ elif [ $elapsed -lt 3600 ]; then
269
+ echo "$((elapsed / 60))m $((elapsed % 60))s"
270
+ else
271
+ echo "$((elapsed / 3600))h $((elapsed % 3600 / 60))m"
272
+ fi
273
+ }
274
+
275
+ # Note: get_phase_info is now in common/phase.sh
276
+
277
+ # Count modified files in worktree
278
+ count_modified_files() {
279
+ local worktree="$1"
280
+ if [ -d "$worktree" ]; then
281
+ cd "$worktree" && git status --short 2>/dev/null | wc -l | tr -d ' '
282
+ else
283
+ echo "0"
284
+ fi
285
+ }
286
+
177
287
  cmd_summary() {
178
288
  ensure_developer
179
289
 
@@ -183,12 +293,26 @@ cmd_summary() {
183
293
  exit 0
184
294
  fi
185
295
 
186
- echo -e "${BLUE}=== Feature Summary ===${NC}"
187
- echo ""
188
-
189
296
  AGENTS_DIR=$(get_agents_dir)
190
297
  REGISTRY_FILE="${AGENTS_DIR}/registry.json"
191
298
 
299
+ # Count running agents
300
+ local running_count=0
301
+ local total_agents=0
302
+ if [ -f "$REGISTRY_FILE" ]; then
303
+ total_agents=$(jq -r '.agents | length' "$REGISTRY_FILE" 2>/dev/null || echo "0")
304
+ while read -r pid; do
305
+ is_running "$pid" && ((running_count++))
306
+ done < <(jq -r '.agents[].pid' "$REGISTRY_FILE" 2>/dev/null)
307
+ fi
308
+
309
+ echo -e "${BLUE}=== Multi-Agent Status ===${NC}"
310
+ echo -e " Agents: ${GREEN}${running_count}${NC} running / ${total_agents} registered"
311
+ echo ""
312
+
313
+ # Check if any agents are running and show detailed view
314
+ local has_running_agent=false
315
+
192
316
  for d in "$features_dir"/*/; do
193
317
  [ ! -d "$d" ] && continue
194
318
  [[ "$(basename "$d")" == "archive" ]] && continue
@@ -196,29 +320,174 @@ cmd_summary() {
196
320
  local name=$(basename "$d")
197
321
  local feature_json="$d/feature.json"
198
322
  local status="unknown"
199
- local agent_status=""
200
323
 
201
324
  if [ -f "$feature_json" ]; then
202
325
  status=$(jq -r '.status // "unknown"' "$feature_json")
203
326
  fi
204
327
 
205
328
  # Check agent status
329
+ local agent_info=""
330
+ local pid=""
331
+ local worktree=""
332
+ local started=""
333
+ local is_agent_running=false
334
+
206
335
  if [ -f "$REGISTRY_FILE" ]; then
207
- local agent_info=$(jq -r --arg name "$name" '.agents[] | select(.feature_dir | contains($name))' "$REGISTRY_FILE" 2>/dev/null)
336
+ agent_info=$(jq -r --arg name "$name" '.agents[] | select(.feature_dir | contains($name))' "$REGISTRY_FILE" 2>/dev/null)
208
337
  if [ -n "$agent_info" ] && [ "$agent_info" != "null" ]; then
209
- local pid=$(echo "$agent_info" | jq -r '.pid')
338
+ pid=$(echo "$agent_info" | jq -r '.pid')
339
+ worktree=$(echo "$agent_info" | jq -r '.worktree_path')
340
+ started=$(echo "$agent_info" | jq -r '.started_at')
210
341
  if is_running "$pid"; then
211
- agent_status=" ${GREEN}[agent running]${NC}"
212
- else
213
- agent_status=" ${RED}[agent stopped]${NC}"
342
+ is_agent_running=true
343
+ has_running_agent=true
214
344
  fi
215
345
  fi
216
346
  fi
217
347
 
218
348
  local color=$(status_color "$status")
219
- echo -e " ${color}●${NC} $name ($status)$agent_status"
349
+
350
+ if [ "$is_agent_running" = true ]; then
351
+ # Detailed view for running agents
352
+ # Read feature.json from worktree (has live phase info)
353
+ local feature_dir_rel=$(echo "$agent_info" | jq -r '.feature_dir')
354
+ local worktree_feature_json="$worktree/$feature_dir_rel/feature.json"
355
+ local phase_source="$feature_json"
356
+ [ -f "$worktree_feature_json" ] && phase_source="$worktree_feature_json"
357
+
358
+ local phase_info=$(get_phase_info "$phase_source")
359
+ local elapsed=$(calc_elapsed "$started")
360
+ local modified=$(count_modified_files "$worktree")
361
+ local branch=$(jq -r '.branch // "N/A"' "$phase_source" 2>/dev/null)
362
+
363
+ # Get recent activity from log
364
+ local log_file="$worktree/.agent-log"
365
+ local last_tool=$(get_last_tool "$log_file")
366
+
367
+ echo -e "${GREEN}▶${NC} ${CYAN}${name}${NC} ${GREEN}[running]${NC}"
368
+ echo -e " Phase: ${phase_info}"
369
+ echo -e " Elapsed: ${elapsed}"
370
+ echo -e " Branch: ${DIM}${branch}${NC}"
371
+ echo -e " Modified: ${modified} file(s)"
372
+ if [ -n "$last_tool" ]; then
373
+ echo -e " Activity: ${YELLOW}${last_tool}${NC}"
374
+ fi
375
+ echo -e " PID: ${DIM}${pid}${NC}"
376
+ echo ""
377
+ elif [ -n "$agent_info" ] && [ "$agent_info" != "null" ]; then
378
+ # Stopped agent
379
+ echo -e "${RED}○${NC} ${name} ${RED}[stopped]${NC}"
380
+ echo -e " ${DIM}PID ${pid} is no longer running${NC}"
381
+ echo ""
382
+ else
383
+ # No agent, just show status
384
+ echo -e " ${color}●${NC} ${name} (${status})"
385
+ fi
220
386
  done
221
387
 
388
+ if [ "$has_running_agent" = true ]; then
389
+ echo -e "${DIM}─────────────────────────────────────${NC}"
390
+ echo -e "${DIM}Use --progress <name> for quick activity view${NC}"
391
+ echo -e "${DIM}Use --detail <name> for more info${NC}"
392
+ fi
393
+ echo ""
394
+ }
395
+
396
+ cmd_progress() {
397
+ if [ -z "$TARGET" ]; then
398
+ echo "Usage: $0 --progress <feature>"
399
+ exit 1
400
+ fi
401
+
402
+ local agent=$(find_agent "$TARGET")
403
+ if [ -z "$agent" ] || [ "$agent" = "null" ]; then
404
+ echo "Agent not found: $TARGET"
405
+ exit 1
406
+ fi
407
+
408
+ local id=$(echo "$agent" | jq -r '.id')
409
+ local pid=$(echo "$agent" | jq -r '.pid')
410
+ local worktree=$(echo "$agent" | jq -r '.worktree_path')
411
+ local feature_dir=$(echo "$agent" | jq -r '.feature_dir')
412
+ local started=$(echo "$agent" | jq -r '.started_at')
413
+ local log_file="$worktree/.agent-log"
414
+
415
+ if [ ! -f "$log_file" ]; then
416
+ echo "Log file not found: $log_file"
417
+ exit 1
418
+ fi
419
+
420
+ # Get phase info from worktree's feature.json
421
+ local worktree_feature_json="$worktree/$feature_dir/feature.json"
422
+ local phase_info="N/A"
423
+ local current_phase=0
424
+ if [ -f "$worktree_feature_json" ]; then
425
+ phase_info=$(get_phase_info "$worktree_feature_json")
426
+ current_phase=$(jq -r '.current_phase // 0' "$worktree_feature_json")
427
+ fi
428
+
429
+ local elapsed=$(calc_elapsed "$started")
430
+ local modified=$(count_modified_files "$worktree")
431
+
432
+ # Check if running
433
+ local status_str
434
+ if is_running "$pid"; then
435
+ status_str="${GREEN}running${NC}"
436
+ else
437
+ status_str="${RED}stopped${NC}"
438
+ fi
439
+
440
+ echo ""
441
+ echo -e "${BLUE}=== Progress: ${id} ===${NC}"
442
+ echo ""
443
+
444
+ # Basic info (like summary)
445
+ echo -e "${CYAN}Status:${NC}"
446
+ echo -e " State: ${status_str}"
447
+ echo -e " Phase: ${phase_info}"
448
+ echo -e " Elapsed: ${elapsed}"
449
+ echo -e " Modified: ${modified} file(s)"
450
+ echo ""
451
+
452
+ # Recent task notifications
453
+ echo -e "${CYAN}Recent Tasks:${NC}"
454
+ local has_tasks=false
455
+ while IFS='|' read -r status summary; do
456
+ [ -z "$status" ] && continue
457
+ has_tasks=true
458
+ local icon
459
+ case "$status" in
460
+ completed) icon="${GREEN}✓${NC}" ;;
461
+ failed) icon="${RED}✗${NC}" ;;
462
+ async_launched) icon="${BLUE}▶${NC}" ;;
463
+ *) icon="${YELLOW}○${NC}" ;;
464
+ esac
465
+ echo -e " ${icon} ${summary}"
466
+ done < <(get_recent_tasks "$log_file" 5 "$current_phase")
467
+
468
+ if [ "$has_tasks" = false ]; then
469
+ echo -e " ${DIM}(no task notifications yet)${NC}"
470
+ fi
471
+ echo ""
472
+
473
+ # Current activity
474
+ echo -e "${CYAN}Current Activity:${NC}"
475
+ local last_tool=$(get_last_tool "$log_file")
476
+ if [ -n "$last_tool" ]; then
477
+ echo -e " Tool: ${YELLOW}${last_tool}${NC}"
478
+ else
479
+ echo -e " ${DIM}(no recent tool calls)${NC}"
480
+ fi
481
+ echo ""
482
+
483
+ # Last message
484
+ echo -e "${CYAN}Last Message:${NC}"
485
+ local last_msg=$(get_last_message "$log_file" 200)
486
+ if [ -n "$last_msg" ]; then
487
+ echo -e " \"${last_msg}...\""
488
+ else
489
+ echo -e " ${DIM}(no recent messages)${NC}"
490
+ fi
222
491
  echo ""
223
492
  }
224
493
 
@@ -408,6 +677,9 @@ case "$ACTION" in
408
677
  summary)
409
678
  cmd_summary
410
679
  ;;
680
+ progress)
681
+ cmd_progress
682
+ ;;
411
683
  detail)
412
684
  cmd_detail
413
685
  ;;
@@ -0,0 +1,51 @@
1
+ # Database Guidelines
2
+
3
+ > Database patterns and conventions for this project.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ <!--
10
+ Document your project's database conventions here.
11
+
12
+ Questions to answer:
13
+ - What ORM/query library do you use?
14
+ - How are migrations managed?
15
+ - What are the naming conventions for tables/columns?
16
+ - How do you handle transactions?
17
+ -->
18
+
19
+ (To be filled by the team)
20
+
21
+ ---
22
+
23
+ ## Query Patterns
24
+
25
+ <!-- How should queries be written? Batch operations? -->
26
+
27
+ (To be filled by the team)
28
+
29
+ ---
30
+
31
+ ## Migrations
32
+
33
+ <!-- How to create and run migrations -->
34
+
35
+ (To be filled by the team)
36
+
37
+ ---
38
+
39
+ ## Naming Conventions
40
+
41
+ <!-- Table names, column names, index names -->
42
+
43
+ (To be filled by the team)
44
+
45
+ ---
46
+
47
+ ## Common Mistakes
48
+
49
+ <!-- Database-related mistakes your team has made -->
50
+
51
+ (To be filled by the team)